Emacs 编辑器

来源:百度文库 编辑:神马文学网 时间:2024/04/28 14:15:38

Emacs 编辑器

Emacs 是什么的简称?

Emacs 能做什么

一个简略的介绍,讲述一下我已经知道的 Emacs 的功能。

Emacs 资料

这里可以找到很多有关 Emacs 的资料。包括入门书籍,网址等。

Emacs Lisp 功能扩展集锦

我搜集到的一些很好的 emacs 扩展。它们使得 Emacs 成为一个多 才多艺的编辑器。

Emacs 笔记

这里简要记录一些 Emacs 的使用技巧。便于查询。

  1. Emacs 键绑定技巧
  2. Emacs 的一些简单舒服的设置
  3. 移动光标命令总结
  4. Emacs Fill 详解
  5. Outline Mode 详解

返回

Emacs 绑定键盘的技巧。

万无一失的绑定方法

很多人绑定一些比较特殊的键的时候,都搞不清楚在

(global-set-key ... ‘my-funtion)

里写些什么。特别是在 xterm 里的时候就更不知所措了。其实有一个万无一失的办法保证你一定写对。这个办法就是:

  1. M-x global-set-key RET 交互式的绑定你的键。
  2. C-x Esc Esc 调出上一条“复杂命令”。

好了,你现在就能在 minibuffer 里看到你应该写在 .emacs 的东西了。

如果你还是失败了……

如果你在第1步的时候发现 Emacs 根本对你的按键没有反应,那么应该怀疑是你的窗口管理器拦截了这个按键。比如,我的 FVWM 设置把 C-f3 设定成了打开一个 FvwmCommand, 所以 Emacs 接收不到这个按键。如果我要绑定一个函数到 C-f3, 我必须让 FVWM 放过 C-f3。

绑定新的前缀键

其实上面的办法只能让你绑定一个已有的前缀。你有可能想绑定一个 save-buffer 到 "C-c C-w C-b a"。上面的办法就不灵了。我们必须使用另外的办法:

(global-set-key (kbd "C-c C-w C-b a") ‘save-buffer)

一点解释

上面的那个 "C-c C-w C-b a" 是自动把 "C-c C-w", "C-c C-w C-b" 都定义成了一个 prefix-command. 你可以这样看到它们:

  1. C-h C-b 显示绑定
  2. C-x o 切换到显示绑定的窗口
  3. C-x C-q 消除这个窗口的只读属性
  4. M-x delete-non-matching-lines RET prefix RET 删除所有不含 "prefix" 字样的行。

现在你清楚的看到了 "C-c C-w", "C-c C-w C-b" 都是 prefix command 吧?

创建新的 prefix command

上面这个办法只对开头的键已经是 prefix command 的键序列起作用,如果你的第一个键不是一个 prefix,那么就会出错。你可以试试:

(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")

所以你必须事先把第一个键设定为 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" 都会自动被定义为 prefix command.

绑定中文命令

现在我举一个例子来说明 prefix command 是如何工作的。我们可以把中文的 存盘 两个字绑定到save-buffer. 这样你用中文输入法敲入“存盘”两个字时,就可以把当前 buffer 保存起来。

(define-prefix-command ‘存-map)(global-set-key (kbd "存") ‘存-map)(define-key 存-map (kbd "盘") ‘save-buffer)

有趣吧?你可以猜到这里面是怎么回事吧?太简单了是不是?当你输入“存”的时候,看到 minibuffer 是这样:

这是因为我们把“存”这个字绑定到了 存-map 这个 prefix-command. 当读到“存”的时候,Emacs 就会等待下一条命令,这个命令是定义在 存-map 这个 map 里的。它读到“盘”,就会执行 save-buffer 了。

不过注意,你真的要在文档里输入“存盘”两个字就得先打 C-q 了。刚才我就打了好多次 C-q,真累啊。还是用一些不常用的词组比较好,或者加一个 ctrl 什么的前缀,就像这个,"C-z 存盘"。

(define-prefix-command ‘ctl-z-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "存盘") ‘save-buffer)

