Neovim 新聞 #11 - 聖誕特輯

2021 年 7 月

真正 的 0.5 版本是我們一路結交的朋友

期待已久的 Neovim v0.5.0 版本終於在 2021 年 7 月 2 日發布。它比大家期望的要晚,但等待是值得的:超過 4000 次的提交,它太大了,甚至破壞了一些發布工具。因此,這些說明無法涵蓋開發過程中進行的許多更改,只能著重於最明顯的改進,其中最大的是:

  1. Lua 作為第一級腳本和配置語言,
  2. 語言伺服器協定 (LSP),
  3. Treesitter (搶先體驗)。

Lua 無處不在!

Neovim 0.5 在使 Lua 成為 Neovim 的第一級腳本語言方面取得了很大的進展,無論是插件開發還是使用者配置。

提醒一下,Lua 是一種小型腳本語言,專為嵌入而設計,通常用於遊戲開發等。此外,還有一個即時編譯器 ( LuaJIT,Neovim 在可用的平台上會使用它構建),可以在相關任務上提供令人印象深刻的效能。本質上,Lua 之所以被選擇是因為它:

  1. 微小 - 非常適合嵌入 (與遠程插件主機相反),
  2. 快速 - LuaJIT 可以比 Vimscript (和未經 JIT 的 Lua) 快幾個數量級,
  3. 簡單 - 小巧但富有表現力的語法 (Lua 5.1) 專為腳本編寫而設計,Neovim 本身通過 API 公開內部函數來提供「標準程式庫」。

有關此選擇的更多詳細資訊,請參閱 Justin M Keyes 在 Vim Conf 2019 的演示文稿 和 TJ DeVries 在 Vimconf.live 的演示文稿

讓我們看看這對插件作者和使用者意味著什麼。

Lua 插件

Neovim 通過例如 vim.api.nvim_open_win() 將其 API 原生公開給 Lua。它還提供透過例如 vim.cmd("echo 'foo'")vim.g.syntax_on 來存取 vimscript (ex) 命令和變數的方法。這允許編寫與用 Vimscript 編寫的插件具有相同功能的插件,同時利用 Lua(JIT) 在循環等核心程式設計語言任務中的效能。也可以使用 Lua 自己的 luarocks 插件生態系統。

相應地,在 0.5 開發週期中,Lua 插件的數量激增,從流行的 Vimscript 插件的重寫到在 Vimscript 中不可能實現的全新插件 - 通常來自完全不熟悉 (neo)vim 插件開發並厭惡學習 Vimscript 來完成該任務的貢獻者。作為漫長開發週期的積極副作用,其中許多插件在 0.5 發布時已經功能齊全且穩定!

這是一個小型且不具代表性的 Lua 插件列表:

  • Plenary – 用於開發 Neovim 插件的有用實用工具程式庫 (其中一些稍後將整合到核心中)。
  • Packer – 一個支援插件依賴、延遲載入和安裝 luarocks 的套件管理器。
  • Telescope – 一個可高度擴展的列表模糊搜尋器。
  • Gitsigns – 一個用於顯示和與 git 儲存庫中檔案上的變更互動的插件 (非同步)。
  • Nvim-compe – 一個適用於各種來源 (包括 Neovim 內建的 LSP 客戶端) 的自動完成框架。
  • Nvim-dap – 一個用於逐步偵錯程式碼的除錯介面協定實作。
  • Colorizer – 一個用於 Neovim 的高效能顏色突出顯示器,無需任何外部依賴。
  • Formatter – 一個用於非同步執行目前緩衝區或範圍的外部格式化工具的插件。
  • Hop.nvim - 一個類似 EasyMotion 的移動插件,無需干擾您的緩衝區。
  • Neogit - 一個類似 Magit 的 Git 介面。

可以在使用者貢獻的 Awesome Neovim 集合中找到更全面的 Neovim 插件列表。

