Emacs 安裝配置使用教程

Emacs 安裝配置使用教程

來源 https://www.jianshu.com/u/a27b97f900f7html

 

序|Preface

先來一篇有趣的簡介:Emacs和Vim:神的編輯器和編輯器之神 - 51CTO.COMnode

爲什麼寫這篇教程?

做爲一個徹頭徹尾的emacs新手,儘管有些薄弱的編程經驗,但上手這麼一個黑客級別的編輯器仍是不免一段陣痛期。雖然網上有不少很是好的教程,好比這篇著名的文章,一年成爲Emacs高手(像神同樣使用編輯器),雖然提供了一個很好的學習框架,但具體的學習內容仍是須要你本身尋找。這篇教程,在某種意義上能夠被視爲按照那個學習框架進行的學習實踐。python

在實踐過程當中,我發現相關基礎知識的優秀教程散佈在互聯網的各個角落,缺少一個有條理的組織,更別提有些排名靠前的教程早已過期,裏面提到的操做和方法已經不適用於最新版的emacs。git

雖然emacs能夠做爲一個簡單的文本編輯器開箱即用,但陡峭的學習曲線主要體如今讓它發揮最大功效的個性化定製之中。這篇教程整理了我在配置emacs過程當中學到的知識,方便新手按部就班的學習。建議你將它做爲一個有內在結構的課程來對待。整個教程大約會花掉你18個小時。github

誰該閱讀這篇教程?

我學習emacs的初衷是爲了作日程管理,記筆記,而且寫研究論文。個人學習和研究常常涉及到各類編程語言,特別是各類統計軟件,好比R,SAS,Stata,Matlab等,固然還有Python。雖然R和Python都支持「文學編程」模式[1],但若是想將多種語言整合進一個文檔的話,emacs的org-babel模式無疑是第一選擇。而既然是想寫研究論文,對於Latex的支持必不可少。因此,我配置的emacs會以方便「文學編程」,多格式導出(主要是Latex和html)以及各類文檔模板爲重點,主要圍繞emacs的兩個插件org和auctex來展開,可能還會涉及到知識整理,以及同Evernote互動的內容。另外,許多配置步驟在Unix系統下會方便不少,但很不幸,我使用的是windows。shell

因此,若是你是emacs小白,但有一點編程經驗,有同我相似的需求,而且也使用windows,那麼這篇文章就是爲你量身定製的。歡迎閱讀!編程

爲何不直接使用高手寫好的配置?

這個教程自己就借鑑了許多高手的配置。我堅信「授人以魚不如授人以漁」的格言。我相信我對你最大的幫助是這篇教程自己,而不是那些配置文檔。但願做爲新手的你,在閱讀完這篇教程後,能得到足夠的信心和動力來打造一個獨屬於你的emacs。windows

如何學習這篇教程?

請注意我使用了「學習」而不是「閱讀」。這意味着你須要本身動手,實踐那些優秀教程提到的操做。本身寫一些代碼,而不是單純的複製粘帖。瀏覽器

凡是附在「參考」後的文章,儘管大部分是英語文章,都請你仔細閱讀。固然,你能夠先瀏覽我寫在後面的筆記和總結,來得到一個初步理解。你甚至能夠只閱讀個人總結來基本理解我要談的事情,這看上去會節省你大量的時間,但其實你在不知不覺中錯過了不少我沒說起但對你很重要的細節。No pain, no gain...若是你堅持不讀參考文章,請至少記得它們的標題。等你遇到問題時,至少知道該用什麼樣的關鍵詞來搜索答案。安全

附在「延伸閱讀」後的文章都頗有價值,有助於你深刻理解前文提到的概念。加了「必讀」標籤的請優先閱讀。標籤"TD"表明文章中出現了不少我還沒說起的技術細節(Technique details),須要更多的背景知識。因此,若是你在閱讀中感到困惑,能夠先跳過,等學習完整個教程後再來閱讀。所以,TD還有一層TODO的意味……

在閱讀我給出的文章時,你可能但願完成一個「知識閉環」後再回來繼續學習。所謂「知識閉環」,就是持續瞭解閱讀過程當中遇到的新概念,直到再也不遇到新的概念爲止。顯然,這會耗費大量的精力,並且你的疑問一般會在後續的教程中獲得解決。我在撰寫這個教程時,並沒假定你完成了「知識閉環」後再繼續學習,因此,建議你只對最大的疑惑作擴展閱讀,好比選擇性的瀏覽文章中包含的超連接。

下載安裝|Download and Installation

官網:http://ftp.gnu.org/gnu/emacs/windows/

打開網頁後,頂部是一段關於如何安裝的說明文檔。

總結:

  • 不須要安裝,解壓縮到某個路徑就能夠了
  • 爲了方便全局調用,請添加bin路徑到環境變量(好比個人,C:\emacs\bin)。你可能須要先了解下環境變量和命令行的基本知識。搜索關鍵詞「windows環境變量PATH」,「啓動cmd」
  • 測試下,在cmd裏,輸入emacs -nw[2],以終端模式來運行emacs;只輸入emacs,以GUI模式來運行
  • 文檔介紹了bin目錄下各個exe文件的功能,也介紹了怎樣徹底卸載,直接刪除就好
  • 解壓縮完成後,能夠運行bin\addpm.exe,這樣會自動生成配置文件.emac和目錄.emacs.d,而且在啓動菜單裏添加應用程序快捷方式。另外,官方文檔裏說還會添加註冊表的相關條目。不過在個人電腦上,註冊表並未新增相應條目
  • 能夠在桌面上新建一個快捷方式(shortcut),位置(location)填入emacs的安裝路徑\bin\runemacs.exe --debug-init。加了flag --debug-init,是爲了方便調試(debug)配置文件。不推薦爲emacs.exe創建快捷方式,由於會額外啓動一個命令行窗口。