看我们更 bt 一点:

(define-prefix-command ‘ctl-z-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "给我存盘啦!") ‘save-buffer)

嗨哟!yes sir!!

define-key 会自动建立很多 prefix command. 不过自己显式用 define-prefix-command 定义前缀命令有一个好处,就是你可以在你的 prefix 里再方便的定义更多的命令,而不用把整个前缀都写一遍。

(define-prefix-command ‘ctl-z-map)(define-prefix-command ‘存-map)(define-prefix-command ‘盘-map)(global-set-key (kbd "C-z") ‘ctl-z-map)(define-key ctl-z-map (kbd "存") ‘存-map)(define-key 存-map (kbd "盘") ‘盘-map)(define-key 盘-map (kbd "!") ‘save-buffer)(define-key 盘-map (kbd "到") ‘write-file)(define-key 盘-map (kbd "退出")   (lambda ()    (interactive)    (save-buffer)    (kill-emacs)))

这样,到了“C-z 存盘-” 这个时候,我们定义了3个分支:

  • “C-z 存盘!”,表示保存这个文件;
  • “C-z 存盘到”,表示保存到另一个文件;
  • “C-z 存盘退出”,这个不用解释了吧。

自定义 prefix command 的另外一个更大的好处就是:你可以修改最上层对 prefix command 的绑定,从而修改许多键的绑定。比如,我们可以把 “存盘” 轻而易举的改成 “保存”:

(define-key ctl-z-map (kbd "保存") ‘盘-map)

这样一来, “C-z 保存!” ,“C-z 保存到” , “C-z 保存退出” 就分别有了 “C-z 存盘!” , “C-z 存盘到” 和 “C-z 存盘退出” 的含义了。


最后更新:2003-05-22 王垠的主页 / WiKi首页/索引/框架页/取消框架

Emacs 的简单设置

我觉得这里的设置对我来说比缺省的设置方便。

  • (setq visible-bell t)

关闭烦人的出错时的提示声。

  • (setq inhibit-startup-message t)

关闭起动时的那个“开机画面”。

  • (setq column-number-mode t) 

显示列号。

  • (setq mouse-yank-at-point t)

不要在鼠标点击的那个地方插入剪贴板内容。我不喜欢那样,经常把我的文档搞的一团糟。我觉得先用光标定位,然后鼠标中键点击要好的多。不管你的光标在文档的那个位置,或是在 minibuffer,鼠标中键一点击,X selection 的内容就被插入到那个位置。

  • (setq kill-ring-max 200)

用一个很大的 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 字符来indent, 这会引起很多奇怪的错误。编辑 Makefile 的时候也不用担心,因为 makefile-mode 会把 TAB 键设置成真正的 TAB 字符,并且加亮显示的。

  • (setq sentence-end "\\([。!?]\\|……\\|[.?!][]\"‘)}]*\\($\\|[ \t]\\)\\)[ \t\n]*")(setq sentence-end-double-space nil)

设置 sentence-end 可以识别中文标点。不用在 fill 时在句号后插入两个空格。

  • (setq enable-recursive-minibuffers t)

可以递归的使用 minibuffer。我经常需要这么做。

  • (setq scroll-margin 3      scroll-conservatively 10000)

防止页面滚动时跳动, scroll-margin 3 可以在靠近屏幕边沿3行时就开始滚动,可以很好的看到上下文。

  • (setq default-major-mode ‘text-mode)

把缺省的 major mode 设置为 text-mode, 而不是几乎什么功能也没有的 fundamental-mode.

  • (show-paren-mode t)(setq show-paren-style ‘parentheses)

括号匹配时显示另外一边的括号,而不是烦人的跳到另一个括号。

  • (mouse-avoidance-mode ‘animate)

光标靠近鼠标指针时,让鼠标指针自动让开,别挡住视线。

  • (setq frame-title-format "emacs@%b")

在标题栏显示buffer的名字,而不是 emacs@wangyin.com 这样没用的提示。

  • (auto-image-file-mode)

