Emacs

Emacs（ˈ，源自Editor MACroS，宏編輯器），是一個文本編輯器家族，它具有可擴展性，使用者以程式設計師和其他以技術工作為主的電腦使用者為主。最初由理察·斯托曼於1975年在MIT協同蓋伊·史提爾二世共同完成。這一創意的靈感來源於TECO宏編輯器TECMAC和TMACS，它們是由蓋伊·史提爾二世、Q5237671、李察·格連布勒、Charles Frankston等人編寫的宏文本編輯器。

自誕生以來，Emacs演化出了眾多分支，其中使用最廣泛的兩種分別是：1984年由理查·斯托曼發起並由他維護至2008年的GNU Emacs，以及1991年發起的XEmacs。XEmacs是GNU Emacs的分支，至今仍保持著相當的兼容性。它們都使用了Emacs Lisp這種有著極強擴展性的程式語言，從而實現了包括編程、編譯乃至網路瀏覽等等功能的擴展。

在Unix文化裡，Emacs是黑客們關於編輯器之戰的兩大主角之一，它的對手是vi（Vim）。

## 歷史

Emacs在1970年代誕生於MIT人工智慧實驗室（MIT AI Lab）。在此之前，人工智慧實驗室的PDP-6和PDP-10電腦上運行的ITS作業系統的默認編輯器是一個叫TECO（Text Editor and Corrector）的行編輯器。與現代的文本編輯器不同，TECO將擊鍵、編輯和文本顯示按照不同的模式進行處理，稍晚出現的vi與它有些類似。在TECO上擊鍵並不會直接將這些字符插入到文檔裡去，必須先輸入一系列相應的TECO指令，而被編輯的文本在輸入命令的時候是不會顯示在螢幕上的。在如今還在使用的UNIX編輯器ed上，我們還能看到類似的工作方式。

1970年代初，理查·史托曼拜訪史丹福大學人工智慧實驗室（Stanford AI Lab）時見到了那裡的"E" editor。這種編輯器有著所見即所得的直觀特點，深深打動了史托曼，後來成為了大部分現代文本編輯器都具有的特性。後來斯托曼回到MIT，那時候MIT AI lab的黑客Carl Mikkelsen已經給TECO加上了稱作「Control-R」的編輯顯示模式，使得螢幕能跟隨使用者的每次擊鍵刷新顯示。斯托曼重寫了這一模式，使它運行得更有效率，後來又加入了宏，允許用戶重新定義運行TECO程序的鍵位。

這一新版的TECO立刻在AI實驗室流行開來，並且很快積累起了大量自定義的宏，這些宏的名字通常就以「MAC」或者「MACS」結尾，意為「宏」（macro）。兩年後，蓋伊·史提爾二世承擔起統一當時存在的各種鍵盤命令集的工作。史提爾和斯托曼經過一夜奮戰，最終由斯托曼完成了這一任務，包括一套擴展和注釋新的宏包的工具。這個完成的系統被稱作EMACS，代表「Editing MACroS」，也代表「E with MACroS」。

根據斯托曼的說法，他採用這個名字是「因為當時`<E>`在ITS裡還沒有被當作縮寫用過」。也有說法指出，當時波士頓在MIT附近有家名為「Emack & Bolio's」的商店出售的冰淇淋很受歡迎，Dave Moon是那裡的老主顧，他就將ITS上一個給文本排版的程序命名為BOLIO，然而斯托曼並不喜歡甚或根本不知道那種冰淇淋，此事後來成了黑客界的一樁公案。

斯托曼意識到過多的定製、在開發過程中事實上的分支以及針對特殊用途的限制，威脅著Emacs的發展。後來他寫道：

Emacs的發布基於社群共享，這意味著所有的發展都要反饋給我，由我進行整合和發布。

最初的Emacs同TECO一樣只能運行在PDP系列的電腦上。Emacs雖然是在TECO的基礎上發展起來的，不過它已經足以被認為是一個新的文本編輯器了。很快，Emacs就成為ITS上的標準編輯程序，接著由Michael McMahon從ITS移植到Tenex和TOPS-20作業系統上。其他Emacs早期的貢獻者還包括Kent Pitman、Earl Killian和Eugene Ciccarelli。到了1979年，Emacs已經是MIT人工智慧實驗室和它的電腦科學實驗室的主流編輯器了。

