@@ -461,6 +461,42 @@ _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
481
+ # types 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 ' /[^/]$/d' \
489
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g'
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/[*@|=]$//g' \
495
+ -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $escape_replacement " ' /g' \
496
+ -e ' s/[^/]$/& /g'
497
+ fi
498
+ }
499
+
464
500
# Complete remote files with ssh. Returns paths escaped with three backslashes
465
501
# (unless -l option is provided).
466
502
# Options:
@@ -505,20 +541,9 @@ _comp_xfunc_scp_compgen_remote_files()
505
541
fi
506
542
507
543
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/[*@|=]$//g' \
519
- -e ' s/' " $_comp_cmd_scp__path_esc " ' /' " $_escape_replacement " ' /g' \
520
- -e ' s/[^/]$/& /g' )
521
- fi
544
+ _files=$( ssh -o ' Batchmode yes' " $_userhost " \
545
+ command ls -aF1dL " $_path *" 2> /dev/null |
546
+ _comp_cmd_scp__escape_path " $_dirs_only " " $_escape_replacement " )
522
547
_comp_compgen -R split -l -- " $_files "
523
548
}
524
549
@@ -543,20 +568,10 @@ _comp_xfunc_scp_compgen_local_files()
543
568
544
569
local files
545
570
_comp_expand_glob files ' "$cur"*' || return 0
546
- if [[ $_dirsonly ]]; then
547
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
548
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
549
- command sed -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
550
- -e ' /[^/]$/d'
551
- ) "
552
- else
553
- _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
554
- command ls -aF1dL " ${files[@]} " 2> /dev/null |
555
- command sed -e ' s/[*@|=]$//g' \
556
- -e " s/$_comp_cmd_scp__path_esc /\\\\ &/g" \
557
- -e ' s/[^/]$/& /g'
558
- ) "
559
- fi
571
+ _comp_compgen -RU files split -l ${1: +-P " $1 " } -- " $(
572
+ command ls -aF1dL " ${files[@]} " 2> /dev/null |
573
+ _comp_cmd_scp__escape_path " $_dirsonly "
574
+ ) "
560
575
}
561
576
562
577
# @deprecated 2.12
0 commit comments