让 Emacs 可以直接打开和显示图片。

  • (global-font-lock-mode t)

进行语法加亮。

  • (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)

把这些缺省禁用的功能打开。

  • (setq version-control t)(setq kept-new-versions 3)(setq delete-old-versions t)(setq kept-old-versions 2)(setq dired-kept-versions 1)

设置一下备份时的版本控制,这样更加安全。

  • (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)))

一个简单的办法设置 auto-mode-alist, 免得写很多 add-to-list.

  • (setq user-full-name "Wang Yin")(setq user-mail-address "wang-y01@mails.tsinghua.edu.cn")

设置有用的个人信息。这在很多地方有用。

  • (setq dired-recursive-copies ‘top)(setq dired-recursive-deletes ‘top)

让 dired 可以递归的拷贝和删除目录。


最后更新:2003-06-26 王垠的主页 / WiKi首页/索引/框架页/取消框架

移动光标

  1. 基本操作。
    • C-f, C-b: 以字符为单位移动。
    • M-f, M-b: 以单词为单位移动。
    • C-a, C-e: 移动到行首,行末。
    • M-m: 移动到第一个非空格字符。(back-to-indentation)
    • M-a, M-e: 移动到句子头,句子尾。
    • M-{, M-}: 移动到段落头,段落尾。
    • C-v, M-v: 翻页。
    • M-<, M->: 到文件头和文件尾。
    • M-r: 加参数,移动到窗口里的某一行。不加参数缺省移动到窗口中间。
    • M-x goto-char: 到文件的第 N 字节。
    • M-x goto-line: 到文件第 N 行。
    • C-x C-n: 设定 goal-column.
    • C-u C-x C-n: 取消 goal-column.
  2. 以语法结构为单位移动。

    文档一般都有各种结构,比如LISP里有S表达式,C语言里的函数,LaTeX 里的 \begin{...}...\end{...} ... 如果我们能够已文档的语法单位来移动,就会使操作非常高效。

    1. defun。defun 在 LISP 里就是最高一级的 sexp,而在 C 语言里,它的含义就是函数。
      C-M-a   到 defun 头C-M-e   到 defun 尾
      这样,我们在C语言程序里可以一个函数一个函数的跳过。也可以从一个函数中间一下跳到函数开头或末尾。
    2. 语法单位(sexp)。语法单位在各种 major mode 有不同的定义:
      • lisp-mode: 一个S表达式。
      • c-mode: 一个变量名,一个 (...), 一个 {...}, 一个 [...], ...

        所以在 Emacs 里,寻找匹配的括号可以在括号处使用 C-M-f 和 C-M-b.

      • Gnus: 一个thread。包括所有的 Re:
      其实 defun 可以被看作最高一级的 sexp。所以范围小一点的移动操作就是在同级 sexp 之间移动。
      C-M-f   到下一个同级语法结构C-M-b   到上一个同级语法结构

      注意,这种移动不能越过语法结构的边界而进入上一级结构。所以,你如果在

      for (i=0; i<10; i++) { ...}
      的 for 循环的括号里向右移动,到达右边括号时,就会被提示到达边界。

      注意,文档中的注释在这两个操作中会被跳过,这是非常方便的。

    3. 进入和退出子结构。

      在LISP中,S表达式是嵌套的括号,进入子结构就是进入到这一级 (...) 里面。而在 C 语言中,进入子结构就是进入 (...), {...}, [...] 的里面。 C-M-d: 进入到下一级结构里。C-M-u: 进入到上一级结构里。

      C-M-a, C-M-e, C-M-f, C-M-b, C-M-d, C-M-u 这几个命令组合起来可以迅速的在程序里移动。往往手可以按住 C-M 不放,所以还是很顺手的。

    4. 段落:
      M-} (forward-paragraph)M-{ (backward-paragraph)
      段落在不同的mode有不同的含义,它的含义是由 paragraph-start 变量决定的。这个正则表达式可以告诉 Emacs 那些符号出现被认为是一个段落开始了。
    5. 句子:
      M-e (backward-sentence)M-a (forward-sentence)

      句子在不同的模式有不同的含义。比如在 c-mode, “句子”成为了“语句”的代名词,所以 M-a 和 M-e 可以以语句为单位移动。

      句子的含义是由 sentence-end 变量决定的。这个正则表达式可以告诉 Emacs 那些符号出现被认为是一个句子结束了……比如我的 sentence-end 是这样设置的:

      (setq sentence-end "\\([。!?]\\|……\\|[.?!][]\"‘)}]*\\($\\|[ \t]\\)\\)[ \t\n]*")
      这样中文的句子就可以被正确识别了。
  3. 一些特殊模式专有的移动方式。
    • HTML 模式。
      1. 跳过同一级 tag。
        C-c C-f  向前跳过同一级 tag (sgml-skip-tag-forward)C-c C-b  向后跳过同一级 tag (sgml-skip-tag-backward)
    • LaTeX 模式。
        C-c C-u   到最近的上一级 \begin{...} 处。
        C-c }     到最近的上一级匹配 {...} 处。


