@@ -457,6 +457,54 @@ _comp_cmd_sftp()
457
457
# things we want to backslash escape in scp paths
458
458
_comp_cmd_scp__path_esc=' [][(){}<>"' " '" ' ,:;^&!$=?`\\|[:space:]]'
459
459
460
+ # Escape shell special characters in filenames by backslash. This also
461
+ # suffixes a space or a slash based on the file type.
462
+ #
463
+ # Note: With a non-empty prefix ($1 of _comp_xfunc_scp_compgen_local_files),
464
+ # Bash will not recognize any filenames, so we need to perform the proper
465
+ # quoting manually. We also need to manually suffix a space or a slash based
466
+ # on the file type because "-o nospace" is specified. One might think of using
467
+ # "compopt +o nospace" instead, but it would suffix a space to directory names
468
+ # unexpectedly.
469
+ #
470
+ # Options:
471
+ # -d Only directory names are selected.
472
+ # @param $1 escape_replacement - If a non-empty value is specified, special
473
+ # characters are replaced with the specified value (instead of the default
474
+ # '\\&').
475
+ # @stdin List of filenames in the "ls -1F" format, where filenames are
476
+ # separated by newlines, and characters /*@|=> are suffixed based on the
477
+ # types of the files.
478
+ _comp_cmd_scp__escape_path ()
479
+ {
480
+ local OPTIND=1 OPTARG=" " OPTERR=0 opt dirs_only=" "
481
+ while getopts ' :d' _flag " $@ " ; do
482
+ case $_flag in
483
+ d) dirs_only=set ;;
484
+ * )
485
+ echo " bash_completion: $FUNCNAME : usage error: $* " >&2
486
+ return 1
487
+ ;;
488
+ esac
489
+ done
490
+ shift " $(( OPTIND - 1 )) "
491
+ local escape_replacement=${1:- ' \\&' }
492
+
493
+ if [[ $dirs_only ]]; then
494
+ # escape problematic characters; remove non-dirs
495
+ command sed \
496
+ -e ' /[^/]$/d' \
497
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g'
498
+ else
499
+ # escape problematic characters; remove executable, symlink, pipe,
500
+ # socket and door indicators; add space at end of file names
501
+ command sed \
502
+ -e ' s/[*@|=>]$//g' \
503
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g' \
504
+ -e ' s/[^/]$/& /g'
505
+ fi
506
+ }
507
+
460
508
# Complete remote files with ssh. Returns paths escaped with three backslashes
461
509
# (unless -l option is provided).
462
510
# Options:
@@ -501,20 +549,10 @@ _comp_xfunc_scp_compgen_remote_files()
501
549
fi
502
550
503
551
local _files
504
- if [[ $_dirs_only ]]; then
505
- # escape problematic characters; remove non-dirs
506
- _files=$( ssh -o ' Batchmode yes' " $_userhost " \
507
- command ls -aF1dL " $_path *" 2> /dev/null |
508
- command sed -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $_escape_replacement " ' /g' -e ' /[^/]$/d' )
509
- else
510
- # escape problematic characters; remove executables, aliases, pipes
511
- # and sockets; add space at end of file names
512
- _files=$( ssh -o ' Batchmode yes' " $_userhost " \
513
- command ls -aF1dL " $_path *" 2> /dev/null |
514
- command sed -e ' s/[*@|=]$//g' \
515
- -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $_escape_replacement " ' /g' \
516
- -e ' s/[^/]$/& /g' )
517
- fi
552
+ _files=$( ssh -o ' Batchmode yes' " $_userhost " \
553
+ command ls -aF1dL " $_path *" 2> /dev/null |
554
+ _comp_cmd_scp__escape_path ${_dirs_only: +' -d' } -- \
555
+ " $_escape_replacement " )
518
556
_comp_compgen -R split -l -- " $_files "
519
557
}
520
558
@@ -539,20 +577,10 @@ _comp_xfunc_scp_compgen_local_files()
539
577
540
578
local files
541
579
_comp_expand_glob files ' "$cur"*' || return 0
542
- if [[ $_dirs_only ]]; then
543
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
544
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
545
- command sed -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
546
- -e ' /[^/]$/d'
547
- ) "
548
- else
549
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
550
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
551
- command sed -e ' s/[*@|=]$//g' \
552
- -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
553
- -e ' s/[^/]$/& /g'
554
- ) "
555
- fi
580
+ _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
581
+ command ls -aF1dL " ${files[@]} " 2> /dev/null |
582
+ _comp_cmd_scp__escape_path ${_dirs_only: +' -d' }
583
+ ) "
556
584
}
557
585
558
586
# @deprecated 2.12
0 commit comments