一個更好、更友善的 ZSH vi(vim) 模式插件。
ZSH
插件。 也許你體驗過 Zsh 中的預設 Vi 模式,開啟預設 Vi 模式後,你逐漸發現它有很多問題,有些功能不完善或不存在,有些行為甚至與原生 Vi 不同(Vim ) 模式。
雖然預設的 Vi 模式有點尷尬和不愉快,但你還是繼續使用它,並在使用了一段時間後逐漸失去了興趣。最終,你失望地放棄了。
你已經很久沒有想到Vi模式了,有一天你無意中發現了這個插件,你讀到這裡才意識到這個插件就是為了解決上述問題,讓你重新愛上Vi模式。臉上突然浮現出笑容,就像重獲美好生活一樣。
冬天來了,春天還會遠嗎?
10p
和4fa
(進行中)。ZSH:>= 5.1.0
在.zshrc
中捆綁zsh-vi-mode
antigen bundle jeffreytse/zsh-vi-mode
將zsh-vi-mode
作為外掛程式載入到.zshrc
中
zplug " jeffreytse/zsh-vi-mode "
在.zshrc
中包含載入命令
zgen load jeffreytse/zsh-vi-mode
在.zshrc
中包含載入命令
zinit ice depth=1
zinit light jeffreytse/zsh-vi-mode
注意: depth=1
冰的使用是可選的,此外掛程式既不建議也不官方支援其他類型的冰。
將zsh-vi-mode
克隆到您的自訂外掛程式儲存庫中
git clone https://github.com/jeffreytse/zsh-vi-mode
$ZSH_CUSTOM /plugins/zsh-vi-mode
然後作為插件載入到.zshrc
中
plugins+=(zsh-vi-mode)
請記住,需要在獲取oh-my-zsh.sh
之前添加插件。
將zsh-vi-mode
新增至您的外掛程式檔案(例如~/.zsh_plugins.txt
)
jeffreytse/zsh-vi-mode
將zsh-vi-mode
作為外掛程式載入到.zshrc
中
plug " jeffreytse/zsh-vi-mode "
將zsh-vi-mode
作為插件載入到.zimrc
中
zmodule jeffreytse/zsh-vi-mode
對於Homebrew用戶,可以透過以下指令安裝
brew install zsh-vi-mode
然後將其來源到您的.zshrc
(或.bashrc
)
source $( brew --prefix ) /opt/zsh-vi-mode/share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
對於Arch Linux用戶,可以透過以下命令安裝
yay -S zsh-vi-mode
或最新更新(不穩定)
yay -S zsh-vi-mode-git
然後將其來源到您的.zshrc
(或.bashrc
)
source /usr/share/zsh/plugins/zsh-vi-mode/zsh-vi-mode.plugin.zsh
對於 Nix 用戶,從 e7e3480530b34a9fe8cb52963ec2cf66e6707e15 開始,您可以透過以下配置取得插件
programs = {
zsh = {
interactiveShellInit = ''
source ${ pkgs . zsh-vi-mode } /share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
'' ;
} ;
} ;
或者如果您更喜歡home-manager
:
home-manager . users . [ your username ] = { pkgs , ... } : {
programs = {
zsh = {
initExtra = ''
source ${ pkgs . zsh-vi-mode } /share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
'' ;
} ;
} ;
} ;
您也可以使用home-manager
的內建「外掛」功能:
home-manager . users . [ your username ] = { pkgs , ... } : {
programs = {
zsh = {
plugins = [
{
name = "vi-mode" ;
src = pkgs . zsh-vi-mode ;
file = "share/zsh-vi-mode/zsh-vi-mode.plugin.zsh" ;
}
] ;
} ;
} ;
} ;
Fig 將應用程式、捷徑和自動完成功能新增至您現有的終端。
只需一鍵安裝zsh-vi-mode
。
可用於 dm9pZCAq 覆蓋層
eselect repository enable dm9pZCAq
emerge --sync dm9pZCAq
emerge app-shells/zsh-vi-mode
然後將其來源到您的.zshrc
(或.bashrc
)
source /usr/share/zsh/site-contrib/zsh-vi-mode/zsh-vi-mode.plugin.zsh
將此儲存庫克隆到某處(例如$HOME/.zsh-vi-mode
)
git clone https://github.com/jeffreytse/zsh-vi-mode.git $HOME /.zsh-vi-mode
然後將其來源到您的.zshrc
(或.bashrc
)
source $HOME /.zsh-vi-mode/zsh-vi-mode.plugin.zsh
使用ESC
或CTRL-[
進入Normal mode
。
但有些人可能喜歡自訂轉義鍵,例如jj
、 jk
等,如果您想自訂轉義鍵,可以從這裡了解更多。
ctrl-p
: 歷史記錄中的上一個指令ctrl-n
:歷史記錄中的下一個命令/
: 在歷史記錄中向後搜尋n
: 重複最後一個/
Normal mode
預設使用塊狀遊標指示, Insert mode
預設使用梁狀遊標指示。
在Normal mode
下,您可以使用vv
在編輯器(例如vi
/ vim
/ nvim
...)中編輯目前命令列,因為它與Visual mode
綁定。
您可以透過ZVM_VI_EDITOR
選項變更編輯器,預設為$EDITOR
。
$
:到行尾^
:到該行的第一個非空白字符0
:到該行的第一個字符w
: [計數] 字數W
: 向前 [count] 個字e
:轉寄到字尾 [count](含)E
: 轉送到 WORD 末尾 [count](含)b
: 向後 [count] 個字B
: 向後 [count] 個字t{char}
:直到右側第 [count] 次出現 {char} 之前T{char}
:直到左側第 [count] 次出現 {char} 之前f{char}
:到右側第 [count] 次出現的 {char}F{char}
:到左側第 [count] 次出現的 {char};
:重複最近的 f、t、F 或 T [count] 次,
: 以相反方向重複最新的 f、t、F 或 T i
: 在遊標前插入文本I
:在該行的第一個字元之前插入文本a
: 在遊標後加入文本A
: 在行尾加入文本o
:在目前命令列下方插入新命令列O
:在目前命令列上方插入新命令列環繞聲操作有兩種鍵綁定模式,預設為classic
模式,您可以透過設定ZVM_VI_SURROUND_BINDKEY
選項來選擇模式。
classic
模式(動詞->s->環繞)S"
: 添加"
用於視覺選擇ys"
: 添加"
進行視覺選擇cs"'
: 將"
更改為'
ds"
: 刪除"
s-prefix
模式(s->動詞->環繞)sa"
: 新增"
進行視覺選擇sd"
:刪除"
sr"'
: 將"
更改為'
請注意,必須以相當快的速度連續按下按鍵序列以避免逾時。您可以使用ZVM_KEYTIMEOUT
選項延長此逾時。
vi"
: 選擇引號內的文字對象va(
: 選取包含括號的文字對象然後您可以對選擇進行任何操作:
vi"
-> S[
或sa[
=> "object"
-> "[object]"
va"
-> S[
或sa[
=> "object"
-> ["object"]
di(
或vi(
-> d
ca(
或va(
-> c
yi(
或vi(
-> y
在正常模式下,輸入ctrl-a
將增加到下一個關鍵字,輸入ctrl-x
將減少到下一個關鍵字。關鍵字可以位於遊標處,也可以位於遊標右側(同一行)。關鍵字可以如下:
例如:
9
=> 10
aa99bb
=> aa100bb
aa100bc
=> aa101bc
0xDe
=> 0xdf
0Xdf
=> 0Xe0
0b101
=> 0b110
0B11
=> 0B101
true
=> false
yes
=> no
on
=> off
T
=> F
Fri
=> Sat
Oct
=> Nov
Monday
=> Tuesday
January
=> February
+
=> -
++
=> --
==
=> !=
!==
=> ===
&&
=> ||
and
=> or
100
=> 99
aa100bb
=> aa99bb
0
=> -1
0xdE0
=> 0xDDF
0xffFf0
=> 0xfffef
0xfffF0
=> 0xFFFEF
0x0
=> 0xffffffffffffffff
0Xf
=> 0Xe
0b100
=> 0b010
0B100
=> 0B011
True
=> False
On
=> Off
Sun
=> Sat
Jan
=> Dec
Monday
=> Sunday
August
=> July
/
=> *
++
=> --
==
=> !=
!==
=> ===
||
=> &&
or
=> and
您可以使用以下選項來自訂更符合您口味的轉義鍵,例如jj
或jk
等。
ZVM_VI_ESCAPE_BINDKEY
:所有模式下的 vi 轉義鍵(預設為^[
=> ESC
)ZVM_VI_INSERT_ESCAPE_BINDKEY
:插入模式下的 vi 轉義鍵(預設為$ZVM_VI_ESCAPE_BINDKEY
)ZVM_VI_VISUAL_ESCAPE_BINDKEY
:可視模式下的 vi 轉義鍵(預設為$ZVM_VI_ESCAPE_BINDKEY
)ZVM_VI_OPPEND_ESCAPE_BINDKEY
:操作員掛起模式下的 vi 轉義鍵(預設為$ZVM_VI_ESCAPE_BINDKEY
)例如:
# Only changing the escape key to `jk` in insert mode, we still
# keep using the default keybindings `^[` in other modes
ZVM_VI_INSERT_ESCAPE_BINDKEY=jk
此插件支援選擇readkey引擎來讀取和處理按鍵事件。透過ZVM_READKEY_ENGINE
選項很容易做到,目前支援以下引擎:
ZVM_READKEY_ENGINE_NEX
:它是更好的 readkey 引擎,可以取代 ZLE(Beta)。ZVM_READKEY_ENGINE_ZLE
:它是 Zsh 的預設 readkey 引擎(ZLE)。ZVM_READKEY_ENGINE_DEFAULT
:它是這個插件的預設引擎(現在是NEX引擎)。NEX 是比 Zsh 的 ZLE 引擎更好的讀取和處理關鍵事件的引擎,目前 NEX 引擎仍處於測試階段,如果您願意,您可以改回 Zsh 的 ZLE 引擎。
例如:
# Change to Zsh's default readkey engine
ZVM_READKEY_ENGINE= $ZVM_READKEY_ENGINE_ZLE
您可以使用ZVM_KEYTIMEOUT
選項來調整等待下一個按鍵的按鍵輸入逾時時間,預設為0.4
秒。
轉義鍵是一種特殊情況,它可以單獨使用。 NEX 引擎在收到轉義字元後等待一段時間,以確定它是獨立的還是轉義序列的一部分。等待期間,額外的按鍵會使轉義鍵充當元鍵。如果沒有其他按鍵輸入,則將其視為獨立轉義處理。
對於NEX引擎,我們可以使用ZVM_ESCAPE_KEYTIMEOUT
選項來調整Escape鍵的等待逾時時間,預設為0.03
秒。
由於有些配置選項依賴於插件中定義的某些變量,但有些則不然。我們需要提供統一的配置入口功能。入口函數的名稱儲存在名為ZVM_CONFIG_FUNC
的選項中,預設值為zvm_config
,您可以變更為其他值以適合您的口味。
如果這個配置函數存在,它會被自動調用,你可以在使用這個插件之前做一些這方面的配置。例如:
function zvm_config() {
ZVM_LINE_INIT_MODE= $ZVM_MODE_INSERT
ZVM_VI_INSERT_ESCAPE_BINDKEY=jk
}
source ~ /zsh-vi-mode.zsh
該插件提供了一種執行額外命令的機制,現在您可以透過以下方面來執行某些操作:
zvm_before_init_commands=()
zvm_after_init_commands=()
zvm_before_select_vi_mode_commands=()
zvm_after_select_vi_mode_commands=()
zvm_before_lazy_keybindings_commands=()
zvm_after_lazy_keybindings_commands=()
由於預設的初始化模式,該插件會覆蓋先前的按鍵綁定,這會導致其他插件(即fzf
、 zsh-autocomplete
等)的按鍵綁定失敗。
您可以透過以下方式解決相容性問題:
# Append a command directly
zvm_after_init_commands+=( ' [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh ' )
或者
# Define an init function and append to zvm_after_init_commands
function my_init() {
[ -f ~ /.fzf.zsh ] && source ~ /.fzf.zsh
}
zvm_after_init_commands+=(my_init)
或者
# The plugin will auto execute this zvm_after_init function
function zvm_after_init() {
[ -f ~ /.fzf.zsh ] && source ~ /.fzf.zsh
}
或如果您正在使用zinit
:
# For postponing loading `fzf`
zinit ice lucid wait
zinit snippet OMZP::fzf
預設情況下,延遲鍵綁定功能已啟用, normal
和visual
模式的所有鍵綁定都應由zvm_after_lazy_keybindings_commands
執行。例如:
# The plugin will auto execute this zvm_after_lazy_keybindings function
function zvm_after_lazy_keybindings() {
bindkey -M vicmd ' s ' your_normal_widget
bindkey -M visual ' n ' your_visual_widget
}
該插件有兩個功能供您定義自訂小部件和鍵綁定。如果出現不必要的問題,最好使用它們,尤其是當您遇到關鍵衝突時。
要定義自訂小工具,您應該:
# If [your_custom_widget] were ignored, it will be the same with <your_custom_widget>
zvm_define_widget < your_custom_widget > [your_custom_function]
要定義鍵綁定,您應該:
zvm_bindkey < keymap > < keys > < widget >
例如:
# Your custom widget
function my_custom_widget() {
echo ' Hello, ZSH! '
}
# The plugin will auto execute this zvm_after_lazy_keybindings function
function zvm_after_lazy_keybindings() {
# Here we define the custom widget
zvm_define_widget my_custom_widget
# In normal mode, press Ctrl-E to invoke this widget
zvm_bindkey vicmd ' ^E ' my_custom_widget
}
該插件提供了一個ZVM_MODE
變量,供您檢索當前的 vi 模式並更好地顯示指示器。
目前支援以下模式:
ZVM_MODE_NORMAL
ZVM_MODE_INSERT
ZVM_MODE_VISUAL
ZVM_MODE_VISUAL_LINE
ZVM_MODE_REPLACE
為了更新 vi 模式指示器,我們應該將指令新增至zvm_after_select_vi_mode_commands
。例如:
# The plugin will auto execute this zvm_after_select_vi_mode function
function zvm_after_select_vi_mode() {
case $ZVM_MODE in
$ZVM_MODE_NORMAL )
# Something you want to do...
;;
$ZVM_MODE_INSERT )
# Something you want to do...
;;
$ZVM_MODE_VISUAL )
# Something you want to do...
;;
$ZVM_MODE_VISUAL_LINE )
# Something you want to do...
;;
$ZVM_MODE_REPLACE )
# Something you want to do...
;;
esac
}
該外掛程式為用戶提供了一些自訂遊標樣式的選項,以實現更好的終端相容性。
ZVM_CURSOR_STYLE_ENABLED
選項停用此功能(預設為true
) # Disable the cursor style feature
ZVM_CURSOR_STYLE_ENABLED=false
# The prompt cursor in normal mode
ZVM_NORMAL_MODE_CURSOR
# The prompt cursor in insert mode
ZVM_INSERT_MODE_CURSOR
# The prompt cursor in visual mode
ZVM_VISUAL_MODE_CURSOR
# The prompt cursor in visual line mode
ZVM_VISUAL_LINE_MODE_CURSOR
# The prompt cursor in operator pending mode
ZVM_OPPEND_MODE_CURSOR
ZVM_CURSOR_USER_DEFAULT
ZVM_CURSOR_BLOCK
ZVM_CURSOR_UNDERLINE
ZVM_CURSOR_BEAM
ZVM_CURSOR_BLINKING_BLOCK
ZVM_CURSOR_BLINKING_UNDERLINE
ZVM_CURSOR_BLINKING_BEAM
ZVM_INSERT_MODE_CURSOR= $ZVM_CURSOR_BEAM
ZVM_NORMAL_MODE_CURSOR= $ZVM_CURSOR_BLOCK
ZVM_OPPEND_MODE_CURSOR= $ZVM_CURSOR_UNDERLINE
# The plugin will auto execute this zvm_config function
zvm_config () {
# Retrieve default cursor styles
local ncur= $( zvm_cursor_style $ZVM_NORMAL_MODE_CURSOR )
local icur= $( zvm_cursor_style $ZVM_INSERT_MODE_CURSOR )
# Append your custom color for your cursor
ZVM_INSERT_MODE_CURSOR= $icur ' ee]12;reda '
ZVM_NORMAL_MODE_CURSOR= $ncur ' ee]12;#008800a '
}
我們可以使用ZVM_TERM
選項設定插件的術語類型來處理終端轉義序列,預設為$TERM
。它可以是xterm-256color
、 alacritty-256color
、 st-256color
等。
您可以使用ZVM_VI_HIGHLIGHT_BACKGROUND
、 ZVM_VI_HIGHLIGHT_FOREGROUND
和ZVM_VI_HIGHLIGHT_EXTRASTYLE
來變更高亮行為(環繞、視線等),顏色值可以是顏色名稱或十六進位顏色值。
例如:
ZVM_VI_HIGHLIGHT_FOREGROUND=green # Color name
ZVM_VI_HIGHLIGHT_FOREGROUND= # 008800 # Hex value
ZVM_VI_HIGHLIGHT_BACKGROUND=red # Color name
ZVM_VI_HIGHLIGHT_BACKGROUND= # ff0000 # Hex value
ZVM_VI_HIGHLIGHT_EXTRASTYLE=bold,underline # bold and underline
您可以透過ZVM_LINE_INIT_MODE
選項來設定命令列初始模式。
目前支援以下模式:
ZVM_MODE_LAST
:從最後一個模式開始(預設)。ZVM_MODE_INSERT
:從插入模式開始。ZVM_MODE_NORMAL
:從正常模式開始。例如:
# Always starting with insert mode for each command line
ZVM_LINE_INIT_MODE= $ZVM_MODE_INSERT
該插件支援惰性鍵綁定功能,並且預設啟用。若要停用它,您可以在載入此外掛程式之前將選項ZVM_LAZY_KEYBINDINGS
設定為false
。此功能會將normal
和visual
模式的所有按鍵綁定推遲到您第一次進入普通模式時。
它可以大大提高啟動速度,特別是你打開終端機只想執行一個簡單的指令。
為了防止插件來源順序引起的與按鍵綁定相關的各種問題,並保持該插件的相同功能,該插件的初始化被推遲到第一個命令列啟動。
然而,幾乎所有插件都是在獲取腳本時初始化的。因此,該插件提供了一個選項ZVM_INIT_MODE
來更改初始化模式。
例如:
# Do the initialization when the script is sourced (i.e. Initialize instantly)
ZVM_INIT_MODE=sourcing
非常感謝問題和請求請求。如果您之前從未為開源專案做出貢獻,我非常樂意引導您完成如何建立拉取請求。
您可以先打開一個問題來描述您想要解決的問題,我們將從那裡開始。
該主題已獲得 MIT 許可 © Jeffrey Tse 的許可。