返回

Emacs Fill 详解

Emacs 具有非常智能的文本编辑能力。它可以自动对文字断行,并且在断开的行首都加入一些 prefix(前缀)。

你编辑 C 程序多行注释的时候,你想要编辑器能够自动缩进到合适的位置并且插入一个 "*",就像这样?

/* 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. */

在你写新闻组的文章的时候,你又想让编辑器使你的文档出现这样漂亮的缩进:

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 等操作或者启动了 auto-fill-mode 的时候,文字在断行时,Emacs 可能会在断开的每行前面加入 prefix(前缀)。这大大方便了编辑类似程序注释这一类文字。

设置 fill-column

fill-column就是说到多少列的时候断行。你可以使用

C-u 70 C-x f

这样的命令把 fill-column 设置为 70. 也可以把光标移动到你想要断行的位置,然后按

C-u C-x f

断开的行可能会被自动加上一个前缀(prefix)。设置prefix的方式主要有两种,手动设置和 adaptive prefix 自动设置。

手动设置 prefix

如果把光标放在段落首后面一个位置,使用

C-x . (set-fill-prefix)

就可以把段落头到光标处的那段字符作为 prefix.

Adaptive Filling

但是没有手动设置 prefix 的时候,Emacs 也可以自动识别段落首的一些字符作为 prefix。这就叫做 Adaptive Filling。

提取候选前缀

Emacs 使用变量 adaptive-fill-regexp 来提取前缀。这个变量是一个正则表达式。它会把fill区域开头的能够匹配的部分作为候选的前缀。很多 major mode 会自动帮你设置好这个变量,所以你通常不用操心。

但是某些时候,你可能希望能够自己操纵这一切。我们下面就来看一个具体的例子。假设如果你要达到这种效果,在同一个文本文件里:

  1. 有一些段落每行由3个 * 开头,这可以被作为一小节的标题以及简短的说明。比如:
    *** Section "Files". The location    of the RGB database. Note, this    is the name of the file minus    the extension (like ".txt" or    ".db"). 
  2. 有一些段落每行由一个 * 号开头,这叫做“强调”。像这样:
    * 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.
  3. 有一些段落由数字编号 1. 2. 3. 开头,以后的每一行要求缩进到标号之后。所有的数字后面的点号要对齐。
    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]*")

这表示前缀可以全是空白字符。或者开头可以有一些空白,接着数字加点或者一个以上的 *,接着一些空白。那么 Emacs 发现开头有这样的字样时,就会把这个字符串作为一个“候选前缀”。

候选前缀的选择