請選擇24以上的版本

延伸閱讀: FAQ 3.2

其餘版本

我的推薦

下面這兩個版本能夠省去大部分配置的麻煩事。不過多勞多得,請自行選擇

更多版本

基本操做

打開emacs,同時按下Ctrlh,而後鍵入t,閱讀新手教程,熟悉界面,基本術語和操做。
請不要跳過這一步!(但不要求熟練掌握)
本文後面的部分已經假定你閱讀了這個教程,因此默認遵循emacs的術語規範。

C表明Ctrl鍵。M表明Alt鍵。RET表明Enter鍵(回車鍵)。C-x表明同時按下CtrlxC-x d RET表明先同時按下Ctrlx,再按下d,最後再按下RET。我在後文的按鍵描述中,會常常省略最後一步的回車操做。另外,請留意描述所用的英文字母的大小寫。

Emacs裏的大部分地方都支持自動補全,快捷鍵是TAB

配置篇|Configuration

編程基礎

你可能會奇怪,爲何配置emacs還須要編程?通常配置一個程序,不都是經過菜單欄打開一個對話框,而後修改裏面提供的選項麼?在emacs裏,的確有這麼一套配置系統,詳見Emacs's Customization Tutorial。但我的不推薦使用。由於,第一,裏面提供的選項並不徹底,許多配置只能經過編程才能作到;第二,它也是經過在你的配置文件中加入一些代碼來實現的。

配置emacs的全部代碼構成了一個配置文檔。Emacs的配置文檔是用elisp語言寫的。elisp是lisp的一種方言。至於lisp語言,有人說它是黑客的語言。不過你並不須要徹底理解elisp才能配置emacs。至少我對elisp談不上熟練。不過我卻是看過一些lisp語言的入門教程,因此可以看得懂elisp的官方幫助文檔。你能夠參考Learn X in Y minutes來快速入個門。因爲elisp的函數命名規則大部分都很直觀,因此只要瞭解了基本語法,大部分配置語句對你來講都會變得很直白。下面列出幾個配置文檔時的經常使用函數,只是讓你熟悉下elisp的語法。更多的函數會在用到時講解。

