--- date: "2024-06-15 00:17:52" --- # 你都用什麼編輯器呀?蛤?Kakoune?沒聽過耶 ʕ•ᴥ•ʔ - 編輯器的全婆俠之旅 kakoune & helix 篇 > [!TLDR] > 我目前用 kakoune 作為主力編輯器。本文會記錄並炫耀目前的設定。 ## 當編輯器開始變慢,就是換換病發作的時候 承認吧,比起找出問題在哪,軟體工程師更善於砍掉重練。 身為使用 NeoVim 的軟體工程師,每天的日常就是:訂閱 Google 快訊 Neovim plugin 關鍵字,每天刷 [Reddit NeoVim](https://www.reddit.com/r/neovim/) subreddit,每小時上 [dotfyle](https://dotfyle.com/) 看有沒有什麼最新的 plugin、有空就刷 [GitHub neovim topic](https://github.com/topics/neovim?o=desc&s=updated) 、隨時關注新專案。一有新的 plugin,**當然第一時間直接裝爆**。 至此,我的 NeoVim 已經變的比 Emacs 還要像作業系統,開啟速度比裝滿 300 個擴充功能的 VSCode 還要久。你問我有什麼頭緒,我怎麼會知道? 只好不得不說再見了,NeoVim。 (本段僅供參考,敬請謹慎服用) ## 「快」是入坑起點,但退坑之因也是速度 去年開始[我從 VSCode 換到了 NeoVim](https://yukai.dev/blog/2023/04/05/my-terminal-development-env-setup) ,雖然在 Apple Silicon M1 上 VSCode 已經表現不錯了,但有時會出現的卡頓還是讓人不爽,加上 VSCode 時不時因為不明原因爽吃一波 CPU 讓續航直接下降(你就承認 extension 裝太多不就好了)。 換到 Neovim 的 [AstroNvim](https://astronvim.com/) 發行版後,從 [Lazygit](https://github.com/jesseduffield/lazygit) 開始,我更熟悉了一系列 TUI Apps。 以 Git 操作為例,原本幾乎所有操作都是在 VSCode 裡面完成(沒辦法,GitLens 和 GitGraph 真是好用),現在反倒多樣化~~碎片化~~~~了許多。我會用 [fzf](https://github.com/junegunn/fzf) 搭上 git、用 Lazygit、用 GitHub 網頁介面、用 [GitHub 官方的 CLI](https://cli.github.com/) 再搭上 fzf、用 [Fork](https://fork.dev/)、請 GPT4 寫一些輔助的 Git Script 等等。雖然碎片化,但我也透過這個過程多了解了一點點 git 的參數,想必一定對開發效率,有著飛越性、質的提升......吧(?) 用了一陣子才發現 Neovim 效能沒想像中好,lsp 與 UI 互動時而卡頓,開啟大檔案有時甚至比 VSCode 還慢,甚至 UI 直接卡死,Telescope 不小心 fuzzy 到大檔也會卡死。上手設定的過程也沒有那麼順利,中途(aka 日常更新外掛的時候)還需要 workaround 一些 `lazy.nvim` 的問題。 經過這幾個月的密集使用 NeoVim,以及[依照慣例](https://yukai.dev/blog/2016/06/22/sublime-atom-vscode-comparison-mid-2016)的「花式客製」,我對編輯器有了***全新的感受***。 ## 快速鍵是帶的走的 「快速鍵」是比較具體的例子,以「編輯的心智模型」來描述更為貼切。從最基礎的 editing motion(以 vim motion 為例就 hjkl/d/visual),到打開編輯器相關附加功能,比如檔案樹瀏覽器、內嵌終端機(~~ㄑㄧㄢ,謝謝~~)、快速跳轉檔案、LSP 操作(重新命名、重構)、搜尋與取代等等。 在不同的編輯器,預設的快速鍵都不盡相同,大多都可以自訂,方便不同習慣、不同鍵盤的使用者可以最大化自己的生產力。[Command Palette](https://www.commandbar.com/blog/command-palette-past-present-and-future/) 被發揚光大後也變成了成了標配一般的存在,即使不清楚預設的快速鍵,各個編輯器也都能透過它,方便的發現並使用功能。 > 畢竟一位真正的工程師,是不會去使用滑鼠的(逃 在體驗不同編輯器的過程中,我對於編輯體驗的認知與操作慢慢擴張,最終內化成一套屬於自己的系統。沒辦法,誰叫 AstroNvim 的預設快速鍵那麼合理又好記憶![^1] 最終,我會成為編輯器界的全婆俠![^2]所有編輯器,都是我的翅膀![^3]我要把我的編輯器自訂天賦,帶到所有編輯器![^4] [^1]: lazyvim 也不錯啦 [^2]: https://bahapedia.fandom.com/zh/wiki/%E6%88%91%E5%A9%86#%E5%85%A8%E5%A9%86%E4%BF%A0 [^3]: https://zh.moegirl.org.cn/zh-tw/%E4%BD%A0%E4%BB%AC%E9%83%BD%E6%98%AF%E6%88%91%E7%9A%84%E7%BF%85%E8%86%80 [^4]: THE 迪西遜,雖然還是會一直拿來當梗,但老漢的強大家都懂 https://www.wikiwand.com/en/The_Decision_(TV_program) ## Helix 設定之旅 我先嘗試使用 Helix 作為我的主力編輯器。 Helix 是個內建功能齊全的終端機介面編輯器,內建 tree-sitter、LSP 整合、內建介面類似 [Telescope](https://github.com/nvim-telescope/telescope.nvim) 的 Command Palette,性能絕佳,用起來幾乎不會感受到有什麼卡頓。唯一的敗筆就是擴充性比較低,目前還沒有外掛系統(Plugin System)可用,但你還是可以透過它提供的兩種功能來做到一點點的擴充: 1. Shell command 2. Shell pipeline Shell command 簡單來說就是執行外部程式;Pipeline 就和常用的命令列管道一樣,可以把編輯器的內容,變成外部程式的輸入。比如程式碼的格式化(Formatting),就是把編輯的文字內容丟給格式化程式(Formatter)。 Helix 提供的這兩個方法簡單有效率,比如開啟 Lazygit 或其他外部程式,都能用很簡單的方式整合進編輯器了,但 Helix 提供給外部程式的資訊其實相當有限。比如想要知道某一行程式碼的 `git blame`,那「檔案路徑」、「行號」等,都是必要資訊,但 Helix 除了內容外就沒有其他資訊了,這就讓某些整合窒礙難行。 不過會看我這樣寫,想必是有什麼解法了吧 XD ### 運用終端機多工器(Multiplexer)[^5] 來獲取編輯器狀態資訊 既然 Helix 不給,那我們就從畫面上,也就是 Helix 的 TUI 產生的文字拿,總可以了吧。 這個解法我是在 [Quan Tong 的部落格](https://quantonganh.com/2023/08/19/turn-helix-into-ide.md)看到,而他是在 helix 的 [subreddit](https://www.reddit.com/r/HelixEditor/comments/13x9a3z/integrating_fuzzylive_grepping_into_helix_my/) 看到。解法如下: ![image](https://hackmd.io/_uploads/BJqzFRqSA.png) * Helix 的狀態列會顯示目前開啟檔案的路徑,與游標資訊 * 用 Tmux/Kitty/Wezterm/zellij 的 API 拿到畫面上的所有文字 (`get-text`) * 用 Regex 把檔名和游標資訊擷取出來 * Works like a charm! :tada: 雖然很神奇,但我腦袋告訴我這鐵定不穩定。比如想要狀態列樣式時,或是視窗寬度不足,而導致狀態列的文字被刪減縮短。各種狀況都會讓這條 Happy path 直接失敗。 [^5]: https://www.wikiwand.com/en/Terminal_multiplexer ### 與 Helix 配合使用檔案樹 <video controls> <source src="https://i.imgur.com/qorIABs.mp4" type="video/mp4"></source> </video> 去年看到 Helix [File Tree 的 PR](https://github.com/helix-editor/helix/pull/5768) 想說快要合併了,可以期待一下。結果結論是超出 Helix 想實作的範圍,直接不合併。好吧,那我只好找個 TUI 的檔案樹湊合湊合了。我先是嘗試了 [nnn](https://github.com/jarun/nnn) 和 [vifm](https://github.com/vifm/vifm) [^6],最後在 [broot](https://github.com/Canop/broot) 定了下來。 那外部的檔案樹就要怎麼配合 Helix 使用? 一樣有點腦漿炸裂[^7]的解法。因為 Helix 的架構設計,你無法在其他 process 去操控編輯器的行為,比如告訴哪個編輯器實體去開啟某個檔案。但你一樣可以透過終端機多工器的 API! * 利用 tmux/wezterm/kitty/zellij 的 API 檢查檔案樹右側面板 (panel)是否有 Helix 開啟 * 若沒有:用 `hx $filepath` 指令開啟一個新面板 * 若有:用 `send-keys` 傳送按鍵模擬 `:e $filepath` 到該面板 聰明的你也想的到了,這種方式同樣沒有那麼穩固。只要右側面板的 Helix 不在一般模式(Normal mode),比如在輸入模式,那這套方法一樣不管用。 身為編輯器真理的探求者,看到有這麼多問題的整合方式,自然不會滿足於此。於是,我向啟發 Helix 設計的 OG 編輯器:Kakoune — 發起了挑戰![^8] [^6]: vifm 也有官方的 helix 整合方式,不過要使用 tmux https://github.com/vifm/vifm/tree/master/data/plugins/editor [^7]: 此處意指 Mind-blowing,附上脳漿炸裂ガール,給有時還會聽聽 V 家的各位 https://www.youtube.com/watch?v=Ey_NHZNYTeE [^8]: 這邊引用類似全能住宅改造王建築師名號、渾名的東西,疫情那陣子狂追,每次看到那段就會笑出來。這邊有[完整列表](https://www.asahi.co.jp/beforeafter/old/takumi/index01.html#shibata-t) ## 有如瘋狂科學家[^9]的執念之作:Kakoune Kakoune 和 Vim 系編輯器最大的差異就是快速鍵,需要將原本的肌肉記憶「擴充」一下。注意我這邊用的詞是擴充,因為既有的 vim 還是會在各種地方用到,所以我還是會根據環境切換。 ![image](https://hackmd.io/_uploads/S1-NK0cB0.png) 在拜讀了 [hadronized](https://github.com/hadronized) 的  [Even more hindsight on Vim, Helix and Kakoune](https://strongly-typed-thoughts.net/blog/more-hindsight-vim-helix-kakoune) 一文後,我下定決心給 Kakoune 一個嘗試。 hadronized 是 [This week in Neovim](https://dotfyle.com/this-week-in-neovim) (TWiN) 的前維護者。去年我回鍋 Neovim 後有好一陣子,TWiN 都在我的每週追番清單裡面。也是他把 [Tree Sitter](https://git.sr.ht/~hadronized/kak-tree-sitter) 帶到 Kakoune 的,實在是一位有夠強的開發者。 Kakoune 有自己一套完整的[設計理念](https://github.com/mawww/kakoune/blob/master/doc/design.asciidoc),把自己精確的定義在「程式碼編輯器」這個範疇。IDE 各式工具內建整合?不做的。檔案瀏覽器?不做的。視窗分割管理?不做的。 那這些不做的功能怎麼辦?Kakoune 從一開始就最大化了「可組合性」(Composibility)。Helix 上述的兩種外部溝通方式可以說是從 Kakoune 來的,而 Kakoune 也把這套組合性最強化。 Kakoune 實作了 Client/Server 的架構,你可從不同 process 連到同一個編輯器 Session,同時編輯同一個 buffer。多視窗支援?只要在不同視窗開啟 Kakoune 連線到同一個編輯 Session 即可。跨程式的互動?直接向 Session 送指令。 Kakoune 穩定又小,保持良好的效能,API 也算是穩定,比較不會有那種一週修一次設定檔的情況(對,我就是在說 NeoVim)。編輯器目前約半年一更版,外掛程式雖然生態系小,但是因為 Kakoune 的設計理念,所以外掛的實作也趨向 shell script 為主,比較複雜的外掛,比如 lsp、tree-sitter 等,社群偏向利用 rust/go/crystal 這種可以編譯成二進位執行檔的語言來實作。 下面就來展示目前我在 Kakoune 中設定~~折騰~~出來的的各種「現代編輯器」的體驗。 [^9]: 瘋狂科學家的比喻是來自於 [By Default](https://www.youtube.com/@VideosByDefault) 這個 YouTube 頻道。雖然頻道只有寥寥數片,但[第一部片](https://www.youtube.com/watch?v=XRpHIa-2XCE)就因為演算法之力突破 50 萬觀看。順暢的口白,幽默的音調,還有各種哏的參照,哼,有趣的男人,你引起我的注意了!他也有[評價 Kakoune 編輯器的影片](https://www.youtube.com/watch?v=5WLlLxU2EZE),也是蠻值得一看的。 ## 在 Kakoune 中體驗現代編輯器的功能 ### Floating window with tmux-popup ![スクリーンショット 2024-06-15 夕方5.44.53](https://hackmd.io/_uploads/S1uizkjSC.png) 請參考我的前一篇文章 - [不會關掉的 tmux popup](https://yukai.dev/blog/2024/03/11/persistent-tmux-popup)。完全取代了 ToggleTerm 功能,還能在編輯器以外的地方使用,更加通用。 ### Git 操作 Kakoune 內建了一系列 git 操作整合,但我其實更常用 Lazygit。Lazygit 可以經過擴充設定,來支援 Conventional commit、GitHub pull request 整合、AI commit message 等功能,更加與編輯器解耦。 對於快速複製程式碼的 GitHub Permalink,我甚至實作了用 Crystal 語言寫的 [gitlinker.cr](https://github.com/Yukaii/gitlinker.cr)。 ![image](https://hackmd.io/_uploads/ry7rKAcrR.png "開啟 Git Blame annotation") ![image](https://hackmd.io/_uploads/ry6StCcBA.png "Lazygit conventional commit 支援") ![image](https://hackmd.io/_uploads/BJ48YC5rR.png "AI 產生 commit message 候選(with fzf)") ![image](https://hackmd.io/_uploads/ry3IKAcrC.png "運用 gh 和 fzf 實作的 GitHub Pull Request TUI 腳本") ### 更多 fzf 相關功能 多虧了 kakoune 社群大大實作的 [kks](https://github.com/kkga/kks),外部腳本可以方便的與 kakoune 互動,拿取資料、傳送指令。下面就是一些透過 fzf 實作出類似 Command Palette 的介面。 ![image](https://hackmd.io/_uploads/BkSvFA5SC.png "目前開啟的 buffers 列表") ![image](https://hackmd.io/_uploads/HkqDK0qHR.png "ripgrep + fzf + tmux popup 的搜尋介面") ![image](https://hackmd.io/_uploads/r1WuFCqr0.png "MRU 選單,快速開啟最近開過的檔案") ### 使用 broot 作為檔案瀏覽器 ![image](https://hackmd.io/_uploads/SJqdYR9rC.png) ### Language server support via kak-lsp ![image](https://hackmd.io/_uploads/SJYO7JsS0.png "Hover action(右下角的提示)") 在去年十一月之後,kak-lsp 支援了同時跑多個 lsp server 的功能。以 JavaScript/TypeScript 開發來說,我可以同時跑 tsserver、css/scss、tailwind、eslint、emmet 等等,應用變的實際許多。最近也有相關的 AI lsp 相關開發,比如 [helix-gpt](https://github.com/leona/helix-gpt)、[lsp-ai](https://github.com/SilasMarvin/lsp-ai) 等等,也讓 kakoune 有某種程度上的 copilot 替代(阿當然還是比不上 VSCode/Zed/NeoVim 這種原廠級支援度的)。 當然 kak-lsp 因為編輯器本身的限制,還是缺少一些支援,比如 ghost text (inline type annotation),floating hover card 等。一切體驗感覺都會更原始一點。 ## A more composable editor, a more complete life > [!QUOTE] > 所謂編輯器的獨特性也只是軟體工程師彰顯身價的炫耀財,平平都是打工人,也只能在那微小有限之處彰顯自己的不平凡(暴論) Kakoune 精簡快速核心的哲學打動了我。除了編輯以外的功能通通委外的哲學,對於我這種 TUI 工具控,也提供了很好的擴充和掌握性,想要什麼、不想要什麼,自己換掉就好,有時遇到 bug,開 PR [貢獻 lsp](https://github.com/kakoune-lsp/kakoune-lsp/pull/718) 或是[編輯器](https://github.com/mawww/kakoune/pull/5101),自然也是不在話下......QQ(阿怎麼哭了) Kakoune 的使用者就是沒那麼多,自然生態系也小了許多。目前比較熱鬧的地方在 [Discord 伺服器](https://discord.com/invite/uzZZG2X),問問題都會很快的得到回應。 **I use Kakoune btw** 希望這句話成為繼「I use Arch btw」之後,最 Geek 的一句自我介紹,共勉之 XD