我们已经轻松提取了可能作为前缀的部分,但是一个候选前缀是否被使用,还有很多因素。Emacs 的策略是非常聪明的。我们下面来看看 Emacs 是怎样为用户着想的。

  1. 多行文字的前缀 — 使用第二行的前缀

    首先,我们经常有这样一种想法:如果我两行开头都有符合候选前缀条件的符号,编辑器应该把第二行的那个候选作为前缀。如果我们输入一些文字:

    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.
    我们第一行输入了一个前缀 "1. ",第二行我们故意退了几格,使得 "1. " 这种数字标号突出在段落之外。但是其它的文字我们可以先不用管。那么第一行找到的候选前缀就是 "1. "(1,一个点,一个空格),第二行的候选前缀是"   "(3个空格)。

    写完一段时,我们按 M-q,这段话就自动采用了第二行的前缀(3个空格)作为 prefix。变成这个样子:

    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.
    如果我们后来不满意。想把第二行开始的那些行多缩进一些,而且把 fill-column 减小一些。我们可以设置 fill-column,然后在第二行开头再加一些空格,按 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,如何把上面那段文字变成现在这样!
  2. 单行文字的前缀选择

    那么如果我们只输入了一行字就要求把这行的前缀作为所有断开的行的前缀呢?比如,我们输入一行,开头以 * 开始。我们希望它在fill的时候断开的行都以 * 开头。

    这是通过设置 adaptive-fill-first-line-regexp 这个变量实现的。这个变量是一个正则表达式。如果它能够匹配我们用 adaptive-fill-regexp 提取出来的前缀,那么这个前缀就被采用。

    (setq adaptive-fill-first-line-regexp "^\\* *$")

    注意我们没有使用简单的 "\\* *",而是使用了行首和行尾的匹配符号,因为我们只希望 "* " 这样的符号作为单行重复前缀,出现在每行的开头,而不希望 "***" 成为每行的开头。 adaptive-fill-regexp 提取出来的候选前缀被作为了 adaptive-fill-first-line-regexp 的输入行,它有行首和行尾。

    我们这是在告诉 Emacs,单行文字如果由一个 * 开头,那么断行后每一行都以 * 作为 prefix。

    如果我们输入一行(麻烦你拖动一下: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 会把这个前缀转成同样长度的空格作为前缀,这正是我们想要的结果。比如我们输入:

    *** Section "Files". The location of the RGB database. Note, this    is the name of the file minus    the extension (like ".txt" or    ".db"). 
    由于 "^\\* *$" 不能匹配提取出来的候选前缀 "*** ",所以 Emacs 把跟它同样长度的4个空格作为了前缀。这样 fill 之后变成了:
    *** Section "Files". The location of the RGB database. Note, this is    the name of the file minus the extension (like ".txt" or ".db").
    这正是我们希望的样子。
  3. 另外一些条件

    前面两种情况有一个前提条件,就是候选前缀不能是用来决定段落开头的字符,否则不采用。这很好理解:如果采用这个前缀,我们自动断行的时候插入的字符会把一段话分成好几段话,那么文档的逻辑结构就被破坏了,这是不合理的。

    另外,编辑程序的时候,前缀的选择还跟当前的注释符号有关。这个问题超出了本文的范围。

总结

这个规则看起来挺复杂,不过我们可以用算法描述的方式简单的描述出来:

1. 使用 adaptive-fill-regexp 把每行开头部分能够匹配的字符提取出来,作   为“候选前缀”。2. 如果文字有两行以上,把第二行的候选前缀插入到断开的所有行开头。3. 如果文字只有一行,看看 adaptive-fill-first-line-regexp 能不能匹配这   行的候选前缀。如果能匹配,使用这个前缀。否则,把这个前缀转成同样长   度的空格,把这些空格作为前缀。

返回

Emacs Outline Mode 示例

Outline mode 是 Emacs 的一个强有力的模式。它可以使你轻松的操纵结构化的文档。它可以让你只显示文档的某一个分支,只显示主干,只显示一个子树。

下面就是一个 LaTeX 文档的各种 outline 操作的结果示范。由于 outline-minor-mode 的键绑定前缀 C-c @ 过于复杂,大部分经常使用 outline 的人想把它设置为另一个键,所以以后我在叙述时直接称呼函数名字和简化前缀的键绑定。具体的键绑定请用 C-h w 查询。

更改前缀可以在启动 outline-minor-mode 之前,用改变 outline-minor-mode-prefix 变量的办法一次完成。比如:

(setq outline-minor-mode-prefix [(control o)])

就可以把前缀改成 C-o. 以后我们实例中的键绑定都使用 C-o.

本文的 Outline

首先,给大家一个 outline 的总体印象。我们使用 outline 来看看本文的主要内容 :)