並非所有這些插件實際上都是用 Lua 編寫的:還有許多其他編譯成 Lua 的語言 (其中一些是類型化的),例如:

Lua 配置

也可以用 Lua 編寫使用者配置:如果有 init.lua,則會取代讀取 init.vim (它們不能共存,並且在您的配置目錄中同時擁有這兩者會產生錯誤),並且執行階段目錄中的 .lua 檔案 ( plugin/colorscheme/after/ 等) 除了 (在) Vimscript 檔案之外還會被載入。請注意,這是完全可選的,並非享受 Neovim 0.5 中引入的新功能所必需的;此外,並非每個 Vimscript 配置選項都具有完全原生的 Lua 對等物。擴展原生 API 以涵蓋這些也是 Neovim 0.6 的目標之一。

有關使用 Lua 進行 Neovim 腳本編寫和配置的全面且最新的指南,請參閱 開始在 Neovim 中使用 Lua。 使用 init.lua 進行 Lua 配置的良好模型是 Defaults.nvim

語言伺服器協定 (LSP)

語言伺服器協定 (LSP) 是一種基於開放 JSON-RPC 的協定,用於程式碼編輯器和語言伺服器之間的通訊,這些伺服器提供程式設計語言特定的功能,例如:

  • 完成,
  • 懸停/工具提示,
  • 跳到定義,
  • 顯示/跳到參考,
  • 顯示方法簽名,
  • 重新命名,
  • 程式碼動作 (自動格式化、組織導入、…),

等等。

想法是將這些功能分為獨立於編輯器但特定於語言的伺服器和獨立於語言但特定於編輯器的用戶端,它們通過 RPC 通過語言伺服器協定進行通訊。(應該指出的是,並非每個伺服器都實作每個功能,而且回應的品質可能會大相逕庭。VS Code 中的「參考實作」也經常添加 LSP 本身未涵蓋的非標準功能。)

Neovim 0.5 提供了一個 (大部分) 用 Lua 編寫的 LSP 用戶端,它提供了一種高度可配置且可擴展的方式來存取這些功能。它並非旨在與功能更豐富且「開箱即用」的插件 (如 CoC.nvim) 競爭,而是旨在根據您的偏好進行客製化 (同時仍然可以使用合理的預設值)。有關概述,請參閱 TJ DeVries 的 Vimconf.live 演示文稿 和他的 較短影片

對於許多語言伺服器,Nvim-lspconfig 已經提供了輕鬆設定一切所需的配置。或者,某些語言也有特定的 LSP 插件,它們提供更整合的設定,例如,適用於 JavaScala

要了解有關 LSP 以及如何在 Neovim 中使用它的更多資訊,請訪問 Nvim-lspconfig (包括其 Wiki) 並閱讀 :h lsp

預計在 0.5.x 開發週期中將會有更多關於 LSP 的工作,以提供改進的配置選項和更好地涵蓋最新的 LSP 規範 (在撰寫本文時為 3.16 版),包括語義突出顯示。

Tree-sitter

Neovim 0.5 增加了對 tree-sitter 的實驗性支援,tree-sitter 是一個將一段程式碼以增量且容錯的方式剖析為語法樹的程式庫;這表示在編輯後重新剖析該程式碼非常快,並且由於例如錯字而造成的剖析錯誤保持局部化,並且不會破壞進一步的剖析。然後可以有效率地查詢這棵樹,以取得有關程式碼的語法資訊。這可以改進和/或加速:

  • 語法突出顯示,
  • 程式碼導覽,
  • 重構,
  • 文字物件和移動,
  • 搜尋和取代,

等等。如果檔案的某些部分包含不同語言的程式碼,tree-sitter 也可以輕鬆地以不同的方式突出顯示這些部分。若要深入瞭解 tree-sitter,請觀看 Tree-sitter - 程式設計工具的新剖析系統 - Max Brunsfield

