Emacs的Tab键

来源:互联网 发布:直播行业现状知乎 编辑:程序博客网 时间:2024/06/04 17:46

在Windows里待久了的人,初用Emacs时,对它的很多按键功能会很不适应,其中之一就是TAB键,有时候按一下TAB键会缩进很多,有时候无论怎么按都没反应,让人摸不着头脑。

Emacs中的TAB键,默认功能是自动排版(在编程mode下),就像VC中的Alt+F8,对光标所在行或者选中区域的所有行按照语言排版格式重新排版。有人问那怎么才能输入一个水平制表符,一个普通的Tab,Emacs默认的方法是组合键C-q Tab,需要3个键,好痛苦啊,如果要改回你认识的Tab键,可以这样重新定义Tab的功能,输入1个Ascii为9的字符(即tab):

(global-set-key (kbd "<tab>") '(lambda () (interactive) (insert-char 9 1)))

但是,请相信我,这不会让你爽多久,很快你会发现Shift-Tab不是反向缩进,而且在选中状态下按Tab,也不是你想象的那样所有行缩进,而是选择被取消并在光标处插入一个普普通通的Tab… 我妥协了,把Tab保留在默认的排版功能,而像多数Emacser那样,把”键入一个Tab“绑定到一个空闲的C-tab组合键上。

(global-set-key [C-tab] '(lambda () (interactive) (insert-char 9 1)))

因为对我来说,需要”键入一个Tab“的情况不是很多,相较起来,也许排版要用的更多。

顺便一提,在网上看到有人把C-i键重定义后,Tab键也会跟着变成同样的功能。(参考:How do I bind a command to C-i without changing TAB?)在原帖的回答里,下面的方法据说最有效,可以改C-i键而又不影响Tab

(setq local-function-key-map (delq '(kp-tab . [9]) local-function-key-map))(global-set-key (kbd "C-i") 'forward-word)

因为在elisp的说明文档里这样讲:In ASCII, C-i and <TAB> are the same character.(参考:GNU Emacs Lisp Reference Manual-21.7.2 Function Keys)我没能完全理解这句话,虽然我知道ASCII里有<TAB>,但是ASCII里竟然还有C-i ?

但是不知道为什么,上面的配置在我电脑上行不通,第一条删除(kp-tab . [9])按键映射,我这里删不掉,或者是最后一个参数改成function-key-map也不行,用C-h v local-function-key-map查看(kp-tab . [9])还在,后来我用delete成功删掉了(delete '(kp-tab . [9]) local-function-key-map)这次(kp-tab . [9])终于没有了,但是改C-i键依然会影响Tab键,WTF!,有高手的话希望能指点一下。下面介绍我实验出来的终极奥义

(global-set-key (kbd "C-i")  'command1)(global-set-key (kbd "<tab>") 'command2)

这下可以使<tab>"和"C-i"不再影响了,但是,Tab键也被全局锁定为这一个功能了,本来Tab键在不同模式下有不同功能,如果这么定义的话,就要追加定义一堆东西,还是放弃吧,放弃C-i键。关于Tab键就折腾到这吧。

软件环境Emacs for Windows, version 24.2OS:Windows7中文版

=======================另一篇=============================

Emacs的Tab

hanlray@gmail.com
Reversion:0.5 Date:2006/08/10

当在buffer里按下Tab键时是什么情况?插入一个tab字符?indent?如果是indent又是如何indent的呢?想要更改indent的宽度该怎么办呢?下面以XHTML这个Major Mode为例,看看emacs是怎样处理的。

  • 用C-h c查看Tab键绑定到了indent-for-tab-command命令上
  • 用C-h f查看indent-for-tab-command函数的描述,发现其依赖一个变量tab-always-indent来动作
  • 用C-h v查看tab-always-indent变量的描述:如果其值为t,indent当前行;如果其值为nil,当光标在left margin(当前行的indentation里)时,indent当前行,否则插入一个tab字符。当前值为t。
  • 怎样indent当前行?由变量indent-line-function决定,其值是实现indent的函数,用C-h v查看其值为sgml-indent-line
  • 不想去看sgml-indent-line是怎么indent的,因为有些indent的算法是比较复杂的,只要知道那些变量可以控制indent的效果就可以了
  • 用C-h m查看当前Mode的描述:XHTML Mode基于SGML mode,用C-h v html-SPC和C-h v sgml-SPC来查看可用变量
  • 发现sgml-basic-offset控制着indent的宽度,不过当前值为2,正合我意,否则之间就可以在该变量描述的那个buffer里用customize对该值进行修改

0 0