Add file completion to tcsh git completion.

For bash completion, the option '-o bashdefault' is used to indicate that when no other choices are available, file completion should be performed. Since this option is not available in tcsh, no file completion is ever performed. Therefore, commands like 'git add ', 'git send-email ', etc, require the user to manually type out the file name. This can be quite annoying. To improve the user experience we try to simulate file completion directly in this script (although not perfectly). The known issues with the file completion simulation are: - Possible completions are shown with their directory prefix. - Completions containing shell variables are not handled. - Completions with ~ as the first character are not handled. Signed-off-by: Marc Khouzam <marc.khouzam@ericsson.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Marc Khouzam committed Dec 11, 2012 at 21:36 UTC 75ed918bda00a0786bab7de3d220765226fe3f1e
1 file changed +54 -15
contrib/completion/git-completion.tcsh
+54 -15
@@ -19,23 +19,26 @@
19 # (e.g. ~/.git-completion.tcsh and ~/.git-completion.bash).
20 # 2) Add the following line to your .tcshrc/.cshrc:
21 # source ~/.git-completion.tcsh
22 +# 3) For completion similar to bash, it is recommended to also
23 +# add the following line to your .tcshrc/.cshrc:
24 +# set autolist=ambiguous
25 +# It will tell tcsh to list the possible completion choices.
26
27 set __git_tcsh_completion_original_script = ${HOME}/.git-completion.bash
28 set __git_tcsh_completion_script = ${HOME}/.git-completion.tcsh.bash
29
30 # Check that the user put the script in the right place
31 if ( ! -e ${__git_tcsh_completion_original_script} ) then
28 - echo "git-completion.tcsh: Cannot find: ${__git_tcsh_completion_original_script}. Git completion will not work."
29 - exit
32 + echo "git-completion.tcsh: Cannot find: ${__git_tcsh_completion_original_script}. Git completion will not work."
33 + exit
34 endif
35
36 cat << EOF > ${__git_tcsh_completion_script}
37 #!bash
38 #
39 # This script is GENERATED and will be overwritten automatically.
36 -# Do not modify it directly. Instead, modify the git-completion.tcsh
37 -# script provided by Git core.
38 -#
40 +# Do not modify it directly. Instead, modify git-completion.tcsh
41 +# and source it again.
42
43 source ${__git_tcsh_completion_original_script}
44
@@ -47,22 +50,58 @@ COMP_WORDS=(\$2)
50 # tell us that the previous word is complete and the cursor
51 # is on the next word.
52 if [ "\${2: -1}" == " " ]; then
50 - # The last character is a space, so our location is at the end
51 - # of the command-line array
52 - COMP_CWORD=\${#COMP_WORDS[@]}
53 + # The last character is a space, so our location is at the end
54 + # of the command-line array
55 + COMP_CWORD=\${#COMP_WORDS[@]}
56 else
54 - # The last character is not a space, so our location is on the
55 - # last word of the command-line array, so we must decrement the
56 - # count by 1
57 - COMP_CWORD=\$((\${#COMP_WORDS[@]}-1))
57 + # The last character is not a space, so our location is on the
58 + # last word of the command-line array, so we must decrement the
59 + # count by 1
60 + COMP_CWORD=\$((\${#COMP_WORDS[@]}-1))
61 fi
62
63 # Call _git() or _gitk() of the bash script, based on the first argument
64 _\${1}
65
66 IFS=\$'\n'
64 -echo "\${COMPREPLY[*]}" | sort | uniq
67 +if [ \${#COMPREPLY[*]} -gt 0 ]; then
68 + echo "\${COMPREPLY[*]}" | sort | uniq
69 +else
70 + # No completions suggested. In this case, we want tcsh to perform
71 + # standard file completion. However, there does not seem to be way
72 + # to tell tcsh to do that. To help the user, we try to simulate
73 + # file completion directly in this script.
74 + #
75 + # Known issues:
76 + # - Possible completions are shown with their directory prefix.
77 + # - Completions containing shell variables are not handled.
78 + # - Completions with ~ as the first character are not handled.
79 +
80 + # No file completion should be done unless we are completing beyond
81 + # the git sub-command. An improvement on the bash completion :)
82 + if [ \${COMP_CWORD} -gt 1 ]; then
83 + TO_COMPLETE="\${COMP_WORDS[\${COMP_CWORD}]}"
84 +
85 + # We don't support ~ expansion: too tricky.
86 + if [ "\${TO_COMPLETE:0:1}" != "~" ]; then
87 + # Use ls so as to add the '/' at the end of directories.
88 + RESULT=(\`ls -dp \${TO_COMPLETE}* 2> /dev/null\`)
89 + echo \${RESULT[*]}
90 +
91 + # If there is a single completion and it is a directory,
92 + # we output it a second time to trick tcsh into not adding a space
93 + # after it.
94 + if [ \${#RESULT[*]} -eq 1 ] && [ "\${RESULT[0]: -1}" == "/" ]; then
95 + echo \${RESULT[*]}
96 + fi
97 + fi
98 + fi
99 +fi
100 +
101 EOF
102
67 -complete git 'p/*/`bash ${__git_tcsh_completion_script} git "${COMMAND_LINE}"`/'
68 -complete gitk 'p/*/`bash ${__git_tcsh_completion_script} gitk "${COMMAND_LINE}"`/'
103 +# Don't need this variable anymore, so don't pollute the users environment
104 +unset __git_tcsh_completion_original_script
105 +
106 +complete git 'p,*,`bash ${__git_tcsh_completion_script} git "${COMMAND_LINE}"`,'
107 +complete gitk 'p,*,`bash ${__git_tcsh_completion_script} gitk "${COMMAND_LINE}"`,'