Clojure

結構編輯

什麼是結構編輯?

文字編輯器將檔案視為字元行。常見功能包括:輸入新字元、按行(上/下)或字元(右/左)導覽、選取/複製/貼上文字、刪除或取代文字等。所有這些操作都在字元或行層級執行。

當我們檢視 Clojure 程式碼時,我們會注意到它可以視為一個巢狀的表單集合,其中每個巢狀層級都是一個具有開始和結束分隔符號的集合:( …​ )[ …​ ]{ …​ } 等。這個規則結構形成一個樹狀結構,而結構編輯是一組新的操作,用於在節點/樹狀結構層級(而非字元/行層級)操作我們的程式碼。

結構編輯在 Lisp 語言的編輯中擁有悠久的歷史,並且最常與 Emacs 和特別是 Emacs paredit 模式相關聯。但是,這些概念比 Lisp 或 Emacs 更為普遍,事實上,幾乎所有設計用於支援 Clojure 的編輯器中都可以找到結構編輯。

類似於基於字元的編輯,結構編輯有方法來建立新的表單、導覽、選取、複製/貼上、刪除等,但所有這些都是針對巢狀表達式,而不是字元或行。此頁面旨在向您介紹結構編輯中的一些高階術語和概念,而不是涵蓋任何特定編輯器或按鍵,因為詳細資訊會因編輯器而異(而且通常也可以自訂)。

當您開始時,請專注於記住一組小的指令(以下將全部涵蓋):kill、slurp forward、barf forward、splice 和 raise。當您遇到其他情況時,請找出適當的結構編輯指令,並將其新增到您的工具組中。

平衡的表單

結構編輯的一般原則是確保所有表單隨時都保持平衡。在您的程式碼中建立新的表單時,這一點會立即顯而易見。如果您輸入集合的開始分隔符號,您的編輯器也會插入結束分隔符號。如果您輸入 (,您的編輯器會插入 (),並將您的游標置於中間,以便您可以在表單內繼續輸入。大多數編輯器還會提供一些視覺回饋,讓您在移動時比對開始和結束分隔符號,甚至可能根據這個結構支援程式碼摺疊和展開。

您可能會遇到的常見問題(特別是在學習時)是意外使用會破壞您的程式碼結構的行編輯指令。例如,如果您有一個多行巢狀表達式,從中間刪除一行很可能會刪除一個左括號,但不會刪除後續行中與它匹配的右括號。別驚慌!

修復此情況的一些常見方法

  • 復原 - 通常您只需復原該行指令,然後改用結構編輯指令

  • 關閉結構編輯,修正問題,然後重新啟用結構編輯 - 在某些編輯器中,頁尾或其他位置有一個按鈕可以切換結構編輯,這相對容易,在其他編輯器中則會比較困難。

  • 使用字元編輯指令修正 - 在某些情況下,例如要刪除懸空的開括號,你可以選取開括號並使用字元刪除功能將其刪除(在結構編輯之外)

  • 使用註解和字元編輯 - 如果你有一個懸空的開括號要關閉,你可以插入一個 Clojure 註解 ;,讓你能夠輸入 ),然後選取 ; 並使用字元編輯將其刪除

導覽和選取

導覽(以及選取,通常作為一個修飾符)是字元和行既有導覽和選取的延伸。除了選取下一個字詞之外,你還可以選擇選取下一個表達式或透過選取包含的表達式(往上)來擴充。別忘了你仍然可以使用滑鼠來選取,如果你覺得這樣最舒服的話。

剪下/貼上又稱 kill/yank

在 Emacs 中剪下文字稱為「kill」,貼上稱為「yank」。在 Emacs 中,kill 會將剪下的文字區塊放入「kill ring」,它實際上是一個堆疊。預設情況下,「yank」會貼上堆疊頂端的文字並將其從 kill ring 中移除。你的編輯器是否支援所有這些功能將取決於編輯器,但重要的是,當你在查看按鍵繫結時,「kill」表示「剪下」。

預設情況下,大多數結構編輯器會從目前位置剪下到目前集合的結尾。大多數編輯器都有各種其他選項,但對於你大部分的工作來說,預設的 kill 和選取就已經足夠了。

Slurp 和 barf

「slurp forward」指令會將目前集合後的表達式作為最後一個項目 slurp 到集合中。「barf forward」則相反,將集合的最後一個項目移到目前集合之外和之後。操作集合第一個元素的向後變體也存在,但不太常見。

拼接和提升

一個常見的情況是想要將目前集合的內容拼接進父集合中。在執行此動作時,你可以選擇在之前(「往後拼接」)或之後(「往前拼接」)刪除項目。你也可以只用游標處元素的值取代父元素,這稱為「提升」。

Parinfer

幾年前,一個新的 Paredit 替代品開發出來,稱為 Parinfer。Parinfer 將縮排連結到巢狀結構,因此你可以透過縮排程式碼來插入子表達式。許多編輯器支援 Parinfer 作為 Paredit 的替代品。如果你不熟悉結構化編輯,你應該試試看它是否適合你!一般來說,這似乎是個人偏好的問題。

資源

以下資源可能對你學習 paredit 指令或如何使用特定編輯器的結構化編輯有所幫助。一般來說,大多數核心指令集類似,且具有可設定的按鍵繫結。預設的按鍵繫結通常可以追溯到 Emacs 中的 Paredit,但不要受此限制,自訂這些按鍵繫結很常見。

原始作者:Alex Miller