參考set

  • 變量賦值。好比(set 'a 5)至關於a=5

參考setq

  • 這個其實就是爲了偷懶,在一次執行多個賦值操做時少打幾個'

參考let

  • let的意義在於批量執行函數時定義共享參數。考慮下面這個使用情景,你但願連續調用函數A,B,C,它們都接受一個字符串參數s,s表明某個路徑。A負責打印字符串s,並提示接下來要利用s作什麼事情;B負責切換到s指定的位置而後執行一些操做;C負責將s加入到某個全局列表中。你固然能夠不用let,在調用函數前加上一句(set 's 一個字符串)便可。但這時定義的s會成爲全局變量,進而污染你的變量空間。

HOME

參考The Emacs Initialization File

  • Emacs配置文檔常見的文件名有兩個,.emacsinit.el,雖然本質上它們都是elisp腳本(像python腳本那樣)。
  • 你能夠用任何文本編輯器來編輯他們。我的推薦使用Notepad++,支持語法高亮,列編輯。Notepad++能夠很方便的進行區域註釋(Ctrl+qShift+Ctrl+q),這對調試配置文檔很重要。固然,在你熟悉emacs後,emacs也許會成爲你的惟一編輯器
  • 當你在使用Notepad++編寫本身的配置文檔時,可能常常須要執行註釋或者反註釋某段代碼的操做。註釋時請用Shift+Ctrl+q,反註釋時請用Ctrl+q。前者會保證在每一行代碼前都加一個;,後者則是,若是本行代碼以;開頭,就刪掉一個;,若是不以;開頭,則添加一個;。容易理解,當代碼塊中包含註釋時,你確定不但願在註釋掉代碼的同時反註釋掉那些註釋。

接下來,讓咱們先來了解emacs在哪裏尋找配置文檔,以及會具體選擇哪一種格式。

參考How Emacs Finds Your Init File,瞭解emacs啓動時配置文件的加載規則

  1. Emacs會在系統中尋找一個名爲HOME的變量,而後拷貝一個副本供本身使用,並在其指定的路徑下尋找配置文件
  • 各個平臺的默認HOME路徑請參考
    HOME and Startup Directories on MS-Windows
  • windows平臺,在cmd使用echo %userprofile%來查看HOME[3]
  • The MS-Windows System Registry介紹了emacs尋找默認參數的路徑的前後順序
    • 注意,環境變量是第一位的,若是沒有才會在註冊表中尋找。也就是說,若是環境變量和註冊表都包含HOME的話,emacs會拷貝前者做爲本身的副本。這一般不是一個好消息。一方面,你但願儘可能按照本身的意願來設置emacs的HOME變量;另外一方面,你可能已經爲別的應用程序建立了系統級別的HOME,以致於不得不把emacs的配置文件也放在那裏
    • 我的認爲,一個更合理的加載邏輯應該是,順序檢測一系列路徑,後面檢測到的值覆蓋前面的。這樣你就能夠經過建立註冊表的方式來避免與系統環境變量的衝突
    • 對於windows 7/8/8.1,若是你的環境變量和註冊表裏都沒有HOME,emacs會把%userprofile%的值設置爲HOME,通常是
      C:\Users\your-user-name\AppData\Roaming
  1. 一般,emacs會優先加載.emacs,若是找不到,而且存在文件夾.emacs.d,會嘗試加載其中的init.el

  2. 基於前面的介紹,一個比較好的安裝配置方案以下:

  • 將emacs的壓縮包解壓到某個路徑

  • 運行bin路徑下的runemacs.exe

  • c-x d ~ RET,編輯區域左上角的文件路徑即emacs的HOME。或者鍵入C-h v user-init-file並查看返回值

  • 在HOME路徑下,emacs會自動生成.emacs.d文件夾,若是沒有請本身創建

  • 在該文件夾下新建init.el,輸入以下代碼

     

;; This file is only for windows 7/8/8.1
;; The only thing it does is to set the HOME directories for emacs,
;; then trigger the init.el in the directory specified by HOME to
;; accomplish the true initialization
;; You should put this file in the default HOME directory right after
;; emacs is installed
(setenv "HOME" "C:/emacs/") ;; you can change this dir to the place you like
(load "~/.emacs.d/init.el")
```

  • 最後一行代碼中,~表明emacs的HOME路徑。因爲前面已經從新設定HOME,因此這行代碼至關於調用C:/emacs/.emacs.d/下的init.el。關於load命令,後面有詳細解釋
  • 順便刪掉前面幾步中你見到的任何.emacs文件,保證emacs利用init.el啓動

這樣作的好處是,除了能夠自定義.emacs.d所在的路徑,還能夠方便的備份整個文件夾,由於插件一般會被安裝到這個文件夾下。若是須要換到其餘電腦甚至平臺時,只須要把整個文件夾複製過去,而後相似於上述步驟那樣,想辦法讓真正的init.el發揮做用便可。
使用init.el而不是.emacs來配置,能夠保證配置文件的結構化和模塊化,方便維護。

最後規定後文要常常用到的幾個代指

  • ~代指重定義後的emacs的HOME路徑
  • user-emacs-directory指代~\emacs.d,該路徑能夠在啓動emacs後經過C-h v user-emacs-directory來查看。
  • init.el代指user-emacs-directory下的版本,是咱們要配置的版本

延伸閱讀:

PATH

從這個章節開始,對於提到的非emacs程序,都假定這些程序的主要可執行文件(exe)所在路徑已經被添加到系統的環境變量PATH中。 對於python,R,pandoc,cygwin等,網上有不少安裝並配置環境變量的教程。仍不熟悉基本操做的能夠先看看「延伸閱讀」的第一篇文章。

在向init.el寫入任何代碼以前,先打開emacs試用一下。鍵入M-x python,若是沒報錯的話,就成功進入了python模式。Emacs並不自帶python,那它是怎麼知道去哪裏調用python.exe的呢?

參考Emacs: Set Environment Variables within Emacs

原來Emacs繼承了windows的環境變量PATH。輸入M-x getenv RET PATH查看PATH[4]

實際上,當你在emacs中運行shell時[5],各個指令的搜索路徑是PATH。而當emacs自身須要尋找某個可執行文件時,好比python,搜索路徑是exec-path,而默認,在windows平臺下,emacs會直接拷貝系統的環境變量。也就是所說,在init.el中修改emacs的PATH副本並不會同時修改exec-path

當咱們安裝了一些只想同emacs結合使用的軟件時,若是不想修改系統的環境變量,能夠在init.el中加入:

(setenv "PATH" (concat "C:/Program Files (x86)/Notepad++" ";" (getenv "PATH") ) ) 

這樣,你就能夠在emacs中打開一個shell,而後鍵入notepad++來調用它了。注意,這個修改並不會在exec-path中追加相應的路徑。若是你但願emacs也能調用notepad++,還須要同步修改exec-path,具體方法請參見原文。

若是你像我同樣不想同步exec-path最簡單的方案就是把相關程序的安裝路徑添加到系統的環境變量中

延伸閱讀:

加載

對於任何軟件,一個駕輕就熟的配置基本基本都要用到插件,好比Chrome。

對於emacs,新安裝的插件常常要你本身去啓動並配置。這是emacs上手難的重要緣由之一。考慮一個最簡單的安裝流程,你從網上下載了某個**.el文件,而後在init.elload這個文件。是否是load那一步顯得很彆扭?而功能更強大的插件可能由更復雜的文件結構組成,須要你作更多的準備工做才能正常使用。這個時候,一個插件管理系統就很必要了。24以上的版本都集成了一個插件管理器elpa,能夠方便的經過M-x list-packages來安裝插件。不過別高興的太早,經過elpa安裝的插件一般仍須要你手動來加載和配置。

注意,是加載,而不是激活。回憶下你是怎麼使用Chrome的插件系統:安裝插件,插件的圖標出如今瀏覽器地址欄的右側,點擊插件的圖標來使用插件(激活其功能),有的插件甚至默認激活。這個過程當中,全部加載和初始化配置的工做都由軟件自動完成,你惟一須要作的就是選擇用不用(激活)而已。

然而,elpa要求你本身完成加載和配置的步驟。通常來講,常見的載入命令有,requireloadautoload等。而所謂的配置就是初始化一些參數。

emacs通常稱「插件」爲"package"或者"library"。本質上,它們都提供一堆定義好的函數,來實現一些操做,進而實現某個功能。這裏多說幾句。在emacs中,連移動光標這種最底層的操做都有對應的函數。好比,你在emacs中能夠鍵入C-f來將光標向右移動一個字符,同時也可鍵入M-x forward-char來實現。任何複雜的功能,好比給文檔生成一個目錄,均可以被分解爲一個個操做,或者說調用一個個函數,而這些函數順序執行下來功能就獲得了實現。

當emacs想要加載某個插件時,歸根到底須要定位並運行一個(也許是一些)腳本文件,那個腳本里定義了實現插件功能所需的變量和函數。emacs將它們轉變爲可供本身使用的對象(elisp object),放到運行環境中等待調用。而腳本自身還能夠在內部進一步加載其餘腳本。下面,來了解加載腳本的幾個語句,loadrequireload-fileautoload

參考Emacs Lisp's Library System: What's require, load, load-file, autoload, feature?

  • load一個位於硬盤上的文件,意味着執行這個文件裏的全部elisp語句,而後將執行結果放進emacs的運行環境
  • Feature能夠理解爲「特點功能」,好比,你在蘋果的App Store裏查看應用程序簡介時,通常都會看到一個以Features開頭的段落。單數形式,feature,通常對應一個插件的名字,由於通常插件的名字直接代表它實現的功能。複數形式,features,是一個用來存儲feature的列表,這個列表能夠告訴emacs哪些插件經被加載了。通常狀況下,一個插件的啓動腳本的結尾會調用(provide '<symbol name>),將'<symbol name>加入到features中去。'<symbol name>通常就是插件的名字
  • (require '<symbol name>)會先查看features裏面是否存在<symbol name>。若是存在,語句執行完畢。若是不存在,基於它來猜一個文件名,或者由require的第二個參數直接指定文件名,而後load文件。注意,load完成後,require函數會再一次查看features列表中是否存在'<symbol name>,若是發現仍是不存在,視參數<soft-flag>來決定是否報錯
  • require的意義在於避免重複加載。好比,某個插件的啓動腳本中須要用到另外一個插件提供的某個函數。那麼它就會require這個插件,保證插件已被載入,而後再執行後續語句。
  • load會搜索load-pathload-file須要指定文件路徑,autoload在一個函數被call後再load指定文件

延伸閱讀 Required Feature

其實,連整個emacs的啓動均可以歸納爲一句話:加載一系列腳本。只不過這些腳本有的是內置的(built in),有的是你安裝的插件包含的,有的是你本身寫的。

配置emacs歸根結底是在配置各類各樣的腳本。

接下來,請思考以下問題。
你能夠在init.elload各類各樣的腳本,使得emacs在啓動時就把整個使用過程當中可能用到的函數一次性準備好。但這樣真的好麼?

參考Autoload

  • autoload告訴emacs某個地方有一個定義好的函數,而且告訴emacs,先別加載,只要記住在調用這個函數時去哪裏尋找它的定義便可
  • 這樣作的一個好處是,避免在啓動emacs時由於執行過多代碼而效率低下,好比啓動慢,卡系統等。想象一下,若是你安裝了大量的有關python開發的插件,而某次打開emacs只是但願寫點日記,你確定不但願這些插件在啓動時就被加載,讓你白白等上幾秒,也不但願這些插件在你作文本編輯時搶佔系統資源(內存,CPU時間等)。因此,一個合理的配置應該是,當你打開某個python腳本,或者手動進入python的編輯模式時,才加載那些插件
  • 一個簡單歸納:「只註冊函數名而不定義函數自己」

前面介紹了幾種加載機制。加載的目的在於定義變量和函數以供使用。任何插件,只有先被加載才能被使用。並且一般,你都但願先加載一個插件,再來配置它。考慮以下情景。

你的插件中定義了一個變量a,默認值是1,插件內定義的許多函數都在內部使用了a。你但願在本身使用這些函數時,用到的a的值是2。有兩種實現途徑。一種是直接到插件的腳本文件中修改a的值爲2。這叫作"hard coding",有不少壞處。好比,每次更新插件,都要從新修改。另外一種方法是,等這個插件已經被加載後,修改相應的elisp object。那天然,你得先讓這個對象存在於emacs中,而後才能修改。因此要先加載,讓須要配置的變量獲得定義,再去修改變量的值。

下面,讓咱們來看看這些腳本文件究竟長什麼樣子。打開emacs內置插件的文件夾,emacs安裝路徑\share\emacs\24.4.91\lisp,你會看到一些子文件夾,一些後綴名爲gz的壓縮文件,以及一些後綴名爲elc的文件。壓縮文件中存放的實際上是同名的.el文件,也就是前面一直在提的腳本。.elc是這個腳本編譯好的版本,能夠加快載入速度,不適合人類閱讀。因此,若是你想查看一個插件的源代碼,請查看.el文件。.el被放在壓縮包是爲了不源代碼被修改,進而形成各類問題。另外,加載插件時,老是會優先加載編譯好的版本,其默認的文件擴展名即.elc;若是不存在,纔會加載.el或者其餘格式的文件。

延伸閱讀

Elpa

有了前面鋪墊的基礎概念後,讓咱們來學習使用elpa。Elpa(Emacs package system)也是一個插件,只不過它是管理插件的插件。在emacs24和更高的版本中,elpa是一個內置插件,腳本文件package.el位於emacs安裝路徑\share\emacs\24.4.91\lisp\emacs-lisp。有些插件由於由多個腳本構成,會被放在一個單獨的文件夾中。初始化這個腳本的主腳本的文件名一般由插件名加上.el構成。注意,若是你修改了一個腳本文件,而且同名.elc存在,那麼必須從新編譯該腳本才能使改動生效。

參考Emacs: How to Install Packages Using ELPA, MELPA, Marmalade

  • 默認的插件安裝路徑是~/.emacs.d/elpa
  • 默認狀況下,elpa的相關函數已經在啓動emacs時註冊(回憶autoload)。直接鍵入M-x list-packages便可調用
  • 因爲在啓動時只是註冊函數名,因此elpa的啓動腳本並未加載。若是你想在配置文檔中修改腳本中定義的變量,好比package-archives,請先(require 'package)該原則適用於其餘插件的配置。也就是說,若是你想在init.el中修改某個插件的某個變量的值,請保證emacs在執行這條修改語句時,相關變量已經獲得定義
  • 通常用來初始化該插件的主腳本的文件名都是插件名.el

爲了保證你能夠自行試驗後文的操做,如今請你到init.el中添加一段代碼:

(require 'package) ;;; Standard package repositories ;; We include the org repository for completeness, but don't normally ;; use it. (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/")) ;;; Also use Melpa for most packages (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/")) (add-to-list 'package-archives '("melpa-stable" . "http://melpa-stable.milkbox.net/packages/")) 

上述代碼給elpa添加了幾個額外的插件來源。不用理會其中的語法,反正在後面配置init.el時我會提醒你刪掉這段代碼。

須要注意,elpa智能但不傻瓜。

參考 Emacs 24 Package System Problems

  • 安裝一個插件後,elpa會自動在插件所在目錄下生成一個autoloads文件。這個文檔本意是方便你調用插件的。好比,你能夠在init.el中加入(load 某某插件-autoloads)來加載該插件
  • 若是你但願用require的方式來加載插件,而且還但願require這個autoloads文件,會出現一個問題。autoloads的結尾並無(provide '某某插件-autoloads),因此require必定會報錯。並且這樣作也沒什麼意義。由於你的目的在於將插件自己的名字放到features列表中,而不是「插件名-autoloads」。因此,請load而不是requireautoloads文件
  • 固然,你也能夠直接加載插件的主腳本,好比(require 'auto-complete)而不是(load 'auto-complete-autoloads)。不過,這樣作有兩個壞處。第一,有些插件可能會指導elpa在生成autoloads文件時加入一些配置代碼。在這種情形下,有可能你經過load這個autoloads文件能成功初始化插件,而直接load或者require插件的主腳本則不能。第二,autoloads由autoload函數構成,autoload的好處如前所述,能夠輕便化emacs的啓動

load-path

下面來談一個很重要的變量,load-path,其變量類別是「列表」,做用範圍是「全局變量」。打開emacs,鍵入C-h v load-path RET。若是你是在剛安裝完emacs後鍵入這個命令,獲得的返回值應該相似這樣:

("c:/emacs/share/emacs/24.4.91/site-lisp" "c:/emacs/share/emacs/site-lisp" 此處省略若干行 

中文部分是我本身加上的,告訴你我爲了節省空間,刪掉了許多行。

每次使用elpa安裝插件後,這個值都會發生改變。好比,在初次使用elpa安裝完ack插件後,
load-path會變爲:

("~/.emacs.d/elpa/ack-1.3/" "c:/emacs/share/emacs/24.4.91/site-lisp" "c:/emacs/share/emacs/site-lisp" 此處省略若干行 

請自行把~腦補爲HOME路徑。

經過對比,不難發現,emacs在啓動時,會將user-emacs-directory/elpa路徑下的的全部文件夾加入到load-path頭部。因爲elpa的默認安裝路徑是~/.emacs.d/elpa,因此第一行會是~/.emacs.d/elpa/ack-1.3/。你用elpa安裝的任何插件,其所在路徑都會位於load-path頭部。我想強調,這個位置,很是重要。

在emacs24及更高的版本中,emacs自帶了一個org插件,位於emacs安裝路徑\share\emacs\24.4.91\lisp\org,這個插件後面會詳細講解。每次啓動emacs,這個路徑都會被添加到load-path中。在emacs中鍵入M-x org-mode會調用org插件,讓編輯區域進入org模式。

org插件有不少相關插件。假設如今,你想經過elpa安裝某個相關插件,好比,bog,執行以下操做:

  • 鍵入M-x list-packages RET,出現選擇編碼的提示,鍵入RET
  • 定位bog:鍵入C-s Extensions for research notes in Org mode,而後鍵入C-s RET
  • 在emacs窗口左側,點擊光標所在行出現的小個左箭頭,而後點擊bog

你會在新出現的窗口看到語句Requires: org-8.0.0, dash-2.5.0,代表該插件依賴額外的兩個插件org和dash。elpa會智能的安裝全部依賴插件。注意,儘管你的emacs自帶org,elpa仍是會選擇安裝本身的插件源中的版本。因此,最後load-path會變爲:

("c:/emacs/.emacs.d/elpa/bog-0.6.0/" "c:/emacs/.emacs.d/elpa/dash-20150311.2355/" "c:/emacs/.emacs.d/elpa/org-20150316/" "c:/emacs/.emacs.d/lisp" "c:/emacs/share/emacs/24.4.91/site-lisp" 此處省略若干行 "c:/emacs/share/emacs/24.4.91/lisp/org" 此處省略若干行 

elpa安裝的org排在了emacs自帶org的前面。

load-path如其名字所示,告訴emacs在加載任何腳本時,若是沒有指明腳本所在路徑,那麼就去load-path所含的路徑中尋找。而後使用第一個找到的腳本。也就是說,此後你調用org插件時,使用的都會是elpa安裝的版本,即插件的一個版本'shadow'了另外一個版本。

'shadow'現象很常見。除了前面提到的'shadow'內置插件,elpa安裝的插件的新版本會'shadow'舊版本。請記住一個很是有用的命令,list-load-path-shadows,它能夠總結全部插件當前的'shadow'狀態。如今,請你本身鍵入M-x list-load-path-shadows RET,而後閱讀下返回的信息。

'shadow'之因此發生,是由於load-path中包含了同一個插件多個版本的腳本路徑,哪一個版本排在前面就使用哪一個。

總結下,在配置插件時,請時常反問本身以下問題:

  • 當我想加載一個插件時,emacs知不知道它的所在路徑?
  • 當我想修改插件定義的某個參數時,是否已經加載了這個插件?
  • 會不會某個已經存在的版本,shadow了我想使用的版本?

最後,學習下修改load-path的經常使用操做。

參考Modifying List Variables

  • 優先關注add-to-list的語法。

延伸閱讀

牛刀小試

整套配置文件的思路參考Emacs配置文件——新手攻略

雖然說是新手攻略,仍是太簡潔了些。不過,請你大概閱讀一遍,並將做者的配置文件下載到本地,解壓,而後將emacs.d-master文件夾下的文件全部文件拷貝到你的user-emacs-directory。這會覆蓋你本身的init.el,沒關係,固然你爲了保險能夠備份下。下面用以前創建的專門用來調試配置文檔的快捷方式運行emacs。emacs會按照init.el的指導自動安裝並配置相關插件。但不知你的運行結果怎樣,個人會報錯。

Required feature ... was not provided

Debugger entered--Lisp error: (error "Required feature `switch-window-autoloads' was not provided") require(switch-window-autoloads) eval-buffer(#<buffer *load*-432260> nil "c:/emacs/.emacs.d/lisp/editing-utils/init-switch-window.el" nil t) 

有了前面鋪墊的基礎,你應該能很好理解錯誤的緣由:應該load一個autoloads文檔,而不是require。定位到出錯的文檔,把(require 'switch-window-autoloads)修改成(load "switch-window-autoloads")。注意,根據requireload的語法規則,我把switch-window-autoloads從一個符號(Symbol)改爲了一個字符串(String)。

順便檢查下同文件夾下的其餘配置文檔,更正相同的錯誤。關閉emacs再次運行。你會發現,後續還會在各類各樣的init文檔中出現一樣的錯誤。請一一更正。

"Cannot open load file" ... "org-exp"

Debugger entered--Lisp error: (file-error "Cannot open load file" "no such file or directory" "org-exp-blocks") require(org-exp) (progn (require (quote org-exp)) (require (quote org-clock)) (require (quote org-fstree))) (lambda nil (progn (require (quote org-exp)) (require (quote org-clock)) (require (quote org-fstree))))() eval-after-load(org (lambda nil (progn (require (quote org-exp)) (require (quote org-clock)) (require (quote org-fstree))))) eval-buffer(#<buffer *load*-5658> nil "c:/emacs/.emacs.d/lisp/init-org.el" nil t) 

這裏的quote指單引號字符'。請打開文檔定位出錯語句。而後Google搜索"org-exp",發現只有org-exp-blocks,估計"org-exp"是做者本身寫的吧。請註釋或刪除(require 'org-exp)

在讀過org-exp-blocks的幫助文檔後,你可能很是想加載這個插件。不過請注意,文檔中提到:

make sure that the path to org's contrib directory is in your load-path and add the following to your .emacs.

什麼是"contrib directory"?檢索下本地的org插件所在文件夾,不管是elpa版本,仍是內置的,都沒有"contrib directory"。Google後發現,這個目錄裏包含了許多org用戶寫的插件,由於不是org官方開發者寫的,因此沒被包含在前面的兩個版本中。

到這裏,也許你會覺得org-exp-blocks也在"contrib directory"中。恭喜你,上當了。

參考Org-mode Contributed Packages

  • 請看"Moved to core"那一部分,很容易找到下面這句話
    "Org-exp-blocks is now part of the Org core. Link to raw file."
  • 也就是說,如今不用手動調用org-exp-blocks了。因此,你其實什麼也不用作
  • 不得不說,有點坑爹。吃一塹長一智,請記住這個頁面,之後配置文件出現問題時,也許不是被'Moved to core',就是被'Obsolete'了

作完以上操做,再次啓動emacs,應該能順利進入歡迎界面了。不過,要知道,仍是有不少未被'Moved to core'但很是有用的插件,通常只包含在org官網提供的beta版本中。那應該怎樣獲取呢?

Build Org

參考Org官網

  • 想得到官方的beta版本,須要用到工具Git。下載並安裝好。
  • 用桌面上出現的Git快捷方式打開Git,鍵入pwd,記住當前的工做路徑。或者你也能夠經過cd命令來切換到你想要的工做路徑
  • 記住當前的工做路徑。鍵入git clone git://orgmode.org/org-mode.git。等待beta版本的org被下載到本地。提示:也許在你的git中,粘帖操做被綁定爲鼠標右鍵
  • 將工做路徑下的org-mode文件夾重名爲org-beta,拷貝到user-emacs-directory。重命名那步沒什麼特別含義,只是爲了區分。若是你選擇拷貝到其餘路徑,請自行調整後續命令
  • 打開init-org.el,在第一行加入(add-to-list 'load-path (expand-file-name "org-beta\\lisp" user-emacs-directory)),相信你不用查閱幫助文檔也能理解expand-file-name的做用。這行代碼將org-beta的核心腳本所在路徑添加到load-path,至關於讓beta版本'shadow'其餘版本
  • 你還須要把org-beta目錄下下的org-contrib\lisp添加到load-path,由於這個目錄即前面所說的"contrib directory"。在第一行下面額外添加代碼:(add-to-list 'load-path (expand-file-name "org-beta\\org-contrib\\lisp" user-emacs-directory))
  • 到這步,你應該能夠正常使用emacs了。不過,爲了真正的「安裝」org-beta,請繼續執行下述操做
  • 額外下載並安裝Cygwin。參考Cygwin詳解「Cygwin在線安裝指南」一節。必定要執行「Cygwin中模塊的各類分類」一節提到的操做,即安裝Devel這個部分的模塊,由於要用到其中的automake模塊。記得安裝完後配置環境變量
  • 打開emacs,鍵入M-x pwd,返回路徑若是不是org-beta所在的那個,就切換過去。具體操做,鍵入C-x d ~ RET .emacs.d/org-mode/ RET
  • 切換後,再次鍵入M-x pwd,確認路徑正確。而後鍵入M-! make。注意,Alt!要一塊兒按,即同時鍵入AltShift和數字鍵1。make命令源於Cygwin中的automake模塊,它會把org-beta的全部核心腳本編譯好,而後創建幫助文檔的索引
  • 打開emacs,鍵入M-x org-version RET,返回信息中包含的路徑若是是org-beta,即代表'shadow'成功
  • 前面幾步的操做也適用於編譯其餘插件

如今,請你執行以下操做:

  • 刪掉user-emacs-directory下的elpa文件夾
  • 從新運行emacs,讓emacs在更正後的配置文檔的指導下從新初始化

你會發現,竟然又報錯了!出錯語句是配置文檔org-magit-autoloads中的(eval-after-load "org" '(progn (org-add-link-type "magit" 'org-magit-open 'org-magit-export) (add-hook 'org-store-link-functions 'org-magit-store-link)))。我想你已經猜到了,這必定跟使用beta版本的org有關。註釋掉init-org.el中的頭兩行代碼,讓emacs使用elpa版本的org。而後打開emacs鍵入M-x list-packages來強制刷新下插件列表。最後再次刪掉elpa文件夾並運行emacs。若是之後你想使用beta版本,記得反註釋掉頭兩行代碼。

一陣繁忙的下載後,emacs應該能不報錯的完成初始化。可是看看編譯記錄(complied log),發現有大量的warning信息。請把log保存下來,以便之後分析。把光標切換到complied log區域,鍵入C-x C-f,而後選擇合適的路徑和文件名,鍵入RET保存log。

後文中我會以init.log來代指這個文件。

恭喜,如今你已經擁有了一個功能很是強大的emacs了。趕快探索下吧。

最後補充下我我的偏好的額外設置。

init.el

關閉煩人的警示音。禁止啓動後的歡迎頁面。

;; Turn off sound alarms completely (setq ring-bell-function 'ignore) ;; disable welcome page (setq inhibit-startup-message t) 

custom-set-variables區域添加代碼,讓emacs啓動後自動全屏。請注意括號的匹配。

(custom-set-variables 其餘代碼 '(initial-frame-alist (quote ((fullscreen . maximized)))) ) 

當你經過emacs的自定義系統(本篇最開始提到)修改emacs設置後,emacs自動將相關代碼添加到init.elcustom-set-variables區域。這裏咱們直接添加代碼來實現功能。

安裝Emacs Speaks Statistics: ESS,使org模式下能夠運行R,SAS等(固然,你要額外安裝這些統計軟件)

參考Installing ESS on your system

  • 同編譯org-beta的步驟相似。我把ess-14.09放到user-emacs-directory,而後運行emacs並切換工做路徑到ess-14.09,最後make
  • init.el中添加
(add-to-list 'load-path (expand-file-name "ess-14.09" user-emacs-directory)) (load "ess-autoloads") 
  • 運行emacs,鍵入M-x R。若是能進入R session,那麼就是安裝成功
  • (load "ess-autoloads")是最小配置,若是你但願用到ess的所有功能,請加載ess-site.el(注意load-path

init-org.el

開啓org模式下的代碼高亮;導出代碼塊時不運行代碼;跳過運行代碼塊時的確認步驟(可能有安全風險)。在註釋;; Various preferences下方添加代碼

;; Various preferences (setq 其餘代碼 ;; turn on the syntax highlight in the org mode org-src-fontify-natively t ;; when exporting the org file, do not evaluate the code block if the exports header is both org-export-babel-evaluate nil ;; skip the confirmation step when evaluate a code block org-confirm-babel-evaluate nil) 

導出PDF時代碼高亮使用minted,在上面的代碼塊下方添加

;; Include the latex-exporter (require 'ox-latex) ;; Add minted to the defaults packages to include when exporting. ;; set snippet-flat to nil to exclude minted for latex preview ;; see http://orgmode.org/worg/org-tutorials/org-latex-preview.html (add-to-list 'org-latex-packages-alist '("" "minted" nil)) ;; Tell the latex export to use the minted package for source ;; code coloration. (setq org-latex-listings 'minted) ;; Let the exporter use the -shell-escape option to let latex ;; execute external programs. ;; This obviously and can be dangerous to activate! ;; multiple compile in order to generate everything (setq org-latex-pdf-process '("xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" "bibtex %b" "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f" "xelatex -shell-escape -interaction nonstopmode -output-directory %o %f")) 

參考Export org-mode code block and result with different styles

  • 這段代碼要求你安裝了Latex和Python。推薦使用TeX LiveAnaconda。確保Latex安裝了minted插件,Python安裝了Pygments插件。另外請配置好環境變量
  • Latex有時須要屢次編譯才能正確導出全部元素。所以會出現三個xelatex語句
  • bibtex命令能夠生成.bbl文件,這個文件用來生成參考文獻列表。放到中間是由於,它須要藉助第一個xelatex生成的.aux文件,一個臨時輔助文件,來實現轉換。原理很簡單。文獻信息存儲在格式爲bibtex的.bib文件中。根據不一樣的文獻引用標準和具體的引用條目(由.aux提供),.bib內的信息在通過篩選、重組後被放入.bbl文件,用來生成最終的文獻引用內容
  • 由於minted包依賴python,因此latex在編譯時須要調用外部程序python。latex以爲這種行爲存在風險,默認禁止。-shell-escape容許latex運行"shell command",進而容許調用python

另外,若是你想在org模式下用RefTex來引用文獻,有一個插件'ox-bibtex',它能夠在導出到Latex和HTML時自動生成參考文獻附錄。'ox-bibtex'在org-contrib中。因此若是要啓用這個插件,請配合啓用org-beta後再加載這個插件。
用這個插件導出Latex時,若是你遵守前面的配置,應該一切正常。HTML導出功能須要用到bibtex2html。許多人在使用這項功能時都會遇到錯誤Executing bibtex2html failed。參考
Emacs: unifying citations between html and latex in org-mode
,問題在於不能使用臨時文件。這個問題最終也沒獲得很好解決。下面我給出一個windows8.1+texlive 2014使用環境下的解決方案,不保證其餘環境也適用。

bibtex2html

其實方案很簡單,安裝最新版本的bibtex2html便可,目前是1.98。這裏只是給不熟悉Unix開發環境的同窗們指個路。

參考Github上的說明文檔

  • 先去下載最新的開發者版本bibtex2html-1.98.tar.gz,解壓到本地文件夾中,好比bibtexdir
  • 運行cygwin,cdbibtexdir
  • 鍵入./configure,等待程序運行完畢
  • 鍵入make,等待程序運行完畢
  • 若是你但願cygwin能在內部調用bibtex2html,再鍵入make install,這會把bibtex2html安裝到cygwin64所在路徑\usr\local\bin
  • 如今,bibtexdir目錄下會出現'bib2bib.exe','bibtex2html.exe' ,'aux2bib'
  • 將三個文件拷貝到系統環境變量PATH中的某個路徑,確保你在cmd中鍵入bibtex2html能夠調用相關.exe文件
  • 大功告成

init-auctex.el

使用Sumatra PDF(請下載並安裝)來預覽PDF。最大的好處是,能夠從PDF逆向定位TEX。即你編譯完.tex文檔並調用Sumatra PDF預覽時,在PDF中雙擊某個位置,emacs會自動打開對應的.tex文件並定位過去。

參考Sync Emacs AUCTeX with Sumatra PDF,在(load "auctex-autoloads")下面添加

;; run latex compiler with option -shell-escape (setq LaTeX-command-style '(("" "%(PDF)%(latex) -shell-escape %S%(PDFout)"))) ;; use Sumatra PDF to preview pdf (setq TeX-source-correlate-mode t) (setq TeX-source-correlate-method 'synctex) (setq TeX-view-program-list '(("Sumatra PDF" ("\"Sumatra安裝路徑/SumatraPDF.exe\" -reuse-instance" (mode-io-correlate " -forward-search %b %n ") " %o")))) 

請將Sumatra安裝路徑替換爲你本身的安裝路徑。並打開Sumatra的option界面,按照參考文章的回答設置Set inverse search command line

其餘配置

參考 Moving The Ctrl Key,綁定ctrlcapslock

我採用AutoHotkey的方式,而且將腳本放到startup文件夾來實現開機自啓。個人電腦上,startup的路徑:
C:\Users\xiaohang\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

延伸閱讀 windows下自定義配置的說明

初入江湖

通過以上配置,你的emacs應該已經比較好用了。不過在emacs世界裏,此時的你還只是個初入江湖的小蝦米。在至關的一段時間內,你會糾結於emacs複雜的按鍵組合,爲想方設法也不能安裝好一個小插件而抓狂。我想說,這都是正常現象。在這些痛苦中,你慢慢成長,從讀官方文檔開始,一點點熟悉elisp,開始欣賞emacs的設計,甚至能本身寫一個小插件。因而,你使用emacs愈來愈順手,愈來愈想打造一個獨屬於本身的配置,最大化你在各個場景下的使用效率。

而個人教程到這裏也要告一段落了。我已經把本身所知悉數傳授給了你,從這裏開始,咱們處在同一個起跑線上。但我想,這套教程並不會結束,由於我還有不少承諾沒同你兌現呢,好比分析init.log,好比講解org模式。不過,相信你通過前面的學習,已經能靠依靠本身探索emacs中的大部分事物了。而我,也會逐漸積累本身的使用心得。

我計劃以下呈現後續的教程:圍繞一個具體的使用情景,我會向你描述個人插件選擇,配置和操做習慣。

最後,若是你以爲這篇文章不錯,請點擊下方的喜歡按鈕,謝謝支持!

好了,朋友們,下期再見~


  1. R-markdown, iPython-notebook

  2. 選項nw表明"no window"

  3. 你也可使用powershell支持的cd ~來直接切換到主目錄,從而得知主路徑的位置……

  4. 這些命令也能夠:M-: (getenv "PATH"),C-h v initial-environment

  5. M-x shell來激活一個shell。你能夠把它簡單理解爲一個運行在emacs裏面的cmd。

========================== End
相關文章
相關標籤/搜索