@@ -461,6 +461,41 @@ _comp_cmd_sftp()
461
461
# things we want to backslash escape in scp paths
462
462
_comp_cmd_scp__path_esc=' [][(){}<>"' " '" ' ,:;^&!$=?`\\|[:space:]]'
463
463
464
+ # Escape shell special characters in filenames by backslash. This also
465
+ # suffixes a space or a slash based on the file type.
466
+ #
467
+ # Note: With a non-empty prefix ($1 of _comp_xfunc_scp_compgen_local_files),
468
+ # Bash will not recognize any filenames, so we need to perform the proper
469
+ # quoting manually. We also need to manually suffix a space or a slash based
470
+ # on the file type because "-o nospace" is specified. One might think of using
471
+ # "compopt +o nospace" instead, but it would suffix a space to directory names
472
+ # unexpectedly.
473
+ #
474
+ # @param $1 dirs_only - If a non-empty value is specified, only directory names
475
+ # are selected.
476
+ # @param $2 escape_replacement - If a non-empty value is specified, special
477
+ # characters are replaced with the specified value (instead of the default
478
+ # '\\&').
479
+ # @stdin - List of filenames in the "ls -1F" format, where filenames are
480
+ # separated by newlines, and characters /=@|* are suffixed based on the types
481
+ # of the files.
482
+ _comp_cmd_scp__escape_path ()
483
+ {
484
+ local dirs_only=$1 escape_replacement=${2:- ' \\&' }
485
+ if [[ $dirs_only ]]; then
486
+ # escape problematic characters; remove non-dirs
487
+ command sed \
488
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g' \
489
+ -e ' /[^/]$/d'
490
+ else
491
+ # escape problematic characters; remove executables, aliases, pipes
492
+ # and sockets; add space at end of file names
493
+ command sed \
494
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g' \
495
+ -e ' s/[*@]$//g' -e ' s/\\[|=]$//g' -e ' s/[^/]$/& /g'
496
+ fi
497
+ }
498
+
464
499
# Complete remote files with ssh. Returns paths escaped with three backslashes
465
500
# (unless -l option is provided).
466
501
# Options:
@@ -505,19 +540,9 @@ _comp_xfunc_scp_compgen_remote_files()
505
540
fi
506
541
507
542
local _files
508
- if [[ $_dirs_only ]]; then
509
- # escape problematic characters; remove non-dirs
510
- _files=$( ssh -o ' Batchmode yes' " $_userhost " \
511
- command ls -aF1dL " $_path *" 2> /dev/null |
512
- command sed -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $_escape_replacement " ' /g' -e ' /[^/]$/d' )
513
- else
514
- # escape problematic characters; remove executables, aliases, pipes
515
- # and sockets; add space at end of file names
516
- _files=$( ssh -o ' Batchmode yes' " $_userhost " \
517
- command ls -aF1dL " $_path *" 2> /dev/null |
518
- command sed -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $_escape_replacement " ' /g' \
519
- -e ' s/[*@]$//g' -e ' s/\\[|=]$//g' -e ' s/[^/]$/& /g' )
520
- fi
543
+ _files=$( ssh -o ' Batchmode yes' " $_userhost " \
544
+ command ls -aF1dL " $_path *" 2> /dev/null |
545
+ _comp_cmd_scp__escape_path " $_dirs_only " " $_escape_replacement " )
521
546
_comp_compgen -R split -l -- " $_files "
522
547
}
523
548
@@ -542,19 +567,10 @@ _comp_xfunc_scp_compgen_local_files()
542
567
543
568
local files
544
569
_comp_expand_glob files ' "$cur"*' || return 0
545
- if [[ $_dirsonly ]]; then
546
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
547
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
548
- command sed -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
549
- -e ' /[^/]$/d'
550
- ) "
551
- else
552
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
553
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
554
- command sed -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
555
- -e ' s/[*@]$//g' -e ' s/\\[|=]$//g' -e ' s/[^/]$/& /g'
556
- ) "
557
- fi
570
+ _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
571
+ command ls -aF1dL " ${files[@]} " 2> /dev/null |
572
+ _comp_cmd_scp__escape_path " $_dirsonly "
573
+ ) "
558
574
}
559
575
560
576
# @deprecated 2.12
0 commit comments