-
Notifications
You must be signed in to change notification settings - Fork 2
/
tcsh-completion.bash
145 lines (129 loc) · 4.99 KB
/
tcsh-completion.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!bash
#
# Copyright (C) 2017 Marc Khouzam <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This script is to be called by the tcsh 'complete' command.
# It should be called by setting up a 'complete' command in the tcsh shell like this:
#
# complete <toolName> 'p,*,`bash tcsh_completion.bash <completionFunction> <completionScript> "${COMMAND_LINE}"`,'
# e.g.
# complete git 'p,*,`bash tcsh_completion.bash __git_wrap__git_main /usr/share/bash-completion/completions/git "${COMMAND_LINE}"`,'
root_path=$(cd `dirname $0` && pwd)
common_functions="${root_path}/common-functions.bash"
# Allow for debug printouts when running the script by hand
if [ "$1" == "-d" ] || [ "$1" == "--debug" ]; then
debug=true
shift
fi
skipCommon=$1
completionFunction=$2
completionScript=$3
commandToComplete=$4
if [ "${debug}" == "true" ]; then
echo =====================================
echo $0 called towards $completionFunction from $completionScript
echo with command to complete: $commandToComplete
fi
if [ ${skipCommon} != "-S" -a -e ${common_functions} ]; then
source ${common_functions}
fi
if [ -e ${completionScript} ]; then
source ${completionScript}
fi
# Set the bash completion variables
#
COMP_LINE=${commandToComplete}
#
# TODO: set the below in case the cursor is in the middle of the line
COMP_POINT=${#COMP_LINE}
#
# TODO: Set to an integer value corresponding to the type of completion
# attempted that caused a completion function to be called:
# 9 (TAB) for normal completion,
# 63 ('?') for listing completions after successive tabs,
# 33 ('!') for listing alternatives on partial word completion,
# 64 ('@') to list completions if the word is not unmodified,
# 37 ('%') for menu completion.
COMP_TYPE=9
#
# TODO: The key (or final key of a key sequence) used to invoke the current completion function.
# Could be 9 for TAB but could also be 27 for Esc or maybe something else I didn't think of.
COMP_KEY=9
#
# Remove the colon as a completion separator because tcsh cannot handle it
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
#
# Set COMP_WORDS in a way that can be handled by the bash script.
COMP_WORDS=(${commandToComplete})
# The cursor is at the end of parameter #1.
# We must check for a space as the last character which will
# tell us that the previous word is complete and the cursor
# is on the next word.
if [ "${commandToComplete: -1}" == " " ]; then
# The last character is a space, so our location is at the end
# of the command-line array
COMP_CWORD=${#COMP_WORDS[@]}
else
# The last character is not a space, so our location is on the
# last word of the command-line array, so we must decrement the
# count by 1
COMP_CWORD=$((${#COMP_WORDS[@]}-1))
fi
# Call the completion command in the real bash script
${completionFunction}
if [ "${debug}" == "true" ]; then
echo =====================================
echo $0 returned:
echo "${COMPREPLY[@]}"
fi
IFS=$'\n'
if [ ${#COMPREPLY[*]} -eq 0 ]; then
# No completions suggested. In this case, we want tcsh to perform
# standard file completion. However, there does not seem to be way
# to tell tcsh to do that. To help the user, we try to simulate
# file completion directly in this script.
#
# Known issues:
# - Possible completions are shown with their directory prefix.
# - Completions containing shell variables are not handled.
# - Completions with ~ as the first character are not handled.
# No file completion should be done unless we are completing beyond
# the first sub-command.
# WARNING: This seems like a good idea for the commands I have been
# using, however, I may have not noticed issues with other
# commands.
if [ ${COMP_CWORD} -gt 1 ]; then
TO_COMPLETE="${COMP_WORDS[${COMP_CWORD}]}"
# We don't support ~ expansion: too tricky.
if [ "${TO_COMPLETE:0:1}" != "~" ]; then
# Use ls so as to add the '/' at the end of directories.
COMPREPLY=(`ls -dp ${TO_COMPLETE}* 2> /dev/null`)
fi
fi
fi
if [ "${debug}" == "true" ]; then
echo =====================================
echo Completions including tcsh additions:
echo "${COMPREPLY[@]}"
echo =====================================
echo Final completions returned:
fi
# tcsh does not automatically remove duplicates, so we do it ourselves
echo "${COMPREPLY[*]}" | sort | uniq
# If there is a single completion and it is a directory, we output it
# a second time to trick tcsh into not adding a space after it.
if [ ${#COMPREPLY[*]} -eq 1 ] && [ "${COMPREPLY[0]: -1}" == "/" ]; then
echo "${COMPREPLY[*]}"
fi