Bash

如何配置 vi-mode bash 用於 yank 和 paste 的緩衝區?

  • June 30, 2020

tldr: 有誰知道如何配置 vi-mode bash 使用什麼緩衝區來拉取(複製)和粘貼?

長版:set editing-mode vi在我的.inputrc, 中使用該readline庫的程序,即 bash,使用類似 vi 的鍵綁定。與此無關,我設置了 vim 和 tmux 以使用系統剪貼板進行拉拽和粘貼。我想對 bash 做同樣的事情。這似乎沒有必要,因為我將主要通過 tmux 使用 bash,但即便如此,能夠使用p(在正常模式下)從剪貼板複製而不是C-a P,或者類似的東西(帶有 tmux 前綴)也會很好。但是,我找不到有關如何配置 bash 的這一方面的任何資訊,甚至找不到 bash 預設使用什麼緩衝區進行 yank 和 paste 的資訊。我:registers在vim中執行時看不到它,所以它似乎不是vim看到的任何寄存器。

在做了一些研究之後,似乎 bash 為此使用了一個內部變數,而不是任何現成的系統緩衝區。它在 bash 和 readline 的手冊條目中被稱為“kill ring”,其實現可以在 GitHub和其他地方閱讀。有可能劫持這個機制來使用系統剪貼板,但這似乎有點太複雜了,我目前無法解決。

我改為使用下面的簡單解決方法,使用 bash 內置bind命令,記錄在 bash 的手冊頁中(搜尋bind \[)。它很好地涵蓋了我的案例,但它沒有涵蓋更高級的殺戮和 vim 動作。如果您發現我的解決方案有什麼不好的地方,請告訴我,因為我沒有編寫 bash 腳本的習慣。

在 ~/.bashrc 中:

# Macros to enable yanking, killing and putting to and from the system clipboard in vi-mode. Only supports yanking and killing the whole line.
paste_from_clipboard () {
 local shift=$1

 local head=${READLINE_LINE:0:READLINE_POINT+shift}
 local tail=${READLINE_LINE:READLINE_POINT+shift}

 local paste=$(xclip -out -selection clipboard)
 local paste_len=${#paste}

 READLINE_LINE=${head}${paste}${tail}
 # Place caret before last char of paste (as in vi)
 let READLINE_POINT+=$paste_len+$shift-1
}

yank_line_to_clipboard () {
 echo $READLINE_LINE | xclip -in -selection clipboard
}

kill_line_to_clipboard () {
 yank_line_to_clipboard
 READLINE_LINE=""
}

bind -m vi-command -x '"P": paste_from_clipboard 0'
bind -m vi-command -x '"p": paste_from_clipboard 1'
bind -m vi-command -x '"yy": yank_line_to_clipboard'
bind -m vi-command -x '"dd": kill_line_to_clipboard'

Edit1: 使用兩個連續按鍵的綁定“yy”和“dd”受keyseq-timeoutreadline 設置的影響。預設值為 500 毫秒,這意味著您必須在第一個字元的 500 毫秒內鍵入第二個字元。因此,如果您設置keyseq-timeout了一個低得多的值,您可能會遇到一些麻煩。

Edit2: 更新粘貼以更精確地模擬 vim 行為。

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