### 其他早期實現

後來幾年，程式設計師們寫了很多類Emacs的編輯器。其中包括Michael McMahon和Daniel Weinreb為Lisp機器寫的EINE（「EINE Is Not EMACS」）和ZWEI（「ZWEI Was EINE Initially」），還有Owen Theodore Anderson寫的Sine。Weinreb的EINE是第一個以Lisp實現的Emacs。1978年，Bernard Greenberg寫了Multics Emacs，大部分由Multics Lisp實現。Multics Emacs後來由Richard Soley維護。很多Emacs的變種，包括GNU Emacs，後來都將Lisp作為自己的擴展語言。

詹姆斯·高斯林，在1981年寫了Gosling Emacs，他後來還發明了NeWS和Java。作為第一個在Unix上運行的類Emacs編輯器，Gosling Emacs由C語言實現，並且以Mocklisp作為擴展語言。1984年，Gosling Emacs成為專有軟體。

### GNU Emacs

1984年，斯托曼開始致力於開發GNU Emacs，這將是一個自由軟體，以代替專有的Gosling Emacs。最初GNU Emacs是在Gosling Emacs的基礎上開發的，不過斯托曼後來用一個真正的Lisp解釋器代替了原來的Mocklisp解釋器，由於Lisp解釋器在此軟體中的核心地位，這意味著實際上重寫了幾乎全部代碼。GNU Emacs是GNU計劃的第一個項目，以C語言編寫，將Emacs Lisp（其解釋器由C實現）作為擴展語言。GNU Emacs最早廣泛發布的版本是15.34，出現於1985年。實際上版本2到12並不存在，GNU Emacs的早期版本都是以「1.x.x」的形式編號，直到1.12版時開發人員放棄了這一記法，因為他們認為主版本號是不應該改動的，所以版本號從「1」跳躍到了「13」。因此，Version 13是第一個public release，它發布於1985年3月20日。

GNU Emacs後來被移植到了Unix系統上。它比Gosling Emacs擁有更多的的功能，尤其是它有一個真正的Lisp作為擴展語言。結果，GNU Emacs很快就取代了Gosling Emacs，成為Unix系統上預設的Emacs編輯器。

到1999年為止，GNU Emacs的開發工作基本是在封閉的情況下進行。這種開發方式在《大教堂和市集》中被稱為「大教堂模式」。從那以後，GNU Emacs項目建立了公共開發郵件列表和匿名CVS代碼訪問，開發工作在一個CVS代碼倉庫中進行。2008年，Emacs開始使用Bazaar進行版本控制。

斯托曼是GNU Emacs的主要維護者，但他曾經有幾次把維護工作交給別人。他於2008年將代碼的維護工作交給了Stefan Monnier和Chong Yidong。他在mail list上發出以下內容：

### XEmacs

1991年，Lucid公司的Jamie Zawinski等人以GNU Emacs 19的一個早期alpha版為基礎，添加了一些新的特性，開發出Lucid Emacs。很快，Lucid Emacs的開發與GNU Emacs漸行漸遠，最終雙方的團隊放棄了將兩者合併的努力。Lucid Emacs被重新命名為XEmacs；至今為止，XEmacs仍然是最流行的Emacs變種之一。

### 其他GNU Emacs的衍生版本

其他的衍生版本，包括：

- Meadow - 一個Windows下的日語版本
- SXEmacs - Steve Youngs實現的衍生版本，基於XEmacs
- Aquamacs - 一個致力於與蘋果的OS X整合的Emacs版本

### 其他Emacs變種

除上述編輯器以外，還有很多不基於GNU Emacs的編輯器，有些項目的目標是創建一個精簡版的Emacs。在1980年代，GNU Emacs只能在很高端的電腦上運行，這就為精簡版的Emacs實現的出現奠定了基礎。還有一些Emacs變種是為了克隆一個完整的Emacs，但是使用不同的Lisp方言或者其他的程式語言。比如：

