├── .gitignore ├── emacs-cookbook.pdf ├── chapters ├── 03_file.pdf ├── 11_org.pdf ├── 13_dired.pdf ├── 14_magit.pdf ├── 031_buffer.pdf ├── 06_threads.pdf ├── 15_package.pdf ├── 010_datatypes.pdf ├── 013_variables.pdf ├── 02_function.pdf ├── 12_bookmarks.pdf ├── 991_emacs26.pdf ├── 011_evaluation.pdf ├── images │ └── bookmark.png ├── 011_control_structures.pdf ├── 012_control_structures.pdf ├── 031_buffer.org ├── 15_package.org ├── 14_magit.org ├── 011_evaluation.org ├── 13_dired.org ├── 013_variables.org ├── 12_bookmarks.org ├── 012_control_structures.org ├── 06_threads.org ├── 11_org.org ├── 02_function.org ├── 010_datatypes.org ├── 03_file.org └── 991_emacs26.org ├── TODO.org ├── README.org ├── cookbook.el └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *.tex 2 | *.aux 3 | *.log 4 | *.toc 5 | *~ 6 | *.out 7 | *.html 8 | -------------------------------------------------------------------------------- /emacs-cookbook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/emacs-cookbook.pdf -------------------------------------------------------------------------------- /chapters/03_file.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/03_file.pdf -------------------------------------------------------------------------------- /chapters/11_org.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/11_org.pdf -------------------------------------------------------------------------------- /chapters/13_dired.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/13_dired.pdf -------------------------------------------------------------------------------- /chapters/14_magit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/14_magit.pdf -------------------------------------------------------------------------------- /chapters/031_buffer.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/031_buffer.pdf -------------------------------------------------------------------------------- /chapters/06_threads.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/06_threads.pdf -------------------------------------------------------------------------------- /chapters/15_package.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/15_package.pdf -------------------------------------------------------------------------------- /chapters/010_datatypes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/010_datatypes.pdf -------------------------------------------------------------------------------- /chapters/013_variables.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/013_variables.pdf -------------------------------------------------------------------------------- /chapters/02_function.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/02_function.pdf -------------------------------------------------------------------------------- /chapters/12_bookmarks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/12_bookmarks.pdf -------------------------------------------------------------------------------- /chapters/991_emacs26.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/991_emacs26.pdf -------------------------------------------------------------------------------- /chapters/011_evaluation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/011_evaluation.pdf -------------------------------------------------------------------------------- /chapters/images/bookmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/images/bookmark.png -------------------------------------------------------------------------------- /chapters/011_control_structures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/011_control_structures.pdf -------------------------------------------------------------------------------- /chapters/012_control_structures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aborn/emacs-cookbook/HEAD/chapters/012_control_structures.pdf -------------------------------------------------------------------------------- /chapters/031_buffer.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Buffer 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-07-06 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * Buffer 13 | 14 | * 创建Buffer 15 | 有两个函数可用于创建Buffer,它们是get-buffer-create和generate-new-buffer 16 | -------------------------------------------------------------------------------- /TODO.org: -------------------------------------------------------------------------------- 1 | #+TITLE: emacs-cookbook todolist 2 | 3 | ----- 4 | * to-do-list 5 | ** 生成pdf文档时,校验pdf是否比org新,如果新,不要生成pdf(说明原org没发生变化) 6 | ** 更新每个org文件的updatetime 7 | ** 删除无用数据 8 | ** 在README.org里生成目录 9 | ** try/catch机制介绍 10 | http://www.gnu.org/software/emacs/manual/html_node/elisp/Handling-Errors.html 11 | https://www.gnu.org/software/emacs/manual/html_node/elisp/Catch-and-Throw.html 12 | -------------------------------------------------------------------------------- /chapters/15_package.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 包管理 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-10-14 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | * Emacs的Package-Mode 12 | 当通过*M-x list-package*命令打开一个*Package*的Buffer,它有如下命令: 13 | 1. i 标识安装 (u 取消标识) 14 | 2. x 执行安装操作 15 | 3. d 标识删除 (x 执行删除操作) 16 | 4. U 标识要更新的package 17 | 5. ~ 标识所有废弃包 18 | 6. M-x package-autoremove 删除那些无用的旧包 19 | 20 | 21 | * 包列表 22 | 1. elisp-slime-nav 写elisp代码时,可用于跳转到函数的定义 23 | -------------------------------------------------------------------------------- /chapters/14_magit.org: -------------------------------------------------------------------------------- 1 | #+TITLE: magit 实践 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-10-25 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | * magit模式简介 12 | magit是emacs下版本管理的强大武器 13 | 14 | * 常用命令 15 | + *magit-dispatch-popup* 命令分发器,在spacemacs里绑定到 *M-m g m* 16 | + *magit-diff* 相当于git diff, 当进入diff-buffer后按 /g/ 更新之 17 | + *magit-status* 相当于git status, 进入status-buffer后按s添加文件或文件夹到本地仓库 18 | + *magit-checkout* 切换分支 19 | + *magit-branch-and-checkout* 从当前分支切一个新的分支 20 | 21 | * 分支操作 22 | 常用的分支操作如下: 23 | + (magit-branch-delete) *b k* 删除一个或多个(本地)分支 24 | + (magit-branch-rename) *b r* 对当前Branch进行重命名 25 | + (magit-get-current-branch) 获取当前分支名 26 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * emacs-cookbook 2 | Emacs 实践笔记(中文) 3 | 4 | ** 为什么写这本书? 5 | Emacs的学习和使用需要长时间的积累。有时候学习了一部分相关的知识,如果长期不使用又会忘记,写这本 6 | 开源书的目标主要是做记录,以备后查。我从2012年就开始使用Emacs,时间不算太长,现在Emacs 7 | 已经成为必备的工具! 8 | 9 | ** 参考 10 | 主要参考: 11 | 1. [[https://www.gnu.org/software/emacs/manual/emacs.html][GNU Emacs manual]] 12 | 2. [[https://www.gnu.org/software/emacs/manual/eintr.html][An Introduction to Programming in Emacs Lisp]] 13 | 3. [[https://www.gnu.org/software/emacs/manual/elisp.html][GNU Emacs Lisp Reference Manual]] 14 | 15 | ** 生成整本书 16 | 执行下列命令生成整本书(本地要安装latex的包): 17 | 18 | #+BEGIN_SRC emacs-lisp 19 | M-x cookbook-run-async 20 | #+END_SRC 21 | 22 | ** 关于进度 23 | 我会随着学习和使用过程,一点点地积累,不断改进。我会一直坚持写下去。如果你也有心想一起参与写作过程,请给我提PR。 24 | 25 | ** 最新版本 26 | 2018-08-01 27 | -------------------------------------------------------------------------------- /chapters/011_evaluation.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 求值 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-05-10 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 求值 13 | Lisp解释器会对表达式进行求值操作,也可以手工调用求值方法 *eval* 。Lisp解释器通常先读取Lisp 14 | 表达式,然后对表达式进行求值。其实,读取和求值是两个相互独立的过程,它们也可以进行单独操作。 15 | 16 | * 表达式类型 17 | 表达式是一种用于求值的lisp对象, Emacs有三种不同的求值表达式类型:标识符(Symbols)、列表和其 18 | 他类型。下面从其他类型开始介绍。 19 | 20 | ** 自解释表达式 21 | 自解释类型,其意思很明确是自己对自己求值,例如25自解释成25,自符串"foo"自解释成"foo"。 22 | 23 | ** 标识符类型 24 | 当标识符类型被求值,它将被当成变量使用,求值的结果就是变量的值。如果变量没有值,Lisp解释器会 25 | 抛出一个错误提示。 26 | #+BEGIN_SRC emacs-lisp 27 | (setq a 123) ;; ⇒ 123 28 | (eval 'a) ;; ⇒ 123 29 | a ;; ⇒ 123 30 | #+END_SRC 31 | 32 | ** 自动载入(Autoloading) 33 | 自动载入的特性允许函数或者宏还没有载入到Emacs中前使用它们。 34 | 35 | * 引用 36 | 引用(quote)是一种特殊表达式,它返回它的参数且不对其进行求值。它提供了一种在程序里包含标识符常 37 | 量和列表却不需要对其求值的使用方式。 38 | #+BEGIN_SRC emacs-lisp 39 | (quote object) 40 | #+END_SRC 41 | 它返回object,但不对object进行求值操作。它提供了一种简写方式,即“'”, *'object* 。 42 | 43 | * 反引号 44 | 反引号(backquote `)可用于列表,它与引用唯一的区别的,它允许对列表中部分元素进行求值。采用逗 45 | 号(,)来标识那些元素需要进行求值,下面是一些例子: 46 | 47 | #+BEGIN_SRC emacs-lisp 48 | `(a list of ,(+ 2 3) elements) ;; ⇒ (a list of 5 elements) 49 | `(1 2 (3 ,(+ 4 5))) ;; ⇒ (1 2 (3 9)) 50 | #+END_SRC 51 | -------------------------------------------------------------------------------- /chapters/13_dired.org: -------------------------------------------------------------------------------- 1 | #+TITLE: dired 实践 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-10-14 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | * dired文件管理 12 | dired的全称为Directory Edit,即目录编辑,是一个非常老的模式。是Emacs下的一个文件管理神器! 13 | 进入当前文件的dired文件管理,*M-x dired* 。 14 | 15 | ** 常用命令 16 | *** 光标移动命令 17 | + *n* 下移 18 | + *p* 上移 19 | 20 | *** 文件操作 21 | + *C* 拷贝文件,dired-recursive-copies变量决定了拷贝的类型,一般为top 22 | + *D* 删除文件,类似的有一个 dired-recursive-deletes 变量可以控制递归删除 23 | + *R* 重命名或者移动文件 24 | + *D* 删除文件或者目录 25 | + *+* 创建目录 26 | + *Z* gzip压缩文件 27 | + *w* 复制文件名(C-u 则复制相对于dired当前目录的相对目录) 28 | + *A* 对文件进行正则表达式搜索,会在第一个匹配的地方停下,然后使用M-, 搜索下一个匹配。 29 | 30 | *** 其他命令 31 | + *RET* 打开文件或者目录 32 | + *g* 刷新当前dired buffer 33 | + *k* 隐藏不想显示出来的文件 34 | + *q* 退出 35 | 36 | ** 标记与操作 37 | dired可以对多个文件进行标记,然后进行批量操作。一个典型的是采用 *d* 对当前文件打上删除标记, 38 | 然后使用 *x* 命令来删除所有标记的文件. 39 | 40 | *** 标记操作命令 41 | + m 以星标记当前文件 42 | + * * 标记所有可执行文件 43 | + * @ 标记所有符号链接 44 | + * / 标记所有目录(不包括 . 和 .. ) 45 | + * s 标记所有文件(不包括 . 和 .. ) 46 | + * . 标记具有给定扩展名的文件 47 | + % m REGEXP 或 * % REGEXP 标记所有匹配到给定的正则表达式 的文件。 48 | + % g REGEXP 标记所有文件 内容 匹配到给定的正则表达式的文件。 49 | 50 | *** 其他标记相关命令 51 | + u 去除当前行的标记 52 | + U 去除所有标记 53 | 54 | ** 批量执行Shell命令 55 | 在dired模式下,可以对标记的文件批量执行shell命令(如果没有标记文件,则对当前文件执行shell), 56 | 运行命令 *dired-do-shell-command* (绑定的快捷键为 *!* ),相应的它有一个对应的异步操作 57 | 的命令 *dired-do-async-shell-command* (绑定的快捷键为 *&* )。 58 | 59 | ** dired的扩展 60 | *** diredful 61 | [[https://github.com/thamer/diredful][diredful]] 可使得不同的文件显示不同的颜色,是一个非常好的扩展 62 | *** dired-icon 63 | [[https://gitlab.com/xuhdev/dired-icon][dired-icon]] 根据文件类型显示相应icon 64 | -------------------------------------------------------------------------------- /chapters/013_variables.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 变量 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-05-18 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 变量 13 | 变量在程序中是一种标识符,其指向某个值,这是一个很通用的编辑概念,不需要做过多解析。在Lisp中, 14 | 每个变量都通过符号类型来表达。变量名就是对应的符号类型名,变量值是保存在符号类型的值单元(value cell)里。 15 | 注意在前一章节里,我们介绍到符号类型既可用于变量名也可用于函数名,它们是相互独立不冲突的。 16 | 17 | * 全局变量 18 | 全局变量在任意时刻都只有一个值,并且这个变量可使用于整个lisp运行环境。我们经常用 *setq* 这个 19 | 特殊表达式将一个值绑定到具体某个符号变量中,如下: 20 | #+BEGIN_SRC emacs-lisp 21 | (setq x '(a b)) 22 | #+END_SRC 23 | 这里setq是一个特殊表达式,所以它不会对第一个参数x进行求值,它会对第二个参数进行求值,然后将求 24 | 得的值绑定到第一个参数对应的变量中。 25 | 26 | ** 不变量 27 | 在Emacs Lisp中,某些符号类型的求值是其本身。最常见的如nil、t,以及以:开头的符号类型(这些 28 | 符号类型称之为关键字keywords)。这些特殊的变量不能再进行绑定,同时其值也无法进行修改。 29 | 30 | #+BEGIN_SRC emacs-lisp 31 | (keywordp object) 32 | #+END_SRC 33 | 用来判断一个对象是否为关键字类型(keywords),即以:开头的符号类型。 34 | 35 | ** 定义全局变量 36 | 变量的定义主要有三个目的: 首先,它 提示阅读代码人的,该符号变量用于一种特殊用途(这里用于变量); 37 | 其次,它提供给Lisp系统,有时候还会赋于初始值和文档;最后,它为编程工具提供信息,如etags,提 38 | 示它去哪里找到变量定义。定义全局变量采用 39 | *defvar* 关键字,它定义一个符号类型为变量。 40 | 41 | #+BEGIN_SRC emacs-lisp 42 | defvar symbol [value [doc-string]] 43 | #+END_SRC 44 | 45 | 还有一种方式,采用 *defconst* 关键字 46 | #+BEGIN_SRC emacs-lisp 47 | defconst symbol value [doc-string] 48 | #+END_SRC 49 | 50 | * 变量是无效的 51 | 当一个符号类型对应的值单元没有被赋值(unassigned)时,称对应的变量为无效的(void)。对于个无效 52 | 变量进行求值,会抛出 *void-variable error* 。 注意变量为无效的(void)与变量值为nil本质上 53 | 是不一样的,nil为一种对象,它可以赋值给变量。 54 | 55 | #+BEGIN_SRC emacs-lisp 56 | (makunbound symbol) 57 | #+END_SRC 58 | makunbound清空符号类型里值单元,使得一个变量成为无效的(void)。它返回符号类型。 59 | 60 | #+BEGIN_SRC emacs-lisp 61 | (boundp variable) 62 | #+END_SRC 63 | boundp 当variable不是无效的(nil)时返回t,否则返回nil。 64 | 65 | * 局部变量 66 | 局部变量一般只用于一段程序,最常用的声明方式是采用 *let* 关键字。它的定义格式如下: 67 | 68 | #+BEGIN_SRC emacs-lisp 69 | let (bindings. . . ) forms. . . 70 | #+END_SRC 71 | 这里的let是一个特殊表达式(Special Forms),它按顺序绑定局部变量。下面是一个例子: 72 | #+BEGIN_SRC emacs-lisp 73 | (let ((y 1) 74 | (z y)) 75 | (list y z)) ;; ⇒ (1 2) 76 | #+END_SRC 77 | 还有一种局部变量,即函数的调用参数,因为这些参数只用于函数调用阶段。 78 | 79 | * Buffer本地变量(Buffer-Local Variables) 80 | Buffer本地变量,从字面意思可以看出,这种类型的变量只应用于Buffer中。这种机制可以满足对于同一 81 | 个变量在不同的Buffer中的值不一样。 82 | 83 | * 文件本地变量(File-Local Variables) 84 | -------------------------------------------------------------------------------- /chapters/12_bookmarks.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 书签 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-10-27 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | #+OPTIONS: toc:nil 8 | 9 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 10 | 11 | ----- 12 | * emacs的书签功能 13 | emacs的书签用于记录你在文件中的阅读位置。它有点类似寄存器,跟寄存器一样,因为它也能记录位置位置。 14 | 但同寄存器有两点不一样:1. 它有比较长的名字; 2. 当emacs关闭的时候,它会自动持久化到 15 | 磁盘。 16 | 17 | ** 设置一个书签 18 | 当我们阅读一个很长的文档,没能一口气读完时。我们希望记住当前文档的最后阅读的位置,以便下次再用emacs 19 | 阅读的时候能快速地定位到。那么,我们设置一个书签,通过 20 | *bookmark-set* 对应快捷键为 *C-x r m* 21 | 22 | ** 列出保存的书签 23 | *bookmark-bmenu-list* 对应快捷键为 *C-x r l* ,它将打开一个*Bookmark List*的buffer同时 24 | 列出所有保存的书签。 25 | 26 | *** 书签列表*Bookmark List* 27 | 在*Bookmark List*这个buffer里,有以下快捷键可以使用: 28 | - a 显示当前书签的标注信息; 29 | - A 在另一个buffer中显示所有书签的所有标注信息; 30 | - d 标记书签,以便用来删除 (x – 执行删除); 31 | - e 编辑当前书签的标注信息; 32 | - m 标记书签,以便用于进一步显示和其他操作 (v – 访问这个书签); 33 | - o 选中当前书签,并显示在另一个window中; 34 | - C-o 在另一个window中切换到当前这个书签; 35 | - r 重命名当前书签; 36 | - w 将当前书签的位置显示在minibuffer里。 37 | 38 | ** 跳转到一个书签 39 | 使用 *bookmark-jump* 函数,可以跳转到一个特定的书签,它绑定的快捷键为 *C-x r b* 。 40 | 如果你的emacs中安装了[[https://github.com/emacs-helm/helm][helm]] 这个插件,你也可以使用 *helm-bookmarks* 这个命令 41 | 来快速查找书签,并跳转到书签位置。 42 | 43 | *** helm-bookmarks 44 | 通过helm-bookmarks命令来查找并跳转书签如下图: 45 | 46 | [[./images/bookmark.png]] 47 | 48 | *** 修改默认排序 49 | 书签查找和跳转的时候,默认的书签排序是按字母排序的。如果想将最近访问的书签放在最前面, 50 | 将下面代码添加到你的emacs配置文件中。 51 | #+NAME: 修改默认排序 52 | #+BEGIN_SRC emacs-lisp 53 | (defadvice bookmark-jump (after bookmark-jump activate) 54 | (let ((latest (bookmark-get-bookmark bookmark))) 55 | (setq bookmark-alist (delq latest bookmark-alist)) 56 | (add-to-list 'bookmark-alist latest))) 57 | #+END_SRC 58 | 59 | ** 删除一个书签 60 | 删除一个书签对应的命令为 *bookmark-delete* 。 61 | 62 | ** 保存书签 63 | 最新版本emacs(老版本的书签保存在 *~/.emacs.bmk* ), 64 | 在退出的时候会自动保存书签。如果想手动保存书签的话,可以采用 65 | *bookmark-save* 这个函数命令。默认的情况,emacs会将书签保存在 *bookmark-default-file* 66 | 变量对应的文件中。在我的机器中,对应的文件如下: 67 | #+NAME: 书签文件路径 68 | #+BEGIN_SRC emacs-lisp 69 | ELISP> bookmark-default-file 70 | "/Users/aborn/.emacs.d/.cache/bookmarks" 71 | ELISP> 72 | #+END_SRC 73 | 74 | ** 其他设置 75 | 有一个变量 *bookmark-save-flag* 。如果这个变量的值为一个数值,它表示修改(或新增) 76 | 多少次书签后,emacs会自动保存书签到磁盘。当这个变量的值被设置为1时,每次对bookmark的改 77 | 动,emacs就会自动保存内容到磁盘相应位置(这样可以防止emacs突然crash时bookmark的丢失)。 78 | 如果这个值设置为nil,表示emacs不会主动保存bookmark,除非用户手动调用 79 | *M-x bookmark-save* 。 80 | 81 | ** bookmark+ 82 | [[https://www.emacswiki.org/emacs/bookmark+.el][bookmark+]] 是对bookmark的一个扩展的包。它有更多的功能: 83 | 1. 原始的bookmark只能对文件位置记录,bookmark+对孤立的buffer(没有关联文件的buffer)也能保存书签; 84 | 2. 支持对书签进行打tag; 85 | 3. 对文档的某个区域保存为书签,而不仅仅是某个位置; 86 | 4. 记录了每个书签的访问次数,及最后一次的访问时间,可以基于它们排序; 87 | 5. 多个书签可以有相同的名字; 88 | 6. 可以对函数、变量等加书签。 89 | 更多功能请参考: https://www.emacswiki.org/emacs/BookmarkPlus#Bookmark%2b 90 | -------------------------------------------------------------------------------- /chapters/012_control_structures.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 控制结构 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-05-08 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 控制结构 13 | Lisp程序由一系列表达式结成,Lisp解释器解释并执行这些表达式。在执行这些表达式过程中用到了控制 14 | 结构,Lisp里的控制结构都是特殊表达式(Special Forms)。最简单的控制结构是顺序执行,也是符合 15 | 人的书写和线性习惯。其他控制结构有:条件语句、迭代。 16 | 17 | * 顺序结构 18 | 顺序结构是最简单的控件结构,如果想自己定义顺序结构,可以采用 *progn* 这个特殊表达式: 19 | #+BEGIN_SRC emacs-lisp 20 | (progn a b c ...) 21 | #+END_SRC 22 | 它的执行结构是最后一句的结果。与之类似有另一个特殊表达式 *(prog1 form1 forms...)* 它也 23 | 是顺序执行,不过它的返回值是form1的返回值。同时还有一个特殊表达式 *(prog2 form1 form2 forms...)* 24 | 它效果也是一样,不过它返回的是form2的值。 25 | 26 | * 条件语句 27 | ELisp提供四种条件语句:if、when、unless和cond 28 | 29 | ** if 30 | if语句跟其他语言的if语言类似,它的结构如下: 31 | 32 | #+BEGIN_SRC emacs-lisp 33 | (if condition then-form else-forms...) 34 | #+END_SRC 35 | 这里有一点要引起注意的是当condition为nil,并且没有给定else-forms时,if返回的是nil。 36 | 37 | ** when 38 | when是if的变体,是当没有else-forms的特殊情况: 39 | #+BEGIN_SRC emacs-lisp 40 | (when condition then-forms. . .) 41 | #+END_SRC 42 | 43 | ** unless 44 | unless也是if的一个变体,是当没有then-form的特殊情况: 45 | #+BEGIN_SRC emacs-lisp 46 | (unless condition forms...) 47 | #+END_SRC 48 | 49 | ** cond 50 | cond是一种选择条件语句,每一个条件语句必须是一个列表,其中列表的头(car clause)是条件,列表 51 | 的其他部分是执行语句。cond的执行过程是按顺序执行,对每个条件语句clause,先对条件部分进行求值, 52 | 如果条件的执行结果不是nil,说明条件满足,则接下来执行条件语句的主体部分,最后返回主体部分的执 53 | 行结果作为cond的结果,其他部分的条件语句则被忽略。 54 | 55 | #+BEGIN_SRC emacs-lisp 56 | (cond ((numberp x) x) 57 | ((stringp x) x) 58 | ((bufferp x) 59 | (setq temporary-hack x) ; multiple body-forms 60 | (buffer-name x)) ; in one clause 61 | ((symbolp x) (symbol-value x))) 62 | #+END_SRC 63 | 有时候当前面所有的条件语句都没有“命中”时,可以采用t进行默认处理,下面是一个例子: 64 | #+BEGIN_SRC emacs-lisp 65 | (setq a 5) 66 | (cond ((eq a 'hack) 'foo) 67 | (t "default")) ;; ⇒ "default" 68 | #+END_SRC 69 | 70 | * 迭代语句 71 | 迭代在程序语言里表示重复执行某段代码,举例来说,如果你想对list的每个元素重复执行相同的计算,这 72 | 就是一个迭代过程。 73 | 74 | ** while 75 | while的定义如下: 76 | #+BEGIN_SRC emacs-lisp 77 | (while condition forms...) 78 | #+END_SRC 79 | while首先对condition进行求值操作,如果结果不是nil,则执行forms里语句;接下来再次对condition 80 | 进行求值,如果不是nil,则执行forms里的语句;这个过程不断重复直到condition的求值为nil。 81 | 82 | #+BEGIN_SRC emacs-lisp 83 | (setq num 0) ;; ⇒0 84 | (while (< num 4) 85 | (princ (format "Iteration %d." num)) 86 | (setq num (1+ num))) 87 | #+END_SRC 88 | 89 | ** dolist 90 | dolist的定义如下: 91 | #+BEGIN_SRC emacs-lisp 92 | dolist (var list [result]) body... 93 | #+END_SRC 94 | dolist对list里的每个元素执行body里的语操作,这里绑定list里的每个元素到var作为局部变量。 95 | 最后返回result,当result省略时,返回nil。下面是一个例子: 96 | #+BEGIN_SRC emacs-lisp 97 | (defun reverse (list) 98 | (let (value) 99 | (dolist (elt list value) 100 | (setq value (cons elt value))))) 101 | #+END_SRC 102 | 103 | ** dotimes 104 | dotimes的定义如下: 105 | #+BEGIN_SRC emacs-lisp 106 | dotimes (var count [result]) body... 107 | #+END_SRC 108 | 它的作用与dolist很类似,它从0(包含)到count(不包含)执行body语句,将当前的值绑定到var,返回 109 | result作为结果。下面是一个例子: 110 | #+BEGIN_SRC emacs-lisp 111 | (dotimes (i 100) 112 | (insert "I will not obey absurd orders\n")) 113 | #+END_SRC 114 | -------------------------------------------------------------------------------- /chapters/06_threads.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 多线程 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-05-29 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 多线程 13 | Emacs从26.1版本开始引入了[[https://www.gnu.org/software/emacs/draft/manual/html_node/elisp/Threads.html][多线程]] 。它提供了一种简单(但功能有限)多线程操作。跟其他编程语言一 14 | 样,在同一个Emacs实例里所有的线程的内存是共享的。每个线程有其自己运行Buffer(Current Buffer) 15 | 和对应的数据(Match Data)。注意:下面的文档都是参考Emacs的草案手册。 16 | 17 | * 基本的线程相关函数 18 | 下面介绍线程操作相关的[[https://www.gnu.org/software/emacs/draft/manual/html_node/elisp/Basic-Thread-Functions.html#Basic-Thread-Functions][基本函数]]。 19 | 20 | ** 创建线程 21 | 我们可以通过 *make-thread* 函数来创建线程并执行对应的task。它的语法如下: 22 | #+BEGIN_SRC emacs-lisp 23 | (make-thread function &optional name) 24 | #+END_SRC 25 | 创建一个名为name的线程,该线程执行function函数,当函数执行结束后,退出该线程。新线程的Current 26 | Buffer继承当前Buffer,这个函数返回一个线程对象。可以通过 *(threadp object)* 来判断一个对 27 | 象是否为线程对象。 28 | 29 | ** thread-join 30 | thread-join,它阻塞当前执行直到线程执行完成,如果线程已经退出,它立刻返回。 31 | #+BEGIN_SRC emacs-lisp 32 | (thread-join thread) 33 | #+END_SRC 34 | 35 | ** thread-yield 36 | 执行下一个可执行的线程。 37 | 38 | ** 获取线程名 39 | 可以通过(thread-name thread)函数来获取线程名。 40 | 41 | ** 线程状态 42 | 判断一个线程是否还在执行(alive),可以用(thread-alive-p thread)。 43 | 44 | ** 当前线程 45 | (current-thread)返回当前线程。 46 | 47 | ** 所有线程列表 48 | 获取当前所有正在运行中的线程(all-threads)。 49 | 50 | * 互斥锁(Mutexes) 51 | [[https://www.gnu.org/software/emacs/draft/manual/html_node/elisp/Mutexes.html][互斥]] 是一种排它锁(exclusive lock),在任何时刻,最多只允许一个线程持有互斥锁。也就是说,当一个线 52 | 程试图获取一个已经被其他线程持有的互斥锁时,它会引发阻塞,直到该互斥锁被释放为止。 53 | 54 | ** 创建一个互斥锁 55 | 创建一个互斥锁对象,采用 *make-mutes* 函数,该函数返回一个互斥锁对象,其名字为name。 56 | #+BEGIN_SRC emacs-lisp 57 | (make-mutex &optional name) 58 | #+END_SRC 59 | 判断一个对象是否为互斥锁使用(mutexp object)。 60 | 61 | ** 获取/释放互斥锁 62 | #+BEGIN_SRC emacs-lisp 63 | (mutex-unlock mutex) 64 | #+END_SRC 65 | 这个操作会引发阻塞,直到当前线程获取互斥锁为止。与之相对的有(mutex-unlock mutex)释放互斥 66 | 锁操作。 67 | 68 | ** with-mutex 69 | #+BEGIN_SRC emacs-lisp 70 | (with-mutex mutex body) 71 | #+END_SRC 72 | 这是一个宏操作,它首先获取一个互斥锁,然后执行body里的行为,最后释放互斥锁。 73 | 74 | * 条件变量(Condition Variables) 75 | [[https://www.gnu.org/software/emacs/draft/manual/html_node/elisp/Condition-Variables.html][条件变量]] 提供线程阻塞直到某个事件发生的机制。线程可以等待一个条件变量,直到别的线程触发这个条件 76 | 才唤醒。条件变量在某些情况下往往与互斥机制相关联。下面是一个例子: 77 | #+BEGIN_SRC emacs-lisp 78 | (with-mutex mutex 79 | (while (not global-variable) 80 | (condition-wait cond-var))) 81 | #+END_SRC 82 | 这里互斥锁保证了原子性。 83 | #+BEGIN_SRC emacs-lisp 84 | (with-mutex mutex 85 | (setq global-variable (some-computation)) 86 | (condition-notify cond-var)) 87 | #+END_SRC 88 | 89 | ** 创建条件变量 90 | 创建条件变量的函数如下: 91 | #+BEGIN_SRC emacs-lisp 92 | (make-condition-variable mutex &optional name) 93 | #+END_SRC 94 | 创建一个与互斥锁mutex的条件变量,其名字为name。判断一个对象是否为条件变量使用 95 | (condition-variable-p object) 96 | 97 | ** 条件等待 98 | #+BEGIN_SRC emacs-lisp 99 | (condition-wait cond) 100 | #+END_SRC 101 | 等待另一个线程去触发条件 *cond* (它是一个条件变量)。这个函数也会阻塞主流程直到条件被触发 102 | 为止。condition-wait 在等待时会释放与之关联的互斥锁,允许其他线程去获取这个互斥锁从而触发 103 | 条件变量。 104 | 105 | ** 条件通知 106 | #+BEGIN_SRC emacs-lisp 107 | (condition-notify cond &optional all) 108 | #+END_SRC 109 | 通知 *cond* 条件变量。一般情况下,一个等待线程被condition-notify被唤醒,当all不是nil时, 110 | 所有等待cond的线程都将收到唤醒通知。 111 | 112 | ** 其他函数 113 | 1. (condition-name cond) 返回条件变量名 114 | 2. (condition-mutex cond) 返回与条件变量相关联的互斥锁 115 | -------------------------------------------------------------------------------- /chapters/11_org.org: -------------------------------------------------------------------------------- 1 | #+TITLE: org 实践 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-10-12 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | * org模式简介 12 | Emacs的org-mode可用于记笔记、管理自己的待办事项(TODO lists),同时,也可用于管理项目。它是一个高效的纯文本编辑系统。 13 | 14 | * 文档结构 15 | Org是基于Outline-mode,并提供灵活的命令编辑结构化的文档。其文档结构语法跟markdown很类似。 16 | ** 目录结构 17 | Org的目录结构在每行最左边以星号标记,星号越多,标题层级越深。下面是一些例子: 18 | 19 | #+BEGIN_EXAMPLE 20 | \* 一级目录 21 | \** 二级目录 22 | \*** 三级目录 23 | 24 | \* 另一个一级目录 25 | #+END_EXAMPLE 26 | 27 | ** 显示与隐藏 28 | 目录结构下的内容可以隐藏起来,通常用采用 *TAB* 和 /S-TAB/ 这两个命令来切换。 29 | 30 | ** 列表 31 | Org提供三种类型的列表:有序列表、无序列表和描述列表 32 | 1. 有序列表以'1.' 或者 '1)' 33 | 2. 无序列表以'-', '+' 或者 '*' 34 | 3. 描述列表 35 | 36 | ** 块结构 37 | 在Org文档中,加入代码块这种类型的块结构,都是采用begin...end这种模式,下面是一个例子: 38 | 39 | #+BEGIN_EXAMPLE 40 | \#+BEGIN_EXAMPLE 41 | \#+END_EXAMPLE 42 | #+END_EXAMPLE 43 | 44 | * 表格 45 | * 超链接 46 | Org模式提供了比较好用的超链接方式,可以链接到普通网页、文件、email等。 47 | ** 链接格式 48 | Org模式支持两种链接,即,内部链接和外部链接。它们有相同的格式: 49 | #+BEGIN_EXAMPLE 50 | [[链接][描述]] 或 当只有链接没有描述 [[链接]] 51 | #+END_EXAMPLE 52 | 一旦链接编辑完成,在org模式下,只显示 *描述* 部分,而不会显示整体(后一种是只显示链接)。 53 | 为了编辑链接和描述,需要通过快捷键 *C-c C-l* 来完成(注意:编辑结束后按Enter完成修改操作)。 54 | *** 内部链接 55 | 内部链接是指向当前文件的链接,它的链接格式: 56 | #+BEGIN_EXAMPLE 57 | [[#链接ID]] 58 | #+END_EXAMPLE 59 | 其中 *链接ID* 是文档中唯一的标识ID 60 | 61 | *** 外部链接 62 | Org支持的外部链接有很多中形式,如文件、网页、新闻组、电子邮件信息、BBDB数据条目等。 63 | 它们以一个短的标识字符串打头,紧接着是一个冒号,冒号后面没有空格字符。 64 | 65 | ** 链接处理相关命令 66 | Emacs org提供了很多链接处理相关的函数 67 | + org-store-link 保存的一个链接到当前位置,以备后面插入使用,原始绑定的快捷键为 *C-c l* 68 | + org-insert-link 插入链接,绑定的快捷键为C-c C-l,如果光标正在一个链接上,那么这个命令 69 | 的行为是编辑这个链接及其描述。 70 | + org-open-at-point 打开当前位置的链接。它将在浏览器中打开这个链接,快捷键为 *C-c C-o* 71 | 其实使用是的 *browse-url-at-point* 72 | 73 | * 待办事项 74 | Org模式用来管理自己的TODO list非常方便 75 | 76 | * 日程表(Agenda View) 77 | 我们可以用Org来按排自己的行程 78 | 79 | ** 日程文件(Agenda files) 80 | 变量org-agenda-files保存了一个文件列表,这些文件用来记录日程,下面是一些操作函数: 81 | C-c [ 将当前文件加入到agenda文件列表最前页面 org-agenda-file-to-front 82 | C-c ] 将当前文件从agenda文件列表中删除 org-remove-file 83 | 84 | ** 分发按键 85 | 默认采用 *C-c a* ,接下的默认的命令有: 86 | 87 | + a 创建一个日程 88 | + t/T 创建一个TODO items 89 | + L 对当前文件生成timeline 90 | 91 | ** 内建Agenda视图 92 | 93 | ** 计划Schedule 94 | 用org来安排日程 95 | 96 | + org-schedule 将当前TODO添加计划时间 97 | 98 | * Org快速记录 99 | 有时候,突然想到一些待办事项,或者一些突发的灵感。这时,我们想用emacs快速记录它,[[http://orgmode.org/manual/Capture.html#Capture][Org-Capture]] 提供 100 | 这个好用的功能。它的前身是org-remember.el(注:从org 8.0开始,org-remember被org-capture) 101 | 替代。 102 | 103 | ** 如何使用org-capture? 104 | 快速记录的命令为 *M-x org-capture* ,默认绑定的快捷键为 C-c c 。当这个命令被调用后,你可以使用 105 | 自己定义好的 [[http://orgmode.org/manual/Capture-templates.html#Capture-templates][模板]] 快速创建记录。一旦完成内容的输入,按下C-c C-c (org-capture-finalize),来完成。 106 | 然后,你就能继续做你当下的事。如果想跳转到刚刚创建的记录的buffer, 用C-u C-c C-c来完成。如果想 107 | 中途中止输入,只要按下 C-c C-k (org-capture-kill)。 108 | 109 | ** org条目复制与移动 110 | 有时候,我们想将当前的某条目转移到其他文件或者其他项目里。这时,我们会用到 org-copy 和 org-refile 111 | 这两个命令。它们对应的快捷键分别是 C-c M-w 及 C-c C-w 。这里有一个问题是,目标文件如何配置? 112 | 目录文件的配置由一个变量决定, *org-refile-targets* ,我自己的配置如下: 113 | 114 | #+BEGIN_SRC emacs-lisp 115 | (setq org-refile-targets 116 | '((nil :maxlevel . 3) ;; 当前文件的最大层级 117 | (aborn-gtd-files :maxlevel . 3))) 118 | #+END_SRC 119 | 120 | 注意:我这时将文件放在 aborn-gtd-files 文件列表里。 121 | 122 | ** 记录模板 123 | 记录的模板为一个列表变量,org-capture-templates,列表的每条记录由如下几段组成: 124 | 125 | #+BEGIN_EXAMPLE 126 | ("t" "Todo" entry (file+headline (expand-file-name org-default-notes-file org-directory) "Tasks") 127 | "* TODO %?\n 创建于:%T %i\n") 128 | #+END_EXAMPLE 129 | 130 | *** 快捷键 131 | 如例子中的那样,"t"表示对应按键t这个快捷键。它能帮助我们快速地选中哪条模板进行快速记录。 132 | 133 | *** 描述 134 | 接下来是一段简单的描述 135 | 136 | *** 类型 137 | 第三段表示类型,有五种类型:entry item checkitem table-line plain 138 | 139 | + entry 普通的Org结点,保证目标文件为org-mode文件,插入的时候将作为目录结点的子结点 140 | (如果没有,将做为顶级结点); 141 | + item 与entry类似,不同点在于它的目标文件可以为简单的纯文本文件; 142 | + checkitem 复选条目; 143 | + table-line 在目标文件中的第一个table中插入新行; 144 | + plain 纯文本记录 145 | 146 | *** 目标文件 147 | 第四个字段配置目标文件 148 | 149 | *** 模板 150 | 第五个字段表示模板,[[http://orgmode.org/manual/Template-expansion.html#Template-expansion][模板参数]] 含义如下: 151 | 152 | + %t 只有日期的时间戳 153 | + %T 日期+时间的时间戳 154 | + %u,%U 如上,只不过它们是inactive的 155 | + %i 初始化文本,当前上下文将作为初始化文本 156 | 157 | *** 属性properties 158 | 最后一个字段表示属性列表,支持以下属性配置: 159 | 160 | + :prepend 一般一个记录条目插入在目标文件的最后,这个属性可以将条目插入在最前 161 | + :immediate-finish 立刻完成,没有交互 162 | + :clock-in 对这个条目设置闹钟 163 | + :kill-buffer 如果目标文件没有相应的访问buffer,插入后,自动关闭buffer 164 | 165 | * Org的导出功能 166 | Org文件支持导出多种格式的目标文件,如ASCII文件、HTML文件(用于发布为Web)、PDF文档等。 167 | 168 | ** 导出的Dispatcher 169 | 任何导出命令都有一个前缀按键,我们称之为Dispatcher,为 *C-c C-e* 170 | 171 | * org-capture.el 172 | Org 8.0 以后版本采用org-capture.el取代原有的org-remember.el 173 | -------------------------------------------------------------------------------- /chapters/02_function.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 函数 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-12-04 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 什么是函数? 13 | 函数是有传入参数的可计算的单元。每个函数的计算结果为函数返回值。大部分计算机语言里,每个函数有 14 | 其自己函数名。从严格意义来说,lisp函数是没有名字的。lisp函数其本质是一个对象,该对象可关联到 15 | 一个标识符(本书把Symbol翻译成标识符),这个标识符就是函数名。 16 | 17 | * 定义函数 18 | 定义一个函数的语法如下: 19 | 20 | #+BEGIN_SRC emacs-lisp 21 | defun name args [doc] [declare] [interactive] body. . . 22 | #+END_SRC 23 | 24 | ** 检查一个函数是否定义 25 | 检查一个变量是否绑定到函数, *fboundp symbol* , 还有一个函数 *(functionp OBJECT)* 26 | 27 | #+BEGIN_SRC emacs-lisp 28 | (fboundp 'info) ; t 29 | (fboundp 'setq) ; t 30 | (fboundp 'xyz) ; nil 31 | (functionp (lambda () (message "Anonymous Functions"))) ; t 32 | (fboundp (lambda () (message "Anonymous Functions"))) ; *** Eval error *** 33 | #+END_SRC 34 | 35 | ** 函数参数 36 | 有些参数是可选的,当用户没有传时,设置一个默认值,下面是一个例子: 37 | #+BEGIN_SRC emacs-lisp 38 | (defun cookbook/fun-option-parameter (a &optional b &rest e) 39 | (when (null b) 40 | (message "paramete b is not provided") 41 | (setq b "ddd")) ;; set to default value 42 | (message "a=%s, b=%s" a b)) 43 | #+END_SRC 44 | 函数cookbook/fun-option-parameter中,a为必传参数,b为可选择参数,e为其余参数,当实际传 45 | 入的参数大于2时,其他参数将组成一个list绑定到e上。 46 | 47 | * 函数调用 48 | 最通用的函数的调用方式是对list进行求值,如对list *(concat "a" "b")* 进行求值,相当于用参 49 | 数"a"和"b"调用函数concat。这种方式用在你清楚程序上下文中调用哪个函数、传递哪个参数。但有时候 50 | 你需要在程序运行时才决定调用哪个函数。针对这种情况,Emacs Lisp提供了另外两种方式 *funcall* 51 | 和 *apply* 。其中apply一般用在运行时行决定传递多少个参数的情况。 52 | 53 | ** funcall 54 | funcall它的语法如下: 55 | 56 | #+BEGIN_SRC emacs-lisp 57 | funcall function &rest arguments 58 | #+END_SRC 59 | 60 | 这里funcall本身是一个函数,因此funcall在调用前,它的所有参数都将事先做求值运算,对funcall 61 | 来说它不知道具体的求值过程。同时请注意第一个参数 *function* 必须为一个Lisp函数或者原生函数, 62 | 不能为特殊表达式(Special Forms)和宏,但可以为匿名函数(lambda表达式)。 63 | 64 | 下面为一个例子: 65 | #+BEGIN_SRC emacs-lisp 66 | (setq f 'list) ;; ⇒ list 67 | (funcall f 'x 'y 'z) ;; ⇒ (x y z) 68 | #+END_SRC 69 | 70 | ** apply 71 | apply的定义如下: 72 | #+BEGIN_SRC emacs-lisp 73 | apply function &rest arguments 74 | #+END_SRC 75 | 76 | apply与funcall作用一样,唯独有一点不一样:它的arguments是一个对象列表,每个对象作为单独的 77 | 参数传入,如下例子: 78 | #+BEGIN_SRC emacs-lisp 79 | (setq f 'list) ;; ⇒ list 80 | (apply f 'x 'y 'z) ;; Wrong type argument: listp, z 81 | (apply '+ 1 2 '(3 4)) ;; ⇒ 10 82 | #+END_SRC 83 | 84 | ** 映射函数(Mapping Functions) 85 | 映射函数操作是指对一个列表或者集合逐个执行指定函数,这节介绍几个常的映射函数:mapcar, 86 | mapc, 和 mapconcat。 87 | 88 | #+BEGIN_SRC emacs-lisp 89 | mapcar function sequence 90 | #+END_SRC 91 | 这个函数功能有与javascript里的array.map操作类型,对 *sequence* 里的每个元素执行function 92 | 操作,返回操作结果列表。这个函数应用非常广泛,以下几个应用举例: 93 | #+BEGIN_SRC emacs-lisp 94 | (mapcar 'car '((a b) (c d) (e f))) ;; ⇒ (a c e) 95 | (mapcar '1+ [1 2 3]) ;; ⇒ (2 3 4) 96 | (mapcar 'string "abc") ;; ⇒ ("a" "b" "c") 97 | #+END_SRC 98 | *mapc* 与 *mapcar* 调用方式一样,唯一不同的点是它始终返回的是 *sequence* 。 99 | 100 | #+BEGIN_SRC emacs-lisp 101 | mapconcat function sequence separator 102 | #+END_SRC 103 | *mapconcat* 对 *sequence* 里的每个元素调用 *function* 最后将结果拼接成一个字符串作为返 104 | 回值,采用separator作为拼接符。 105 | 106 | * 匿名函数 107 | 在elisp里有三种方式可以定义匿名函数: *lambda* 宏、 *function* 特殊表达式、 *#'* 可读语 108 | 法。 109 | ** lambda宏 110 | 它的定义如下: 111 | 112 | #+BEGIN_SRC emacs-lisp 113 | lambda args [doc] [interactive] body. . . 114 | #+END_SRC 115 | 116 | 这个宏返回一个匿名函数,实际上这个宏是自引用(self-quoting)。 117 | #+BEGIN_SRC emacs-lisp 118 | (lambda (x) (* x x)) ;; ⇒ (lambda (x) (* x x)) 119 | #+END_SRC 120 | 121 | 下面是另一个例子: 122 | #+BEGIN_SRC emacs-lisp 123 | (lambda (x) 124 | "Return the hyperbolic cosine of X." 125 | (* 0.5 (+ (exp x) (exp (- x))))) 126 | #+END_SRC 127 | 上面的表达式被计算成一个函数对象。 128 | 129 | ** function特殊表达式 130 | 定义如下: 131 | 132 | #+BEGIN_SRC emacs-lisp 133 | function function-object 134 | #+END_SRC 135 | 这是一个特殊表达式(Special Forms),表示对 *function-object* 不作求值操作。其实在实际使 136 | 用中我们往往采用它的简写 *#'* ,因此下面三个是等价的: 137 | 138 | #+BEGIN_SRC emacs-lisp 139 | (lambda (x) (* x x)) 140 | (function (lambda (x) (* x x))) 141 | #'(lambda (x) (* x x)) 142 | #+END_SRC 143 | 144 | * 获取函数单元内容 145 | 当我们把一个标识符(Symbol)定义为函数,其本质是将函数对象存储在标签符号对应的函数单元(标识符 146 | 还有一个变量单元用于存储变量),下面是介绍函数单元处理方法: 147 | 148 | ** symbol-function 149 | 定义如下: 150 | 151 | #+BEGIN_SRC emacs-lisp 152 | symbol-function symbol 153 | #+END_SRC 154 | 这个函数返回标识符symbol对应的函数对象,它不校验返回的函数是否为合法的函数。如果symbol的函数 155 | 单元为空,返回nil。 156 | 157 | ** fboundp 158 | 用于判断symbol对应的函数单元是否为nil 159 | #+BEGIN_SRC emacs-lisp 160 | fboundp symbol 161 | #+END_SRC 162 | 当symbol在函数单元有一个对象时返回t,否则返回nil。 163 | 164 | * 特殊表达式(Special Forms)和宏 165 | 有些与函数看起来很像的类型,它们也接受参数,同时计算出结果。但在Elisp里,他们不被当成函数,下 166 | 面给出简单介绍: 167 | 168 | ** 内建函数(primitive) 169 | 是用C语言写的,可被调用的函数; 170 | 171 | ** special form 172 | 一种类型的内建函数,如if, and 和while 173 | -------------------------------------------------------------------------------- /chapters/010_datatypes.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 基本数据类型 2 | #+AUTHOR: aborn 3 | #+DATE: 2016-12-21 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | 13 | * Lisp的数据类型 14 | Lisp的对象至少属于一种数据类型。Emacs里最基础的数据类型称之为原始类型(primitive type), 15 | 这些原始类型包括整型、浮点、cons、符号(symbol)、字符串、数组、哈希表(hash-table)、subr、 16 | 二进制编码函数(byte-code function),再加上一些特殊的类型,如buffer。同时,每种原始类型都 17 | 有一个对应的函数去校验对象是否属于其类型。 18 | 19 | * 符号类型(Symbols) 20 | 符号类型是一种有唯一标识的命名对象。它常用于变量及函数名。判断一个对象是否为符号类型用 21 | *symbolp object* 方法。 22 | 23 | ** 符号类型的组成 24 | 每个符号类型由四部分组成,每部分称之为单元,每个单元指向其他对象。 25 | *** 名字 26 | 即符号标识,获取符号标识名的函数为(symbol-name symbol) 27 | *** 变量值 28 | 当标识对象作为变量时的值 29 | *** 函数 30 | 标识函数定义,函数单元可保存另一个标识对象、或者keymap、或者一个键盘宏 31 | *** 属性列表 32 | 标识对象的属性列表(plist),获取属性列表函数为(symbol-plist symbol) 33 | 34 | 注意,其中 *名字* 为字符串类型,不可改变,其他三个组成部分可被赋值为任意lisp对象。 35 | 其值为属性列表(plist)。一个以冒号开头的符号类型称之为keyword symbol,它常用于常量类型。 36 | 37 | ** 定义符号类型 38 | 定义符号类型对象是一种特殊的lisp表达式,它表示将标识类型用于特殊用途。 39 | *** defvar 和 devconst 40 | 它们是一种特殊表达式(Special Forms),它定义一个标识作为全局变量。实际应用中往往使用 41 | *setq*,它可以将任意变量值绑定到标识对象。 42 | *** defun 43 | 用于定义函数,它的作用是创建一个lambda表达式,并将其存储在标识对象的函数单元里。 44 | *** defmacro 45 | 定义标识符为宏,创建一个宏对象并前对象保存在函数单元里。 46 | 47 | ** 符号类型操作函数 48 | 常见的与标识类型相关的函数有 *make-symbol* 和 *intern* 49 | 50 | *** make-symbol 51 | #+BEGIN_SRC emacs-lisp 52 | make-symbol name 53 | #+END_SRC 54 | 这个函数返回一个新的标识对象,它的名字是 *name* (必须为字符串) 55 | 56 | *** intern 57 | #+BEGIN_SRC emacs-lisp 58 | intern name &optional obarray 59 | #+END_SRC 60 | 这个函数返回一个被绑定的名字为 *name* 的标识对象。如果标识符不在变量 *obarray* 对应的 61 | 对象数组(obarray)里,创建一个新的,并加入到对象对象数组里。当无obarray参数时,采用全局的 62 | 对象数组obarray。 63 | 64 | ** 标识符属性 65 | 标识符属性记录了标识符的额外信息,下面的函数是对标签符属性进行操作: 66 | 67 | *** get symbol property 68 | 获取标识符属性为property的属性值,属性不存在返回nil 69 | 70 | *** put symbol property value 71 | 设置标识符属性property的值为value,如果之前存在相同的属性名,其值将被覆盖。这个函数返回 72 | value。下面是一些例子: 73 | 74 | #+BEGIN_SRC emacs-lisp 75 | (put 'fly 'verb 'transitive) ;; ⇒'transitive 76 | (put 'fly 'noun '(a buzzing little bug)) ;; ⇒ (a buzzing little bug) 77 | (get 'fly 'verb) ;; ⇒ transitive 78 | (symbol-plist 'fly) ;; ⇒ (verb transitive noun (a buzzing little bug)) 79 | #+END_SRC 80 | 81 | *** 标准标识符属性 82 | 下面列的一些标准标识符属性用于emacs的特殊用途 83 | **** :advertised-binding 84 | 用于函数的key的绑定 85 | **** interactive-form 86 | 用于交互函数,不要手工设置它,通过 *interactive* 特殊表达式来设置它 87 | **** disabled 88 | 如果不为nil,对应的函数不能作为命令 89 | **** theme-face 90 | 用于主题设置 91 | 92 | * 列表 93 | 列表是由零个或者多个元素组成的序列,列表中的每个元素都可由任意的对象组成。 94 | 95 | ** 关联列表alist (Association Lists) 96 | 关联列表是一种特殊的列表,它的每个元素都是一个点对构成,如下示例: 97 | 98 | #+BEGIN_SRC emacs-lisp 99 | (setq alist-of-colors 100 | '((rose . red) (lily . white) (buttercup . yellow))) 101 | #+END_SRC 102 | 103 | 关联列表可以用来记录key-value这样的map结构;对每个元素做car操作拿到key,做cdr操作即拿到 104 | 相关系的value。 105 | 106 | *** 关联列表操作 107 | + (assoc key alist) 获取列表第一个key所关联的值;下面是一个例子: 108 | 109 | #+BEGIN_SRC emacs-lisp 110 | ELISP> (assoc 'rose alist-of-colors) 111 | (rose . red) 112 | #+END_SRC 113 | 114 | 注意:这里用得比较是equal函数,如想用eq函数,请采用(assq key alist)这个函数 115 | 116 | + (rassoc value alist) 获取列表第一个value为 *value* 所关联的值; 117 | + (assoc-default key alist) 获取列表中第一个key为 *key* 的value; 118 | 119 | #+BEGIN_SRC emacs-lisp 120 | ELISP> (assoc-default 'rose alist-of-colors) 121 | red 122 | #+END_SRC 123 | 124 | ** 属性列表plist (Property Lists) 125 | 属性列表是由成对元素(paired elements)组成的列表,每个元素对关联着一个属性的名及其 126 | 对应属性值。下面是一个例子: 127 | 128 | #+BEGIN_SRC emacs-lisp 129 | (pine cones numbers (1 2 3) color "blue") 130 | #+END_SRC 131 | 132 | 这里pine关联其值为cons,numbers关联其值为(1 2 3),一般每个元素对的关联值是由symbol类型 133 | 组成的。 134 | 135 | *** 属性列表的操作 136 | + (plist-get plist property) 返回属性列表中属性名为property的属性值: 137 | 138 | #+BEGIN_SRC emacs-lisp 139 | ELISP> (setq pl '(pine cones numbers (1 2 3) color "blue")) 140 | (pine cones numbers 141 | (1 2 3) 142 | color "blue") 143 | ELISP> (plist-get pl 'pine) 144 | cones 145 | ELISP> (plist-get pl 'numbers) 146 | (1 2 3) 147 | #+END_SRC 148 | 149 | + (plist-member plist property) 如果属性列表plist中含有属性property,则返回non-nil。 150 | + (plist-put plist property value) 保存属性property及值value的属性对 151 | 152 | #+BEGIN_SRC emacs-lisp 153 | (setq my-plist '(bar t foo 4)) ;; => (bar t foo 4) 154 | (setq my-plist (plist-put my-plist 'foo 69)) ;; => (bar t foo 69) 155 | (setq my-plist (plist-put my-plist 'quux '(a))) ;; => (bar t foo 69 quux (a)) 156 | #+END_SRC 157 | 158 | ** 对列表进行排序 159 | 对列表进行排序可以采用sort这个函数 *(sort list predicate)* 。不过这个函数是有副作用的, 160 | 这个函数调用后会改变原有list的结构。第三个参数predicate传入的是一个比较函数,它接收两个参数。 161 | 如果是想递增排序,当第一个参数小于第二个参数时返回non-nil,否则返回nil。注意这个sort函数 162 | 对list的排序,始终保持car部分不变。下面是一个例子: 163 | 164 | #+BEGIN_SRC emacs-lisp 165 | ELISP> (setq nums '(1 3 2 6 5 4 0)) 166 | (1 3 2 6 5 4 0) 167 | ELISP> (sort nums '<) 168 | (0 1 2 3 4 5 6) 169 | ELISP> nums 170 | (1 2 3 4 5 6) 171 | #+END_SRC 172 | 173 | 注意这里的nums排序后,的car与原来list的car是一样的。所以一般采用重新赋值的方式 174 | *(setq nums (sort nums ’<))* 175 | -------------------------------------------------------------------------------- /cookbook.el: -------------------------------------------------------------------------------- 1 | ;;; cookbook.el --- produce cookbook pdf -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2016-2018 Aborn Jiang 4 | 5 | ;; Author: Aborn Jiang 6 | ;; Version: 0.1.0 7 | ;; Package-Requires: ((cl-lib "0.5") (f "0.19.0") (s "1.10.0") (async "1.9")) 8 | ;; Keywords: emacs cookbook 9 | ;; URL: https://github.com/aborn/emacs-cookbook 10 | 11 | ;; This file is NOT part of GNU Emacs. 12 | 13 | ;; This program is free software: you can redistribute it and/or modify 14 | ;; it under the terms of the GNU General Public License as published by 15 | ;; the Free Software Foundation, either version 3 of the License, or 16 | ;; (at your option) any later version. 17 | 18 | ;; This program is distributed in the hope that it will be useful, 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | ;; GNU General Public License for more details. 22 | 23 | ;; You should have received a copy of the GNU General Public License 24 | ;; along with this program. If not, see . 25 | 26 | ;;; Commentary: 27 | 28 | ;; The package to build cookbook 29 | ;; 30 | 31 | ;;; Code: 32 | 33 | (require 'cl-lib) 34 | (require 'f) 35 | (require 's) 36 | (require 'async) 37 | 38 | (defvar cookbook-root-dir "~/github/emacs-cookbook/") 39 | (defvar cookbook-name "emacs-cookbook") 40 | 41 | (defgroup cookbook nil 42 | "cookbook group" 43 | :prefix "cookbook-" 44 | :group 'org-export-pdf) 45 | 46 | (defcustom cookbook-chapters-dir 47 | (expand-file-name "chapters" cookbook-root-dir) 48 | "Chapters root path" 49 | :type 'string 50 | :group 'cookbook) 51 | 52 | (defun cookbook-chapter-org-files () 53 | "Get all chater org files. 获得所有org文件名" 54 | (cl-remove-if-not 55 | #'(lambda (x) 56 | (and (s-ends-with? ".org" x) 57 | (not (s-ends-with? "README.org" x)))) 58 | (f-files cookbook-chapters-dir))) 59 | 60 | (defun cookbook-run-async () 61 | "Do cookbook-run actioin use async method. 异步生成emacs-cookbook.pdf" 62 | (interactive) 63 | (message "start export all org files to pdf formart.") 64 | (async-start 65 | `(lambda () 66 | ,(async-inject-variables "\\`load-path\\'") 67 | ,(async-inject-variables "\\`org-latex-pdf-process\\'") 68 | ,(async-inject-variables "\\`org-element-use-cache\\'") 69 | (require 'cookbook) 70 | (require 'cl-lib) 71 | (require 'f) 72 | (require 's) 73 | (cookbook-run)) 74 | (lambda (result) 75 | (message "%S" result) 76 | (message "finished export all org files to pdf formart.")))) 77 | 78 | (defun cookbook-run () 79 | "Export all org file to pdf." 80 | (interactive) 81 | (let* ((files (cookbook-chapter-org-files))) 82 | (mapc #'(lambda (x) 83 | (let* ((src-file x)) 84 | (cookbook-org-to-pdf src-file))) 85 | files) 86 | (cookbook-produce) 87 | (cookbook-update-readme))) 88 | 89 | (defun cookbook-org-to-pdf (src-file) 90 | "export source file to dest files" 91 | ;;(message "src-file: %s dest-file:%s" src-file dest-file) 92 | (let* ((dest-file (concat 93 | (substring src-file 0 (- (length src-file) 3)) 94 | "pdf"))) 95 | (when (file-newer-than-file-p src-file dest-file) 96 | ;; when org file change, do convert. 97 | (find-file src-file) 98 | (org-latex-export-to-pdf)))) 99 | 100 | (defun cookbook-header-content () 101 | (concat 102 | "#+TITLE: Emacs实践笔记\n" 103 | "#+AUTHOR: aborn\n" 104 | (format "#+DATE: %s\n" (format-time-string "%Y-%m-%d %H:%M" (current-time))) 105 | "#+EMAIL: aborn.jiang@gmail.com\n" 106 | "#+LANGUAGE: zh\n" 107 | "#+LATEX_HEADER: \\usepackage{xeCJK}\n\n" 108 | "#+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup\n\n" 109 | "-----\n")) 110 | 111 | (defun cookbook-extract-org-content () 112 | "Extract current buffer org content (hearder content excluded.)" 113 | (let* ((content (buffer-string)) 114 | (s-begin (string-match "-----\n" content))) 115 | (when s-begin 116 | (cookbook-wrap-star-for-each-lines (substring-no-properties content (+ s-begin 5)))))) 117 | 118 | (defun cookbook-extract-org-title () 119 | "Extract current buffer org title, note: it should be a space before title." 120 | (let* ((content (buffer-string)) 121 | (start-prefix "+TITLE:") 122 | (s-begin (string-match start-prefix content)) 123 | (s-end (string-match "\n" content))) 124 | (when (and s-begin s-end) 125 | (concat "*" 126 | (substring-no-properties 127 | content 128 | (+ s-begin (length start-prefix)) s-end) 129 | "\n")))) 130 | 131 | (defun cookbook-produce-text-content () 132 | (concat 133 | (cookbook-header-content) 134 | (cl-reduce 'concat 135 | (mapcar #'(lambda (org-file) 136 | (find-file org-file) 137 | (concat 138 | (cookbook-extract-org-title) 139 | (cookbook-extract-org-content))) 140 | (cookbook-chapter-org-files))))) 141 | 142 | (defun cookbook-org-file-name () 143 | (expand-file-name 144 | (concat cookbook-name ".org") 145 | cookbook-root-dir)) 146 | 147 | (defun cookbook-produce () 148 | "Produce cookbook org & pdf." 149 | (interactive) 150 | (let* ((cookbook-content (cookbook-produce-text-content)) 151 | (cookbook-file (cookbook-org-file-name))) 152 | (find-file cookbook-file) 153 | (erase-buffer) 154 | (insert cookbook-content) 155 | (save-buffer) 156 | (cookbook-org-to-pdf cookbook-file))) 157 | 158 | (defun cookbook-wrap-star-for-each-lines (content) 159 | "Return book style star * for org mode." 160 | (cl-reduce 'concat 161 | (mapcar #'(lambda (item) 162 | (if (s-starts-with? "*" item) 163 | (concat "*" item "\n") 164 | (concat item "\n"))) 165 | (split-string content "\n" t)))) 166 | 167 | (defun cookbook-is-begin-of-line? () 168 | "check current position if begin of line." 169 | (let* ((cpoint (point)) 170 | (bline nil) 171 | (eline nil)) 172 | (save-excursion 173 | (beginning-of-line) 174 | (setq bline (point)) 175 | (end-of-line) 176 | (setq eline (point))) 177 | (and (equal cpoint bline) 178 | (equal cpoint eline)))) 179 | 180 | (defun cookbook-insert-code-format () 181 | "Insert code format" 182 | (interactive) 183 | (let* ((cpoint (point))) 184 | (unless (cookbook-is-begin-of-line?) 185 | (insert "\n")) 186 | (insert "#+BEGIN_SRC emacs-lisp\n") 187 | (setq cpoint (point)) 188 | (insert "\n#+END_SRC\n") 189 | (goto-char cpoint))) 190 | 191 | (defun cookbook-extract-readme (readme-file) 192 | "Update readme file time-stamp" 193 | (let* (content s-end time) 194 | (with-temp-buffer 195 | (insert-file-contents readme-file) 196 | (setq time (format-time-string "%Y-%m-%d")) 197 | (setq content (buffer-string)) 198 | (setq s-end (string-match "** 最新版本" content)) 199 | (message "%s" time) 200 | (when s-end 201 | (concat 202 | (substring-no-properties 203 | content 0 (+ s-end 11)) 204 | time)) 205 | ))) 206 | 207 | (defun cookbook-update-readme () 208 | "Update readme file" 209 | (interactive) 210 | (let* ((readme-file (expand-file-name "README.org" cookbook-root-dir)) 211 | (content (cookbook-extract-readme readme-file))) 212 | (if content 213 | (progn (find-file readme-file) 214 | (erase-buffer) 215 | (insert content) 216 | (save-buffer)) 217 | (message "errror in update readme.org file")))) 218 | 219 | (provide 'cookbook) 220 | ;;; cookbook.el ends here 221 | -------------------------------------------------------------------------------- /chapters/03_file.org: -------------------------------------------------------------------------------- 1 | #+TITLE: 文件 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-04-08 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 文件及访问 13 | 文件是操作系统永久保存数据的单元,为了编辑文件,我们必要告诉Emacs去读取一个文件,并将文件的内 14 | 容保存在一个Buffer里,这样Buffer与文件就关联在一起。下面介绍与文件访问相关的函数,由于历史原 15 | 因这些函数的命令都是以 *find-* 开头的,不是以 *visit-* 开头。 16 | 17 | ** 打开文件 18 | 如果想在buffer里打开一个文件,其命令是 *find-file* (C-x C-f)。当文件已经在buffer中存在时, 19 | 这个命令返回文件对应的buffer。如果当前没有buffer对应文件,则,创建一个buffer,并将其文件 20 | 内容读到buffer中,并返回这个buffer。字义如下: 21 | 22 | #+BEGIN_SRC emacs-lisp 23 | (find-file filename &optional wildcards) 24 | #+END_SRC 25 | 26 | 这个函数有一个对应的hook变量,叫 *find-file-hook* 它的值是一个函数列表。这些函数在文件被 27 | 打开后依次执行。 28 | 29 | ** 文件保存 30 | 文件被载入到buffer后,我们可以对其进行修改;修改完了后,将内容保存回文件,其对应的函数为: 31 | 32 | #+BEGIN_SRC emacs-lisp 33 | (save-buffer &optional backup-option) 34 | #+END_SRC 35 | 36 | 文件保存对应有两个hook变量,为: *before-save-hook* 和 *after-save-hook* 分别表示保 37 | 存前的hook函数列表和保存后的hook函数列表。与之类似的还有一个函数 *write-file* 38 | 39 | #+BEGIN_SRC emacs-lisp 40 | (write-file filename &optional confirm) 41 | #+END_SRC 42 | 这个函数的功能是将当前buffer的内容写入到filename对应的文件中,并将当前buffer与这个文件进 43 | 行关联 44 | 45 | ** 读取文件内容(Reading from Files) 46 | 将文件内容复制到buffer,可以使用 *insert-file-contents* 函数,注意在Lisp代码里不要使用 47 | *insert-file* 命令,因为它会设置mark标识。 48 | 49 | #+BEGIN_SRC emacs-lisp 50 | (insert-file-contents filename &optional visit beg end replace) 51 | #+END_SRC 52 | 这个函数在当前buffer的位置插入文件 *filename* 的内容,它返回一个它包含一个文件名和数据长度 53 | 信息的列表。如果文件不存在(或不可读),则会抛出错误异常!当这个函数执行后会调用 *after-insert-file-functions* 54 | 列表里的函数。一般情况下,在这个列表里的函数其中有一个是用来检测文件内容的编码。与这个函数类似 55 | 的一个函数为(insert-file-contents-literally filename &optional visit beg end [Function] replace) 56 | ,它们唯一的区别的后者不内容进行格式化、不对字符做转换。 57 | 58 | 如果参数visit不是nil时,执行这个函数后会将当前buffer设置为未修改(unmodified)状态。 59 | 60 | ** 往文件里写内容(Writing to Files) 61 | 将buffer里的内容(或者部分内容)直接写入到一个文件,可以采用 *append-to-file* 和 *write-region* 62 | 函数。注意这里不要写入正在访问的文件,否则会出现异常情况: 63 | 64 | #+BEGIN_SRC emacs-lisp 65 | (append-to-file start end filename) 66 | #+END_SRC 67 | 这个函数的作用是将当前buffer里的部分内容(从start到end部分内容)追加到文件 *filename* 的 68 | 后面。如果是在lisp中使用,这个函数完全等价于 (write-region start end filename t)。 69 | 70 | #+BEGIN_SRC emacs-lisp 71 | (write-region start end filename &optional append visit lockname mustbenew) 72 | #+END_SRC 73 | 这个函数的作用与append-to-file类似,不过其参数更多。 74 | 1. 当start为nil时,这个函数写入的是当前buffer所有内容,这时end参数没有用; 75 | 2. 当start为string时,这个函数写入的内容是string的内容,这时end参数失效; 76 | 3. 当append不是nil时,表示往现有文件里进行追加,当append是一个数字时,表示从当前文件开始到append的位置开始写入。 77 | 4. 当mustbenew不为nil时,当覆盖已有文件时,会询问用户,并获得用户确定后再操作。 78 | 79 | #+BEGIN_SRC emacs-lisp 80 | (with-temp-file file body) 81 | #+END_SRC 82 | *with-temp-file* 是一个宏操作,它将创建一个临时buffer作为当前buffer,在这个buffer里对 83 | body进行求值,最后将这个buffer的内容写入到文件 *file* 里。当整个body执行完成后,Emacs将 84 | 会把这个临时buffer关闭,恢复到执行with-temp-file之前的当前buffer。它将body的最后执行结 85 | 果作为with-temp-file的返回结果。 86 | 87 | * 文件锁 88 | 当多个用户同时修改一个文件里,这时候需要文件锁。Emacs里的文件锁是保存在同一目录下的一个文件, 89 | 它有一个特殊的名字. 90 | 91 | #+BEGIN_SRC emacs-lisp 92 | (file-locked-p filename) 93 | #+END_SRC 94 | *file-locked-p* 这个函数用来检查文件是否被锁。当文件没有被锁,则返回nil;如果被Emacs进程 95 | 锁了,则返回t,当被其他job锁了,则返回使用都信息。 96 | 97 | #+BEGIN_SRC emacs-lisp 98 | (lock-buffer &optional filename) 99 | #+END_SRC 100 | 如果当前buffer被修改过,这个函数锁定当前buffer所关联的文件。与之相对应的操作有解锁,可以使用 101 | (unlock-buffer) 这个函数。 102 | 103 | #+BEGIN_SRC emacs-lisp 104 | (ask-user-about-lock file other-user) 105 | #+END_SRC 106 | 当一个用户修改正在被另一个用户锁定的文件时,询问用户。该函数的返回值(即用户的选择),决定Emacs 107 | 接下来该如何执行。 108 | 109 | * 文件基本信息函数 110 | 下面介绍一些与文件基本信息相关的函数 111 | 112 | ** 文件是否存在 113 | 判断一个文件是否存在采用 *file-exists-p* 这个函数: 114 | #+BEGIN_SRC emacs-lisp 115 | (file-exists-p filename) 116 | #+END_SRC 117 | 与之类似的有: *file-readable-p* 、 *file-executable-p* 、 *file-writable-p* 、 118 | *file-directory-p* *file-symlink-p* 这几个函数。 119 | 120 | ** 文件新旧比较 121 | #+BEGIN_SRC emacs-lisp 122 | (file-newer-than-file-p filename1 filename2) 123 | #+END_SRC 124 | 当filename1比filename2新时,该函数返回t。如果filename1不存在,则返回nil。如果filename1 125 | 存在,但filename2不存在,则返回t。 126 | 127 | ** 文件模式 128 | #+BEGIN_SRC emacs-lisp 129 | (file-modes filename) 130 | #+END_SRC 131 | 这个函数返回文件的属性,跟linux里的chmod命令相对应,它返回的是一个整数:它包含了文件的读、 132 | 写和可执行权限。 133 | #+BEGIN_SRC emacs-lisp 134 | (file-modes "~/junk/diffs") ;; ⇒ 492 ; Decimal integer. 135 | #+END_SRC 136 | 137 | ** 文件属性 138 | 这小节介绍与文件属性有关的一些函数,如文件的所属人、所属组、文件大小、文件的最新读取和修改时 139 | 间等。 140 | #+BEGIN_SRC emacs-lisp 141 | (file-attributes filename &optional id-format) 142 | #+END_SRC 143 | 这个函数返回文件对应的属性列表,下面是一个调用示例: 144 | #+BEGIN_SRC emacs-lisp 145 | (file-attributes "~/tree.txt") 146 | ;; 返回如下 147 | (nil 1 501 20 148 | (23331 5030 438781 943000) 149 | (23331 4821 822935 764000) 150 | (23331 4821 822935 764000) 151 | 10496 "-rw-r--r--" t 8602715307 16777220) 152 | #+END_SRC 153 | 属性列表按顺序说明如下: 154 | 0. t 表示目录,字符串表示符号链接,nil 为文本文件; 155 | 1. 这个文件有多少名字与之关联,一般为1,当有符号链接时不一样; 156 | 2. 文件的UID; 157 | 3. 文件的GID; 158 | 4. 文件最近accessTime,有4个元素的列表(sec-high sec-low microsec picosec); 159 | 5. 文件最后修改时间; 160 | 6. 文件状态最后被修改时间;主要是用chmod来改变文件模式; 161 | 7. 文件大小,单位byte; 162 | 8. 文件模式; 163 | 9. 未使用值,主要用来做向下兼容; 164 | 10. 文件的inode编码; 165 | 11. 设备的文件系统码; 166 | 167 | * 文件操作 168 | ** 文件复制和重命名 169 | 文件重命名函数为 *rename-file* 170 | #+BEGIN_SRC emacs-lisp 171 | (rename-file filename newname &optional ok-if-already-exists) 172 | #+END_SRC 173 | 174 | 复制文件函数为 *copy-file* 175 | #+BEGIN_SRC emacs-lisp 176 | (copy-file oldname newname &optional ok-if-exists time 177 | preserve-uid-gid preserve-extended-attributes) 178 | #+END_SRC 179 | 这个函数的作用是复制老的文件 *oldname* 到新的文件 *newname*, 这里有一点要注意的是如果新的 180 | 文件名 *newname* 为目录,则复制老的文件到这个目录(文件名保持为 *oldname* 不变)。当参数 181 | time不为nil时,则新文件保持与老文件相同的最后修改时间属性信息。 182 | 183 | ** 文件删除 184 | 文件删除的函数为 *delete-file* 185 | #+BEGIN_SRC emacs-lisp 186 | (delete-file filename &optional trash) 187 | #+END_SRC 188 | 这里有一点要注意的是如果文件filename为符号链接,这个函数只删除符号链接,不删除原目标文件。 189 | 190 | ** 设置文件属性 191 | 设置文件属性函数为 *set-file-modes* 192 | #+BEGIN_SRC emacs-lisp 193 | (set-file-modes filename mode) 194 | #+END_SRC 195 | 这里的mode必须为整数,下面是一个例子: 196 | #+BEGIN_SRC emacs-lisp 197 | (set-file-modes "a.txt" #o644) 198 | #+END_SRC 199 | 如果想获取默认的文件权限属性,可使用(default-file-modes)来获取,它返回的是一个整数。 200 | 201 | * 文件查找 202 | ** locate-file 203 | #+BEGIN_SRC emacs-lisp 204 | (locate-file filename path &optional suffixes predicate) 205 | #+END_SRC 206 | *locate-file* 这个函数用来查找在path目录下文件名为filename的文件,如果找到则返回绝对文件 207 | 名。注意第二个参数path必需为目录列表,像 *exec-path* 对应的列表一样。下面是一个例子: 208 | #+BEGIN_SRC emacs-lisp 209 | (locate-file "03_file.org" '("/Users/aborn/github/emacs-cookbook/chapters/")) 210 | ;; "/Users/aborn/github/emacs-cookbook/chapters/03_file.org" 211 | (locate-file "03_file" '("/Users/aborn/github/emacs-cookbook/chapters/") '(".tex" ".org")) 212 | ;; "/Users/aborn/github/emacs-cookbook/chapters/03_file.tex" 213 | #+END_SRC 214 | 可选参数 suffixes 为后缀列表,查找所有后缀,以第一个查到为准。注意,这里的文件查找只会查找 215 | path目录,不会查找其子目录。 216 | 217 | ** executable-find 218 | #+BEGIN_SRC emacs-lisp 219 | (executable-find program) 220 | #+END_SRC 221 | executable-find用于查找可执行文件,查找所有 *exec-path* 目录下的可执行文件(以及查找所 222 | 有后缀为exec-suffixes列表里的可执行文件),下面是一个例子: 223 | #+BEGIN_SRC emacs-lisp 224 | (executable-find "emacs") 225 | ;; "/usr/local/bin/emacs" 226 | #+END_SRC 227 | 228 | * 文件与目录 229 | 判断文件是否在一个目录下,怎么做? 230 | 231 | #+BEGIN_SRC emacs-lisp 232 | (file-in-directory-p file dir) 233 | #+END_SRC 234 | 235 | 如果file是一个在目录dir或者dir子目录下的文件,则返回t。如果file与dir处于同一目录,也返回t。 236 | 如果想列出一个目录下的所有文件,那就要用到 *directory-files* 这个函数,其定义如下: 237 | 238 | #+BEGIN_SRC emacs-lisp 239 | (directory-files directory &optional full-name match-regexp nosort) 240 | #+END_SRC 241 | 242 | 这个函数按字母顺序返回目录 directory 下的所有文件。参数 full-name 不为nil时,则返回每个文 243 | 件的绝对路径,否则返回相对路径。match-regexp 如果不是nil,该函数返回只与match-regexp相匹 244 | 配的文件列表。nosort如果不为nil,则不按字母排序。 245 | 246 | ** 创建、复制和删除目录 247 | 对目录的创建、复制和删除都有相关的处理函数,下面一一介绍: 248 | 249 | #+BEGIN_SRC emacs-lisp 250 | (make-directory dirname &optional parents) 251 | #+END_SRC 252 | *make-directory* 创建一个目录名为dirname的目录 253 | 254 | * 文件名与文件路径 255 | 我们知道大部分操作系统,文件名由两部分组成:文件名和路径,任何一个文件都在某个具体路径下。下面 256 | 介绍一些与之相关的函数操作。 257 | 258 | ** 文件名、路径、文件后缀 259 | #+BEGIN_SRC emacs-lisp 260 | (file-name-directory filename) 261 | #+END_SRC 262 | 263 | *file-name-directory* 返回的文件名里的目录部分,如果文件名里没有包含目录部分,则返回nil。 264 | 与这个函数对应的一个函数为 *file-name-nondirectory* ,它返回非目录部分。如果想获取文件的 265 | 后缀,采用如下函数: 266 | #+BEGIN_SRC emacs-lisp 267 | (file-name-extension filename &optional period) 268 | #+END_SRC 269 | 这里有一点要引起注意,如果一个文件名以点号(.)开始,如.emacs,file-name-extension返回的后 270 | 缀不是.emacs,而是nil。 271 | 272 | #+BEGIN_SRC emacs-lisp 273 | (file-name-sans-versions filename &optional keep-backup-version) 274 | #+END_SRC 275 | *file-name-sans-versions* 这个函数返回不包含任何版本、备份号等信息的"纯"文件名,下面是 276 | 一些例子: 277 | #+BEGIN_SRC emacs-lisp 278 | (file-name-sans-versions "~rms/foo.~1~") ;; ⇒ "~rms/foo" 279 | (file-name-sans-versions "~rms/foo~") ;; ⇒ "~rms/foo" 280 | (file-name-sans-versions "~rms/foo") ;; ⇒ "~rms/foo" 281 | #+END_SRC 282 | 283 | ** 文件路径 284 | *expand-file-name* 这个函数将文件名转成绝对文件名: 285 | 286 | #+BEGIN_SRC emacs-lisp 287 | (expand-file-name filename &optional directory) 288 | #+END_SRC 289 | 290 | 如果directory参数存在,将filename作为其相对路径,否则使用 *default-directory* 变量。 291 | 这个函数在写elisp代码时经常用到,下面是一些例子: 292 | 293 | #+BEGIN_SRC emacs-lisp 294 | (expand-file-name "foo") 295 | ;; ⇒ "/xcssun/users/rms/lewis/foo" 296 | (expand-file-name "../foo") 297 | ;; ⇒ "/xcssun/users/rms/foo" 298 | (expand-file-name "foo" "/usr/spool/") ⇒ "/usr/spool/foo" 299 | #+END_SRC 300 | 301 | 与expand-file-name相似的函数还有 *file-truename* 这个函数 302 | #+BEGIN_SRC emacs-lisp 303 | (file-truename filename) 304 | #+END_SRC 305 | 下面是一些例子 306 | #+BEGIN_SRC emacs-lisp 307 | (file-truename "~/tree.txt") ;; "/Users/aborn/tree.txt" 308 | (file-truename "../tree.txt") ;; "/Users/tree.txt" 309 | (file-truename "../../tree.txt") ;; "/tree.txt" 310 | #+END_SRC 311 | 312 | 特别说明: *default-directory* 是一个Buffer的本地变量(Buffer-Local Variable),仅对 313 | 当前Buffer有效,且它是一个绝对路径(但可以以~开头)。 314 | 315 | 有时候,有程序里路径是含有环境变量的(Bash里是以$开头的),如想将这些环境变量转成其相应的值, 316 | 则可使用 *substitute-in-file-name* 这个函数: 317 | #+BEGIN_SRC emacs-lisp 318 | (substitute-in-file-name filename) 319 | #+END_SRC 320 | 如下例子: 321 | #+BEGIN_SRC emacs-lisp 322 | (substitute-in-file-name "$HOME/bin") 323 | ;; "/Users/aborn/bin" 324 | #+END_SRC 325 | 326 | ** 目录文件列表 327 | 目录是一种特殊的文件,它可以包含其他文件或文件夹。获取目录下所有文件列表(像ls命令一样),可 328 | 以使用 *directory-files* 这个函数: 329 | 330 | #+BEGIN_SRC emacs-lisp 331 | (directory-files directory &optional full-name match-regexp nosort) 332 | #+END_SRC 333 | 这个函数返回directory下所有文件列表(包括目录),默认是按字母顺序排列。参数full-name不是nil 334 | 时,返回的是包含路径的绝对文件名,默认是返回相对文件名。参数match-regexp不是nil时,只返回与 335 | match-regexp正则表达式相匹配的文件名。参数nosort不为nil时,这个函数不对文件列表进行排序, 336 | 可用于对文件顺序不关系的场景(这时可最快获取返回结果)。这个函数只返回当前目录下的所有文件, 337 | 如果想递归获取所有的文件列表,可采用 *directory-files-recursively* 函数: 338 | 339 | #+BEGIN_SRC emacs-lisp 340 | (directory-files-recursively directory regexp &optional include-directories) 341 | #+END_SRC 342 | 这个函数递归的搜索在目录directory及其子目录下所有文件名与regexp相匹配的文件,返回文件的绝 343 | 对路径列表。默认情况下返回的文件名是深度优先排序,也就是说子目录的文件名排序在其父目录之前, 344 | 处于同一级目录的文件是按字母排序。当include-directories不为nil时,目录文件也包括其搜索 345 | 结果中。 346 | 347 | * 文件格式转换 348 | Emacs将文件从磁盘载入到buffer中,或者将buffer中内容写入到磁盘中,需要经过许多步骤。如 349 | *insert-file-contents* 读取文件内容到buffer,*write-region* 写入一个buffer到文件。 350 | 351 | ** 整体流程 352 | 对于 *insert-file-contents* 过程: 353 | 1. 初始化,从文件中插入字节到buffer; 354 | 2. 解码,根据文件编码进行解码操作; 355 | 3. 按 *format-alist* 进行的格式化列表对其进行格式化; 356 | 4. 调用所有在 *after-insert-file-functions* 列表中的函数。 357 | 358 | 对于 *write-region* 过程: 359 | 1. 初始化,调用 *write-region-annotate-functions* 列表中的函数; 360 | 2. 按 *format-alist* 定义的格式化列表对其进行格式化处理; 361 | 3. 按适当编码格式对其进行编码成字节; 362 | 4. 用字节修改其文件。 363 | 364 | ** 格式转换 365 | 从以上整体流程我们可以看得出,其中格式化都使用 *format-alist* 进行处理,这个列表的每一项定 366 | 义了一种格式转换,它的定义如下: 367 | 368 | #+BEGIN_SRC emacs-lisp 369 | (name doc-string regexp from-fn to-fn modify mode-fn preserve) 370 | #+END_SRC 371 | 下面介绍每个参数含义: 372 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /chapters/991_emacs26.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Emacs 26特性 2 | #+AUTHOR: aborn 3 | #+DATE: 2018-06-21 4 | #+EMAIL: aborn.jiang@gmail.com 5 | #+LANGUAGE: zh 6 | #+LATEX_HEADER: \usepackage{xeCJK} 7 | 8 | #+SETUPFILE: ~/github/org-html-themes/setup/theme-readtheorg.setup 9 | 10 | ----- 11 | 12 | * 本文档说明 13 | 这是Emacs 26 版本发布说明的中文翻译版本: 14 | 15 | GNU Emacs NEWS -- history of user-visible changes. 16 | 17 | Copyright (C) 2016-2018 Free Software Foundation, Inc. 18 | See the end of the file for license conditions. 19 | 20 | Please send Emacs bug reports to bug-gnu-emacs@gnu.org. 21 | If possible, use M-x report-emacs-bug. 22 | 23 | This file is about changes in Emacs version 26. 24 | 25 | See file HISTORY for a list of GNU Emacs versions and release dates. 26 | See files NEWS.25, NEWS.24, ..., NEWS.18, and NEWS.1-17 for changes 27 | in older Emacs versions. 28 | 29 | You can narrow news to a specific version by calling 'view-emacs-news' 30 | with a prefix argument or by typing C-u C-h C-n. 31 | 32 | 33 | * Emacs 26.2安装变化 34 | 35 | ** 使用'--with-xwidgets'参数构建Emacs需要依赖WebKit2 36 | 构建支持xwidgets版本的Emacs,需要先安装webkit2gtk-4.0 包,要求版本在2.12及以上版本。这 37 | 个改变其实从Emacs 26.1开始的,只不过没有发布文档里提到。 38 | 39 | * Emacs 26.2中特殊模式和包的变化 40 | 41 | ** Gnus 42 | 43 | Mailutils movemail will now be used if found at runtime. 44 | *mail-source-movemail-program* 这个变量的默认值已经改为 *movemail* 。这样做的目地是 45 | 确保使用GNU的邮件工作包里的移动邮件程序,如果发现它在exec-path目录里(即使在构建时没有找到)。 46 | 可以通过定制 *mail-source-movemail-program* 变量的值来切换到其他程序。 47 | 48 | ** Shell模式 49 | Shell模式下的Buffer的 *scroll-conservatively* 变量默认值变为101。这样使得在Shell模式 50 | 下,当有新的输出添加到屏幕时,更好地模拟在文本终端下的滚动行为。重新将 *scroll-conservatively* 51 | 变量的值设置为0或者任何其他值,就可回退出老版本的行为(可以在shell-mode-hook的函数列表中 52 | 设置)。这个改变也是从Emacs 26.1就有,不过没有在其文档中提到。 53 | 54 | ** VC 55 | 56 | 优化了VC对Mercurial的支持。Emacs为了更快的操作速度,尽量避免唤起 *hg* 。 57 | 58 | *** 新vc-hg选项 59 | 新增'vc-hg-parse-hg-data-structures'用来控制vc-hg是否解析直接Mercurial数据结构,或者 60 | 采用执行hg来替代。默认值为t (老版本值为nil)。 61 | 62 | 新增'vc-hg-symbolic-revision-styles'用来控制在mode line模式下版本的展示样式。 63 | 64 | 新增'vc-hg-use-file-version-for-mode-line-version'用来控制将版本展示在mode 65 | line里是那些已经访问过的文件还是那整体工作仓库的拷贝。 66 | 67 | *** Mercurial版本在mode-line的显示变化 68 | 老版本,mode-line显示的是本地修改的版本数值 (1, 2, 3, ...)。从26.1版本开始,默认显示做 69 | 了变化,当前显示的是全局的修改版本值,格式为修改的hash值。如果想恢复到之前的显示,只需要修 70 | 改变量 *vc-hg-symbolic-revision-styles* 的值为 *("{rev}")* 。 71 | 72 | * Emacs 26.1安装变化 73 | 74 | ** 默认情况下编译Emacs需要libgnutls这个库 75 | 采用 *configure --with-gnutls=no* 这个选项已经废弃。 76 | 77 | ** GnuTLS版本需要2.12.2或者更高版本 78 | 79 | ** The new option 'configure --with-mailutils' causes Emacs to rely on 80 | GNU Mailutils to retrieve email. It is recommended, and is the 81 | default if GNU Mailutils is installed. When --with-mailutils is not 82 | in effect, the Emacs build procedure by default continues to build and 83 | install a limited 'movemail' substitute that retrieves POP3 email only 84 | via insecure channels. To avoid this problem, use either 85 | --with-mailutils or --without-pop when configuring; --without-pop 86 | is the default on platforms other than native MS-Windows. 87 | 88 | ** The new option 'configure --enable-gcc-warnings=warn-only' causes 89 | GCC to issue warnings without stopping the build. This behavior is 90 | now the default in developer builds. As before, use 91 | '--disable-gcc-warnings' to suppress GCC's warnings, and 92 | '--enable-gcc-warnings' to stop the build if GCC issues warnings. 93 | 94 | ** When GCC warnings are enabled, '--enable-check-lisp-object-type' is 95 | now enabled by default when configuring. 96 | 97 | ** The Emacs server now has socket-launching support. This allows 98 | socket based activation, where an external process like systemd can 99 | invoke the Emacs server process upon a socket connection event and 100 | hand the socket over to Emacs. Emacs uses this socket to service 101 | emacsclient commands. This new functionality can be disabled with the 102 | configure option '--disable-libsystemd'. 103 | 104 | ** A systemd user unit file is provided. Use it in the standard way: 105 | 'systemctl --user enable emacs'. 106 | (If your Emacs is installed in a non-standard location, you may 107 | need to copy the emacs.service file to eg ~/.config/systemd/user/) 108 | 109 | ** New configure option '--disable-build-details' attempts to build an 110 | Emacs that is more likely to be reproducible; that is, if you build 111 | and install Emacs twice, the second Emacs is a copy of the first. 112 | Deterministic builds omit the build date from the output of the 113 | 'emacs-version' and 'erc-cmd-SV' functions, and the leave the 114 | following variables nil: 'emacs-build-system', 'emacs-build-time', 115 | 'erc-emacs-build-time'. 116 | 117 | ** Emacs can now be built with support for Little CMS. 118 | 119 | If the lcms2 library is installed, Emacs will enable features built on 120 | top of that library. The new configure option '--without-lcms2' can 121 | be used to build without lcms2 support even if it is installed. Emacs 122 | linked to Little CMS exposes color management functions in Lisp: the 123 | color metrics 'lcms-cie-de2000' and 'lcms-cam02-ucs', as well as 124 | functions for conversion to and from CIE CAM02 and CAM02-UCS. 125 | 126 | ** The configure option '--with-gameuser' now defaults to 'no', 127 | as this appears to be the most common configuration in practice. 128 | When it is 'no', the shared game directory and the auxiliary program 129 | update-game-score are no longer needed and are not installed. 130 | 131 | ** Emacs不再对IRIX系统做支持 132 | 我们希望这部分Emacs用户不会因此受到影响,因为SGI从2013年12份开始已经停止了对IRIX的支持。 133 | 134 | * Emacs 26.1启动的变化 135 | 136 | ** 新增'--fg-daemon'选项 137 | 这个选项跟'--daemon'类似, 只有一点不一样的那就是它是运行在前台并且不是fork的。这个选项的 138 | 目的是用于现在启动系统,如systemd,它管理许多传统的常住行为(daemon behavior)。同时,这个 139 | '--bg-daemon' 选项是 '--daemon' 的别名。 140 | 141 | ** 新增'--module-assertions'选项 142 | When given this option, Emacs will perform expensive correctness 143 | checks when dealing with dynamic modules. This is intended for module 144 | authors that wish to verify that their module conforms to the module 145 | requirements. The option makes Emacs abort if a module-related 146 | assertion triggers. 147 | 148 | ** Emacs now supports 24-bit colors on capable text terminals. 149 | Terminal is automatically initialized to use 24-bit colors if the 150 | required capabilities are found in terminfo. See the FAQ node 151 | "(efaq) Colors on a TTY" for more information. 152 | 153 | ** Emacs在启动的时候遵守X资源"scrollBar" 154 | 这个效果与工具条(tool bar)里的"toolBar"资源类似。 155 | 156 | * Emacs 26.1的变化 157 | 158 | ** 'buffer-offer-save' 添加新值 159 | 'buffer-offer-save' 添加新的选项'always'。当配置为这个值时命令'save-some-buffers'将 160 | 将这个buffer作为保存项(offer this buffer for saving)。 161 | 162 | ** Security vulnerability related to Enriched Text mode is removed. 163 | 164 | *** Enriched Text mode does not evaluate Lisp in 'display' properties. 165 | This feature allows saving 'display' properties as part of text. 166 | Emacs 'display' properties support evaluation of arbitrary Lisp forms 167 | as part of processing the property for display, so displaying Enriched 168 | Text could be vulnerable to executing arbitrary malicious Lisp code 169 | included in the text (e.g., sent as part of an email message). 170 | Therefore, execution of arbitrary Lisp forms in 'display' properties 171 | decoded by Enriched Text mode is now disabled by default. Customize 172 | the new option 'enriched-allow-eval-in-display-props' to a non-nil 173 | value to allow Lisp evaluation in decoded 'display' properties. 174 | 175 | This vulnerability was introduced in Emacs 21.1. To work around that 176 | in Emacs versions before 25.3, append the following to your ~/.emacs 177 | init file: 178 | 179 | (eval-after-load "enriched" 180 | '(defun enriched-decode-display-prop (start end &optional param) 181 | (list start end))) 182 | 183 | ** Functions in 'write-contents-functions' can fully short-circuit the 184 | 'save-buffer' process. Previously, saving a buffer that was not 185 | visiting a file would always prompt for a file name. Now it only does 186 | so if 'write-contents-functions' is nil (or all its functions return 187 | nil). 188 | 189 | ** New variable 'executable-prefix-env' for inserting magic signatures. 190 | This variable affects the format of the interpreter magic number 191 | inserted by 'executable-set-magic'. If non-nil, the magic number now 192 | takes the form "#!/usr/bin/env interpreter", otherwise the value 193 | determined by 'executable-prefix', which is by default 194 | "#!/path/to/interpreter". By default, 'executable-prefix-env' is nil, 195 | so the default behavior is not changed. 196 | 197 | ** The variable 'emacs-version' no longer includes the build number. 198 | This is now stored separately in a new variable, 'emacs-build-number'. 199 | 200 | ** Emacs now provides a limited form of concurrency with Lisp threads. 201 | Concurrency in Emacs Lisp is "mostly cooperative", meaning that 202 | Emacs will only switch execution between threads at well-defined 203 | times: when Emacs waits for input, during blocking operations related 204 | to threads (such as mutex locking), or when the current thread 205 | explicitly yields. Global variables are shared among all threads, but 206 | a 'let' binding is thread-local. Each thread also has its own current 207 | buffer and its own match data. 208 | 209 | See the chapter "(elisp) Threads" in the ELisp manual for full 210 | documentation of these facilities. 211 | 212 | ** The new user variable 'electric-quote-chars' provides a list 213 | of curved quotes for 'electric-quote-mode', allowing user to choose 214 | the types of quotes to be used. 215 | 216 | ** The new user option 'electric-quote-context-sensitive' makes 217 | 'electric-quote-mode' context sensitive. If it is non-nil, you can 218 | type an ASCII apostrophe to insert an opening or closing quote, 219 | depending on context. Emacs will replace the apostrophe by an opening 220 | quote character at the beginning of the buffer, the beginning of a 221 | line, after a whitespace character, and after an opening parenthesis; 222 | and it will replace the apostrophe by a closing quote character in all 223 | other cases. 224 | 225 | ** The new variable 'electric-quote-inhibit-functions' controls when 226 | to disable electric quoting based on context. Major modes can add 227 | functions to this list; Emacs will temporarily disable 228 | 'electric-quote-mode' whenever any of the functions returns non-nil. 229 | This can be used by major modes that derive from 'text-mode' but allow 230 | inline code segments, such as 'markdown-mode'. 231 | 232 | ** The new user variable 'dired-omit-case-fold' allows the user to 233 | customize the case-sensitivity of dired-omit-mode. It defaults to 234 | the same sensitivity as that of the filesystem for the corresponding 235 | dired buffer. 236 | 237 | ** Emacs now uses double buffering to reduce flicker when editing and 238 | resizing graphical Emacs frames on the X Window System. This support 239 | requires the DOUBLE-BUFFER extension, which major X servers have 240 | supported for many years. If your system has this extension, but an 241 | Emacs built with double buffering misbehaves on some displays you use, 242 | you can disable the feature by adding 243 | 244 | '(inhibit-double-buffering . t) 245 | 246 | to default-frame-alist. Or inject this parameter into the selected 247 | frame by evaluating this form: 248 | 249 | (modify-frame-parameters nil '((inhibit-double-buffering . t))) 250 | 251 | ** The customization group 'wp', whose label was "text", is now 252 | deprecated. Use the new group 'text', which inherits from 'wp', 253 | instead. 254 | 255 | ** The new function 'call-shell-region' executes a command in an 256 | inferior shell with the buffer region as input. 257 | 258 | ** The new user option 'shell-command-dont-erase-buffer' controls 259 | if the output buffer is erased between shell commands; if non-nil, 260 | the output buffer is not erased; this variable also controls where 261 | to set the point in the output buffer: beginning of the output, 262 | end of the buffer or save the point. 263 | When 'shell-command-dont-erase-buffer' is nil, the default value, 264 | the behavior of 'shell-command', 'shell-command-on-region' and 265 | 'async-shell-command' is as usual. 266 | 267 | ** The new user option 'async-shell-command-display-buffer' controls 268 | whether the output buffer of an asynchronous command is shown 269 | immediately, or only when there is output. 270 | 271 | ** New user option 'mouse-select-region-move-to-beginning'. 272 | This option controls the position of point when double-clicking 273 | mouse-1 on the end of a parenthetical grouping or string-delimiter: 274 | the default value nil keeps point at the end of the region, setting it 275 | to non-nil moves point to the beginning of the region. 276 | 277 | ** New user option 'mouse-drag-and-drop-region'. 278 | This option allows you to drag the entire region of text to another 279 | place or another buffer. Its behavior is customizable via the new 280 | options 'mouse-drag-and-drop-region-cut-when-buffers-differ', 281 | 'mouse-drag-and-drop-region-show-tooltip', and 282 | 'mouse-drag-and-drop-region-show-cursor'. 283 | 284 | ** The new user option 'confirm-kill-processes' allows the user to 285 | skip a confirmation prompt for killing subprocesses when exiting 286 | Emacs. When set to t (the default), Emacs will prompt for 287 | confirmation before killing subprocesses on exit, which is the same 288 | behavior as before. 289 | 290 | ** 'find-library-name' will now fall back on looking at 'load-history' 291 | to try to locate libraries that have been loaded with an explicit path 292 | outside 'load-path'. 293 | 294 | ** Faces in 'minibuffer-prompt-properties' no longer overwrite properties 295 | in the text in functions like 'read-from-minibuffer', but instead are 296 | added to the end of the face list. This allows users to say things 297 | like '(read-from-minibuffer (propertize "Enter something: " 'face 'bold))'. 298 | 299 | ** The new variable 'extended-command-suggest-shorter' has been added 300 | to control whether to suggest shorter 'M-x' commands or not. 301 | 302 | ** icomplete now respects 'completion-ignored-extensions'. 303 | 304 | ** Non-breaking hyphens are now displayed with the 'nobreak-hyphen' 305 | face instead of the 'escape-glyph' face. 306 | 307 | ** Approximations to quotes are now displayed with the new 'homoglyph' 308 | face instead of the 'escape-glyph' face. 309 | 310 | ** New face 'header-line-highlight'. 311 | This face is the header-line analogue of 'mode-line-highlight'; it 312 | should be the preferred mouse-face for mouse-sensitive elements in the 313 | header line. 314 | 315 | ** 'C-x h' ('mark-whole-buffer') will now avoid marking the prompt 316 | part of minibuffers. 317 | 318 | ** 'fill-paragraph' no longer marks the buffer as changed unless it 319 | actually changed something. 320 | 321 | ** The locale language name 'ca' is now mapped to the language 322 | environment 'Catalan', which has been added. 323 | 324 | ** 'align-regexp' has a separate history for its interactive argument. 325 | 'align-regexp' no longer shares its history with all other 326 | history-less functions that use 'read-string'. 327 | 328 | ** The networking code has been reworked so that it's more 329 | asynchronous than it was (when specifying :nowait t in 330 | 'make-network-process'). How asynchronous it is varies based on the 331 | capabilities of the system, but on a typical GNU/Linux system the DNS 332 | resolution, the connection, and (for TLS streams) the TLS negotiation 333 | are all done without blocking the main Emacs thread. To get 334 | asynchronous TLS, the TLS boot parameters have to be passed in (see 335 | the manual for details). 336 | 337 | Certain process oriented functions (like 'process-datagram-address') 338 | will block until socket setup has been performed. The recommended way 339 | to deal with asynchronous sockets is to avoid interacting with them 340 | until they have changed status to "run". This is most easily done 341 | from a process sentinel. 342 | 343 | ** 'make-network-process' and 'open-network-stream' sometimes allowed 344 | :service to be an integer string (e.g., :service "993") and sometimes 345 | required an integer (e.g., :service 993). This difference has been 346 | eliminated, and integer strings work everywhere. 347 | 348 | ** It is possible to disable attempted recovery on fatal signals. 349 | Two new variables support disabling attempts to recover from stack 350 | overflow and to avoid automatic auto-save when Emacs is delivered a 351 | fatal signal. 'attempt-stack-overflow-recovery', if set to nil, 352 | will disable attempts to recover from C stack overflows; Emacs will 353 | then crash as with any other fatal signal. 354 | 'attempt-orderly-shutdown-on-fatal-signal', if set to nil, will 355 | disable attempts to auto-save the session and shut down in an orderly 356 | fashion when Emacs receives a fatal signal; instead, Emacs will 357 | terminate immediately. Both variables are non-nil by default. 358 | These variables are for users who would like to avoid the small 359 | probability of data corruption due to techniques Emacs uses to recover 360 | in these situations. 361 | 362 | ** File local and directory local variables are now initialized each 363 | time the major mode is set, not just when the file is first visited. 364 | These local variables will thus not vanish on setting a major mode. 365 | 366 | ** A second dir-local file (.dir-locals-2.el) is now accepted. 367 | See the doc string of 'dir-locals-file' for more information. 368 | 369 | ** Connection-local variables can be used to specify local variables 370 | with a value depending on the connected remote server. For details, 371 | see the node "(elisp) Connection Local Variables" in the ELisp manual. 372 | 373 | ** International domain names (IDNA) are now encoded via the new 374 | puny.el library, so that one can visit Web sites with non-ASCII URLs. 375 | 376 | ** The new 'list-timers' command lists all active timers in a buffer, 377 | where you can cancel them with the 'c' command. 378 | 379 | ** 'switch-to-buffer-preserve-window-point' now defaults to t. 380 | Applications that call 'switch-to-buffer' and want to show the buffer at 381 | the position of its point should use 'pop-to-buffer-same-window' in lieu 382 | of 'switch-to-buffer'. 383 | 384 | ** The new variable 'debugger-stack-frame-as-list' allows displaying 385 | all call stack frames in a Lisp backtrace buffer as lists. Both 386 | debug.el and edebug.el have been updated to heed to this variable. 387 | 388 | ** Values in call stack frames are now displayed using 'cl-prin1'. 389 | The old behavior of using 'prin1' can be restored by customizing the 390 | new option 'debugger-print-function'. 391 | 392 | ** NUL bytes in text copied to the system clipboard are now replaced with "\0". 393 | 394 | ** The new variable 'x-ctrl-keysym' has been added to the existing 395 | roster of X keysyms. It can be used in combination with another 396 | variable of this kind to swap modifiers in Emacs. 397 | 398 | ** New input methods: 'cyrillic-tuvan', 'polish-prefix', 'uzbek-cyrillic'. 399 | 400 | ** The 'dutch' input method no longer attempts to support Turkish too. 401 | Also, it no longer converts 'IJ' and 'ij' to the compatibility 402 | characters U+0132 LATIN CAPITAL LIGATURE IJ and U+0133 LATIN SMALL 403 | LIGATURE IJ. 404 | 405 | ** File name quoting by adding the prefix "/:" is now possible for the 406 | local part of a remote file name. Thus, if you have a directory named 407 | "/~" on the remote host "foo", you can prevent it from being 408 | substituted by a home directory by writing it as "/foo:/:/~/file". 409 | 410 | ** The new variable 'maximum-scroll-margin' allows having effective 411 | settings of 'scroll-margin' up to half the window size, instead of 412 | always restricting the margin to a quarter of the window. 413 | 414 | ** Emacs can scroll horizontally using mouse, touchpad, and trackbar. 415 | You can enable this by customizing 'mouse-wheel-tilt-scroll'. If you 416 | want to reverse the direction of the scroll, customize 417 | 'mouse-wheel-flip-direction'. 418 | 419 | ** The default GnuTLS priority string now includes %DUMBFW. 420 | This is to avoid bad behavior in some firewalls, which causes the 421 | connection to be closed by the remote host. 422 | 423 | ** Emacsclient changes 424 | 425 | *** Emacsclient has a new option '-u' / '--suppress-output'. 426 | This option suppresses display of return values from the server 427 | process. 428 | 429 | *** Emacsclient has a new option '-T' / '--tramp'. 430 | This helps with using a local Emacs session as the server for a remote 431 | emacsclient. With appropriate setup, one can now set the EDITOR 432 | environment variable on a remote machine to emacsclient, and 433 | use the local Emacs to edit remote files via Tramp. See the node 434 | "(emacs) emacsclient Options" in the user manual for the details. 435 | 436 | *** Emacsclient now accepts command-line options in ALTERNATE_EDITOR 437 | and '--alternate-editor'. For example, ALTERNATE_EDITOR="emacs -Q -nw". 438 | Arguments may be quoted "like this", so that for example an absolute 439 | path containing a space may be specified; quote escaping is not 440 | supported. 441 | 442 | ** New user option 'dig-program-options' and extended functionality 443 | for DNS-querying functions 'nslookup-host', 'dns-lookup-host', 444 | and 'run-dig'. Each function now accepts an optional name server 445 | argument interactively (with a prefix argument) and non-interactively. 446 | 447 | ** 'describe-key-briefly' now ignores mouse movement events. 448 | 449 | ** The new variable 'eval-expression-print-maximum-character' prevents 450 | large integers from being displayed as characters by 'M-:' and similar 451 | commands. 452 | 453 | ** Two new commands for finding the source code of Emacs Lisp 454 | libraries: 'find-library-other-window' and 'find-library-other-frame'. 455 | 456 | ** The new variable 'display-raw-bytes-as-hex' allows you to change 457 | the display of raw bytes from octal to hex. 458 | 459 | ** You can now provide explicit field numbers in format specifiers. 460 | For example, '(format "%2$s %1$s %2$s" "X" "Y")' produces "Y X Y". 461 | 462 | ** Emacs支持在Buffer里显示行号(可选项) 463 | 这个显示行号的原生支持与之前的 *linum-mode* 提供的功能一样,但它更快。并且,不会因为行号的 464 | 显示而占用边距。通过配置Buffer本地变量display-line-numbers去开启这个行号显示项。或者还 465 | 可以通过打开 *display-line-numbers-mode* 这个minor模式也能达到相同效果。还有一种方式, 466 | 那就是打开全局的 *global-display-line-numbers-mode* 模式。当这些模式打开后,配置 467 | *display-line-numbers-type* 的值会与 *display-line-numbers* 的值相同。行号不会显示 468 | 在所有的minibuffer的窗口以及提示窗口,因为他们不是用于此处。 469 | 470 | Lisp程序可以通过设置 *display-line-numbers-disable* 的文本属性或者屏幕当前行第一个字符 471 | 的属性来关闭此功能。做成可配置的包目的是为了更好地做显示控制。Lisp程序想知道多少屏幕宽度被行 472 | 号所占用,可以通过 *line-number-display-width* 这个函数来获取。 *linum-mode* 和其他 473 | 类似的包可以废弃,不再使用。Emacs官方推荐使用新的原生方法来显示行号。 474 | 475 | ** 添加'arabic-shaper-ZWNJ-handling'用户选项用来处理Arabic文本渲染中的ZWNJ问题 476 | 477 | * Emacs 26.1中编辑操作的变化 478 | 479 | ** 新加变量 'column-number-indicator-zero-based'. 480 | Traditionally, in Column Number mode, the displayed column number 481 | counts from zero starting at the left margin of the window. This 482 | behavior is now controlled by 'column-number-indicator-zero-based'. 483 | If you would prefer for the displayed column number to count from one, 484 | you may set this variable to nil. (Behind the scenes, there is now a 485 | new mode line construct, '%C', which operates exactly as '%c' does 486 | except that it counts from one.) 487 | 488 | ** New single-line horizontal scrolling mode. 489 | The 'auto-hscroll-mode' variable can now have a new special value, 490 | 'current-line', which causes only the line where the cursor is 491 | displayed to be horizontally scrolled when lines are truncated on 492 | display and point moves outside the left or right window margin. 493 | 494 | ** New mode line constructs '%o' and '%q', and user option 495 | 'mode-line-percent-position'. '%o' displays the "degree of travel" of 496 | the window through the buffer. Unlike the default '%p', this 497 | percentage approaches 100% as the window approaches the end of the 498 | buffer. '%q' displays the percentage offsets of both the start and 499 | the end of the window, e.g. "5-17%". The new option 500 | 'mode-line-percent-position' makes it easier to switch between '%p', 501 | '%P', and these new constructs. 502 | 503 | ** Two new user options 'list-matching-lines-jump-to-current-line' and 504 | 'list-matching-lines-current-line-face' to show the current line 505 | highlighted in *Occur* buffer. 506 | 507 | ** The 'occur' command can now operate on the region. 508 | 509 | ** New bindings for 'query-replace-map'. 510 | 'undo', undo the last replacement; bound to 'u'. 511 | 'undo-all', undo all replacements; bound to 'U'. 512 | 513 | ** 'delete-trailing-whitespace' deletes whitespace after form feed. 514 | In modes where form feed was treated as a whitespace character, 515 | 'delete-trailing-whitespace' would keep lines containing it unchanged. 516 | It now deletes whitespace after the last form feed thus behaving the 517 | same as in modes where the character is not whitespace. 518 | 519 | ** Emacs no longer prompts about editing a changed file when the file's 520 | content is unchanged. Instead of only checking the modification time, 521 | Emacs now also checks the file's actual content before prompting the user. 522 | 523 | ** Various casing improvements. 524 | 525 | *** 'upcase', 'upcase-region' et al. convert title case characters 526 | (such as Dz) into their upper case form (such as DZ). 527 | 528 | *** 'capitalize', 'upcase-initials' et al. make use of title-case forms 529 | of initial characters (correctly producing for example Džungla instead 530 | of incorrect DŽungla). 531 | 532 | *** Characters which turn into multiple ones when cased are correctly handled. 533 | For example, fi ligature is converted to FI when upper cased. 534 | 535 | *** Greek small sigma is correctly handled when at the end of the word. 536 | Strings such as ΌΣΟΣ are now correctly converted to Όσος when 537 | capitalized instead of incorrect Όσοσ (compare lowercase sigma at the 538 | end of the word). 539 | 540 | ** Emacs can now auto-save buffers to visited files in a more robust 541 | manner via the new mode 'auto-save-visited-mode'. Unlike 542 | 'auto-save-visited-file-name', this mode uses the normal saving 543 | procedure and therefore obeys saving hooks. 544 | 'auto-save-visited-file-name' is now obsolete. 545 | 546 | ** New behavior of 'mark-defun'. 547 | Prefix argument selects that many (or that many more) defuns. 548 | Negative prefix arg flips the direction of selection. Also, 549 | 'mark-defun' between defuns correctly selects N following defuns (or 550 | -N previous for negative arguments). Finally, comments preceding the 551 | defun are selected unless they are separated from the defun by a blank 552 | line. 553 | 554 | ** New command 'replace-buffer-contents'. 555 | This command replaces the contents of the accessible portion of the 556 | current buffer with the contents of the accessible portion of a 557 | different buffer while keeping point, mark, markers, and text 558 | properties as intact as possible. 559 | 560 | ** New commands 'apropos-local-variable' and 'apropos-local-value'. 561 | These are buffer-local versions of 'apropos-variable' and 562 | 'apropos-value', respectively. They show buffer-local variables whose 563 | names and values, respectively, match a given pattern. 564 | 565 | ** More user control of reordering bidirectional text for display. 566 | The two new variables, 'bidi-paragraph-start-re' and 567 | 'bidi-paragraph-separate-re', allow customization of what exactly are 568 | paragraphs, for the purposes of bidirectional display. 569 | 570 | ** New variable 'x-wait-for-event-timeout'. 571 | This controls how long Emacs will wait for updates to the graphical 572 | state to take effect (making a frame visible, for example). 573 | 574 | 575 | * Emacs 26.1中特殊模式和包的变化 576 | 577 | ** Emacs 26.1采用Org 9.1.6版本. 578 | 具体变化可查看ORG-NEWS文件 579 | 580 | ** 新函数cl-generic-p 581 | 582 | ** Dired的变化 583 | 584 | *** You can answer 'all' in 'dired-do-delete' to delete recursively all 585 | remaining directories without more prompts. 586 | 587 | *** Dired supports wildcards in the directory part of the file names. 588 | 589 | *** You can now use '`?`' in 'dired-do-shell-command'. 590 | It gets replaced by the current file name, like ' ? '. 591 | 592 | *** A new option 'dired-always-read-filesystem' defaulting to nil. 593 | If non-nil, buffers visiting files are reverted before they are 594 | searched; for instance, in 'dired-mark-files-containing-regexp' a 595 | non-nil value of this option means the file is revisited in a 596 | temporary buffer; this temporary buffer is the actual buffer searched: 597 | the original buffer visiting the file is not modified. 598 | 599 | *** Users can now customize mouse clicks in Dired in a more flexible way. 600 | The new command 'dired-mouse-find-file' can be bound to a mouse click 601 | and used to visit files/directories in Dired in the selected window. 602 | The new command 'dired-mouse-find-file-other-frame' similarly visits 603 | files/directories in another frame. You can write your own commands 604 | that invoke 'dired-mouse-find-file' with non-default optional 605 | arguments, to tailor the effects of mouse clicks on file names in 606 | Dired buffers. 607 | 608 | *** In wdired, when editing files to contain slash characters, 609 | the resulting directories are automatically created. Whether to do 610 | this is controlled by the 'wdired-create-parent-directories' variable. 611 | 612 | *** 'W' is now bound to 'browse-url-of-dired-file', and is useful for 613 | viewing HTML files and the like. 614 | 615 | *** New variable 'dired-clean-confirm-killing-deleted-buffers' 616 | controls whether Dired asks to kill buffers visiting deleted files and 617 | directories. The default is t, so Dired asks for confirmation, to 618 | keep previous behavior. 619 | 620 | ** html2text is now marked obsolete. 621 | 622 | ** smerge-refine-regions can refine regions in separate buffers. 623 | 624 | ** Info menu and index completion uses substring completion by default. 625 | This can be customized via the 'info-menu' category in 626 | 'completion-category-overrides'. 627 | 628 | ** The ancestor buffer is shown by default in 3-way merges. 629 | A new option 'ediff-show-ancestor' and a new toggle 630 | 'ediff-toggle-show-ancestor'. 631 | 632 | ** TeX: Add luatex and xetex as alternatives to pdftex 633 | 634 | ** Electric-Buffer-menu 635 | 636 | *** Key 'U' is bound to 'Buffer-menu-unmark-all' and key 'M-DEL' is 637 | bound to 'Buffer-menu-unmark-all-buffers'. 638 | 639 | ** hideshow mode got four key bindings that are analogous to outline 640 | mode bindings: 'C-c @ C-a', 'C-c @ C-t', 'C-c @ C-d', and 'C-c @ C-e'. 641 | 642 | ** bs 643 | 644 | *** Two new commands 'bs-unmark-all', bound to 'U', and 645 | 'bs-unmark-previous', bound to . 646 | 647 | ** Buffer-menu 648 | 649 | *** Two new commands 'Buffer-menu-unmark-all', bound to 'U' and 650 | 'Buffer-menu-unmark-all-buffers', bound to 'M-DEL'. 651 | 652 | ** Checkdoc 653 | 654 | *** 'checkdoc-arguments-in-order-flag' now defaults to nil. 655 | 656 | ** Gnus 657 | 658 | *** The ~/.newsrc file will now only be saved if the native select 659 | method is an NNTP select method. 660 | 661 | *** A new command for sorting articles by readedness marks has been 662 | added: 'C-c C-s C-m C-m'. 663 | 664 | *** In 'message-citation-line-format' the '%Z' format is now the time 665 | zone name instead of the numeric form. The '%z' format continues to 666 | be the numeric form. The new behavior is compatible with 667 | 'format-time-string'. 668 | 669 | ** Ibuffer 670 | 671 | *** New command 'ibuffer-jump'. 672 | 673 | *** New filter commands 'ibuffer-filter-by-basename', 674 | 'ibuffer-filter-by-file-extension', 'ibuffer-filter-by-directory', 675 | 'ibuffer-filter-by-starred-name', 'ibuffer-filter-by-modified' 676 | and 'ibuffer-filter-by-visiting-file'; bound respectively 677 | to '/b', '/.', '//', '/*', '/i' and '/v'. 678 | 679 | *** Two new commands 'ibuffer-filter-chosen-by-completion' 680 | and 'ibuffer-and-filter', the second bound to '/&'. 681 | 682 | *** The commands 'ibuffer-pop-filter', 'ibuffer-pop-filter-group', 683 | 'ibuffer-or-filter' and 'ibuffer-filter-disable' have the alternative 684 | bindings '/', '/S-', '/|' and '/DEL', respectively. 685 | 686 | *** The data format specifying filters has been extended to allow 687 | explicit logical 'and', and a more flexible form for logical 'not'. 688 | See 'ibuffer-filtering-qualifiers' doc string for full details. 689 | 690 | *** A new command 'ibuffer-copy-buffername-as-kill'; bound 691 | to 'B'. 692 | 693 | *** New command 'ibuffer-change-marks'; bound to '* c'. 694 | 695 | *** A new command 'ibuffer-mark-by-locked' to mark 696 | all locked buffers; bound to '% L'. 697 | 698 | *** A new option 'ibuffer-locked-char' to indicate 699 | locked buffers; Ibuffer shows a new column displaying 700 | 'ibuffer-locked-char' for locked buffers. 701 | 702 | *** A new command 'ibuffer-unmark-all-marks' to unmark 703 | all buffers without asking confirmation; bound to 704 | 'U'; 'ibuffer-do-replace-regexp' bound to 'r'. 705 | 706 | *** A new command 'ibuffer-mark-by-content-regexp' to mark buffers 707 | whose content matches a regexp; bound to '% g'. 708 | 709 | *** Two new options 'ibuffer-never-search-content-name' and 710 | 'ibuffer-never-search-content-mode' used by 711 | 'ibuffer-mark-by-content-regexp'. 712 | 713 | ** Browse-URL 714 | 715 | *** Support for opening links to man pages in Man or WoMan mode. 716 | 717 | ** Comint 718 | 719 | *** New user option 'comint-move-point-for-matching-input' to control 720 | where to place point after 'C-c M-r' and 'C-c M-s'. 721 | 722 | *** New user option 'comint-terminfo-terminal'. 723 | This option allows control of the value of the TERM environment 724 | variable Emacs puts into the environment of the Comint mode and its 725 | derivatives, such as Shell mode and Compilation Shell minor-mode. The 726 | default is "dumb", for compatibility with previous behavior. 727 | 728 | ** Compilation mode 729 | 730 | *** Messages from CMake are now recognized. 731 | 732 | *** The number of errors, warnings, and informational messages is now 733 | displayed in the mode line. These are updated as compilation 734 | proceeds. 735 | 736 | ** Grep 737 | 738 | *** Grep commands will now use GNU grep's '--null' option if 739 | available, which allows distinguishing the filename from contents if 740 | they contain colons. This can be controlled by the new custom option 741 | 'grep-use-null-filename-separator'. 742 | 743 | *** The grep/rgrep/lgrep functions will now ask about saving files 744 | before running. This is controlled by the 'grep-save-buffers' 745 | variable. 746 | 747 | ** Edebug 748 | 749 | *** Edebug can be prevented from pausing 1 second after reaching a 750 | breakpoint (e.g. with "f" and "o") by customizing the new option 751 | 'edebug-sit-on-break'. 752 | 753 | *** New customizable option 'edebug-max-depth'. 754 | This allows you to enlarge the maximum recursion depth when 755 | instrumenting code. 756 | 757 | *** 'edebug-prin1-to-string' now aliases 'cl-prin1-to-string'. 758 | This means edebug output is affected by variables 'cl-print-readably' 759 | and 'cl-print-compiled'. To completely restore the previous printing 760 | behavior, use 761 | 762 | (fset 'edebug-prin1-to-string #'prin1-to-string) 763 | 764 | ** Eshell 765 | 766 | *** 'eshell-input-filter's value is now a named function 767 | 'eshell-input-filter-default', and has a new custom option 768 | 'eshell-input-filter-initial-space' to ignore adding commands prefixed 769 | with blank space to eshell history. 770 | 771 | ** EUDC 772 | 773 | *** Backward compatibility support for BBDB versions less than 3 774 | (i.e., BBDB 2.x) is deprecated and will likely be removed in the next 775 | major release of Emacs. Users of BBDB 2.x should plan to upgrade to 776 | BBDB 3.x. 777 | 778 | ** eww 779 | 780 | *** New 'M-RET' command for opening a link at point in a new eww buffer. 781 | 782 | *** A new 's' command for switching to another eww buffer via the minibuffer. 783 | 784 | *** The 'o' command ('shr-save-contents') has moved to 'O' to avoid collision 785 | with the 'o' command from 'image-map'. 786 | 787 | *** A new command 'C' ('eww-toggle-colors') can be used to toggle 788 | whether to use the HTML-specified colors or not. The user can also 789 | customize the 'shr-use-colors' variable. 790 | 791 | *** Images that are being loaded are now marked with gray 792 | "placeholder" images of the size specified by the HTML. They are then 793 | replaced by the real images asynchronously, which will also now 794 | respect width/height HTML specs (unless they specify widths/heights 795 | bigger than the current window). 796 | 797 | *** The 'w' command on links is now 'shr-maybe-probe-and-copy-url'. 798 | 'shr-copy-url' now only copies the url at point; users who wish to 799 | avoid accidentally accessing remote links may rebind 'w' and 'u' in 800 | 'eww-link-keymap' to it. 801 | 802 | ** Ido 803 | 804 | *** The commands 'find-alternate-file-other-window', 805 | 'dired-other-window', 'dired-other-frame', and 806 | 'display-buffer-other-window' are now remapped to Ido equivalents if 807 | Ido mode is active. 808 | 809 | ** Images 810 | 811 | *** Images are automatically scaled before displaying based on the 812 | 'image-scaling-factor' variable (if Emacs supports scaling the images 813 | in question). 814 | 815 | *** It's now possible to specify aspect-ratio preserving combinations 816 | of :width/:max-height and :height/:max-width keywords. In either 817 | case, the "max" keywords win. (Previously some combinations would, 818 | depending on the aspect ratio of the image, just be ignored and in 819 | other instances this would lead to the aspect ratio not being 820 | preserved.) 821 | 822 | *** Images inserted with 'insert-image' and related functions get a 823 | keymap put into the text properties (or overlays) that span the 824 | image. This keymap binds keystrokes for manipulating size and 825 | rotation, as well as saving the image to a file. These commands are 826 | also available in 'image-mode'. 827 | 828 | *** A new library for creating and manipulating SVG images has been 829 | added. See the "(elisp) SVG Images" section in the ELisp reference 830 | manual for details. 831 | 832 | *** New setf-able function to access and set image parameters is 833 | provided: 'image-property'. 834 | 835 | *** New commands 'image-scroll-left' and 'image-scroll-right' 836 | for 'image-mode' that complement 'image-scroll-up' and 837 | 'image-scroll-down': they have the same prefix arg behavior and stop 838 | at image boundaries. 839 | 840 | ** Image-Dired 841 | 842 | *** Now provides a minor mode 'image-dired-minor-mode' which replaces 843 | the function 'image-dired-setup-dired-keybindings'. 844 | 845 | *** Thumbnail generation is now asynchronous. 846 | The number of concurrent processes is limited by the variable 847 | 'image-dired-queue-active-limit'. 848 | 849 | *** 'image-dired-thumbnail-storage' has a new option 'standard-large' 850 | for generating 256x256 thumbnails according to the Thumbnail Managing 851 | Standard. 852 | 853 | *** Inherits movement keys from 'image-mode' for viewing full images. 854 | This includes the usual char, line, and page movement commands. 855 | 856 | *** All the -options types have been changed to argument lists 857 | instead of shell command strings. This change affects 858 | 'image-dired-cmd-create-thumbnail-options', 859 | 'image-dired-cmd-create-temp-image-options', 860 | 'image-dired-cmd-rotate-thumbnail-options', 861 | 'image-dired-cmd-rotate-original-options', 862 | 'image-dired-cmd-write-exif-data-options', 863 | 'image-dired-cmd-read-exif-data-options', and introduces 864 | 'image-dired-cmd-pngnq-options', 'image-dired-cmd-pngcrush-options', 865 | 'image-dired-cmd-create-standard-thumbnail-options'. 866 | 867 | *** Recognizes more tools by default, including pngnq-s9 and OptiPNG. 868 | 869 | *** 'find-file' and related commands now work on thumbnails and 870 | displayed images, providing a default argument of the original file name 871 | via an addition to 'file-name-at-point-functions'. 872 | 873 | ** The default 'Info-default-directory-list' no longer checks some obsolete 874 | directory suffixes (gnu, gnu/lib, gnu/lib/emacs, emacs, lib, lib/emacs) 875 | when searching for info directories. 876 | 877 | ** The commands that add ChangeLog entries now prefer a VCS root directory 878 | for the ChangeLog file, if none already exists. Customize 879 | 'change-log-directory-files' to nil for the old behavior. 880 | 881 | ** Support for non-string values of 'time-stamp-format' has been removed. 882 | 883 | ** Message 884 | 885 | *** 'message-use-idna' now defaults to t (because Emacs comes with 886 | built-in IDNA support now). 887 | 888 | *** When sending HTML messages with embedded images, and you have 889 | exiftool installed, and you rotate images with EXIF data (i.e., 890 | JPEGs), the rotational information will be inserted into the outgoing 891 | image in the message. (The original image will not have its 892 | orientation affected.) 893 | 894 | *** The 'message-valid-fqdn-regexp' variable has been removed, since 895 | there are now top-level domains added all the time. Message will no 896 | longer warn about sending emails to top-level domains it hasn't heard 897 | about. 898 | 899 | *** 'message-beginning-of-line' (bound to 'C-a') understands folded headers. 900 | In 'visual-line-mode' it will look for the true beginning of a header 901 | while in non-'visual-line-mode' it will move the point to the indented 902 | header's value. 903 | 904 | ** Package 905 | 906 | *** The new variable 'package-gnupghome-dir' has been added to control 907 | where the GnuPG home directory (used for signature verification) is 908 | located and whether GnuPG's option '--homedir' is used or not. 909 | 910 | *** Deleting a package no longer respects 'delete-by-moving-to-trash'. 911 | 912 | ** Python 913 | 914 | *** The new variable 'python-indent-def-block-scale' has been added. 915 | It controls the depth of indentation of arguments inside multi-line 916 | function signatures. 917 | 918 | ** Tramp 919 | 920 | *** The method part of remote file names is mandatory now. 921 | A valid remote file name starts with "/method:host:" or 922 | "/method:user@host:". 923 | 924 | *** The new pseudo method "-" is a marker for the default method. 925 | "/-::" is the shortest remote file name then. 926 | 927 | *** The command 'tramp-change-syntax' allows you to choose an 928 | alternative remote file name syntax. 929 | 930 | *** New connection method "sg", which supports editing files under a 931 | different group ID. 932 | 933 | *** New connection method "doas" for OpenBSD hosts. 934 | 935 | *** New connection method "gdrive", which allows access to Google 936 | Drive onsite repositories. 937 | 938 | *** Gateway methods in Tramp have been removed. 939 | Instead, the Tramp manual documents how to configure ssh and PuTTY 940 | accordingly. 941 | 942 | *** Setting the "ENV" environment variable in 943 | 'tramp-remote-process-environment' enables reading of shell 944 | initialization files. 945 | 946 | *** Tramp is able now to send SIGINT to remote asynchronous processes. 947 | 948 | *** Variable 'tramp-completion-mode' is obsoleted. 949 | 950 | ** 'auto-revert-use-notify' is set back to t in 'global-auto-revert-mode'. 951 | 952 | ** JS mode 953 | 954 | *** JS mode now sets 'comment-multi-line' to t. 955 | 956 | *** New variable 'js-indent-align-list-continuation', when set to nil, 957 | will not align continuations of bracketed lists, but will indent them 958 | by the fixed width 'js-indent-level'. 959 | 960 | ** CSS mode 961 | 962 | *** Support for completing attribute values, at-rules, bang-rules, 963 | HTML tags, classes and IDs using the 'completion-at-point' command. 964 | Completion candidates for HTML classes and IDs are retrieved from open 965 | HTML mode buffers. 966 | 967 | *** CSS mode now binds 'C-h S' to a function that will show 968 | information about a CSS construct (an at-rule, property, pseudo-class, 969 | pseudo-element, with the default being guessed from context). By 970 | default the information is looked up on the Mozilla Developer Network, 971 | but this can be customized using 'css-lookup-url-format'. 972 | 973 | *** CSS colors are fontified using the color they represent as the 974 | background. For instance, #ff0000 would be fontified with a red 975 | background. 976 | 977 | ** Emacs now supports character name escape sequences in character and 978 | string literals. The syntax variants '\N{character name}' and 979 | '\N{U+code}' are supported. 980 | 981 | ** Prog mode has some support for multi-mode indentation. 982 | This allows better indentation support in modes that support multiple 983 | programming languages in the same buffer, like literate programming 984 | environments or ANTLR programs with embedded Python code. 985 | 986 | A major mode can provide indentation context for a sub-mode. To 987 | support this, modes should use 'prog-first-column' instead of a 988 | literal zero and avoid calling 'widen' in their indentation functions. 989 | See the node "(elisp) Mode-Specific Indent" in the ELisp manual for 990 | more details. 991 | 992 | ** ERC 993 | 994 | *** New variable 'erc-default-port-tls' used to connect to TLS IRC 995 | servers. 996 | 997 | ** URL 998 | 999 | *** The new function 'url-cookie-delete-cookie' can be used to 1000 | programmatically delete all cookies, or cookies from a specific 1001 | domain. 1002 | 1003 | *** 'url-retrieve-synchronously' now takes an optional timeout parameter. 1004 | 1005 | *** The URL package now supports HTTPS over proxies supporting CONNECT. 1006 | 1007 | *** 'url-user-agent' now defaults to 'default', and the User-Agent 1008 | string is computed dynamically based on 'url-privacy-level'. 1009 | 1010 | ** VC and related modes 1011 | 1012 | *** 'vc-dir-mode' now binds 'vc-log-outgoing' to 'O'; and has various 1013 | branch-related commands on a keymap bound to 'B'. 1014 | 1015 | *** 'vc-region-history' is now bound to 'C-x v h', replacing the older 1016 | 'vc-insert-headers' binding. 1017 | 1018 | *** New user option 'vc-git-print-log-follow' to follow renames in Git logs 1019 | for a single file. 1020 | 1021 | ** CC mode 1022 | 1023 | *** Opening a .h file will turn C or C++ mode depending on language used. 1024 | This is done with the help of the 'c-or-c++-mode' function, which 1025 | analyzes buffer contents to infer whether it's a C or C++ source file. 1026 | 1027 | ** New option 'cpp-message-min-time-interval' to allow user control 1028 | of progress messages in cpp.el. 1029 | 1030 | ** New DNS mode command 'dns-mode-ipv6-to-nibbles' to convert IPv6 addresses 1031 | to a format suitable for reverse lookup zone files. 1032 | 1033 | ** Ispell 1034 | 1035 | *** Enchant is now supported as a spell-checker. 1036 | 1037 | Enchant is a meta-spell-checker that uses providers such as Hunspell 1038 | to do the actual checking. With it, users can use spell-checkers not 1039 | directly supported by Emacs, such as Voikko, Hspell and AppleSpell, 1040 | more easily share personal word-lists with other programs, and 1041 | configure different spelling-checkers for different languages. 1042 | (Version 2.1.0 or later of Enchant is required.) 1043 | 1044 | ** Flymake 1045 | 1046 | *** Flymake has been completely redesigned 1047 | 1048 | Flymake now annotates arbitrary buffer regions, not just lines. It 1049 | supports arbitrary diagnostic types, not just errors and warnings (see 1050 | variable 'flymake-diagnostic-types-alist'). 1051 | 1052 | It also supports multiple simultaneous backends, meaning that you can 1053 | check your buffer from different perspectives (see variable 1054 | 'flymake-diagnostic-functions'). Backends for Emacs Lisp mode are 1055 | provided. 1056 | 1057 | The old Flymake behavior is preserved in the so-called "legacy 1058 | backend", which has been updated to benefit from the new UI features. 1059 | 1060 | ** Term 1061 | 1062 | *** *term-char-mode* 模式下的buffer默认为只读模式 1063 | 1064 | 这个buffer默认设置为只读模式主要防止其他除了程序过滤器之外的任何对其进行修改的行为;并且光 1065 | 标的移动也在有所限制,主要用为了保持每次命令执行后光标都处理“当前”位置。这也是为了在交互式 1066 | 命令中使得emacs更加方便获取其状态。 1067 | 1068 | 可以通过 *term-char-mode-buffer-read-only* 来控制buffer是否为只读,Emacs 26以后这 1069 | 个值默认设置不为nil,如果想关闭只读,设置其值为nil就行。同理可以通过另一个变量,即: 1070 | *term-char-mode-point-at-process-mark* 来控制光标是否可上下移动, 其默认值不是nil。 1071 | 如果想让光标能上下移动,设置这个值为nil。 1072 | 1073 | ** Xref 1074 | 1075 | *** When an *xref* buffer is needed, 'TAB' quits and jumps to an xref. 1076 | 1077 | A new command 'xref-quit-and-goto-xref', bound to 'TAB' in *xref* 1078 | buffers, quits the window before jumping to the destination. In many 1079 | situations, the intended window configuration is restored, just as if 1080 | the *xref* buffer hadn't been necessary in the first place. 1081 | 1082 | 1083 | * Emacs 26.1新的模式和包 1084 | 1085 | ** 新的Elisp数据结构库radix-tree 1086 | 1087 | ** New library 'xdg' with utilities for some XDG standards and specs. 1088 | 1089 | ** HTML 1090 | 1091 | *** A new submode of 'html-mode', 'mhtml-mode', is now the default 1092 | mode for *.html files. This mode handles indentation, 1093 | fontification, and commenting for embedded JavaScript and CSS. 1094 | 1095 | ** New mode 'conf-toml-mode' is a sub-mode of 'conf-mode', specialized 1096 | for editing TOML files. 1097 | 1098 | ** New mode 'conf-desktop-mode' is a sub-mode of 'conf-unix-mode', 1099 | specialized for editing freedesktop.org desktop entries. 1100 | 1101 | ** New minor mode 'pixel-scroll-mode' provides smooth pixel-level scrolling. 1102 | 1103 | ** New major mode 'less-css-mode' (a minor variant of 'css-mode') for 1104 | editing Less files. 1105 | 1106 | ** New package 'auth-source-pass' integrates 'auth-source' with the 1107 | password manager password-store (http://passwordstore.org). 1108 | 1109 | 1110 | * Emacs 26.1中不兼容的Lisp部分说明 1111 | 1112 | ** 'password-data' is now a hash-table so that 'password-read' can use 1113 | any object for the 'key' argument. 1114 | 1115 | ** Command 'dired-mark-extension' now automatically prepends a '.' to the 1116 | extension when not present. The new command 'dired-mark-suffix' behaves 1117 | similarly but it doesn't prepend a '.'. 1118 | 1119 | ** Certain cond/pcase/cl-case forms are now compiled using a faster jump 1120 | table implementation. This uses a new bytecode op 'switch', which 1121 | isn't compatible with previous Emacs versions. This functionality can 1122 | be disabled by setting 'byte-compile-cond-use-jump-table' to nil. 1123 | 1124 | ** If 'comment-auto-fill-only-comments' is non-nil, 'auto-fill-function' 1125 | is now called only if either no comment syntax is defined for the 1126 | current buffer or the self-insertion takes place within a comment. 1127 | 1128 | ** ucs-names为哈希表(hash table) 1129 | 1130 | ** if-let和when-let现在支持绑定列表(如Scheme Request for Implementation 2中的实现一样). 1131 | 1132 | ** term-mod的一些变量 1133 | C-up, C-down, C-left和C-right快捷键保持跟在xterm下一样。这样在readline模式下,表现得像forward-word一样 1134 | 1135 | ** Customizable variable 'query-replace-from-to-separator' 1136 | now doesn't propertize the string value of the separator. 1137 | Instead, text properties are added by 'query-replace-read-from'. 1138 | Additionally, the new nil value restores pre-24.5 behavior 1139 | of not providing replacement pairs via the history. 1140 | 1141 | ** 下面一些老的函数、变量、和样式(face)被移除 1142 | 1143 | *** make-variable-frame-local 不再是frame-local. 1144 | 1145 | *** 在subr.el库里下列被移除: 1146 | window-dot, set-window-dot, read-input, show-buffer, eval-current-buffer, string-to-int. 1147 | 1148 | *** icomplete-prospects-length 1149 | 1150 | *** 所有默认值为FOO的default-FOO变量,使用default-value和setq-default分别去获取和修改FOO 1151 | 所有被移除的变量如下: default-mode-line-format, default-header-line-format, 1152 | default-line-spacing, default-abbrev-mode, default-ctl-arrow, 1153 | default-truncate-lines, default-left-margin, default-tab-width, 1154 | default-case-fold-search, default-left-margin-width, 1155 | default-right-margin-width, default-left-fringe-width, 1156 | default-right-fringe-width, default-fringes-outside-margins, 1157 | default-scroll-bar-width, default-vertical-scroll-bar, 1158 | default-indicate-empty-lines, default-indicate-buffer-boundaries, 1159 | default-fringe-indicator-alist, default-fringe-cursor-alist, 1160 | default-scroll-up-aggressively, default-scroll-down-aggressively, 1161 | default-fill-column, default-cursor-type, 1162 | default-cursor-in-non-selected-windows, 1163 | default-buffer-file-coding-system, default-major-mode, and 1164 | default-enable-multibyte-characters. 1165 | 1166 | *** 许多在22.1版本被废弃的样式 1167 | 1168 | ** 变量text-quoting-style改为可定制选项 1169 | 它控制是否以及怎样在消息和帮助界面显示ASCII的引用符。从Emacs 25开始它的值和语义没有变化。 1170 | 在特定的情况下,当这个变量的值为grave时,所有的引用显示按原样输出。 1171 | 1172 | ** 函数check-declare-file和check-declare-directory的变化 1173 | 它们将输出更加紧凑的诊断输出,辅助函数check-declare-errmsg已经被移除。 1174 | 1175 | ** 正则表达集合 *[:blank:]* 的变化 1176 | 当前可匹配统一编码的空格(如在UTS技术标准18里定义的那样),如果你仅仅想匹配空格和tab符,请使用 *[ \t]* 。 1177 | 1178 | ** min和max函数不在对结果进行截断(round) 1179 | 老版本的Emacs,当参数中含有浮点类型时,这些函数返回一个浮点的值(有时这些数值是不正确的), 1180 | 例如,在64位的机器里(max 1e16 10000000000000001)返回的是第二个参数,而不是第一个。 1181 | 1182 | ** 变量old-style-backquotes的变化 1183 | 这个变量已经声明为内部使用,同时重命名为lread--old-style-backquotes。任何用户代码不应用使用这个变量 1184 | 1185 | ** default-file-name-coding-system默认指定的编码系统不处理CRLF 1186 | 例如,默认由原来的utf-8改为utf-8-unix。在这个变化之前, Emacs有时会对文件名中含有这些控制 1187 | 字符做错误处理 1188 | 1189 | ** file-attributes, file-symlink-p和make-symbolic-link的变化 1190 | 这三个函数不再改变本地符号链接的目标文件,使得Emacs可以在不考虑链接文件的内容对其进行获取和 1191 | 复制。具体包括以下方面的变化。 1192 | 1193 | *** file-attributes和file-symlink-p不再对那些以“/”开头并含有“:”的符号链接预添加"/:"。例如 1194 | 如果一个符号链接"x"其目标文件为"/y:z:",调用 *(file-symlink-p "x")* 现在返回"/y:z:"而不是之前的"/:/y:z:" 1195 | 1196 | *** 在创建一个符号链接时make-symbolic-link不再查找目标文件名是否可处理,例如 1197 | *(make-symbolic-link "/y:z:" "x")* 现在直接创建一个指向"/y:z:"的符号链接,而不是导致失败。 1198 | 1199 | *** 当目标文件和新文件名远端相同时make-symbolic-link将移除符号链接的远端部分,例如 1200 | *(make-symbolic-link "/x:y:a" "/x:y:b")* 创建一个“a”的符号链接, *(make-symbolic-link "/x:y:a" "/x:z:b")* 1201 | 创建一个“/x:y:a”的符号链接。 1202 | 1203 | *** 当make-symbolic-link第三个可选参数为整数(作为交互式调用)时,扩展的符号链接目标以"~"开头 1204 | 例如(make-symbolic-link "~y" "x")创建一个目标为"~y"的符号链接,为了达到老版本的效果 1205 | 使用(make-symbolic-link (expand-file-name "~y") "x")。为了防止在交互式环境下的这种 1206 | 扩展,可对目标文件加上"/:"这样的前缀。例如(make-symbolic-link "/:~y" "x" 1) 1207 | 创建一个符号链接指向"~y". 1208 | 1209 | ** file-truename在一个符号链接指定为远程文件语法时返回一个引用的文件名 1210 | 1211 | ** 模块函数的实现有轻微的变化 1212 | 作为特殊考虑,函数internal--module-call已经被删除,对此有依赖的系统可能会导致异常 1213 | 1214 | ** write-region的LOCKNAME参数会被传递给文件名处理器 1215 | 1216 | ** 构建最新的GTK+的变化 1217 | 当构建最新版本的GTK+时, Emacs使用gtk_window_move来移除frames,同时忽略变量x-gtk-use-window-move 1218 | 的值,这个变量已经被废弃。 1219 | 1220 | ** 一些文件创建或者重命名的变化 1221 | 这些函数在处理目标参数为目录类型时有一些变化,如,当在GNU或者类POSIX体系里其参数以“/”结尾。 1222 | 当这些函数的目地参数D为已经存在的目录时,其目的是在这个目录里操作。举例(rename-file "e" "f/") 1223 | 结果为'f/e'. Although this formerly happened sometimes even when 1224 | D was not a directory name, as in (rename-file "e" "f") where 'f' 1225 | happened to be a directory, the old behavior often contradicted the 1226 | documentation and had inherent races that led to security holes. A 1227 | call like (rename-file C D) that used the old, undocumented behavior 1228 | can be written as (rename-file C (file-name-as-directory D)), a 1229 | formulation portable to both older and newer versions of Emacs. 1230 | Affected functions include 'add-name-to-file', 'copy-directory', 1231 | 'copy-file', 'format-write-file', 'gnus-copy-file', 1232 | 'make-symbolic-link', 'rename-file', 'thumbs-rename-images', and 1233 | 'write-file'. 1234 | 1235 | ** overlays-at返回的结果列表按优先级降序排列 1236 | 老版本的文档说明里指出当函数的第二个参数不为nil里,返回的结果为降序,但实际的代码返回的却是 1237 | 升序的结果。这个版本修复了这个问题,返回的结果正如文档中说明的那样按降序。 1238 | 1239 | ** format的优化 1240 | format避免了在大多数据情况下分配一个新的字符串。format在之前的文档中返回一个新分配的字符串, 1241 | 但这文档说明不是很准确,由于 *(eq x (format x))* 在x是一个空字符串时,返回的是t。format 1242 | 文档中不再提及返回一个新分配的字符串,当前的实现如在文档中提及的那样避免了大部分情况下字符串的 1243 | 无用拷贝,如 *(format "foo")* 和 *(format "%s" "foo")* 。 1244 | 1245 | ** 函数eldoc-message可接收一个参数 1246 | 在对多参数的程序调用之前,应该对其进行format操作。尽管不鼓励这样做,对ElDoc的支持,通过设置 1247 | eldoc-documentation-function函数,而不是直接调用eldoc-message。 1248 | 1249 | ** 对&rest或者&optional不正确的使用作为一种错误类型处理 1250 | 例如&optional后面没有一个变量,或者对&optional多次使用: 1251 | #+BEGIN_SRC emacs-lisp 1252 | (defun foo (&optional &rest x)) 1253 | (defun bar (&optional &optional x)) 1254 | #+END_SRC 1255 | 老版本里,Emacs只是忽略额外的关键字,或者在某种情况下给出一个不正确的结果。 1256 | 1257 | ** pinentry.el库被移除 1258 | 这个库以及对GnuPG和pinentry的修改目的是使得Emacs可采用GnuPG2.0来实现密码的输入。然而, 1259 | 这次修改变动只针对GnuPG大于2.1(包含)版本做了实现,对GnuPG2.0版本不兼容。对于GnuPG2.1及 1260 | 后续版本,不再需要pinentry.el。因此这个库成了无用库,被我们移除了。GnuPG 2.0不再被上游项 1261 | 目支持。 1262 | 1263 | 为了兼容这个变化,你需要设置epa-pinentry-mode为loopback,或者为默认值nil。从你的 1264 | gpg-agent.conf配置文件里删除allow-emacs-pinentry(一般在~/.gnupg目录)。 1265 | 1266 | 注意之前提到的,通过Minibuffer输入密码的安全性比其他图形界面的要差。但是,现在看来是差别不 1267 | 大:read-password函数阻止了通过日志的方式泄漏密码的可能。Emacs仍没有通过使用安全内存来保护 1268 | 密码机制,但这种攻击在当前计算机系统(指没有实现内存交互)是不可能。 1269 | 1270 | * Emacs 26.1中Lisp的变化 1271 | 1272 | ** 函数assoc接受一个可选的第三位参数TESTFN,当这个参数不为空时,其用于比较而不是相等 1273 | 1274 | ** 在alist-get、map-elt和map-put中新增可选参数TESTFN,当不为nil时,这个参数指定一个具体的比较函数,而不是用默认的assq和eql 1275 | 1276 | ** 新增函数seq-set-equal-p用于检查SEQUENCE1和SEQUENCE2是否含有相同元素(不考虑顺序) 1277 | 1278 | ** 新增函数mapbacktrace,用于将一个函数应用于当前椎栈的所有frames中 1279 | 1280 | ** 新增函数file-name-case-insensitive-p测试给定的一个文件是否在一个不区分大小写的文件系统里 1281 | 1282 | ** 为file-attributes添加多个寄存器返回值 1283 | 他们是file-attribute-type, file-attribute-link-number, file-attribute-user-id, 1284 | file-attribute-group-id, file-attribute-access-time, file-attribute-modification-time, 1285 | file-attribute-status-change-time, file-attribute-size, file-attribute-modes, 1286 | file-attribute-inode-number, file-attribute-device-number和file-attribute-collect 1287 | 1288 | ** 新增函数buffer-hash用于快速计算一个Buffer内容的非连续(non-consing)的哈希值 1289 | 1290 | ** interrupt-process的变化 1291 | interrupt-process采用列表interrupt-process-functions来实现传递SIGINT信号决定哪个函 1292 | 数会被调用。这可使Tramp实现向远程异步进程发送SIGINT信号。老的实现方式被迁移到internal-default-interrupt-process。 1293 | 1294 | ** 函数read-multiple-choice弹出多选择提问窗,提供一种手工方式来显示帮助信息 1295 | 1296 | ** comment-indent-function的值可返回一个cons用于指定格式化范围 1297 | 1298 | ** 函数make-temp-file新增加一个可选参数TEXT 1299 | 1300 | ** 新增函数define-symbol-prop 1301 | 1302 | ** 新增函数secure-hash-algorithms,其返回secure-hash支持的算法列表,详情请参考Emacs手册 1303 | 1304 | ** Emacs开放了GnuTLS的加密接口(API) 1305 | 对应的函数为gnutls-macs和gnutls-hash-mac; gnutls-digests和gnutls-hash-digest; 1306 | gnutls-ciphers和gnutls-symmetric-encrypt和gnutls-symmetric-decrypt 1307 | 1308 | ** 函数gnutls-available-p返回在Emacs中支持的GnuTLS库的功能列表 1309 | 1310 | ** Emacs可通过新函数make-record、record和recordp来实现用户定义类型的记录。 1311 | 记录用于描述cl-defstruct和defclass的实例。例如当你的代码里定义了新的记录类型,使用package-naming去命名这些类型,从而且避免类型冲突。 1312 | 1313 | ** save-some-buffers采用save-some-buffers-default-predicate决定哪些buffer会被确定询问,当PRED参数为nil时,save-some-buffers-default-predicate也为nil,表示询问所有正在访问的Buffer。 1314 | 1315 | ** string-(to|as|make)-(uni|multi)byte 被声明为废弃 1316 | 1317 | ** 新变量while-no-input-ignore-events用于设置哪些特定的while-no-input事件可以被忽略,它的值是一个symbol的列表 1318 | 1319 | ** 新增函数undo-amalgamate-change-group去除两个状态undo之间的边界 1320 | 1321 | ** 新变量definition-prefixes是有相应文件定义的哈希表的映射前缀,可用于获取那些还没加载的定义(如C-h f)。 1322 | 1323 | ** 新变量syntax-ppss-table用于在syntax-ppss控制syntax-table 1324 | 1325 | ** define-derived-mode可指定一个:after-hook形式, 当新的mode的hook被执行后它将被求值,可用于在mode启动时,mode-hook引起配置发生变化的情况 1326 | 1327 | ** 自动加载产生的文件名不包含时间戳,可通过设置变量autoload-timestamps的值不是nil产生时间戳 1328 | 1329 | ** gnutls-boot接受一个参数:complete-negotiation,表示即使在非阻塞的socket链接里协商应该完成 1330 | 1331 | ** 新增变量flyspell-sort-corrections-function,它是flyspell.el库里的变量,用于排序修正 1332 | 1333 | ** 新增命令fortune-message用于在echo区域显示名言警句 1334 | 1335 | ** 新增函数func-arity返回任意函数的参数列表信息,用于替代之前的subr-arity 1336 | 1337 | ** 新增函数region-bounds用于交互情境,主要用于提供区域边界(超过一个的长方形区域),只需要传递一个参数,取代之前的两个参数(region-beginning和region-end) 1338 | 1339 | ** parse-partial-sexp函数的返回列表新增一种元素,元素10。 当最后一个被扫描的字符可能是两个结构字符的第一个字符时,如注释符,这个元素的值就是最一个字符的语法值 1340 | 1341 | ** parse-partial-sexp函数返回列表的第9个元素作为固定返回元素,可用于Lisp编程。它的值是括号所含位置的列表,从最外层开始。 1342 | 1343 | ** read-color在将颜色作为背景色时将显示颜色名 1344 | 1345 | ** 函数redirect-debugging-output可在非GNU/Linux平台上运行 1346 | 1347 | ** 新增函数string-version-lessp比较两个字符串,这里会把不连续的数字解析成数值,然后进行比较例如"foo2.png"比"foo12.png"小 1348 | 1349 | ** 数值比较和logb操作由于内部数据的取位操作,不再返回精确值。例如(< most-positive-fixnum (+ 1.0 most-positive-fixnum))在64位的机器上返回t 1350 | 1351 | ** 函数ffloor, fceiling, ftruncate和fround如文档所述只接受浮点类型参数。先前是可接受整型参数有些会返回无意义的结果如(< N (ffloor N))返回t 1352 | 1353 | ** 在GNU/Linux x86-64机器上的长浮点型位数至少包含EMACS_INT_WIDTH - 3个bit。格式化返回不正确值是由于取舍问题,例如(eql N (string-to-number (format "%.0f" N)))现在返回t 1354 | 1355 | ** 调用那些浮点类型的整型时会抛出异常(如果传入的参数不是整型)例如(decode-char 'ascii 0.5)现在会抛出错误异常 1356 | 1357 | ** 函数string-trim-left, string-trim-right和string-trim接受可选参数指定子串的正则表达式 1358 | 1359 | ** 新增函数char-from-name,作用于将Unicode编辑的字符串转换为对应的字符码(character code) 1360 | 1361 | ** 新增函数sxhash-eq和sxhash-eql 1362 | 这两个函数返回一个Lisp对象的哈希值,其分别用于eq和eql函数。如果两个对象是eq(eql), 则其函 1363 | 数sxhash-eq(sxhash-eql)计算的哈希值也一样。 1364 | 1365 | ** 函数sxhash被重命名为sxhash-equal,为了兼容sxhash成为sxhash-equal别名 1366 | 1367 | ** make-hash-table默认的刷新阈值从0.8改成0.8125, 避免舍入的小问题 1368 | 1369 | ** 新增函数add-variable-watcher用于当一个变量的值发生变化时的函数调用。用于实现新的调试命令debug-on-variable-change 1370 | 1371 | ** 新变量print-escape-control-characters改变prin1和print输出控制字符为反斜杠 1372 | 1373 | ** 时间转换函数支持时间区间规划参数 1374 | 其可为OFFSET或者列表(OFFSET ABBR)整型的OFFSET是相对于UT(Universal Time)时间的东向偏移 1375 | (单位秒)。字符串ABBR是时间区间的简写。受影响的函数有current-time-string, 1376 | current-time-zone, decode-time,format-time-string和set-time-zone-rule. 1377 | 1378 | ** format-time-string函数支持%q,用于日历的季度 1379 | 1380 | ** 新的内置函数mapcan,避免不必要的链接(consing)和gc操作 1381 | 1382 | ** car和cdr,以及cXXXr和cXXXXr的结构已经集成为Elisp一部分 1383 | 1384 | ** gensym已经集成进Elisp一部分 1385 | 1386 | ** 基础列表函数,如length和member,做了相应优化成列表循环 1387 | 1388 | ** 新增加函数make-nearby-temp-file和temporary-file-directory,用于在远端或者所在目录创建临时文件 1389 | 1390 | ** 在GNU平台操作一个本地文件时,同时另一个进程改变文件系统时,file-attributes函数不再进行死循环;如果不是GNU的平台遇到同样情况,file-attributes尝试去检测死循环,同时返回nil 1391 | 1392 | ** 新函数file-local-name可用于指定远端进程的参数 1393 | 1394 | ** 新增加函数file-name-quote、file-name-unquote和file-name-quoted-p 1395 | 用于对文件名加前缀"/:"进行引用或者取消引用 1396 | 1397 | ** 新增错误类型file-missing作为file-error子类型 1398 | 如果操作不存在的文件,将采用这种错误类型取代之前的file-error这种错误类型 1399 | 1400 | ** delete-directory函数的变化 1401 | 当递归操作进行时,同时有其他进程在执行delete-directory前删除了目录或者文件时,不再抛错误异常。 1402 | 1403 | ** 新的错误类型user-search-failed,与search-failed类似,但像user-error一样禁止高度机制 1404 | 1405 | ** 函数line-number-at-pos的变化 1406 | 函数line-number-at-pos支持传递第二个可选参数absolute。 如果这个参数为nil, 默认将返回包 1407 | 含收缩(potential narrowing)的行号。如果这个参数不为nil,它将不考虑收缩情况,返回绝对的 1408 | 行号。 1409 | 1410 | ** 函数color-distance的调整 1411 | 函数color-distance在新版本支持第二个可选参数 *metric* 。当这个参数不为nil时,它将接收两 1412 | 个参数(两个颜色值)返回一个距离值。 1413 | 1414 | ** Frame和Window操作 1415 | 1416 | *** 调整frame大小方式的改变 1417 | 请使用 *window-size-change-functions* 代替老的 *window-configuration-change-hook* 。 1418 | 1419 | *** Frame大小是否被调整 1420 | 判断Frame是否被调整可使用新函数 *frame-size-changed-p* 。这里的大小是否被调整过是从上 1421 | 一次调用 *window-size-change-functions* 算起。 1422 | 1423 | *** 函数frame-geometry也会返回frame的外边界宽度 1424 | 1425 | *** 新增部分frame相关参数及老参数一些语义变化 1426 | 1427 | **** 'z-group'将frame置于其他之上或之下 1428 | 1429 | **** 'min-width'和'min-height'用于指定frame的绝对最小范围 1430 | 1431 | **** 'parent-frame'使得一个frame成为另一个frame的子frame。详情请参数Elisp手册的Elisp子frames部分 1432 | 1433 | **** 'delete-before'在删除一个frame前触发删除另一个 1434 | 1435 | **** 'mouse-wheel-frame'指定另一个frame的窗口可滚动 1436 | 1437 | **** 'no-other-frame' 新增 'next-frame' 和 'previous-frame' 跳过当前frame 1438 | 1439 | **** 'skip-taskbar' 从任务条(taskbar)中删除frame的图标,同时,可通过'Alt-'跳过这个frame 1440 | 1441 | **** 'no-focus-on-map' 避免一个规划过的frame获得输入选中 1442 | 1443 | **** 'no-accept-focus' 表示frame不希望通过鼠标获得输入选中 1444 | 1445 | **** 'undecorated' 从frame中移除窗口管理样式 1446 | 1447 | **** 'override-redirect' 让窗口管理忽视当前frame 1448 | 1449 | **** 'width' and 'height' 支持按比例指定和按像素值 1450 | 1451 | **** 'left' and 'top' 支持按比例指定 1452 | 1453 | **** 'keep-ratio' 当父frame被调整时,保持子frame的大小和位置不变 1454 | 1455 | **** no-special-glyphs在frame中将覆盖截断和连续符号的显示 1456 | 1457 | **** auto-hide-function和minibuffer-exit分别用于处理自动隐藏frame和从minibuffer中退出 1458 | 1459 | **** fit-frame-to-buffer-margins和fit-frame-to-buffer-sizes用于处理frame对其buffer的大小适应 1460 | 1461 | **** drag-internal-border, drag-with-header-line, drag-with-mode-line, snap-width, top-visible and bottom-visible允许通过拖拽来调整frame的大小 1462 | 1463 | **** minibuffer当初始值被指定为nil时,设置为默认的minibuffer窗口 1464 | 1465 | *** 新增函数frame-list-z-order返回按z(栈)顺序的frame列表 1466 | 1467 | *** 函数'x-focus-frame'不激活它的frame变成可选项 1468 | 1469 | *** 变量focus-follows-mouse增加第三个有意义的值auto-raise 1470 | 这个值用于当鼠标进入frame时,标明窗口管理自动聚焦这个frame。 1471 | 1472 | *** 新增函数frame-restack,用于调整frame的层级关系 1473 | 1474 | *** 新增internal-border用于指定frame的外部边界背景 1475 | 1476 | *** select-window函数NORECORD参数增加 *mark-for-redisplay* 选项 1477 | 这个选项类似其他不是nil的值,但它标记窗口(WINDOW)重新显示 1478 | 1479 | *** 正式支持对边窗(side windows) 1480 | 显示操作函数display-buffer-in-side-window可将buffer显示在边空上。更从详情请参考ELisp 1481 | 手册里的边窗口部分。 1482 | 1483 | *** 支持原子窗口 1484 | 更从详情请参考ELisp手册里的原子窗口部分 1485 | 1486 | *** 新增display-buffer列表项window-parameters 1487 | 分配给要展示buffer的窗口参数 1488 | 1489 | *** 新增函数display-buffer-reuse-mode-window 1490 | 这个函数是一个交互函数,适用在display-buffer-alist。例如,当打开一个帮助手册,为了避免 1491 | 再次创建一个已经存在的窗口,可用这个机制完成。 1492 | #+BEGIN_SRC emacs-lisp 1493 | (add-to-list 'display-buffer-alist 1494 | '("\\`\\*Man .*\\*\\'" . 1495 | (display-buffer-reuse-mode-window 1496 | (inhibit-same-window . nil) 1497 | (mode . Man-mode)))) 1498 | #+END_SRC 1499 | 1500 | *** 新窗口参数no-delete-other-windows 1501 | 防止窗口被delete-other-windows命令删除掉 1502 | 1503 | *** 新窗口参数mode-line-format和'header-line-format 1504 | 这两个参数允许buffer本地(buffer-local)修改进行覆盖。 1505 | 1506 | *** 新增命令window-swap-states 1507 | 这个命令用于交换两个打开的windows的状态(选中和被选中),这个方法常用于当前只有两个窗口时, 1508 | 交换两个窗口的内容。 1509 | 1510 | *** 新增window-pixel-width-before-size-change和window-pixel-height-before-size-change函数 1511 | 用于当window-size-change-functions运行里,检测哪个窗口大小发生了变化 1512 | 1513 | *** 新增函数window-lines-pixel-dimensions用于返回一个窗口文本行的像素大小 1514 | 1515 | *** 新增函数window-largest-empty-rectangle用于返回在窗口里没有文本区域最大矩形大小 1516 | 1517 | *** 函数'mouse-autoselect-window'语义微调 1518 | 详情参考Elisp手册里的"(elisp) Mouse Window Auto-selection"函数。 1519 | 1520 | *** 'select-frame-by-name' 在当前的显示器里无法找到一个匹配的frame,可返回一个在其他显示器上的frame 1521 | 1522 | ** 'tcl-auto-fill-mode'已经声明废弃 1523 | 这个函数的功能可通过设置 *comment-auto-fill-only-comments* 来实现。 1524 | 1525 | ** 新增pcase模式'rx'用于匹配rx风格的正则表达式 1526 | 详情请参考'rx--pcase-macroexpander'函数文档。 1527 | 1528 | ** 新增区域二次选择函数 1529 | 新增加函数'secondary-selection-to-region'和 1530 | 'secondary-selection-from-region',满足用户再次设置区间的开始和结束。 1531 | 1532 | ** 新增函数'lgstring-remove-glyph' 1533 | 这个函数于用修改底层布局引擎(如m17n-flt, uniscribe)返回的gstring。 1534 | 1535 | * Emacs 26.1 在一些特殊模式和包中的变化 1536 | 1537 | ** 在Windows7&以上系统对快捷键的捕获性能更好 1538 | 新的键盘钩子代码(hooking code)更加准捕获系统快捷键如'Win-*'和'Alt-TAB', 通过这种方式, 1539 | Emacs比系统更早地获取按键事件。这使得'w32-register-hot-key'函数功能违背了所有Windows7 1540 | 开始的原意功能。Windows NT及之后版本可以注册任务快捷键的组合。(在Windows 9X,之前的限制, 1541 | 在Emacs的手册里已经说明了依然需要申请)。 1542 | 1543 | ** 'convert-standard-filename' 函数的变化 1544 | 在MS-Windows系统中'convert-standard-filename'函数不再将斜线(/)替换成反斜线(\)。老版 1545 | 本在MS-Windows系统中这个函数将文件名里的斜线(/)强制转成反斜线(\)。因为不再这样做,如果你 1546 | Lisp代码里使用了 *convert-standard-filename* 这个函数去做这个变化,你需要自己手工处理 1547 | 一下这块的代码。如按照如下方式: 1548 | 1549 | #+BEGIN_SRC emacs-lisp 1550 | (let ((start 0)) 1551 | (while (string-match "/" file-name start) 1552 | (aset file-name (match-beginning 0) ?\\) 1553 | (setq start (match-end 0)))) 1554 | #+END_SRC 1555 | 1556 | ** MS-Windows平台下的GUI会话像Posix平台一样将被当作SIGINT 1557 | Ctrl-C (SIGINT)信号在MS-Windows平台GUI的效果与Posix平台一样:Eamcs保存会话然后退出。 1558 | 譬如,如果你在Windows shell里启动emacs.exe程序,然后在shell窗口里按下Ctrl-C,也会产生 1559 | 同样效果。 1560 | 1561 | ** Windows XP及以后系统'signal-process'支持SIGTRAP 1562 | 在Windows系统下对'kill'的仿真映射到SIGTRAP信号去调用'DebugBreakProcess'接口。这会导致 1563 | 检索程序终止执行,然后把控制权交给调试者(debugger)。如果没有调试者绑定到搜索程序,这个调用 1564 | 将被忽略。这跟POSIX系统的默认行为形成对比,POSIX系统是会终止检索程序的执行(终止前会做一次 1565 | core dump)。 1566 | 1567 | ** macOS系统里的一些小优化 1568 | 1. 修复在macOS系统里'set-mouse-position'和'set-mouse-absolute-pixel-position'命令不生效问题; 1569 | 2. 在macOS系统,从命令行中也可打开Emacs GUI程序; 1570 | 3. macOS 10.9+ 'ns-appearance'和'ns-transparent-titlebar'改变frame的显示; 1571 | 4. macOS 10.8+系统里使用'ns-use-thin-smoothing'开启瘦字段更加柔和; 1572 | 5. Darwin系统'process-attributes'返回更多信息; 1573 | 6. macOS 10.7+ 鼠标方向键和触摸板的滚动效果表现更加与原生系统相同,新增变量'ns-mwheel-line-height' 、'ns-use-mwheel-acceleration'和'ns-use-mwheel-momentum'用来定制化这些行为。 1574 | 1575 | 1576 | * GNU Emacs协议声明原文 1577 | 1578 | This file is part of GNU Emacs. 1579 | 1580 | GNU Emacs is free software: you can redistribute it and/or modify 1581 | it under the terms of the GNU General Public License as published by 1582 | the Free Software Foundation, either version 3 of the License, or 1583 | (at your option) any later version. 1584 | 1585 | GNU Emacs is distributed in the hope that it will be useful, 1586 | but WITHOUT ANY WARRANTY; without even the implied warranty of 1587 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1588 | GNU General Public License for more details. 1589 | 1590 | You should have received a copy of the GNU General Public License 1591 | along with GNU Emacs. If not, see . 1592 | --------------------------------------------------------------------------------