by Aleksandar Pasaric from Pexelsby Aleksandar Pasaric from Pexels

合輯:Python 開發環境設定:zsh、zinit、pyenv、Poetry、Docker

2022/03/18重要更新:

這兩天看到這篇〈zinit 作者刪庫事件以及後續代替方案〉,才知道原來 zinit 的原作者竟然無預警把 GitHub 上的 repo 刪除了!嚴格來說是把 organization 刪了,所以其下的好多 repo 都變成孤兒,包括一些常用的 zsh 套件。

不過原來的 repo 已經有社群的 fork 版並持續維護中,所以本文內容除了 zinit 與部分套件的安裝網址、路徑有修正外,其餘使用上並不受影響,我暫時也沒打算換到新的管理器,因為其實都大同小異。


將 zsh 套件管理器從 zplug 改為 zinit〉曾提過要嘗試在自己新開的 VM 上面使用之前沒用過的 zsh 套件管理器——zinit,取代原來在 Mac 上的 zplug 方案。安裝後也進行了簡單的回顧

後來工作上又開了好幾個 VM,也是裝 Ubuntu,因為覺得設定有點麻煩所以一直使用預設的 bash shell,但操作起來的效率與體驗,和 zsh 完全不能比。

只能說 zsh 真的用過就回不去了!想想還是下定決心,把整個流程寫下來,作為日後重置 VM 時的參考。

至於為何不選用最常見的套件管理器——Oh My Zsh,前述文章已有提及,基本上就是安裝了太多不必要的功能,著實不夠簡潔。

本文主旨

只用最簡單的設定,獲取最重要的幾項功能,就能讓生產力得到大幅提升。

和前一篇關於安裝 pyenv 的文章一樣,為確保內容的正確與可行,我繼續使用同一個 Google f1-micro VM 來同步進行。

值得一提的是,因為安裝 pyenv 時要修改.zshrc,如果同時要安裝 zsh 與 pyenv,那麼建議先從本篇的 zsh 設定做起,再安裝 pyenv,順序上較為合理、流暢。


Ubuntu 安裝與設定 zsh

這部分很簡單,幾個指令即可完成。

apt 安裝

1
2
3
sudo apt-get update;
sudo apt-get upgrade -y;
sudo apt-get install -y zsh;

將 zsh 設定為登入時的預設 shell

安裝完 zsh 後,打zsh就可以登入使用。

sudo cat /etc/shells指令可以看到目前 VM 上所有可用的 shell 路徑,包括了我們剛剛裝好的 zsh:

1
2
3
4
5
6
/bin/sh
/bin/bash
/usr/bin/bash
...
/bin/zsh
/usr/bin/zsh

使用下列指令將「當前使用者」的登入 shell 預設為/bin/zsh

1
sudo usermod -s /bin/zsh $USER

這樣之後登入就不必再打zsh進行切換了。

重登後,可使用echo $SHELL確認輸出結果是否為/bin/zsh

1
2
echo $SHELL
/bin/zsh

新增.zshrc.zprofile

登入後,系統可能會提示你沒有.zshrc相關檔案等等,這很正常,直接以指令新增即可。如果打算把.bashrc的內容複製貼上到.zshrc,要注意無法照單全收,因為兩者不完全相容。

同時新增.zprofile

1
2
touch .zshrc
touch .zprofile

安裝 zinit

zsh 有很多套件管理器(package manager),安裝了管理器和套件後,才能發揮 zsh 真正強大之處,其中最有名的套件管理器不用說就是 Oh My Zsh

強大但複雜的 package manager

然而,有用過 zsh 套件管理器的都知道,無論 Oh My Zsh、zplug 還是本篇的 zinit,它們實際上都有非常豐富的語法和設定,都要弄清楚恐怕會讓人一個頭十個大,所涉及的 Linux、shell 相關知識也往往不是一般工程師的擅長領域。

因此,我們還是回歸簡潔精神,貫徹 80/20 法則,只設定最常用的那幾個外掛功能即可。因為光用這幾項功能,就已經能讓效率提升數倍了。

略過佈景主題,推薦 Powerlevel10k

本篇會略過佈景主題部分,倒不是它不重要,只是每個人各有偏好。真的不知道要選哪個的話,相信 Powerlevel10k 還是目前最多人推薦的選項,我自己也是用它,而它在安裝上又有一些必要設定,且很可能需要額外安裝字型才能正常顯示。

總之,這部分並非本篇重點,所以暫且不提。

2022/08/14已新增文章:zsh 透過 zinit 安裝 Powerlevel10k 佈景主題

簡潔的信仰

關於所要安裝的外掛功能,之前都是複製貼上別人的.zshrc設定,為了寫這篇文章我又花了 2 小時把真正必要的部分弄清楚一點,以下就只進行這些必要設定,省略我也不確定是什麼功能的配置內容。

不得不承認,這些看起來很複雜的設定,往往是令人卻步、不想使用 zinit 等小眾管理器的主因,我第一次看到也覺得麻煩!

所幸,如果只是簡單的安裝與使用,實際上一點也不困難。本文就是獻給那些不想被 Oh My Zsh 強制幫你裝一堆用不到的功能,而希望更加輕量、簡潔的用戶。