- MicroEMACS，原作者是Dave Conroy，後來由Daniel Lawrence進一步開發，有很多變種。
- Mg，原名MicroGNUEmacs，是一個MicroEMACS的公共領域分支，比MicroGNUEmacs更加接近於GNU Emacs。現在默認安裝在OpenBSD上。
- NotGNU，一個小型、快速的Emacs實現，是免費軟體，支持DOS、Win16、Win32和GNU/Linux，作者為Julie Melbin。
- JOVE（Jonathan's Own Version of Emacs），Jonathan Payne為類Unix系統寫的Emacs不可編程的Emacs實現。
- Zile是Zile Is Lossy Emacs的遞歸縮寫，以C語言編寫。
- Climacs，以Common Lisp編寫的Emacs變種。
- QEmacs，一個由Fabrice Bellard編寫的小型編輯器，支持UTF-8，可以快速編輯上百兆大小的文件。
- Epsilon，一個由Lugaru Software開發的Emacs變種。支持MS-DOS、MS-Windows、GNU/Linux、FreeBSD、O/S 2等作業系統。它使用了一個與C語言語法類似的非Lisp語言作為擴展語言。
- EmACT，1986年由Christian Jullien從MicroEmacs衍生而來，原始碼可以在SourceForge獲取。
- Hemlock，最初以Spice Lisp實現，後來改為Common Lisp。Hemlock是CMU Common Lisp的一部分，受到了Zmacs的影響。

### 可以模擬Emacs的編輯器

- Yi，以Haskell語言編寫，內置一個Emacs模擬器。
- Joe's Own Editor內置一個Emacs模擬器。
- JED內置一個Emacs模擬器。

## 版權

Emacs的版權遵從GNU通用公共許可證，賦予他人自由地對包括C和Lisp在內的Emacs源文件進行修改和再發行的權利。較早版本的GNU Emacs文檔是在一種點對點（ad-hoc）的許可下發布的，要求所有修改過的副本都要包含某些特定的文字。例如，GNU Emacs的使用者手冊中必須包含如何獲得GNU Emacs的說明，以及理查·史托曼的文章——《GNU宣言》。作為較早版本的GNU Emacs的分支，XEmacs的手冊也採用相同的使用許可。較新版本的GNU Emacs文檔則採用《GNU自由文檔許可證》，以使用「不變段落」（"invariant sections"）的形式包含有同樣的文本，並且要求這些文檔自我聲明為「GNU手冊」（GNU Manuals）。

## 功能特點

Emacs不僅僅是一個編輯器，它是一個整合環境，或可稱它為集成開發環境，這些功能如讓使用者置身於全功能的作業系統中。Emacs可以：

- 收發電子郵件、上新聞組（Gnus）
- 無縫直接編輯遠程檔案（Tramp）
- 通過Telnet登錄遠程主機
- 操作殼層（M-x EShell，Term）
- 結合git, mercurial等版本控制系統並直接操作（Magit，VC）
- 上Twitter（Twittering-mode）
- 登錄IRC和朋友交流（M-x ERC，rcirc）
- 電子數據表
- 模擬其他編輯器，如vi（Evil-mode）、WordStar、EDT、TPU等
- 編輯Wiki (Wikipedia-mode)
- 對多種程式語言的編輯，如C/C++、Perl、Python、Lisp等等
- 調試程序，結合GDB，EDebug等。
- 玩遊戲
- 計算器
- 心理諮詢（M-x doctor）
- 煮咖啡
- 記筆記、日記（Org-mode）
- 管理日程，Task，待辦事項（ToDo），約會等GTD（Org-mode）
- 寫作與出版（Org-mode，Muse-mode）
- 目錄管理（Dired）
- 文件比較、合併（Ediff）
- 閱讀info和man文檔（M-x info，woman）
- 瀏覽網站（M-x eww）
- 為各種程序（TeX、LaTeX等）提供統一的操作界面

此外Emacs還有如下特點：

- 實時編輯器
- Self-documenting
- 可定製性
- 可擴展性（集成Lisp語言）

### 可定製性

