文字編輯器將檔案視為字元行。常見功能包括:輸入新字元、按行(上/下)或字元(右/左)導覽、選取/複製/貼上文字、刪除或取代文字等。所有這些操作都在字元或行層級執行。
當我們檢視 Clojure 程式碼時,我們會注意到它可以視為一個巢狀的表單集合,其中每個巢狀層級都是一個具有開始和結束分隔符號的集合:( … )
、[ … ]
、{ … }
等。這個規則結構形成一個樹狀結構,而結構編輯是一組新的操作,用於在節點/樹狀結構層級(而非字元/行層級)操作我們的程式碼。
結構編輯在 Lisp 語言的編輯中擁有悠久的歷史,並且最常與 Emacs 和特別是 Emacs paredit 模式相關聯。但是,這些概念比 Lisp 或 Emacs 更為普遍,事實上,幾乎所有設計用於支援 Clojure 的編輯器中都可以找到結構編輯。
類似於基於字元的編輯,結構編輯有方法來建立新的表單、導覽、選取、複製/貼上、刪除等,但所有這些都是針對巢狀表達式,而不是字元或行。此頁面旨在向您介紹結構編輯中的一些高階術語和概念,而不是涵蓋任何特定編輯器或按鍵,因為詳細資訊會因編輯器而異(而且通常也可以自訂)。
當您開始時,請專注於記住一組小的指令(以下將全部涵蓋):kill、slurp forward、barf forward、splice 和 raise。當您遇到其他情況時,請找出適當的結構編輯指令,並將其新增到您的工具組中。
結構編輯的一般原則是確保所有表單隨時都保持平衡。在您的程式碼中建立新的表單時,這一點會立即顯而易見。如果您輸入集合的開始分隔符號,您的編輯器也會插入結束分隔符號。如果您輸入 (
,您的編輯器會插入 ()
,並將您的游標置於中間,以便您可以在表單內繼續輸入。大多數編輯器還會提供一些視覺回饋,讓您在移動時比對開始和結束分隔符號,甚至可能根據這個結構支援程式碼摺疊和展開。
您可能會遇到的常見問題(特別是在學習時)是意外使用會破壞您的程式碼結構的行編輯指令。例如,如果您有一個多行巢狀表達式,從中間刪除一行很可能會刪除一個左括號,但不會刪除後續行中與它匹配的右括號。別驚慌!
修復此情況的一些常見方法
復原 - 通常您只需復原該行指令,然後改用結構編輯指令
關閉結構編輯,修正問題,然後重新啟用結構編輯 - 在某些編輯器中,頁尾或其他位置有一個按鈕可以切換結構編輯,這相對容易,在其他編輯器中則會比較困難。
使用字元編輯指令修正 - 在某些情況下,例如要刪除懸空的開括號,你可以選取開括號並使用字元刪除功能將其刪除(在結構編輯之外)
使用註解和字元編輯 - 如果你有一個懸空的開括號要關閉,你可以插入一個 Clojure 註解 ;
,讓你能夠輸入 )
,然後選取 ;
並使用字元編輯將其刪除
導覽(以及選取,通常作為一個修飾符)是字元和行既有導覽和選取的延伸。除了選取下一個字詞之外,你還可以選擇選取下一個表達式或透過選取包含的表達式(往上)來擴充。別忘了你仍然可以使用滑鼠來選取,如果你覺得這樣最舒服的話。
在 Emacs 中剪下文字稱為「kill」,貼上稱為「yank」。在 Emacs 中,kill 會將剪下的文字區塊放入「kill ring」,它實際上是一個堆疊。預設情況下,「yank」會貼上堆疊頂端的文字並將其從 kill ring 中移除。你的編輯器是否支援所有這些功能將取決於編輯器,但重要的是,當你在查看按鍵繫結時,「kill」表示「剪下」。
預設情況下,大多數結構編輯器會從目前位置剪下到目前集合的結尾。大多數編輯器都有各種其他選項,但對於你大部分的工作來說,預設的 kill 和選取就已經足夠了。
「slurp forward」指令會將目前集合後的表達式作為最後一個項目 slurp 到集合中。「barf forward」則相反,將集合的最後一個項目移到目前集合之外和之後。操作集合第一個元素的向後變體也存在,但不太常見。
幾年前,一個新的 Paredit 替代品開發出來,稱為 Parinfer。Parinfer 將縮排連結到巢狀結構,因此你可以透過縮排程式碼來插入子表達式。許多編輯器支援 Parinfer 作為 Paredit 的替代品。如果你不熟悉結構化編輯,你應該試試看它是否適合你!一般來說,這似乎是個人偏好的問題。
以下資源可能對你學習 paredit 指令或如何使用特定編輯器的結構化編輯有所幫助。一般來說,大多數核心指令集類似,且具有可設定的按鍵繫結。預設的按鍵繫結通常可以追溯到 Emacs 中的 Paredit,但不要受此限制,自訂這些按鍵繫結很常見。
動畫 Paredit,作者 Dan Midwood
Smartparens for Spacemacs,作者 Practicalli
Cursive 結構化編輯指南,來自 Cursive 使用者指南
Calva paredit 指南,來自 Calva 使用者指南
原始作者:Alex Miller