鮑彬 武云濤
摘? 要:Emacs是高擴展性的編輯器,可通過配置支持多種復雜編輯模式。不同于其它編輯器的簡單配置腳本,Emacs的配置和擴展是通過 Emacs-lisp語言完成的,Emacs配置普遍被認為是較為復雜的和難以掌握的。文章著重探討并分析了Emacs配置與擴展的相關技術。
關鍵詞:Emacs;Lisp;配置;擴展
中圖分類號:TP391 文獻標志碼:A 文章編號:2095-2945(2019)16-0134-03
Abstract: Emacs is a highly extensible editor that can be configured to support a variety of complex editing modes. Unlike the simple configuration scripts of other editors, the configuration and extension of Emacs is done through the Emacs-lisp language. Emacs configuration is generally considered to be more complex and difficult to master. This paper mainly discusses and analyzes the related technologies of Emacs configuration and extension.
Keywords: Emacs; Lisp; configuration; extension
1 Emacs簡介
Emacs是著名的文本編輯器,最初是在上世紀70年代完成。Emacs是“Editing MACros”的縮寫,意為宏編輯器。不同于一般的編輯器,Emacs具有極強的可擴展性。在文本編輯之外,Emacs通過與其他工具結合起來能夠支持各種語言程序開發(fā),上網(wǎng)和新聞組,文件和系統(tǒng)管理,撰寫文章等一系列功能,成為一個具有強大功能且高度集成的生產(chǎn)力工具。
2 Emacs與常見文本編輯器配置方式比較
2.1 Emacs和Vi比較
Emacs和Vi是深受程序員喜愛的兩大編輯器,各有特點。Vi是著名的輕量級文本編輯器,在完成輕量級任務時有很大優(yōu)勢,比如簡單調(diào)整系統(tǒng)配置,遠程終端的簡單訪問和操作。Vi的強大之處在于其編輯快捷鍵易用,和終端無縫結合。相比之下,Emacs復雜度要高很多,但在處理復雜任務,大量不同類型的文件時,Emacs將更有優(yōu)勢。值得注意的是,Vi也需要通過一定配置才能發(fā)揮較強的功能,比如大部分程序員為了方便開發(fā),還是結合多個較復雜插件將Vi配置為集成開發(fā)環(huán)境。在這個角度上,Vi擴展的編寫不如Emacs用Lisp語言開發(fā)那么方便,雖然理論上Vi也是可以用通用語言Python去擴展的,但畢竟不是原生的擴展語言。事實上通過合理配置,Emacs其實是可以模擬大部分Vi的特性的,這也是目前比較流行的模式,不使用原生的Vi,而是把Vi的特性結合進入Emacs中,兩者兼用。這個思路是目前大多數(shù)流行的Emacs配置采用的。
2.2 Emacs和Sublime Text,VS Code比較
近些年也有一些新的可擴展文本編輯器,比較有名的有Sublime Text,微軟寫的VS Code,這些工具也都意在提供高可擴展性的編輯工具,尤其是多種語言程序的開發(fā)工具。這些編輯器優(yōu)勢在于易于上手,其擴展性更多的是通過官方豐富的插件來完成的,對于新手更加友好。用戶也可以通過簡單腳本文件定制編輯器特性,不過其所支持的定制語言不夠強大,定制復雜配置是不容易的。相比而言,Emacs的可擴展性更強,定制方式更加靈活,所以很多人依然選擇使用Emacs而不是轉入新的文本編輯工具。對于經(jīng)驗豐富的編程人員來講,Emacs更容易按照自己的工作習慣加以配置和擴展,在眾多工具中依然是最佳的選擇。Emacs的另一個優(yōu)勢之處是可以和系統(tǒng)結合,不僅僅限制在集成開發(fā)環(huán)境這樣一個功能,而是可以擴展為可以替代Office,圖片瀏覽器,網(wǎng)頁瀏覽器等軟件的多功能集成工具。這是目前任何一款可擴展文本工具都是無法做到的,這也是Emacs作為一個古老軟件至今依然保持開發(fā)活躍的原因。當然,Emacs開源和社區(qū)高度開放的特性也是其優(yōu)勢之處和更容易擴展的原因之一。
3 Emacs配置與擴展技術
3.1 Emacs-lisp擴展編程
Emacs配置與擴展可以通過Emacs-lisp語言開發(fā)。Emacs-lisp語言是Lisp語言的一種方言。Lisp是早期的程序設計語言之一,其語言設計源于lambda計算理論,語言簡潔并能夠優(yōu)雅的支持目前主流的程序設計范式。Emacs-lisp包含完整的Lisp語言特性,這是由于Emacs底層用C語言實現(xiàn)了Lisp的解釋器和基本的內(nèi)置編輯函數(shù)。因此Emacs的大部分功能是由Emacs-lisp實現(xiàn)的,同樣也可以用Emacs-lisp語言方便的進行擴展,進一步Emacs-lisp語言也可直接訪問Emacs的內(nèi)置功能函數(shù)接口。這樣的特性使得使用Emacs-lisp進行程序設計和Emacs配置開發(fā)非常方便。
3.2 Emacs配置加載
Emacs的入口文件可以是~/.emacs或者~/.emacs.d/init.el。常見的方式是使用后者,因為后者有利于模塊化配置程序。Emacs配置一般是有一定規(guī)模的復雜程序,模塊化設計可以使配置程序易讀易改。Emacs-lisp語言的每一個模塊對應一個文件,在文件尾部使用provide使模塊可被其它程序引用,引用方式是通過require指定,從而加載模塊中的所有變量和函數(shù),使其對當前程序可見。為了模塊能被Emacs發(fā)現(xiàn)并正確加載,通常需要在init.el文件開始部分使用load-path指定所需所有模塊的路徑,作為加載配置的起始點。Emacs加載模塊并非只有這一種方式,事實上,為了加快Emacs的啟動速度,不是所有模塊都在init.el初始化時加載。最好的加載實踐是在Emacs啟動時僅加載基本模塊,其它功能模塊時在被使用時動態(tài)加載,比如啟動時不加載Python開發(fā)相關模塊,而且在打開Python文件進行編輯時才加載。有兩種方式可以實現(xiàn)動態(tài)模塊加載,不使用第三方工具的情況下,可以用autoload設置動態(tài)加載的函數(shù),結合宏with-eval-after-load指定動態(tài)加載配置代碼,實現(xiàn)模塊函數(shù)當調(diào)用時才加載,相關函數(shù)在模塊加載后才執(zhí)行。目前比較流行的方式是使用第三方工具use-package,該工具包定義了use-package宏,能夠以簡潔的方式指定模塊中需要動態(tài)加載的函數(shù)和變量,以及指定配置代碼與模塊加載的相對順序。