GNU Emacs幾乎所有的功能都可以定製，有的可以通過C語言實現，有的可以通過一個Lisp的方言——Emacs Lisp來實現。在Lisp環境中，變量和子程序可以在不重新編譯/啟動Emacs的前提下被修改。Emacs使用者可以根據自身的需要和偏好對編輯器進行定製。強大而自由的個人定製功能是Emacs受到廣泛歡迎的重要原因之一。定製Emacs主要有三種方法：

- 使用Emacs的交互式定製功能（即customize）。Emacs提供了圖形化的交互界面，使使用者能夠對可定製的公共變量進行設置，也可以定製配色主題。這種方法使Emacs的初學者不需要接觸Emacs Lisp代碼即可完成定製。
- 將一系列按鍵記錄為宏，調用這一宏可以自動重複進行已經記錄的一系列複雜操作。宏可以保存並命名，以便按名調用，不過同一時刻只能存在一個匿名的宏。
- 通過使用Emacs Lisp完成Emacs的定製。這種方法最為複雜，但是也提供了更多的靈活性和更強大的功能。使用者通常將個人定製的Emacs Lisp代碼保存在一個名為`.emacs(.el)`（或init.el）的配置文件中，Emacs程序運行之初便讀取這一文件，完成使用者要求的配置。使用者可以通過`.emacs`文件重設變量、重新定義按鍵的綁定（key bindings）、以及定義新的命令，以方便使用者個人的使用。很多高級用戶的`.emacs`文件的個性化配置長達數百行甚至更多，這些個人的定製使他們的Emacs不僅與默認配置的功能不同，每個人的Emacs之間也千差萬別。這種差異能很好的滿足不同個性的偏好和不同工作的需求。

如果一段Emacs Lisp代碼確實有用，它通常會被打包並發布給其他使用者。在網際網路上能找到很多這樣來自第三方的Emacs Lisp庫，例如能用於編輯維基百科條目的wikipedia-mode。Usenet上的新聞組 gnu.emacs.sources專門發布新的Emacs Lisp庫。有些第三方代碼最終還成為了Emacs的一部分。

手工配置安裝各種Emacs Lisp代碼畢竟有些麻煩。為了解決這個問題，Emacs 24自帶包管理器ELPA（package.el）。使用者可以方便的瀏覽可用的包（M-x package-list-packages）和自動下載安裝包（M-x package-install）。詳細資訊可以參考Emacs Wiki上的 ELPA詞條。

### 性能

在GNU Emacs剛誕生時，它比相同系統上的其他編輯器運行速度要慢很多，但是現代的電腦可以很快地運行GNU Emacs。早期的GNU Emacs可以處理256 MB以下的文件，GNU Emacs 23.2將這一限制提升到512 MB，而在64位系統的GNU Emacs 24中，這個限制是大約2 EiB。

### 平台

Emacs是目前世界上最具可移植性的重要軟體之一，能夠在當前絕大多數作業系統上運行，包括各種類Unix系統（GNU/Linux、FreeBSD、NetBSD、OpenBSD、Solaris、AIX、OS X等）、MS-DOS、Microsoft Windows等。甚至在Android和諾基亞的Maemo上，Emacs也能運行。

GNU Emacs既可以在文本終端也可以在圖形使用者界面環境下運行。在類Unix系統上，GNU Emacs使用X-Window產生GUI，或者直接使用「框架」（widget toolkit），例如Motif、LessTif或GTK+等等。Emacs也能夠利用OS X和Microsoft Windows的本地圖形系統產生GUI。用GUI環境下的Emacs能提供菜單欄（Menubar）、工具欄（toolbar）、滾動條以及環境菜單（context menu）等交互方式。

### 編輯模式

#### 主模式

Emacs採取的編輯方式是對不同類型的文本進入相應的編輯模式，即「主模式」（major mode）。Emacs針對多種文檔定義了不同的主模式，包括普通文本文件、各種程式語言的源文件、HTML文檔、TEX與LaTeX文檔，以及其他類型的文本文件等等。

每種主模式都有特殊的Emacs Lisp變量和函數，使使用者在這種模式下能更方便的處理這一特定類型的文本。例如，各種程式語言的主模式通常會提供：