目標是用 tree-sitter 取代目前基於 vim 正則表達式的語法,不僅為了更好、更快的語法突出顯示,還為了以新的和改進的方式進行結構化文字編輯。但是,0.5 中對 tree-sitter 的支援仍應視為「搶先體驗」:它的運作狀況足以進行測試並了解可能實現的目標,但不應依賴它進行生產性使用,因為在 Neovim 中將 tree-sitter 宣告為穩定之前,需要解決許多嚴重的錯誤和效能回歸。另請注意,為某種語言啟用基於 tree-sitter 的突出顯示目前會完全禁用該檔案類型的內部基於正則表達式的語法引擎,這可能會破壞其他依賴它的功能。解決這些問題並改進 API 將是導致 0.6 版本發布的開發週期的主要重點。

此外,Neovim 本身僅提供一個 (Lua) API,用於使用捆綁的 tree-sitter 程式庫產生和查詢語法樹;請參閱 :h treesitter。使用者面向的功能 (如上述提到的功能) 是在諸如以下插件中實作:

  • Nvim-treesitter – 突出顯示、摺疊、增量選擇。
  • Playground – 用於輕鬆顯示剖析樹並對其執行查詢的實用工具函數。
  • Nvim-treesitter-textobjects – 為 vim 風格的移動和操作提供更好的文字物件。
  • Nvim-refactor – 突出顯示定義、導航、智慧重新命名。
  • Architext – 結構化文字編輯(例如,語法感知搜尋和取代)。

關於使用這些功能的更多資訊,請參閱 Nvim-treesitter 的 README 或觀看 Thomas Vigouroux 的 Vimconf.live 演講

LSP 和 tree-sitter 之間有什麼區別?

這是一個常見問題,特別是自從 LSP 在 3.16 版本提供「語義高亮」以來。簡而言之,tree-sitter 在單個檔案上運行,將檔案解析為語法樹,該語法樹用於支援各種增強的程式碼導航和操作功能。另一方面,語言伺服器跨多個檔案和專案庫運行,使用各種不同的、伺服器相關的方法來解析每個檔案的語法樹。(當然,tree-sitter 是此目的的一個可能選擇,實際上被例如 bash-language-serverwasm-language-server 使用。)

特別是,這意味著語言伺服器可以使用來自不同檔案的語義資訊來註解目前檔案的樹狀結構:例如,在一個檔案中宣告為 const 的變數,如果在不同的檔案中使用,則可以紅色突出顯示 – 這是 tree-sitter 無法做到的,因為在突出顯示時它只能存取後者檔案。

有關更多詳細資訊,請觀看 TJ DeVries 關於此主題的演講

其他變更

當然,這些並不是 0.5 版本中的唯一重大變更。以下是具代表性的新功能的簡短摘要。

裝飾

有一個改進的裝飾提供程式 API,允許設定和與 extmark (當周圍文字被編輯時會移動的不可見錨定文字標記)、虛擬文字(現在可以在螢幕上的任何位置繪製的文字覆蓋)和高亮(nvim-treesitter 大量利用)進行互動。

這個來自 @sunjon貼文的範本展示了使用此 API 可以實現的效果

浮動視窗

浮動視窗的 API 現在包括一個「z-index」(允許控制浮動視窗的堆疊方式)以及對邊框的支援。

選取時高亮顯示

