一個(gè)簡(jiǎn)略的介紹,講述一下我已經(jīng)知道的 Emacs 的功能。
這里可以找到很多有關(guān) Emacs 的資料。包括入門(mén)書(shū)籍,網(wǎng)址等。
我搜集到的一些很好的 emacs 擴展。它們使得 Emacs 成為一個(gè)多 才多藝的編輯器。
這里簡(jiǎn)要記錄一些 Emacs 的使用技巧。便于查詢(xún)。
很多人綁定一些比較特殊的鍵的時(shí)候,都搞不清楚在
(global-set-key ... ‘my-funtion)
里寫(xiě)些什么。特別是在 xterm 里的時(shí)候就更不知所措了。其實(shí)有一個(gè)萬(wàn)無(wú)一失的辦法保證你一定寫(xiě)對。這個(gè)辦法就是:
好了,你現在就能在 minibuffer 里看到你應該寫(xiě)在 .emacs 的東西了。
如果你在第1步的時(shí)候發(fā)現 Emacs 根本對你的按鍵沒(méi)有反應,那么應該懷疑是你的窗口管理器攔截了這個(gè)按鍵。比如,我的 FVWM 設置把 C-f3 設定成了打開(kāi)一個(gè) FvwmCommand, 所以 Emacs 接收不到這個(gè)按鍵。如果我要綁定一個(gè)函數到 C-f3, 我必須讓 FVWM 放過(guò) C-f3。
其實(shí)上面的辦法只能讓你綁定一個(gè)已有的前綴。你有可能想綁定一個(gè) save-buffer 到 "C-c C-w C-b a"。上面的辦法就不靈了。我們必須使用另外的辦法:
(global-set-key (kbd "C-c C-w C-b a") ‘save-buffer)
上面的那個(gè) "C-c C-w C-b a" 是自動(dòng)把 "C-c C-w", "C-c C-w C-b" 都定義成了一個(gè) prefix-command. 你可以這樣看到它們:
現在你清楚的看到了 "C-c C-w", "C-c C-w C-b" 都是 prefix command 吧?
(global-set-key (kbd "C-z C-c C-w b") ‘find-file)
出現錯誤:(error "Key sequence C-z C-c C-w b uses invalid prefix characters")
所以你必須事先把第一個(gè)鍵設定為 prefix:
(define-prefix-command ‘ctl-z-map)(global-set-key (kbd "C-z") ‘ctl-z-map)
然后再用
(global-set-key (kbd "C-z C-c C-w b") ‘find-file)
就行了。"C-z C-c" 和 "C-z C-c C-w" 都會(huì )自動(dòng)被定義為 prefix command.
現在我舉一個(gè)例子來(lái)說(shuō)明 prefix command 是如何工作的。我們可以把中文的 存盤(pán) 兩個(gè)字綁定到save-buffer. 這樣你用中文輸入法敲入“存盤(pán)”兩個(gè)字時(shí),就可以把當前 buffer 保存起來(lái)。
(define-prefix-command ‘存-map)(global-set-key (kbd "存") ‘存-map)(define-key 存-map (kbd "盤(pán)") ‘save-buffer)
有趣吧?你可以猜到這里面是怎么回事吧?太簡(jiǎn)單了是不是?當你輸入“存”的時(shí)候,看到 minibuffer 是這樣:

這是因為我們把“存”這個(gè)字綁定到了 存-map 這個(gè) prefix-command. 當讀到“存”的時(shí)候,Emacs 就會(huì )等待下一條命令,這個(gè)命令是定義在 存-map 這個(gè) map 里的。它讀到“盤(pán)”,就會(huì )執行 save-buffer 了。
不過(guò)注意,你真的要在文檔里輸入“存盤(pán)”兩個(gè)字就得先打 C-q 了。剛才我就打了好多次 C-q,真累啊。還是用一些不常用的詞組比較好,或者加一個(gè) ctrl 什么的前綴,就像這個(gè),"C-z 存盤(pán)"。
(define-prefix-command ‘ctl-z-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "存盤(pán)") ‘save-buffer)
看我們更 bt 一點(diǎn):
(define-prefix-command ‘ctl-z-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "給我存盤(pán)啦!") ‘save-buffer)
嗨喲!yes sir!!
define-key 會(huì )自動(dòng)建立很多 prefix command. 不過(guò)自己顯式用 define-prefix-command 定義前綴命令有一個(gè)好處,就是你可以在你的 prefix 里再方便的定義更多的命令,而不用把整個(gè)前綴都寫(xiě)一遍。
(define-prefix-command ‘ctl-z-map)(define-prefix-command ‘存-map)(define-prefix-command ‘盤(pán)-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "存") ‘存-map)(define-key 存-map (kbd "盤(pán)") ‘盤(pán)-map)(define-key 盤(pán)-map (kbd "!") ‘save-buffer)(define-key 盤(pán)-map (kbd "到") ‘write-file)(define-key 盤(pán)-map (kbd "退出") (lambda () (interactive) (save-buffer) (kill-emacs)))
這樣,到了“C-z 存盤(pán)-” 這個(gè)時(shí)候,我們定義了3個(gè)分支:
自定義 prefix command 的另外一個(gè)更大的好處就是:你可以修改最上層對 prefix command 的綁定,從而修改許多鍵的綁定。比如,我們可以把 “存盤(pán)” 輕而易舉的改成 “保存”:
(define-key ctl-z-map (kbd "保存") ‘盤(pán)-map)
這樣一來(lái), “C-z 保存!” ,“C-z 保存到” , “C-z 保存退出” 就分別有了 “C-z 存盤(pán)!” , “C-z 存盤(pán)到” 和 “C-z 存盤(pán)退出” 的含義了。
我覺(jué)得這里的設置對我來(lái)說(shuō)比缺省的設置方便。
(setq visible-bell t)
關(guān)閉煩人的出錯時(shí)的提示聲。
(setq inhibit-startup-message t)
關(guān)閉起動(dòng)時(shí)的那個(gè)“開(kāi)機畫(huà)面”。
(setq column-number-mode t)
顯示列號。
(setq mouse-yank-at-point t)
不要在鼠標點(diǎn)擊的那個(gè)地方插入剪貼板內容。我不喜歡那樣,經(jīng)常把我的文檔搞的一團糟。我覺(jué)得先用光標定位,然后鼠標中鍵點(diǎn)擊要好的多。不管你的光標在文檔的那個(gè)位置,或是在 minibuffer,鼠標中鍵一點(diǎn)擊,X selection 的內容就被插入到那個(gè)位置。
(setq kill-ring-max 200)
用一個(gè)很大的 kill ring. 這樣防止我不小心刪掉重要的東西。我很努莽的,你知道 :P
(setq default-fill-column 60)
把 fill-column 設為 60. 這樣的文字更好讀。
(setq-default indent-tabs-mode nil)(setq default-tab-width 8)(setq tab-stop-list ())(loop for x downfrom 40 to 1 do (setq tab-stop-list (cons (* x 4) tab-stop-list)))
不用 TAB 字符來(lái)indent, 這會(huì )引起很多奇怪的錯誤。編輯 Makefile 的時(shí)候也不用擔心,因為 makefile-mode 會(huì )把 TAB 鍵設置成真正的 TAB 字符,并且加亮顯示的。
(setq sentence-end "\\([。???]\\|……\\|[.?!][]\"‘)}]*\\($\\|[ \t]\\)\\)[ \t\n]*")(setq sentence-end-double-space nil)
設置 sentence-end 可以識別中文標點(diǎn)。不用在 fill 時(shí)在句號后插入兩個(gè)空格。
(setq enable-recursive-minibuffers t)
可以遞歸的使用 minibuffer。我經(jīng)常需要這么做。
(setq scroll-margin 3 scroll-conservatively 10000)
防止頁(yè)面滾動(dòng)時(shí)跳動(dòng), scroll-margin 3 可以在靠近屏幕邊沿3行時(shí)就開(kāi)始滾動(dòng),可以很好的看到上下文。
(setq default-major-mode ‘text-mode)
把缺省的 major mode 設置為 text-mode, 而不是幾乎什么功能也沒(méi)有的 fundamental-mode.
(show-paren-mode t)(setq show-paren-style ‘parentheses)
括號匹配時(shí)顯示另外一邊的括號,而不是煩人的跳到另一個(gè)括號。
(mouse-avoidance-mode ‘a(chǎn)nimate)
光標靠近鼠標指針時(shí),讓鼠標指針自動(dòng)讓開(kāi),別擋住視線(xiàn)。
(setq frame-title-format "emacs@%b")
在標題欄顯示buffer的名字,而不是 emacs@wangyin.com 這樣沒(méi)用的提示。
(auto-image-file-mode)
讓 Emacs 可以直接打開(kāi)和顯示圖片。
(global-font-lock-mode t)
進(jìn)行語(yǔ)法加亮。
(put ‘set-goal-column ‘disabled nil)(put ‘narrow-to-region ‘disabled nil)(put ‘upcase-region ‘disabled nil)(put ‘downcase-region ‘disabled nil)(put ‘LaTeX-hide-environment ‘disabled nil)
把這些缺省禁用的功能打開(kāi)。
(setq version-control t)(setq kept-new-versions 3)(setq delete-old-versions t)(setq kept-old-versions 2)(setq dired-kept-versions 1)
設置一下備份時(shí)的版本控制,這樣更加安全。
(mapcar (function (lambda (setting) (setq auto-mode-alist (cons setting auto-mode-alist)))) ‘(("\\.xml$". sgml-mode) ("\\\.bash" . sh-mode) ("\\.rdf$". sgml-mode) ("\\.session" . emacs-lisp-mode) ("\\.l$" . c-mode) ("\\.css$" . css-mode) ("\\.cfm$" . html-mode) ("gnus" . emacs-lisp-mode) ("\\.idl$" . idl-mode)))一個(gè)簡(jiǎn)單的辦法設置 auto-mode-alist, 免得寫(xiě)很多 add-to-list.
(setq user-full-name "Wang Yin")(setq user-mail-address "wang-y01@mails.tsinghua.edu.cn")
設置有用的個(gè)人信息。這在很多地方有用。
(setq dired-recursive-copies ‘top)(setq dired-recursive-deletes ‘top)
讓 dired 可以遞歸的拷貝和刪除目錄。
文檔一般都有各種結構,比如LISP里有S表達式,C語(yǔ)言里的函數,LaTeX 里的 \begin{...}...\end{...} ... 如果我們能夠已文檔的語(yǔ)法單位來(lái)移動(dòng),就會(huì )使操作非常高效。
C-M-a 到 defun 頭C-M-e 到 defun 尾這樣,我們在C語(yǔ)言程序里可以一個(gè)函數一個(gè)函數的跳過(guò)。也可以從一個(gè)函數中間一下跳到函數開(kāi)頭或末尾。
所以在 Emacs 里,尋找匹配的括號可以在括號處使用 C-M-f 和 C-M-b.
C-M-f 到下一個(gè)同級語(yǔ)法結構C-M-b 到上一個(gè)同級語(yǔ)法結構
注意,這種移動(dòng)不能越過(guò)語(yǔ)法結構的邊界而進(jìn)入上一級結構。所以,你如果在
for (i=0; i<10; i++) { ...}的 for 循環(huán)的括號里向右移動(dòng),到達右邊括號時(shí),就會(huì )被提示到達邊界。 注意,文檔中的注釋在這兩個(gè)操作中會(huì )被跳過(guò),這是非常方便的。
在LISP中,S表達式是嵌套的括號,進(jìn)入子結構就是進(jìn)入到這一級 (...) 里面。而在 C 語(yǔ)言中,進(jìn)入子結構就是進(jìn)入 (...), {...}, [...] 的里面。 C-M-d: 進(jìn)入到下一級結構里。C-M-u: 進(jìn)入到上一級結構里。
C-M-a, C-M-e, C-M-f, C-M-b, C-M-d, C-M-u 這幾個(gè)命令組合起來(lái)可以迅速的在程序里移動(dòng)。往往手可以按住 C-M 不放,所以還是很順手的。
M-} (forward-paragraph)M-{ (backward-paragraph)段落在不同的mode有不同的含義,它的含義是由 paragraph-start 變量決定的。這個(gè)正則表達式可以告訴 Emacs 那些符號出現被認為是一個(gè)段落開(kāi)始了。 M-e (backward-sentence)M-a (forward-sentence)
句子在不同的模式有不同的含義。比如在 c-mode, “句子”成為了“語(yǔ)句”的代名詞,所以 M-a 和 M-e 可以以語(yǔ)句為單位移動(dòng)。
句子的含義是由 sentence-end 變量決定的。這個(gè)正則表達式可以告訴 Emacs 那些符號出現被認為是一個(gè)句子結束了……比如我的 sentence-end 是這樣設置的:
(setq sentence-end "\\([。???]\\|……\\|[.?!][]\"‘)}]*\\($\\|[ \t]\\)\\)[ \t\n]*")這樣中文的句子就可以被正確識別了。
C-c C-f 向前跳過(guò)同一級 tag (sgml-skip-tag-forward)C-c C-b 向后跳過(guò)同一級 tag (sgml-skip-tag-backward)
C-c C-u 到最近的上一級 \begin{...} 處。C-c } 到最近的上一級匹配 {...} 處。Emacs 具有非常智能的文本編輯能力。它可以自動(dòng)對文字斷行,并且在斷開(kāi)的行首都加入一些 prefix(前綴)。
你編輯 C 程序多行注釋的時(shí)候,你想要編輯器能夠自動(dòng)縮進(jìn)到合適的位置并且插入一個(gè) "*",就像這樣?
/* seed the random number generator * first try the random file /dev/random * if there isn‘t such a file in the system * use current time to seed the RNG. */
在你寫(xiě)新聞組的文章的時(shí)候,你又想讓編輯器使你的文檔出現這樣漂亮的縮進(jìn):
1. I seed the random number generator first try the random file /dev/random if there isn‘t such a file in the system use current time to seed the RNG.2. I need more powerful randomized binary search tree algorithm to store my wavefront elements.
這些 * 和 行首留出的空白就叫做 prefix。每當使用 fill-paragraph 等操作或者啟動(dòng)了 auto-fill-mode 的時(shí)候,文字在斷行時(shí),Emacs 可能會(huì )在斷開(kāi)的每行前面加入 prefix(前綴)。這大大方便了編輯類(lèi)似程序注釋這一類(lèi)文字。
fill-column就是說(shuō)到多少列的時(shí)候斷行。你可以使用
C-u 70 C-x f
這樣的命令把 fill-column 設置為 70. 也可以把光標移動(dòng)到你想要斷行的位置,然后按
C-u C-x f
斷開(kāi)的行可能會(huì )被自動(dòng)加上一個(gè)前綴(prefix)。設置prefix的方式主要有兩種,手動(dòng)設置和 adaptive prefix 自動(dòng)設置。
如果把光標放在段落首后面一個(gè)位置,使用
C-x . (set-fill-prefix)
就可以把段落頭到光標處的那段字符作為 prefix.
但是沒(méi)有手動(dòng)設置 prefix 的時(shí)候,Emacs 也可以自動(dòng)識別段落首的一些字符作為 prefix。這就叫做 Adaptive Filling。
Emacs 使用變量 adaptive-fill-regexp 來(lái)提取前綴。這個(gè)變量是一個(gè)正則表達式。它會(huì )把fill區域開(kāi)頭的能夠匹配的部分作為候選的前綴。很多 major mode 會(huì )自動(dòng)幫你設置好這個(gè)變量,所以你通常不用操心。
但是某些時(shí)候,你可能希望能夠自己操縱這一切。我們下面就來(lái)看一個(gè)具體的例子。假設如果你要達到這種效果,在同一個(gè)文本文件里:
*** Section "Files". The location of the RGB database. Note, this is the name of the file minus the extension (like ".txt" or ".db").
* There is normally no need to* change the default. Multiple* FontPath entries are allowed* (they are concatenated together)* By default, Red Hat 6.0 and later* now use a font server independent* of the X server to render fonts.
1. I seed the random number generator first try the random file /dev/random if there isn‘t such a file in the system use current time to seed the RNG.2. I need more powerful randomized binary search tree algorithm to store my wavefront elements.
這些 "*** ", "* ", "1. ", "2. ", " " 就叫做前綴。為了識別這些前綴,我們把 adaptive-fill-regexp 設置為:
(setq adaptive-fill-regexp "[ \t]+\\|[ \t]*\\([0-9]+\\.\\|\\*+\\)[ \t]*")
這表示前綴可以全是空白字符?;蛘唛_(kāi)頭可以有一些空白,接著(zhù)數字加點(diǎn)或者一個(gè)以上的 *,接著(zhù)一些空白。那么 Emacs 發(fā)現開(kāi)頭有這樣的字樣時(shí),就會(huì )把這個(gè)字符串作為一個(gè)“候選前綴”。
我們已經(jīng)輕松提取了可能作為前綴的部分,但是一個(gè)候選前綴是否被使用,還有很多因素。Emacs 的策略是非常聰明的。我們下面來(lái)看看 Emacs 是怎樣為用戶(hù)著(zhù)想的。
首先,我們經(jīng)常有這樣一種想法:如果我兩行開(kāi)頭都有符合候選前綴條件的符號,編輯器應該把第二行的那個(gè)候選作為前綴。如果我們輸入一些文字:
1. I seed the random number generator first try the random file /dev/random if there isn‘t such a file in the system use current time to seed the RNG.我們第一行輸入了一個(gè)前綴 "1. ",第二行我們故意退了幾格,使得 "1. " 這種數字標號突出在段落之外。但是其它的文字我們可以先不用管。那么第一行找到的候選前綴就是 "1. "(1,一個(gè)點(diǎn),一個(gè)空格),第二行的候選前綴是" "(3個(gè)空格)。
寫(xiě)完一段時(shí),我們按 M-q,這段話(huà)就自動(dòng)采用了第二行的前綴(3個(gè)空格)作為 prefix。變成這個(gè)樣子:
1. I seed the random number generator first try the random file /dev/random if there isn‘t such a file in the system use current time to seed the RNG.如果我們后來(lái)不滿(mǎn)意。想把第二行開(kāi)始的那些行多縮進(jìn)一些,而且把 fill-column 減小一些。我們可以設置 fill-column,然后在第二行開(kāi)頭再加一些空格,按 M-q。就成了這樣:
1. I seed the random number generator first try the random file /dev/random if there isn‘t such a file in the system use current time to seed the RNG.想一下你如果不用 Emacs,如何把上面那段文字變成現在這樣!
那么如果我們只輸入了一行字就要求把這行的前綴作為所有斷開(kāi)的行的前綴呢?比如,我們輸入一行,開(kāi)頭以 * 開(kāi)始。我們希望它在fill的時(shí)候斷開(kāi)的行都以 * 開(kāi)頭。
這是通過(guò)設置 adaptive-fill-first-line-regexp 這個(gè)變量實(shí)現的。這個(gè)變量是一個(gè)正則表達式。如果它能夠匹配我們用 adaptive-fill-regexp 提取出來(lái)的前綴,那么這個(gè)前綴就被采用。
(setq adaptive-fill-first-line-regexp "^\\* *$")
注意我們沒(méi)有使用簡(jiǎn)單的 "\\* *",而是使用了行首和行尾的匹配符號,因為我們只希望 "* " 這樣的符號作為單行重復前綴,出現在每行的開(kāi)頭,而不希望 "***" 成為每行的開(kāi)頭。 adaptive-fill-regexp 提取出來(lái)的候選前綴被作為了 adaptive-fill-first-line-regexp 的輸入行,它有行首和行尾。
我們這是在告訴 Emacs,單行文字如果由一個(gè) * 開(kāi)頭,那么斷行后每一行都以 * 作為 prefix。
如果我們輸入一行(麻煩你拖動(dòng)一下:P) :
* There is normally no need to change the default. Multiple FontPath entries are allowed (they are concatenated together) By default, Red Hat 6.0 and later now use a font server independent of the X server to render fonts.按 M-q,它就變成了:
* There is normally no need to change the default. Multiple FontPath* entries are allowed (they are concatenated together) By default, Red* Hat 6.0 and later now use a font server independent of the X server* to render fonts.
如果adaptive-fill-first-line-regexp 不能匹配從單行取出的前綴,Emacs 會(huì )把這個(gè)前綴轉成同樣長(cháng)度的空格作為前綴,這正是我們想要的結果。比如我們輸入:
*** Section "Files". The location of the RGB database. Note, this is the name of the file minus the extension (like ".txt" or ".db").由于 "^\\* *$" 不能匹配提取出來(lái)的候選前綴 "*** ",所以 Emacs 把跟它同樣長(cháng)度的4個(gè)空格作為了前綴。這樣 fill 之后變成了:
*** Section "Files". The location of the RGB database. Note, this is the name of the file minus the extension (like ".txt" or ".db").這正是我們希望的樣子。
前面兩種情況有一個(gè)前提條件,就是候選前綴不能是用來(lái)決定段落開(kāi)頭的字符,否則不采用。這很好理解:如果采用這個(gè)前綴,我們自動(dòng)斷行的時(shí)候插入的字符會(huì )把一段話(huà)分成好幾段話(huà),那么文檔的邏輯結構就被破壞了,這是不合理的。
另外,編輯程序的時(shí)候,前綴的選擇還跟當前的注釋符號有關(guān)。這個(gè)問(wèn)題超出了本文的范圍。
這個(gè)規則看起來(lái)挺復雜,不過(guò)我們可以用算法描述的方式簡(jiǎn)單的描述出來(lái):
1. 使用 adaptive-fill-regexp 把每行開(kāi)頭部分能夠匹配的字符提取出來(lái),作 為“候選前綴”。2. 如果文字有兩行以上,把第二行的候選前綴插入到斷開(kāi)的所有行開(kāi)頭。3. 如果文字只有一行,看看 adaptive-fill-first-line-regexp 能不能匹配這 行的候選前綴。如果能匹配,使用這個(gè)前綴。否則,把這個(gè)前綴轉成同樣長(cháng) 度的空格,把這些空格作為前綴。
Outline mode
是 Emacs 的一個(gè)強有力的模式。它可以使你輕松的操縱結構化的文檔。它可以讓你只顯示文檔的某一個(gè)分支,只顯示主干,只顯示一個(gè)子樹(shù)。
下面就是一個(gè) LaTeX 文檔的各種 outline 操作的結果示范。由于 outline-minor-mode 的鍵綁定前綴 C-c @ 過(guò)于復雜,大部分經(jīng)常使用 outline 的人想把它設置為另一個(gè)鍵,所以以后我在敘述時(shí)直接稱(chēng)呼函數名字和簡(jiǎn)化前綴的鍵綁定。具體的鍵綁定請用 C-h w 查詢(xún)。
更改前綴可以在啟動(dòng) outline-minor-mode 之前,用改變 outline-minor-mode-prefix 變量的辦法一次完成。比如:
(setq outline-minor-mode-prefix [(control o)])
就可以把前綴改成 C-o. 以后我們實(shí)例中的鍵綁定都使用 C-o.
首先,給大家一個(gè) outline 的總體印象。我們使用 outline 來(lái)看看本文的主要內容 :)