對工程師而言,簡潔是一種信仰。

Install zinit

話不多說,我們直接參考官方文件的指令進行安裝:

1
bash -c "$(curl --fail --show-error --silent --location https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"

設定 zinit

這邊是重點中的重點,輕量化的套件管理器如 zplug 或這裡的 zinit,基本上都是安裝 zsh 後,直接在.zshrc加上相對應的配置語句即可。

.zshrc新增配置語句

而不同的管理器也有不同的語法,你可能根本不想知道這些語法細節,至少我是如此。所以通常裝完後就是去複製別人的.zshrc內容,以下我也會提供複製素材,並稍加介紹每一行設定的作用為何。

新增所需的全部配置會放在最後,讓我先闡述一下這些功能。

zsh 套件四天王

各種動漫作品中常常出現四天王,而如果別人的配置你看多了,無論是哪一款 zsh 管理器,以下這四個絕對是最常出現的:

1
2
3
4
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-history-substring-search
zinit light zdharma-continuum/fast-syntax-highlighting

簡單介紹:

  1. zsh-completions:強化 zsh 以tab鍵「命令自動補全」功能。強化的部分很多,其中一項是cd指令後面可以只接資料夾或檔名的「模糊搜尋」,按tab就會幫你搜尋與匹配。比如打cd sk就幫你找到cd Desktop/
  2. zsh-autosuggestions:輸入一部分內容就會以灰字提示相同前綴的最後一個使用過的指令,超級方便。這或許就是最強的一項功能沒有之一
  3. zsh-history-substring-search:可視為「以方向鍵取得與切換歷史指令」的強化版,差別在於你可以先輸入部分指令比如docker container,此時再按方向鍵就「只會限制搜尋以此前綴開頭」的歷史指令,大幅縮小搜尋範圍。輸入部分不需要是完整指令。
  4. fast-syntax-highlighting:這個應該就比較不用解釋,指令、參數、有效無效的指令都會有自己的顏色。

重點展示

主要展示上述第二、四項功能,尤其是第二項。

  • 灰字很常出現,都是以目前輸入內容為前綴的最後一次內容。按快捷鍵後就可以直接套用。
  • 指令有錯誤時(通常是指令不存在、輸入不完全、拼寫有誤)顯示為紅色粗體,指令正確時(包括正確的 alias)顯示為綠色。
  • 完整的指令包含參數會有不同顏色的 syntax highlight。

Oh My Zsh 相容性補強

Oh My Zsh 佔據了 zsh 管理器的大片江山,有其強大之處,其餘的管理器必然要支援其部分功能,以降低你搬家的心理門檻。況且已造好的優質輪子,豈有不借用之理?

以下這幾個是 Oh My Zsh 的內建功能,可相容於 zinit,推薦一併安裝:

1
2
3
4
zinit snippet OMZ::lib/completion.zsh
zinit snippet OMZ::lib/history.zsh
zinit snippet OMZ::lib/key-bindings.zsh
zinit snippet OMZ::lib/theme-and-appearance.zsh

這些算是 Oh My Zsh 內建的功能而非獨立外掛,以下是我實測後的功能介紹:

  • lib/completion.zsh:類似前述的zsh-completions。一個特色是持續按tab會移動到命令列外的選單,此時可以用方向鍵選擇。
  • lib/history.zsh:共用history指令的快取內容,我沒裝的話,一登出 zsh 就找不到原來的歷史紀錄了。
  • lib/key-bindings.zsh:沒裝的話我zsh-history-substring-search的 key-binding 設定會無效,所以還是乖乖裝了。
  • lib/theme-and-appearance.zsh:有裝的話終端機的佈景主題配色才會套用到 VM 上。

Key bindings

我只設了兩組而已,其中給zsh-history-substring-search的部分(即前兩行)是必要的。

1
2
3
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
bindkey ',' autosuggest-accept

前兩行:設定後才能用上下鍵來使用zsh-history-substring-search

第三行:zsh-autosuggestions在暗字提示出現後,要按方向鍵來補完,新增此 key binding 後,按,也可以達成同樣效果了。需要這個設定的原因是:,鍵在整個鍵盤的位置上,離中心比較近,會比遠處的方向鍵更加方便操作。

其他

1
zinit load djui/alias-tips

從名稱就能看得出來,它的功能就是你明明設了alias卻打了完整的指令,會提示你alias的存在,讓你習慣多使用alias。這部分非必要,我只放在其他。


小結

以上這幾樣設定已經足夠覆蓋大部分的日常使用情境,最後附上設定檔,請將下列內容置於.bashrc.zshrc並重新啟動 shell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# zsh 套件四天王
zinit light zsh-users/zsh-completions
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-history-substring-search
zinit light zdharma-continuum/fast-syntax-highlighting

# Oh My Zsh 功能
zinit snippet OMZ::lib/completion.zsh
zinit snippet OMZ::lib/history.zsh
zinit snippet OMZ::lib/key-bindings.zsh
zinit snippet OMZ::lib/theme-and-appearance.zsh

# key binding
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
bindkey ',' autosuggest-accept

# 其他
zinit load djui/alias-tips

參考