Neovim 現在有一個內建函數,可以短暫地高亮顯示選取的區域(類似於 https://github.com/machakann/vim-highlightedyank),可以從 Lua 設定。要使用它,您可以將以下內容新增到您的 init.vim

au TextYankPost * lua vim.highlight.on_yank {higroup="IncSearch", timeout=150, on_visual=true}

有關更多配置選項,請參閱 :h vim.highlight.on_yank()

Vim 修補程式

在此版本中的 4000 多個 commit 中,大約有 1000 個是從 Vim 移植的修補程式和執行階段更新 – 幾乎所有這些都是由令人驚嘆的 @janlazo 完成或在其協助下完成的。特別是,執行階段檔案(語法檔案、文件等)已與 Vim 完全同步至 2021 年 5 月,並且已經包含許多後續的變更。

社群

與本通訊的座右銘一致,最顯著的積極變化之一是社群的成長以及與之互動的新方式。

Discourse

以前,支援請求和討論分散在 Reddit、Gitter 和 GitHub Discussions 中,要么是暫時的,要么很難搜尋。我們現在已經整合到新的 Neovim Discourse 周圍,這是一個免費且開放原始碼的論壇平台,除了精美的網頁介面外,還具有郵件清單和 RSS 功能。Neovim Discourse 是一個官方的核心專案,由核心團隊成員管理。

Matrix

Neovim 的官方聊天室位於 Gitter。在 Matrix(一個聯合聊天協定)收購 Gitter 後,現在也可以從 Matrix 存取此聊天室;它也橋接到 IRC 網路 Libera.chat。由於使用者數量不斷增加,現在還有其他更具體的聊天室,用於 開發和圍繞 neovim 的開發GUI離題聊天

(上面的連結是透過 Element 存取聊天室的連結,這是一個基於網頁的 Matrix 用戶端;您也可以透過其他許多 Matrix 用戶端 存取。)

Vimconf.live

由於全球 COVID-19 大流行,VimConf 2020 不幸被迫取消。取而代之的是舉辦了一場虛擬的 Vimconf.live 會議,有 16 位演講者和來自 12 個國家的 1000 多名註冊參與者。如果您錯過了,可以在 Youtube 播放清單上觀看講座。

Twitch

大流行的另一個影響是對 Twitch 上開放原始碼開發的直播興趣增加。Vimconf.live 的許多演講者都是活躍的實況主;特別是,TJ DeVries 定期以「開放原始碼」方式直播他在 Neovim 上的工作,Neovim 0.5 的發布也在他的頻道上直播。(更新:發布直播的編輯播放清單現在在 YouTube 上。)

Neovim 開發

參與 Neovim 開發的人數也增加了。在 0.4.4 和 0.5.0 之間,有 301 位獨特的 commit 作者,而 0.3.8 和 0.4.4 之間有 112 位(在可比較的時間範圍內)。

贊助

您現在可以透過 Github SponsorsOpenCollective 贊助 Neovim。(BountySource 開始對其服務條款協議進行令人擔憂的變更,因此不再推薦使用。)

接下來是什麼?

如前所述,在 0.5.x 發布週期中,將會進一步改進 0.5 中引入的頭燈功能

使 tree-sitter 成為穩定且更快的語法突出顯示(及其他)替代方案是 0.6.0 版本的主要目標。這包括對裝飾 API 的基礎工作,以允許諸如內嵌摺疊或插入虛擬行和列(「反隱藏」)之類的功能。

除此之外,值得注意的目標是 更好的檔案變更偵測,以及進一步將 TUI(終端 UI)與 Neovim 核心分離,目標是允許遠端 TUI 實例。

最後,我們的目標是更定期和頻繁地發布版本(至少對於修補程式版本),這有望改變「neovim 0.6 何時?」的迷因。

感謝

非常感謝所有參與該專案的人,他們幫助 Neovim 0.5 成為現實 – 無論他們是貢獻者、贊助者、錯誤報告者或支持者。為了避免完整地列出所有人員,以下是一些您可以感謝的人員,他們促成了本信件中列出的功能

最後,感謝 @justinmk@brammool 的基礎工作和遠見 – *vim 社群團結起來會更強大!

新聞

新聞存檔中查找更多更新。還有一個RSS 訂閱源

什麼是 Neovim?

Neovim 是一個基於 Vim 的文字編輯器,專為 可擴展性可用性 而設計,以鼓勵新的應用程式和貢獻

討論

造訪 #neovim:matrix.org 或 irc.libera.chat 上的 #neovim 與團隊聊天。