- 語法高亮（「font lock」）：對源文件文本中的關鍵字、注釋加以不同的字體和顏色（「faces」）。
- 自動縮進，用來維護文件的格式一致。
- 自動插入文件所需要的結構元素，如空格、換行以及括號。
- 特殊的編輯命令，比如跳轉到函數的開頭或者結尾，或者（在類似於XML的標記語言中）驗證文檔還有插入關閉標籤。

#### 次模式

Emacs還能進一步定義「次模式」（minor mode），用以深度定製Emacs。一個GNU Emacs的緩衝區（buffer）只能關聯於一種主模式，卻能同時關聯多個次模式。比如，編寫C語言的主模式可以同時定義多個次模式，每個次模式有著不同的縮進風格（indent style）。

### 國際化

Emacs支持對多種文字的文本編輯，加上對多種字符集、字母系統、書寫系統，以及不同文化的書寫習慣都提供了支持，使得世界上大多數語言的使用者都能通過Emacs進行文本處理。Emacs還能通過調用諸如Aspell這樣的外部程序，實現多種語言的拼寫檢查。GNU Emacs 24添加了對雙向文字的支持。

Emacs支持包括UTF-8在內的諸多編碼系統。GNU Emacs從23開始以UTF-8作為自身的編碼系統，而在之前的版本，Emacs擁有一種特殊的內部編碼系統MULE（MULti-language Environment），在讀寫文件時進行編碼和解碼。XEmacs編碼系統和GNU Emacs相似，但具體的實現方法不完全一樣。

一個叫做Emacspeak的子系統可以通過音訊反饋，讓擁有視覺障礙的使用者和盲人使用者使用Emacs。

## 使用Emacs

### 命令

在普通的編輯模式下，GNU Emacs和其他文本編輯器一樣，允許用戶通過按下鍵盤上的鍵插入其相對應的字符，也可以使用鍵盤上的方向鍵來移動光標。使用各種修飾鍵（如Ctrl、Alt、Shift等）和其它的普通鍵配合可以調用Emacs Lisp函數和宏。

某些GNU Emacs命令會調用外部程序，比如使用Aspell進行拼寫檢查或者使用GCC進行程序編譯，解析被調用的外部程序的輸出，並將結果顯示出來。習慣IBM Common User Access的使用者可以使用「cua-mode」，「cua-mode」曾經是一個第三方插件，從GNU Emacs 22開始被包含在Emacs中。

下表給出了一些基本命令。Ctrl鍵以大寫C表示，Meta鍵Alt鍵以大寫M表示。

命令｜快捷鍵｜功能

`forward-word`｜`M-f`｜向前移動一個單詞。

`isearch-forword`｜`C-s`｜遞增搜索

`undo`｜`C-/`｜撤銷最後一次操作，如果多次執行則取消以前的操作。

`keyboard-quit`｜`C-g`｜取消當前的命令。

`find-file`｜`C-x C-f`｜在一個新的緩衝區里訪問某個文件（使用者給定文件名）。

`save-buffer`｜`C-x C-s`｜將緩衝區的內容保存到文件。

`save-some-buffers`｜`C-x s`｜保存所有的緩衝區

`save-with-newname`｜`C-x C-w`｜將緩衝區的內容另存為一個新的文件。

`save-buffers-kill-emacs`｜`C-x C-c`｜提示是否保存文件，然後退出Emacs。

`set-mark-command`｜`C-[空格]<sup>注</sup>`｜設定標記，用於剪切或複製。

`kill-region`｜`C-w`｜剪切標記到當前光標所在處的文本。

`kill-ring-save`｜`M-w`｜複製標記到當前光標所在處的文本。

`yank`｜`C-y`｜從Emacs的剪貼板中粘貼文本。

`kill-buffer`｜`C-x k`｜關閉當前buffer。

註：中文系統C-空格一般為系統輸入法，可使用C-@代替。

### 小緩衝

Emacs使用「小緩衝」（通常在最下面一行）顯示資訊提示以及輸入命令和命令參數。在合適的情況下，小緩衝支持使用製表鍵或空格鍵補全。每個frame只有一個小緩衝。