這是一個(gè)非常簡(jiǎn)單的 LaTeX 文檔: outline.tex

我們來(lái)把文檔的各部分術(shù)語(yǔ)解釋一下。
M-x outline-minor-mode 就可以啟動(dòng) Outline。還有一個(gè) outline-mode 是一個(gè) major mode,一般都不用它。
光標在任何位置,只要執行這些操作,文檔的顯示就會(huì )變化成需要的樣子。
這個(gè)操作如果不帶參數,隱藏所有文檔子結構,只剩最上層。

這是參數為4的操作,顯示至文檔第4層子結構。

文檔的所有 Entry 都被隱藏。只顯示主干。

所有文檔部分展開(kāi)時(shí),光標移動(dòng)到 Chapter 1,執行 hide-subtree。整個(gè) Chapter 1 的子樹(shù)被折疊起來(lái)。

所有文檔部分展開(kāi)時(shí),光標移動(dòng)到 Chapter 1,執行 hide-other。除了 Chapter 1,其它子樹(shù)全部被折疊起來(lái)。這個(gè)操作正好與 hide-subtree 互補。

所有文檔部分展開(kāi)時(shí),光標移動(dòng)到 Chapter 1,執行 hide-leaves。所有 Chapter 1 子樹(shù)下的所有級別的 entry 被隱藏。也就是說(shuō),Chapter 1 下,只顯示 branch.

所有文檔部分展開(kāi)時(shí),光標移動(dòng)到 Chapter 1,執行 hide-entry。Chapter 1 的 Entry 被隱藏,但是所有子樹(shù)都不動(dòng)。

顯示所有文檔。結果就是原文檔。
為了演示,我們從全部隱藏的情況開(kāi)始:

show-children 只顯示直接的下一代子樹(shù),而不顯示間接的下一代。這里, \begin{document} 的直接的下一代就是 \chapter{...}。

把光標移動(dòng)到 Chapter 1,執行 show-entry。Chapter 1 的 Entry 被顯示,但是所有子結構還是保持隱藏。

把光標移動(dòng)到 Chapter 1,執行 show-branches。Chapter 1 這棵子樹(shù)之下的各級“樹(shù)干”被顯示,但是各級 entry 還是保持隱藏。Chapter 1 自己的 entry,由于我們上一步已經(jīng)顯示,所以保持不變。

把光標移動(dòng)到 Chapter 1,執行 show-subtree。Chapter 1 及其所有子結構全部被擴展。

在 outline 模式下,有幾種特殊方便的移動(dòng)方式。
聯(lián)系客服