看到一篇特別好的關(guān)于 zsh ?的文章,第一時間轉(zhuǎn)發(fā)過來,文末有原文鏈接,感謝作者的經(jīng)驗分享~
如果你折騰過 shell,那你肯定遇到過 oh-my-zsh,這個巨大的框架什么都好,就是有點慢。在用了一年多 oh-my-zsh 之后,我有點煩了那種卡卡的感覺,想換一個 shell 試試。在嘗試 fish 之后我放棄了這種所謂的現(xiàn)代 shell,我還是更喜歡完全文本化的配置,fish 的語法跟 bash 差別太大我也不是很喜歡,畢竟 bash 的語法是日常繞不過的坎,我希望盡量貼合 bash。這個思路下可選的其實并不多,要么是 bash,要么是曾經(jīng)要兼容 bash 但是后來放棄了不過也勉強能兼容的 zsh
所以問題就變成了,怎么把 zsh 搞快一點?
稍微搜索一下,我找到了這么幾個文檔
1 可以看作是安利,zsh 是個好 shell,除了配置有點麻煩以外其他都很贊
2 是朋友發(fā)給我的一個優(yōu)化文,主要是講述了 zsh 啟動過程中每個配置文件的作用和他們之間的先后加載順序,還提到了一個幾乎所有 oh my zsh 的優(yōu)化文章都會提的一個東西:lazy load
3 是一個實際優(yōu)化案例,思路跟 2 里的幾乎一樣,也是減少子進程和懶加載,不過更加實戰(zhàn),很多腳本都可以直接照著跑
我在自己嘗試了一番之后發(fā)現(xiàn),其實不用這些優(yōu)化策略,配置好的 zsh 也可以很快,只要控制好加載的內(nèi)容就足夠了,接下來我敘述一下我的折騰過程
1. 明確需求
沒錯,哪怕只是做自己的事也需要明確一下需求,為什么我需要 oh my zsh 呢?
因為我不會裝插件和主題,以前用的都是 oh my zsh 自帶的插件和主題,只需要跑一下 oh my zsh 的一鍵安裝腳本就可以用了
那我到底需要 oh my zsh 的什么功能?或者叫現(xiàn)在我對 shell 的需求是什么?
- 配色好看一點
- 能展示當前路徑,git 分支信息和狀態(tài)
- 最好是帶補全和提示
- 命令有顏色提示,輸錯了能提示一下
- 能搜索歷史記錄和目錄下的文件
最后我做出來的效果如下:
可以看到這幾種情況
- command 在 $PATH 中存在,是淺綠色的,如果不存在,是紅色
- 正常情況下提示符是淺綠色delta,如果上一條執(zhí)行錯誤,是紅色的×,如果是 vi mode,是藍色的 V
- 如果目錄是個 git repo,顯示當前所在的分支名,如果有更改或者遠端有更改,將狀態(tài)展示在分支名后面
下圖是搜索歷史記錄,在 shell 里摁 CTRL+R 觸發(fā)搜索,CTRL+N/P 選擇上一項/下一項
下圖是搜索當前路徑下文件,格式是 command + 空格 ++ ll + TAB,CTRL+N/P 選擇上一項/下一項,選擇到合適的文件之后摁回車,出現(xiàn)在 shell 里的內(nèi)容是 command + 內(nèi)容(ll 只是用來做觸發(fā)關(guān)鍵字的,可以自定義)
2. 找到工具
插件管理工具
需求和目的明確之后只需要找對應(yīng)的工具了,首先是把框架搭起來,oh my zsh 肯定是不能用了,那就找一個插件管理工具來幫我們管插件。
我找到的是 zinit,從跑分上看,它的速度比欽定的 antigen 快,看了下用法也算簡單,那就它了
高亮/補全/提示
其次是找插件,我的需求就是語法高亮、補全和提示,正好 zsh-users 的倉庫里有這 3 個
正好可以滿足需求,用 zinit 裝上即可
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-syntax-highlighting
只要把這 3個插件一裝上,在 zsh 里輸入 command 就已經(jīng)有高亮和提示效果了
主題
在 oh my zsh 時期,我用的主題是 pure,但是那個主題稍微想自定義一下都很困難,需要學(xué)習的概念有點多,我這次正好就放棄了,重新?lián)Q一個
我選擇了比較現(xiàn)代的、用Rust寫的 Starship,它的優(yōu)點是速度很快、配置簡單、文檔齊全、默認配色就足夠好看,自己做微調(diào)也相對容易,最后我的配置文件長這樣
add_newline = true
[directory]
truncation_length = 0
truncate_to_repo = false
[git_branch]
format = "[$branch]($style) "
# format = "[$symbol$branch]($style) "
[golang]
format = "[$symbol()]($style)"
[cmd_duration]
format = "[$duration]($style) "
min_time = 3_000
[character]
success_symbol = "[Δ](bold green)"
error_symbol = "[?](bold red)"
vicmd_symbol = "[V](bold blue) "
[username]
style_user = "yellow bold"
style_root = "black bold"
format = "[$user@]($style)"
disabled = false
[hostname]
ssh_only = true
format = "[$hostname](bold yellow) "
disabled = false
[package]
disabled = true
[gcloud]
disabled = true
[aws]
disabled = true
搜索
搜索分為搜索歷史和搜索當前目錄下的文件,搜索當然是用超好用的 fzf,fzf 的配置超簡單,運行速度很快,照著官方文檔弄就行,我唯一改了的是反轉(zhuǎn)了一下上下,我不是很喜歡搜索結(jié)果在最下面的默認展示風格,于是調(diào)整了一下
# 反轉(zhuǎn)展示結(jié)果
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'
# 搜索文件時的觸發(fā)因子
export FZF_COMPLETION_TRIGGER='ll'
# 搜索文件時改成 fd 搜索且允許搜索隱藏文件
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
# 下面這個文件是 fzf 安裝期間自動生成的,不用改
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
我在官方文檔的提示下安裝了 ripgrep/fd/bat 等工具,這些工具都是用 Rust 寫的 grep/find/cat 的替代品,速度很贊,推薦使用
3. 跑個分
配置好之后直接跑個分
# 不加載配置
for i in $(seq 1 5); do /usr/bin/time /bin/zsh --no-rcs -i -c exit; done
# 正常加載配置
for i in $(seq 1 5); do /usr/bin/time /bin/zsh -i -c exit; done
在完全沒有用任何 lazy load 和減少子進程之類的優(yōu)化的情況下,啟動速度也不過是 0.2s 左右,而且這里面還夾雜了我所有的其他初始化腳本(當然這里面也沒有什么很重的初始化內(nèi)容),對于我來說已經(jīng)很滿意了。
由于我的 ssh key 也放在 dotfiles 里的,現(xiàn)在不能公開完整的配置文件,過幾天我換個倉庫重新來過之后,會把我的 dotfiles 倉庫放出來。