如何使用 emacs 键绑定转置命令行参数?

如何使用 emacs 键绑定转置命令行参数?

使用 Bash 并设置 emacs 键绑定,转置单词键绑定 ( M-t) 不会转置参数,而是转置“单词”(根据其自己的单词定义)。

所以如果我有这个:

vimdiff project-number-One/Vagrantfile project-number-Two/Vagrantfile.old

当我输入时,我的光标位于第一个和第二个参数之间optiont,我最终得到的是

vimdiff project-number-One/project Vagrantfile-number-Two/Vagrantfile.old

这显然不是我想要的。我怎样才能转置参数?

答案1

在 bash 中,不同的命令有不同的单词概念。C-w杀死前面的空格,但大多数其他命令包括M-t使用标点符号分隔的单词。

将光标放在第一个参数和第二个参数之间时,C-w C-e SPC C-y将调换两个单词的位置。

如果你想绑定一个键来调换空格分隔的单词,那就更复杂了。看bash 中 emacs 风格的键绑定的令人困惑的行为。这是一些经过最低限度测试的代码。

transpose_whitespace_words () {
  local prefix=${READLINE_LINE:0:$READLINE_POINT} suffix=${READLINE_LINE:$READLINE_POINT}
  if [[ $suffix =~ ^[^[:space:]] ]] && [[ $prefix =~ [^[:space:]]+$ ]]; then
    prefix=${prefix%${BASH_REMATCH[0]}}
    suffix=${BASH_REMATCH[0]}${suffix}
  fi
  if [[ $suffix =~ ^[[:space:]]+ ]]; then
    prefix=${prefix}${BASH_REMATCH[0]}
    suffix=${suffix#${BASH_REMATCH[0]}}
  fi
  if [[ $prefix =~ ([^[:space:]]+)([[:space:]]+)$ ]]; then
    local word1=${BASH_REMATCH[1]} space=${BASH_REMATCH[2]}
    prefix=${prefix%${BASH_REMATCH[0]}}
    if [[ $suffix =~ [^[:space:]]+ ]]; then
      suffix=${suffix#${BASH_REMATCH[0]}}
      READLINE_LINE=${prefix}${BASH_REMATCH[0]}$space$word1$suffix
      READLINE_POINT=$((${#READLINE_LINE} - ${#suffix}))
    fi
  fi
}
bind -x '"\e\C-t": transpose_whitespace_words'

这在 zsh 中更容易......

答案2

如果您的光标在那里:

vimdiff projectOne/Vagrantfile projectTwo/Vagrantfile
                              ^

按 Alt + BTTBBTFTBBTT


或者简单:

Ctrl+ WCtrl+ E,插入空格,然后按Ctrl+Y

答案3

为了快速简单的解决方案,将其添加到您的 inputrc (为自己选择合适的键):

"\e\C-b": shell-backward-kill-word
"\eh": shell-backward-word
"\e\C-f": shell-forward-word
# Swap the preceding two arguments (control + alt + t)
"\e\C-t": "\e\C-b\eh\C-y"
# Swap the preceding argument with the next (control + alt + p)
"\e\C-p": "\e\C-b\e\C-f\C-y"

如果有shell-*这些函数的版本单词由非引用的 shell 元字符分隔

元字符

当不加引号时,用于分隔单词的字符。元字符是空格、制表符、换行符或以下字符之一:“|”、“&”、“;”、“(”、“)”、“<”或“>”。

Ctrl注意:在按+ Alt+之前,光标必须位于第二个参数之后t,因此它可以有效地将光标之前的参数推向行首。

$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
                                                             ^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
                                     ^
$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
                         ^

Ctrl注意:在按+ Alt+之前,光标必须位于第一个参数之后p,因此它可以有效地将光标之前的参数拉向行尾。

$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
                         ^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
                                     ^
$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
                                                             ^

答案4

您需要按BTTBBT而不是单个T

相关内容