@matheusbsbs / matheus-bagliano / commits / dbda3b1090
Fork 0

bash: simple reimplementation of _get_comp_words_by_ref

Add a minimal implementation of _get_comp_words_by_ref so $ git show head:g <tab><tab> on bash 4 can complete paths within the head commit without requiring the bash_completion functions to be loaded. This is a follow-up to the previous patch (bash: get --pretty=m<tab> completion to work with bash v4). Based on bash-completion 2.x (commit bf763033, 2010-10-26) but tweaked for simplicity and to allow zsh to parse the code. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Improved-by: SZEDER Gábor <szeder@ira.uka.de>

Jonathan Nieder committed Dec 14, 2010 at 22:57 UTC dbda3b10902e13826862505900eb7a537505a492
1 file changed +110 -8
contrib/completion/git-completion.bash
+110 -8
@@ -321,26 +321,128 @@ __gitcomp_1 ()
321 done
322 }
323
324 +# The following function is based on code from:
325 +#
326 +# bash_completion - programmable completion functions for bash 3.2+
327 +#
328 +# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
329 +# © 2009-2010, Bash Completion Maintainers
330 +# <bash-completion-devel@lists.alioth.debian.org>
331 +#
332 +# This program is free software; you can redistribute it and/or modify
333 +# it under the terms of the GNU General Public License as published by
334 +# the Free Software Foundation; either version 2, or (at your option)
335 +# any later version.
336 +#
337 +# This program is distributed in the hope that it will be useful,
338 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
339 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
340 +# GNU General Public License for more details.
341 +#
342 +# You should have received a copy of the GNU General Public License
343 +# along with this program; if not, write to the Free Software Foundation,
344 +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
345 +#
346 +# The latest version of this software can be obtained here:
347 +#
348 +# http://bash-completion.alioth.debian.org/
349 +#
350 +# RELEASE: 2.x
351 +
352 +# This function can be used to access a tokenized list of words
353 +# on the command line:
354 +#
355 +# __git_reassemble_comp_words_by_ref '=:'
356 +# if test "${words_[cword_-1]}" = -w
357 +# then
358 +# ...
359 +# fi
360 +#
361 +# The argument should be a collection of characters from the list of
362 +# word completion separators (COMP_WORDBREAKS) to treat as ordinary
363 +# characters.
364 +#
365 +# This is roughly equivalent to going back in time and setting
366 +# COMP_WORDBREAKS to exclude those characters. The intent is to
367 +# make option types like --date=<type> and <rev>:<path> easy to
368 +# recognize by treating each shell word as a single token.
369 +#
370 +# It is best not to set COMP_WORDBREAKS directly because the value is
371 +# shared with other completion scripts. By the time the completion
372 +# function gets called, COMP_WORDS has already been populated so local
373 +# changes to COMP_WORDBREAKS have no effect.
374 +#
375 +# Output: words_, cword_, cur_.
376 +
377 +__git_reassemble_comp_words_by_ref()
378 +{
379 + local exclude i j first
380 + # Which word separators to exclude?
381 + exclude="${1//[^$COMP_WORDBREAKS]}"
382 + cword_=$COMP_CWORD
383 + if [ -z "$exclude" ]; then
384 + words_=("${COMP_WORDS[@]}")
385 + return
386 + fi
387 + # List of word completion separators has shrunk;
388 + # re-assemble words to complete.
389 + for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
390 + # Append each nonempty word consisting of just
391 + # word separator characters to the current word.
392 + first=t
393 + while
394 + [ $i -gt 0 ] &&
395 + [ -n "${COMP_WORDS[$i]}" ] &&
396 + # word consists of excluded word separators
397 + [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
398 + do
399 + # Attach to the previous token,
400 + # unless the previous token is the command name.
401 + if [ $j -ge 2 ] && [ -n "$first" ]; then
402 + ((j--))
403 + fi
404 + first=
405 + words_[$j]=${words_[j]}${COMP_WORDS[i]}
406 + if [ $i = $COMP_CWORD ]; then
407 + cword_=$j
408 + fi
409 + if (($i < ${#COMP_WORDS[@]} - 1)); then
410 + ((i++))
411 + else
412 + # Done.
413 + return
414 + fi
415 + done
416 + words_[$j]=${words_[j]}${COMP_WORDS[i]}
417 + if [ $i = $COMP_CWORD ]; then
418 + cword_=$j
419 + fi
420 + done
421 +}
422 +
423 if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
424 _get_comp_words_by_ref ()
425 {
426 + local exclude cur_ words_ cword_
427 + if [ "$1" = "-n" ]; then
428 + exclude=$2
429 + shift 2
430 + fi
431 + __git_reassemble_comp_words_by_ref "$exclude"
432 + cur_=${words_[cword_]}
433 while [ $# -gt 0 ]; do
434 case "$1" in
435 cur)
330 - cur=${COMP_WORDS[COMP_CWORD]}
436 + cur=$cur_
437 ;;
438 prev)
333 - prev=${COMP_WORDS[COMP_CWORD-1]}
439 + prev=${words_[$cword_-1]}
440 ;;
441 words)
336 - words=("${COMP_WORDS[@]}")
442 + words=("${words_[@]}")
443 ;;
444 cword)
339 - cword=$COMP_CWORD
340 - ;;
341 - -n)
342 - # assume COMP_WORDBREAKS is already set sanely
343 - shift
445 + cword=$cword_
446 ;;
447 esac
448 shift