本文档是"ZHL的emacs笔记"的一部分。
本文档的格式是为了快速检索与浏览而专门调整的,最好用emacs来查看,将tab
缩进显式设为3个字符,设置不自动换行,并使用outline模式,以提高学习和工
作效率。具体配置可参考文档"ZHL的emacs笔记:配置小技巧"。
本文档主要讲述的是emacs中view模式和diff模式两个非常常用的功能,包括功能
描述、配置方法以及命令索引,当然,主要是本人在使用过程中所关注的细节以
及积累的经验。
希望本文档能给emacs同好一些帮助,任何问题或建议可以发信到 seaxii@126 来讨论。
文档正文----------------------------------------------------------------
**文本相关:outline模式、Org模式、View模式、文件比较、text模式、fill模式、Abbrev模式、Picture模式、2C模式。
**View模式:辅模式,也可作为主模式。专用于查看文件而非修改。
说明:1、Kill操作仅是将内容放入kill buffers中而并不执行删除动作。
2、可重新绑定一些单字母键以便能单手快速滚屏和移动光标,参见"emacs配置小技巧"第[[89]]。
view-mode :翻转view模式。
view-file :以view模式打开文件。
view-file-other-window :
view-file-other-frame :
view-buffer :以view模式打开缓冲区。
diff函数view-buffer-other-window :
view-buffer-other-frame :
h 或 H 或 ?  describe-mode :
数字  digit-argument :数字直接作为数字前辍。
-
  negative-argument :反向前辍。
