Libghostty Is Coming

Mitchell Hashimoto

Libghostty 即將登場

兩年多前,在我最早幾場關於 Ghostty 的公開演講之一中,我分享了對於 libghostty 的願景:一個可嵌入的函式庫,讓任何應用程式都能嵌入自己功能完整、現代且快速的 terminal emulator(終端機模擬器)。Libghostty 終於開始成形,我很興奮能分享更多關於它的計畫細節。

第一個 libghostty 函式庫將是 libghostty-vt:一個 zero-dependency(零依賴) 的函式庫,提供用於解析 terminal sequences(終端序列) 與維護終端狀態的 API,直接萃取自 Ghostty 經過實際驗證的核心。它甚至不需要 libc!

聲明:本文主要是 libghostty 的路線圖更新,並宣布其中首個可交付的元件。Zig API 現已開放測試,但 C API 尚未就緒,很快就會推出。兩者目前皆處於早期測試階段,尚未達到可供一般使用的成熟度。


為什麼需要 libghostty?

先從一些背景開始,說明我為什麼認為 libghostty 必須存在。

有數百個程式實作了某種形式的 terminal emulation(終端機模擬)。最明顯的就是像 Ghostty、Kitty、iTerm2 等實際的通用型 terminal emulators。此外,像 tmuxzellij 這類 terminal multiplexers(終端機多工器) 也是完整的 terminal emulators!1 編輯器也會嵌入自己的 terminal emulators,例如用於 JetBrains 產品的 jediterm、用於 VS Code 的 Xterm.js,或 Zed 中的 Alacritty

除了功能完整的 terminal emulators,許多網站與應用程式也會實作唯讀的 terminal emulation 來顯示紀錄或指令輸出。例如,GitHub Actions 輸出會解析簡單的顏色序列(但幾乎僅此而已)。而像 Vercel 或 Render 這類代管服務供應商,則實作了簡易形式的 terminal emulation,允許在建置紀錄中清除與重繪行,以及解析顏色。

這些實作大多是臨時拼湊、一次性的解法。它們並未使用任何共用的函式庫或程式碼庫。2 Terminal emulation 是個看似簡單、實則充滿意想不到的複雜度與邊界情況的經典難題。3 因此,這些實作大多不完整、充滿錯誤且速度緩慢。4

除了正確性之外,對大多數開發者而言,實作任何形式的 terminal emulation 都是在浪費時間。Terminal emulation 並非 JetBrains、Visual Studio Code、GitHub、Vercel、Render 等公司的核心業務。如果能有一個穩定、可重複使用且在各處表現一致的解決方案,對他們將大有助益。

我對此的解答就是 libghostty:一個跨平台、極低依賴的函式庫,透過 C API 開放功能豐富、正確且快速的終端機功能,讓任何應用程式在任何地方都能嵌入使用。


起點:libghostty-vt

第一個 libghostty 函式庫將是 libghostty-vt:一個 zero-dependency(甚至不需要 libc)的函式庫,提供用於解析 terminal sequences 與維護終端狀態的 API,例如游標位置、當前樣式、文字換行等。

解析 terminal sequences 是 terminal emulator 最核心的功能,從像 Ghostty 這樣的完整 terminal emulators,到像 GitHub Actions 或 Vercel 建置輸出那種簡單的唯讀、僅樣式顯示的視圖,都需要它。

state diagram(狀態圖)乍看之下或許相對簡單,但要正確實作卻出乎意料地困難。例如,Jediterm 未能正確處理 intermediates(中間字元),導致這個廣泛支援的「變更游標形狀」序列,在本文撰寫當時會在每一款 JetBrains 編輯器中吞掉一個字元。

