在 zle 鍵綁定中使用 fzf
我有以下功能
.zshrc
function foo() { filename="$(fzf)" } zle -N foo bindkey '^X' foo
現在,如果我
foo
通過鍵入它來呼叫它,它會按預期工作,但是如果我通過鍵綁定呼叫它^X
,則fzf
緩衝區是空的。任何人都可以重現這個嗎?我怎樣才能解決這個問題?
如果要點是
fzf
在目前游標位置插入輸出,正確引用,它應該是這樣的:insert-quoted-fzf-output() { local output output=$(fzf</dev/tty) && LBUFFER+=${(q-)output} } zle -N insert-quoted-fzf-output bindkey '^X' insert-quoted-fzf-output
也就是說,您需要在
$LBUFFER
(游標左側的編輯緩衝區部分)的末尾插入該輸出,引用(這裡使用q-
參數擴展標誌以最小化引用量),並且您需要fzf
從終端。fzf
如果失敗,您可能希望小元件返回非零退出狀態。您在這里關於空
fzf
緩衝區的具體問題是關於缺少</dev/tty
重定向。如果將
fzf
其作為fzf < /dev/null
.如果你執行
info zsh widgets
(假設你有zsh
可用info
格式的文件;在某些系統上,你可能需要安裝一個zsh-doc
包),你會看到(強調我的):18.5 使用者定義的小元件
使用者定義的小元件,被實現為 shell 函式,可以執行任何普通的 shell 命令。
zle
他們還可以使用內置命令 執行其他小元件(無論是內置的還是使用者定義的) 。該函式的標準輸入從 /dev/null 重定向,以防止外部命令通過從終端讀取無意中阻塞 ZLE,但read -k
或read -q
可用於讀取字元。當它的標準輸入不是終端時,
fzf
讀取它以建構提供給使用者的選項列表。/dev/null
是一種特殊的設備,任何讀取任何內容的嘗試都會返回任何內容,這解釋了為什麼會得到一個空緩衝區。在那裡恢復終端使其切換回模式,在該模式下,它不是讀取 stdin 以獲取選項列表,而是讀取$FZF_DEFAULT_COMMAND
命令的輸出(預設為某些find
命令)。另一種選擇是自己實際執行該
find
命令。如果您使用的是 GNU 系統,您甚至可以對其進行改進以增加更多的可靠性和效率:output=$( LC_ALL=C find -L . -name . -o '(' \ -name '.*' -o \ -fstype sysfs -o \ -fstype devfs -o \ -fstype devtmpfs -o \ -fstype proc ')' -prune -o -type f -printf '%P\0' 2> /dev/null | fzf --read0 --print0 ) && output=${output%$'\0'}