<  beginning-of-buffer :头。
>  end-of-buffer :尾。
o  View-scroll-to-buffer-end :尾。并使尾部成为窗口最后一行。
SPC  View-scroll-page-forward :下滚一页。数字前辍指定下滚数行。
BS  View-scroll-page-backward :上滚一页。数字前辍指定上滚数行。
z  View-scroll-page-forward-set-page-size :下滚一页。数字前辍指定下滚数页。
w  View-scroll-page-backward-set-page-size :上滚一页。数字前辍指定上滚数页。
F  View-revert-buffer-scroll-page-forward :下滚一页。如果需要,则:撤销自上次对文件存盘后的所有修改。即从磁盘上取回文件内容。
d  View-scroll-half-page-forward :下滚半页。数字前辍指定下滚数行。
u  View-scroll-half-page-backward :上滚半页。数字前辍指定上滚数行。
RET 或 C-j  View-scroll-line-forward :下滚一行。
y  View-scroll-line-backward :上滚一行。
=  what-line :打印行号。
g  View-goto-line :去某行。默认为首行,数字前辍指定行数。
%  View-goto-percent :去百分之多少处。默认为100,数字前辍指定百分数。
.  set-mark-command :设置标记。
x  exchange-point-and-mark :光标在当前位置和标记之间跳转一下,以显示文本块范围。
@  View-back-to-mark :跳到上一个标记处,该标记出栈(从mark
ring)。当开始查询或跳转到某行或跳到首尾时将设置标记并进栈。
m  point-to-register :保存位置到字符寄存器(character register)中。需给出一个字符名。
'  register-to-point :跳转到字符寄存器(character register)中字符指定的位置。需给出一个字符名。命令 register-to-point 是命令 jump-to-register 的别名。
s  isearch-forward :前向递增查。
r  isearch-backward :后向递增查。
/  View-search-regexp-forward :前向正则表达式查从下一页开始。正则表达式若以 ! 或 @ 开头则有特殊意义,! 表示查不匹配,@ 表示从头开始查。
\  View-search-regexp-backward :后向正则表达式查从上一页开始。正则表达式若以 ! 或 @ 开头则有特殊意义,! 表示查不匹配,@ 表示从尾开始查。
n  View-search-last-regexp-forward :前向开始最后一个正则表达式查。
p  View-search-last-regexp-backward :后向开始最后一个正则表达式查。
q  View-quit :退出view模式。并试图恢复该窗口和缓冲区到先前状态。
Q  View-quit-all :退出view模式。并试图恢复所有处于view模式的窗口和缓冲区到先前状态。
e  View-exit :退出view模式。但保留该缓冲区以便进行修改编辑。
E  View-exit-and-edit :退出view模式。但保留该缓冲区并使其变为可编辑以便进行修改编辑。
c  View-leave :退出view模式。但并不关闭该缓冲区而是试图切换到其它缓冲区。
C  View-kill-and-leave :退出view模式。并关闭该缓冲区。
变量 view-read-only :若为 non-nil ,则缓冲区切换到只读状态时会自动进入View辅模式,而再切换回非只读状态时会自动退出View辅模式。还有其它条件控制是否连带进入View辅模式,具休参见"只读状态与View辅模式"。
变量 view-mode-hook :进入view主模式/辅模式时的勾子函数。
变量 view-mode-map :view主模式/辅模式的局部键位映射图。
**文件比较:
**说明:1、比较文件是一个基本功能,emacs中包含很多类似功能,比如 compare-windows 、 diff模式 、 ediff模式 ,等等。
2、关于文件比较的配置,参见"emacs配置小技巧"第97。
**diff模式:操作比较结果(即patch)的模式。
说明:1、象 diff 、diff-backup 等命令是以命令行工具diff为后端来生成比较结果的,在Linux上使用没问题,但在emacs for windows加cygwin中使用会因为路径的问题而出错,若是使用cygwin自带的emacs想来也应该是没问题的。
(2012-06-05 15:34:45)后来在看了diff函数的代码后知道了问题所在,是因为执行命令行工具diff的shell使用的并非cygwin提供的bash,尽管Shell模式已经设置成打开cygwin的bash,但这并没有使得执行shell命令时也用cygwin的bash,因而在路径分析时会有问题,在将变
量 shell-file-name 的值指定为 C:/cygwin/ 后,执行 diff-backup 等命令就不会报路径错误了,具体参见"执行shell命令"的说明。
2、命令 next-error / previous-error 针对diff模式也一样有效,与在 compile 命令的输出中使用的效果完全相同,非常方便。
3、在diff模式中,若缓冲区是只读的,则其下子命令所绑定的组合键中的 ESC 键(即 M- )是可以省略的,即有很多命令可以单键操作。
4、如果手工修改了diff模式缓冲区(即修改了patch),diff-mode will try to update the hunk headers for you on-the-fly. --没明白。
5、该模式中,每个比较所得的差异点,即改动,称为一个 hunk 。
6、关于乱码问题:在用 diff / diff-backup 命令生成比较结果并放于一个新建缓冲区(*Diff*)中后,显示的可能是乱码,这是由于对比较操作的输出采用的解码方式不匹配造成的。如果参与比较的文件是utf-8编码的,则比较结果也应该是utf-8编码的,此时若以非utf-8方式对比较结果进行解码则必然导致乱码。以何种方式对比较结果进行解码,是由当前shell环境I/O的编解码配置决定的,具体参见"中文支持"中对变量 process-coding-system-alist 的描述。如果能正确解码,那么显示就会正常,与新建缓冲区(*Diff*)最后采用的是何种编码系统无关。
diff-mode :进入diff模式。状态行主模式名为 Diff 。一般打开patc件(比如扩展名为 .patch 的)或用 diff 命令生成比较结果时自动进入该模式,很少手工使用该命令进入。
diff :利用命令行工具diff比较两个文件内容,或比较两个目录下所有文件内容,会生成一个新的缓冲区来装入比较结果并进入diff模式。加前导参数则可手工指定比较命令行的选项。
diff-backup :同diff命令,但直接比较指定文件和其备份文件。直接回车则使用当前缓冲区对应的文件。
M-o 或 M-RET 或 C-c C-c  diff-goto-source :打开源文件并定位到光标所在改动点。默认会打开参与
比较的两个文件中的后一个文件,若想打开另一个文件,有两个办法:1、加一个数字前辍即可打开另一个文件,并且,若数字前辍大于8则以后再打开的都是另一个文件,其实打开哪个文件是由变量 diff-jump-to-old-file 决定的,当数字前辍大于8时,该变量也被设置。2、可使用 diff-reverse-direction 命令先翻转一下文件比较顺序,再定位文件时即打开的是另一个文件。
M-P 或 M-{  diff-file-prev :移动光标到上一个文件。一个patch可能包含多个文件的多处改动。
M-N 或 M-}  diff-file-next :移动光标到下一个文件。
M-p 或 M-<backtab>  diff-hunk-prev :移动光标到上一条改动。 <backtab> 即 S-TAB 。
M-n 或 M-TAB  diff-hunk-next :移动光标到下一条改
动。
C-c C-f  next-error-follow-minor-mode :翻转光标跟随定位辅模式,状态行模式名为 Fol 。打开该模式后,当在各条改动上移动时,会自动在另一窗口定位源文件。也同样适用于 compilation 、grep 、occur 等缓冲区。
C-c C-w  diff-ignore-whitespace-hunk :重新评估当前改动,忽略那些由于white space造成的不同。white space是指空格符和TAB符。该命令对于忽略由于排版缩进而导致的不同很有帮助。
M-K  diff-file-kill :去掉当前文件的所有改动。即修改patch,将其中针对某个文件的所有差异点都移除。
M-k  diff-hunk-kill :去掉当前改动。即修改patch,将其中某个差异点移除。
M-q  quit-window :当前缓冲放到最后,若加前导参数则会杀掉当前缓冲。
C-c C-d  diff-unified->context :切换显示方式为上下文方式(context diffs),即修改前的信息显示为一段,修改后的信息显示为一段,并在两段中都用符号标记出改动的行。这种方式显示的更直观一些。
C-c C-u  diff-context->unified :切换显示方式为合成体方式(unified diffs),即在同一段中既显示修改前的行也显示修改后的行,并用不同符号分别标记出修改前后的各行。这种方式显示的更紧凑一些。
C-c C-r  diff-reverse-direction :在比较结果中颠倒参与比较的两个文件的先后顺序,这会导致缓冲区内容的改变,也即patch方向的改变(加补丁还是退补丁)。在用 next-error / previous-error 或 diff-goto-source 定位文件内容时,总是跳到后一个文件的对应不同的位置,那么使用该命令颠倒文件比较顺序后,再定位时,跳到的就是另一个文件了。
C-c C-a  diff-apply-hunk :应用当前改动,应用到两个文件中的哪个上面是由变量 diff-jump-to-old-file 决定的,另外,加前导命令则导致 REVERSE the hunk 。
C-c C-b  diff-refine-hunk
C-c C-e  diff-ediff-patch
C-c C-n  diff-restrict-view
C-c C-s  diff-split-hunk
C-c C-t  diff-test-hunk
C-x 4 A  diff-add-change-log-entries-other-window
变量 diff-command :指定了使用的比较命令,默认为"diff"。
变量 diff-switches :指定了比较命令行的选项,默认为"-c",即默认(比较操作的)输出和(diff模式的)显示为上下文方式,可修改为"-u",即将默认(比较操作的)输出和(diff模式的)显示调整为合成体方式。
变量 diff-mode-hook :为diff模式初始化过程中最后一步所运行的勾子。
变量 diff-jump-to-old-file :决定了打开哪个源文件,即参与比较的两个文件中的哪一个。
**只读状态与View辅模式:
1、diff模式缓冲若是只读的则可使用一些方便的单键命令,但因配置了 view-read-only 的全局值为t,所以只读状态下总是会打开View辅模式,而其某些单键绑定覆盖了diff模式
的,所以想配置成在diff模式中进入只读状态时不同时打开View辅模式。
2、因为不想修改 view-read-only 的全局值,当时还不会设置缓冲本地值,所以做了以下设置:
(add-hook 'diff-mode-hook
'(lambda ()
(setq view-read-only nil)
(if buffer-read-only
(if view-mode
(view-mode))
(toggle-read-only 1))
(setq view-read-only t)))  ;;全局值翻回来。
此时用 diff-backup 打开的diff模式缓冲确实达到了目的,进入了只读状态且没有连带打开View辅模式。
但若打开一个.patc件就不对了,View辅模式还是被打开了。
3、想是打开文件的过程中有些什么手脚,于是又加了这一段:
(add-hook 'find-file-hook
'(lambda ()
(when (equal major-mode 'diff-mode)
(if buffer-read-only
(toggle-read-only -1))
(setq view-read-only nil)
(toggle-read-only 1)
(setq view-read-only t))))  ;;全局值翻回来。
此时再打开.patc件则可以看到在只读状态下且没有View辅模式了,但失败的是diff模式里的某些单键绑定也丢了。
想其原因可能还是因为View辅模式进了又出导致的。
后来发现,只要重进一下diff模式就好了,如下:
(add-hook 'find-file-hook
'(lambda ()
(when (equal major-mode 'diff-mode)
(if buffer-read-only
(toggle-read-only -1))
(setq view-read-only nil)
(toggle-read-only 1)
(diff-mode)  ;;重入一下diff模式。
(setq view-read-only t))))
4、以上配置基本可以工作了,但有一缺点是,若翻转两下只读状态则View辅模式还会出来。
而在occur模式下却发现,其翻转只读状态时View辅模式从来不会出现,而且该缓冲也未设置 view-read-only 本地值,全局值依然为t。
研究 toggle-read-only 的源码发现其是否打开View辅模式还有一个条件,即主模式的 mode-class 属性的值不能为 special ,而occur模式恰恰设置了该属性值,所以不会连带打开View辅模式。
另外,也看到函数 after-find-file 的实现,确实在打开文件的最后会根据 buffer-read-only 和 view-read-only 的值来保证进入View辅模式,而且也会检查主模式属性,与 toggle-read-only 做的基本一样。
那么,通过设置主模式属性,用以下几行,问题就全解决了:
(add-hook 'diff-mode-hook
'(lambda ()
(put major-mode 'mode-class 'special)
(setq buffer-read-only t)))
5、后来知道了

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。