對於僅需樣式的解析,許多開發者會跳過完整的 state diagram。相反地,他們在網路上隨意搜尋一下,解析像 \e[31\e[41m 這類簡單的 ANSI 序列,就宣稱「支援顏色」。但僅樣式的序列遠比那複雜得多,例如它們支援 RGB,而 RGB 本身就有十多種格式。而我至今仍未找到任何一個能正確渲染這個複雜的樣式序列的網頁主控台。5

libghostty-vt 旨在解決上述所有問題。

libghostty-vt 萃取自 Ghostty,並繼承了所有實戰帶來的好處:SIMD 優化的解析、非常出色的 Unicode 支援、高度優化的記憶體使用量、經過模糊測試與 Valgrind 測試的穩健程式碼庫,以及出色的功能相容性,例如解析 Kitty Graphics Protocol 或 Tmux Control Mode 等,不一而足。

這一切都被封裝進單一的 zero-dependency C API(甚至不依賴 libc),使其能輕鬆嵌入任何主流的語言生態系。

憑藉極小的體積,libghostty-vt 將具備高度的可攜性。初期目標平台為 macOS 與 Linux,並同時支援 x86_64aarch64 架構,因為這些是 Ghostty 應用程式的主要目標平台。但我計畫將支援擴展至更多目標,例如 Windows、嵌入式裝置,以及透過 WASM 支援的網頁。libghostty 的支援範圍將比 Ghostty 圖形介面本身更廣,因為其範疇更為聚焦。


長遠展望

libghostty-vt 只是個開始。長期而言,我們將提供更多 libghostty-<x> 函式庫,開放更多功能,例如輸入處理(鍵盤編碼是其中一大重點)、GPU rendering(GPU 渲染)(只要提供 OpenGL 或 Metal 的繪製平面,剩下的就交給我們)、處理整個終端機視圖的 GTK widgets(GTK 元件) 與 Swift frameworks(Swift 框架)等,不一而足。

隨著基礎元件趨於穩定,我們將持續提供越來越多的功能。這些功能將以一系列函式庫的形式組織,以盡量降低依賴需求、程式碼大小與整體維護複雜度。


libghostty-vt 狀態

我剛剛合併了libghostty-vt 作為 Zig 模組開放的 pull request。這個 PR 也包含一個最小化的範例程式。如果你是 Zig 開發者,可以立即開始試用 libghostty-vt

C API 尚未就緒,但這正是我目前著手處理的工作,很快就會開放測試。所需的工作僅是定義 C API,因為核心邏輯當然早已完備,且已被 Ghostty 使用多年。此外,Ghostty 的 macOS 應用程式本身就已經在使用一個僅供內部使用的 C API

如果你去查看那個僅供內部使用的 C 標頭檔,請忽略其中的混亂。它並不是一個好的 C API。它僅供內部使用,目的只是滿足 macOS 應用程式的需求。這並非可供一般使用的 libghostty,儘管它已經被實際的商業產品用來嵌入 Ghostty。我們將以全新的方式為更廣泛的用途定義 C API。

我計畫將 libghostty 的版本號與 Ghostty 應用程式分開管理。本文標誌著公開 alpha 階段(不保證 API 穩定性),我希望能藉此吸引一些開發者來試用,並在 C API 就緒後為其撰寫各種語言的綁定。

我希望能在未來 6 個月內發布 libghostty-vt 的標記版本,但一切仍取決於它是否已準備就緒。


徵求回饋

我們正處於 libghostty 設計 API 的關鍵階段,而設計 API 的最佳方式就是來自真實使用者的回饋。Ghostty 是一個使用者,我們也有一些社群成員正在進行其他使用 libghostty 的專案,但我們多多益善!

如果你在自己的專案或組織中看到 libghostty 的使用情境,請加入 Ghostty Discord,與正在開發此專案的開發者們協作。如果你不想加入 Discord,也可以直接寫信給我(電子郵件位於本網站頁尾)。

所謂「alpha」品質指的是 API(函式與型別)本身。核心邏輯與 Ghostty 共用,在實際環境中已極為穩定且久經考驗。


下一個新領域

我非常興奮 Ghostty 應用程式終於達到了足夠的穩定度,讓我們可以開始朝 libghostty 的目標邁進。libghostty 是 Ghostty 的下一個新領域,我認為它有能力帶來比 Ghostty 作為獨立應用程式本身更深遠的影響。

別擔心,Ghostty 應用程式仍有許多規劃中的更新,這絲毫不會減損我對它的熱情與計畫。更廣泛地使用 libghostty 也將帶來功能更豐富、更穩定的 Ghostty 應用程式,因為 Ghostty 本身就是 libghostty 的使用者之一。

Boo. 👻

註腳

  1. 這些程式擁有其子行程的 pty(虛擬終端機),解析所有的 escape codes(逸出碼),管理螢幕狀態,並最終透過向上層 terminal emulator 發送自己的逸出碼來完成「渲染」。

  2. 許多網站確實有使用 Xterm.js,而 GTK 生態系則有 libvte。但這僅涵蓋了整體的一小部分,且上述每個例子在其各自的範疇內都有所限制。

  3. 我在終端機模擬上投入了將近 3 年的時間,而我們仍在發現奇怪的邊界情況

  4. 這裡有幾個造成實際影響的問題範例:Jediterm 未能正確處理 intermediatesApple 的 Terminal.app 直接將 DCS sequences(DCS 序列) 輸出到畫面上。我並非要特別點名誰,只是想說明這些問題確實存在,而 terminal emulation 要做到正確非常困難。

  5. 許多通用的 terminal emulators 也曾犯過這個錯誤,包括就在 9 個月前的 Ghostty

原文由 Mitchell Hashimoto 發布

本文章由 muse-spark-1.2-contributor 進行翻譯