Bash

撤消標籤擴展?

  • November 12, 2015

在 bash 中,按下Tab會呼叫可程式完成功能,並且 (a) 擴展為與鍵入的內容匹配的唯一路徑或命令,或者 (b) 可能選項的列表。

是否可以撤消按 進行的整個擴展Tab

例子:

  1. 我目前的命令是ls application/views/.
  2. 該命令有兩種可能的擴展:helpers/scripts/.
  3. 我鍵入h``e``Tab,擴展為helpers/
  4. 我意識到我的意思是另一個 scripts
  5. 現在我必須刪除整個擴展“helpers/”。

我通常只是在整個路徑上退格(helpers/在這種情況下),因為我發現引人注目的 readline undo Control+_乏味。我想要的是一個刪除擴展的完整匹配的單個鍵序列,不管我最初輸入的任何字元以及末尾添加的任何空格或斜杠。


由註釋或我自己閱讀的GNU 參考建議的鍵序列的執行列表。這些都沒有實現目標

  • Meta+ b– 回到前一個/, but doesn't delete. * Meta+Del` – Deletes one character, not the entire word.

  • Meta+Backspace – Moves back one character without deleting.

  • Control+W – Deletes the entire path, not just the expansion. So in my example, after pressing Tab, bash expands that to ls application/views/helpers, then when I press Control+W, bash deletes application/views/helpers. If relevant, I’m using the vi editing mode on a Gentoo Linux box. I’ve checked my configuration and I’ve not remapped any characters.`

You're giving the keystrokes, but not the *readline bindings*, this can explain differences in observed behaviour (try bind -p`).

The only way I can think of to do exactly what you ask is to use a custom completion function that saves the buffer state, and a separate key binding which invokes a companion shell function to restore it.

In addition to @Mark Plotnick’s excellent suggestion to use menu-complete, other readline/bash options are:

  • shell-backward-kill-word this removes a “shell word” which in the case of an expanded file or path will be the complete file or path name
  • backward-kill-word this removes a “readline word”, which in the case of a file or path will be a file or directory name component, including the trailing /
  • undo which undoes each change atomically, but this almost certainly requires several attempts to fully remove a complete expansion, this is almost certainly the function you have bound to to ctrl-_ (bash default)
  • set-mark and kill-region are lesser used readline features, set-mark marks the current cursor position, and kill-region deletes from the mark to the cursor. This requires you to invoke set-mark (default meta-space) in advance so that you can later use kill-region to delete back to it (no default binding)
  • possible-completions (bound to meta-=) which lists the completions without modifying the command buffer

You could also write your own function to modify the input buffer, and bind it to a function (here’s one I made earlier) but I don’t see how that would be very much better than backward-kill-word in this case.

You can test bindings on the fly without using .inputrc using bash’s bind command, e.g.:

bind "\C-o: backward-kill-word"
bind "\C-o: shell-backward-kill-word"

backward-kill-word is the best fit, default binding is meta``ctrl-h. set-mark/kill-region would be better, but I can’t think of a neat way to automate the use of this though.`

引用自:https://unix.stackexchange.com/questions/242368