不優(yōu)化,zsh 也超快

看到一篇特別好的關(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. Faster and enjoyable ZSH (maybe)
  3. 我就感覺到快 —— zsh 和 oh my zsh 冷啟動速度優(yōu)化

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 的需求是什么?

  1. 配色好看一點
  2. 能展示當前路徑,git 分支信息和狀態(tài)
  3. 最好是帶補全和提示
  4. 命令有顏色提示,輸錯了能提示一下
  5. 能搜索歷史記錄和目錄下的文件

最后我做出來的效果如下:

final1

可以看到這幾種情況

  1. command 在 $PATH 中存在,是淺綠色的,如果不存在,是紅色
  2. 正常情況下提示符是淺綠色delta,如果上一條執(zhí)行錯誤,是紅色的×,如果是 vi mode,是藍色的 V
  3. 如果目錄是個 git repo,顯示當前所在的分支名,如果有更改或者遠端有更改,將狀態(tài)展示在分支名后面

下圖是搜索歷史記錄,在 shell 里摁 CTRL+R 觸發(fā)搜索,CTRL+N/P 選擇上一項/下一項

final2

下圖是搜索當前路徑下文件,格式是 command + 空格 ++ ll + TAB,CTRL+N/P 選擇上一項/下一項,選擇到合適的文件之后摁回車,出現(xiàn)在 shell 里的內(nèi)容是 command + 內(nèi)容(ll 只是用來做觸發(fā)關(guān)鍵字的,可以自定義)

final3

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

v

在完全沒有用任何 lazy load 和減少子進程之類的優(yōu)化的情況下,啟動速度也不過是 0.2s 左右,而且這里面還夾雜了我所有的其他初始化腳本(當然這里面也沒有什么很重的初始化內(nèi)容),對于我來說已經(jīng)很滿意了。

由于我的 ssh key 也放在 dotfiles 里的,現(xiàn)在不能公開完整的配置文件,過幾天我換個倉庫重新來過之后,會把我的 dotfiles 倉庫放出來。

原文鏈接:https://shuxiao.wang/posts/zsh-refresh/

評論