删除最后一个字 (Ctrl-W):使 bash shell 表现得像 vim 命令行

let*_*tar 7 keyboard-shortcuts bash vim command-line

在 bash shell 中可用的许多有用的键盘快捷键中,有Ctrl-W删除光标左侧的单词。假设我的命令行如下所示:

cp some-file /foo/bar/baz/copy
Run Code Online (Sandbox Code Playgroud)

现在我希望能够按下Ctrl-W并最终得到以下结果:

cp some-file /foo/bar/baz/
Run Code Online (Sandbox Code Playgroud)

在 Vim 的命令行中,它实际上是这样工作的:只有字母数字字符被视为“单词”,而特殊字符(如/)用作标记新“单词”开始的分隔符。

但不幸的是,它在我迄今为止使用的所有 shell 中都不是这样工作的。只有空格才能分隔“单词”,因此使用上面显示的命令行按下快捷方式会给我:

cp some-file
Run Code Online (Sandbox Code Playgroud)

有没有办法让 Bash 表现得像 Vim?我可以将一些配置放入我的.bashrc?

ter*_*don 11

这与 Vim 无关,所有编辑器都这样(包括 emacs),他们将非单词字符视为分隔符。无论如何,您所谈论的行为readline由其控制,其手册列出了许多您可以为其分配快捷方式的命令。我在这里粘贴了一些相关的内容,但我建议您阅读man readline以获取更多信息:

   backward-word (M-b)
          Move  back  to  the  start  of the current or previous word.  Words 
          are composed of alphanumeric characters (letters and digits).

   kill-line (C-k)
          Kill the text from point to the end of the line.
   kill-word (M-d)
          Kill from point the end of  the  current  word,  or  if  between
          words,  to  the  end  of the next word.  Word boundaries are the
          same as those used by forward-word.
   backward-kill-word (M-Rubout)
          Kill the word behind point.  Word boundaries  are  the  same  as
          those used by backward-word.
   unix-word-rubout (C-w)
          Kill  the  word behind point, using white space as a word bound?
          ary.  The killed text is saved on the kill-ring.
   unix-filename-rubout
          Kill the word behind point, using  white  space  and  the  slash
          character  as  the word boundaries.  The killed text is saved on
          the kill-ring.
Run Code Online (Sandbox Code Playgroud)

所以,你想要的是backward-kill-word,它使用非字母数字字符作为单词边界。默认情况下,它被分配给Alt+Backspace/etc/inputrc如果您希望它们应用于所有用户或(更好)您自己的本地$HOME/.inputrc.

据我所知,Ctrl+W似乎是保留的,你不能使用那个,但你可以选择另一个快捷方式,例如Ctrl+ J$HOME/.inputrc如果文件不存在,则创建一个文件并将此行添加到其中:

Control-J: backward-kill-word 
Run Code Online (Sandbox Code Playgroud)

对于大多数现代终端模拟器来说,这应该足够了。但是,一些较旧的终端使用不同的代码。xterm例如,如果您使用的是 ,则上面的行应写为:

C-J: backward-kill-word 
Run Code Online (Sandbox Code Playgroud)

  • `\Cw` 不是保留的。只需运行 `bind 'set bind-tty-special-chars off'` 关闭 `bind-tty-special-chars` 设置,该设置会导致 readline 重新读取并重新绑定终端的特殊字符(在这种情况下`werase` 字符)每次输入新行时。 (5认同)

rom*_*inl 5

您可以通过将以下几行放入~/.inputrc并启动一个新的 shell来启用 readline(以及 bash 的)所谓的“vi 模式” :

set editing-mode vi
set keymap vi-command
Run Code Online (Sandbox Code Playgroud)

但是您会注意到它的<C-w>工作方式与默认的 Emacs 模式相同:单词以空格分隔。不过,您可以执行dT/或类似的命令。这仍然是一种模拟,而不是真正的交易。readline 的手册中列出了可用的映射:

$ man readline
/VI
Run Code Online (Sandbox Code Playgroud)

另请参阅Vim wiki 上的此页面

但是我认为 readline 的 vi 模式没有那么有用,如果您经常发现自己需要认真编辑命令行……为什么不真正使用 Vim呢?

<C-x><C-e>
Run Code Online (Sandbox Code Playgroud)