原文档

这是一个非常简单的 LaTeX 文档: outline.tex

我们来把文档的各部分术语解释一下。

  1. heading: 是指文档里的标题,比如 Chapter 1, Chapter 2, Section 1, ... 的那些行。
  2. branch: 是指一颗子树下所有 heading 的集合。想一想“树干”。
  3. entry: 是指文档里不是 heading 的那些内容。比如,"Entry for topmost level", "Entry for Chapter 1", "Entry for Chapter 2", ... 这些才是文档的主要内容。
  4. leaves: 是指一棵子树里的所有 entry。
  5. body: 是指文档里所有 entry 的集合。注意这个概念跟 leaves 的区别是范围上的区别。

启动 Outline

M-x outline-minor-mode 就可以启动 Outline。还有一个 outline-mode 是一个 major mode,一般都不用它。

全局隐藏操作

光标在任何位置,只要执行这些操作,文档的显示就会变化成需要的样子。

hide-sublevels(C-o C-q)

这个操作如果不带参数,隐藏所有文档子结构,只剩最上层。

M-4 hide-sublevels(M-4 C-o C-q)

这是参数为4的操作,显示至文档第4层子结构。

hide-body(C-o C-t)

文档的所有 Entry 都被隐藏。只显示主干。

对一个子树(Chapter 1)的隐藏操作

hide-subtree(C-o C-d)

所有文档部分展开时,光标移动到 Chapter 1,执行 hide-subtree。整个 Chapter 1 的子树被折叠起来。

hide-other(C-o C-o)

所有文档部分展开时,光标移动到 Chapter 1,执行 hide-other。除了 Chapter 1,其它子树全部被折叠起来。这个操作正好与 hide-subtree 互补。

hide-leaves(C-o C-l)

所有文档部分展开时,光标移动到 Chapter 1,执行 hide-leaves。所有 Chapter 1 子树下的所有级别的 entry 被隐藏。也就是说,Chapter 1 下,只显示 branch.

hide-entry(C-o C-c)

所有文档部分展开时,光标移动到 Chapter 1,执行 hide-entry。Chapter 1 的 Entry 被隐藏,但是所有子树都不动。

全局显示操作

show-all(C-o C-a)

显示所有文档。结果就是原文档。

对一个子树的显示操作

为了演示,我们从全部隐藏的情况开始:

show-children(C-o C-i)

show-children 只显示直接的下一代子树,而不显示间接的下一代。这里, \begin{document} 的直接的下一代就是 \chapter{...}。

show-entry(C-o C-e)

把光标移动到 Chapter 1,执行 show-entry。Chapter 1 的 Entry 被显示,但是所有子结构还是保持隐藏。

show-branches(C-o C-k)

把光标移动到 Chapter 1,执行 show-branches。Chapter 1 这棵子树之下的各级“树干”被显示,但是各级 entry 还是保持隐藏。Chapter 1 自己的 entry,由于我们上一步已经显示,所以保持不变。

show-subtree(C-o C-s)

把光标移动到 Chapter 1,执行 show-subtree。Chapter 1 及其所有子结构全部被扩展。

Outline mode 下的移动操作

在 outline 模式下,有几种特殊方便的移动方式。

  1. C-o C-n (outline-next-visible-heading) 移动到下一个可见标题。
  2. C-o C-p (outline-previous-visible-heading) 移动到上一个可见标题。
  3. C-o C-f (outline-forward-same-level) 移动到下一个同级可见标题。
  4. C-o C-b (outline-backward-same-level) 移动到上一个同级可见标题。
  5. C-o C-u (outline-up-heading) 到上一级标题。

返回