### 文件管理與顯示

Emacs將文本存放在緩衝區中。使用者可以創建新的緩衝區，也可以關閉不需要的緩衝區，Emacs可以同時存在很多緩衝區。大部分的緩衝區的文本來自文本文件，使用者可以編輯緩衝區的內容，並且保存到磁碟上。緩衝區也可以保存臨時文本，比如「help」庫顯示的文檔字串。

### 程式語言支持

#### Python

- Emacs 內建的 python-mode
- Elpy

### Emacs小拇指

很多Emacs使用者都有過重複性勞損的經歷，原因是Emacs強烈依賴Ctrl鍵和Meta鍵，也由於Ctrl鍵在現代鍵盤中的位置。

解決方法有軟體方法，也有硬體方法。軟體方法包括：

- 使用 ergoemacs-mode 定製鍵盤布局。
- 定製鍵盤布局，使Ctrl和大寫鎖定鍵交換位置。其他相似的方法包括將大寫鎖定鍵定義為Ctrl，或交換Ctrl和Meta鍵。
- god-mode 可以讓 Emacs 不用修飾鍵就觸發命令。
- 使用 evil-mode，一個高級的 Vim 模擬層。
- Emacs有一個內置的「Viper-mode」，允許用戶使用vi的鍵綁定來進行基本的文本編輯，而使用Emacs本身的鍵綁定來進行更高級的操作。
- 讓一個更容易按的鍵（如空格鍵）擁有多種功能，當那個鍵和其他鍵一起按下時，功能為Ctrl鍵的。
- 使用語音輸入控制Emacs。
- 很多軟體，如xwrits，可以提醒使用者進行定期的休息。

硬體方法包括使用特殊的鍵盤，如Kinesis鍵盤的修飾鍵放在大拇指很容易按到的位置，或者微軟自然鍵盤，它的修飾鍵對稱的放置在鍵盤的兩邊，並且可以使用手掌按下。腳控踏板也是一種方法。

如果使用普通鍵盤，可以在按Ctrl組合鍵時手掌下移，用無名指擊Ctrl，或者直接以小指掌骨壓下Ctrl，以規避小指過度利用。

「Emacs小拇指」是近些年才出現的。在Emacs誕生時，鍵盤的Ctrl鍵非常大，並且在空格鍵的旁邊，使用大拇指很容易按。

Vim 的擁護者經常以Emacs小拇指作為切換編輯器的原因，雖然有些 Vim 使用者（因為相似的原因）也會交換模式轉換鍵和大小寫轉換鍵的功能。

## 外部連結

- GNU Emacs官方網站，包括：
- GNU Emacs常見問題解答
- GNU Emacs for Windows常見問題解答
- A paper on the design of the original Emacs，by Stallman
- "Multics Emacs: The History, Design and Implementation" by B. Greenberg
- "Emacs Timeline" by J. Zawinski
- "List of Emacs implementations" by C. Finseth
- Reviewed entry in the Free Software Directory
- Emacs實現列表
- WikEmacs
- Emacs中文網(已失效)
- Emacs China中文論壇
- 中文Emacs User's Guide
- IBM dw教程：生活在Emacs中
- Emacs Wiki：一個關於Emacs的wiki。網站上有英語、漢語等多種語言。EmacsWiki主要是提供一些Emacs的使用教程、技巧和使用者貢獻的配置文件。像其他wiki一樣，所有人都可以編輯。不過EmacsWiki沒有註冊的制度，不需要帳戶就可以編輯整個wiki。

## 參考文獻

- 註：本文第一部分，部分引用自遵守GFDL的《Emacs使用者指南》漢譯版

## 基本資料

- 日語原文：GNU Emacs
- 作者：理查·史托曼和蓋伊·史提爾二世
- 開發者：GNU計劃
- 作業系統：GNU/Linux、FreeBSD、AIX 4.3.3或更高、macOS、MS-DOS、Windows、NetBSD、OpenBSD、Solaris等
- 類型：文本編輯器
- 軟體版本週期：170
- 軟體版本週期：2001年
- 許可協議：GNU通用公共許可證