现在的位置: 首页 > 综合 > 正文

emacs补全

2013年01月02日 ⁄ 综合 ⁄ 共 3784字 ⁄ 字号 评论关闭

原文地址: http://blog.csdn.net/astropeak/article/details/6666527

emacs中的补全大致可为三类:前缀补全、模板补全和语义补全。前两种补全可应用于任 何文字的输入,第三种补全只针对具有固定语法的编程语言。默认情况下(不安装任何插 件),emacs提供基本的前缀补全和模板补全功能,虽然这两种补全相对于普通的编辑器 已经能够较为有效得提高输入效率,但其完成方式仍不够人性化,并且对于某些高级的补 全功能,仍然无法完成。但emacs素来是以可扩展性著称的,存在大量优秀的插件可用来 增强它的能力。对于补全,可用的插件自然也不少。在这些插件的“辅佐”下,emacs的补 全能力可以说非常强悍。

  1. 基本补全功能

    1. 前缀补全

      前缀补全在emacs文档中又被称为动态补全,是指在输入若干个字母后,便可对这 几个字母进行补全,补全候选结果将来源于当前所有缓冲区中的单词,这些单词以 所输入的字母序列打头。补全的操作过程为:

      输入若干个字母(至少一个),然后按下动态补全命令(dabbrev-expand)对应快 捷键,则第一个补全候选结果将被显示出来。此时若该结果是目标单词,则可直接 继续后续的输入;若该结果不是想要的单词,需再按下补全快捷键,则下一个候选 结果被显示,重复這一步骤,直到找到所需的单词。emacs将优先显示离光标最近 的那个单词,因此,若目标单词离当前位置较远或在另一缓冲区中,则可能需要较 多的按键次数才能找到目标单词。

      • 优点

        实现“一次输入,多次补全”的输入方式,这一点(尤其)对于较长单词(如程序 中较长的变量名,函数名等)的输入将带来极大的便利,同时也可避免一个单词 多次输入时拼写错误的问题。

      • 不足

        补全时补全候选列表不可见,难以预知目标单词在其中的位置,在候选结果较多 时,容易出现多按一次快捷键而错过目标结果的情况,此时只能重新进行补全, 因补全的搜索顺序不可逆。

    2. 模板补全

      默认情况下的模板补全通过缩写模式(abbrev-mode)完成,因此要实现模板补全, 需处于该模式下。模板补全的原理为:所有模板被保存在一个文件中,当输入模板 名,按下任意非文字字符后,则该模板名将被替换为模板的内容。

      模板可在输入的过程中创建。例如若想创建一个名为“def”,内容为“#define ”的 模板,则首先在任何位置输入“def”,然后按下快捷键“C-x a i l”,则emacs会提 示输入模板内容,然后输入“#define ”,按回车,则该模板被创建。以上快捷键实 际调用的命令为"inverse-add-mode-abbrev",即将这个模板插入到当前模式的模 板列表中,因此这个模板只能在当前模式下使用。若想定义一个全局可见的模板, 则可使用命令: inverse-add-global-abbrev,对应的快捷键为“C-x
      a i g”。

      若想输入模板名本身,而非将其替换为模板内容,可在输入模板名后按下“C-q”, 则模板名将不会被替换为模板内容。

      • 优点

        对于需要经常输入的大段内容,作为模板输入,将有效提高输入效率。

      • 不足

        无法控制光标的位置,替换完成后,光标总是位于模板内容之后(因此这里的模 板并不是真正的模板,仅仅是一个缩写)。

  2. yasnippet插件——模板补全

    yasnippet插件是所有模板补全类插件中功能最强的一个,用该插件几乎可以完成任何 能够想象的模板任务。yasnippet预置了很多模板,其中包括十几种编程语言、latex 源文件和基本文本所需的模板。利用这些模板,可以极大的提高输入效率。

    yasnippet提供的模板非常智能,模板可实现光标的定位,并且支持变量。变量用于处 理模板中内容可能发生变化的那些内容。可以为变量提供一个默认值,并且默认值可 动态的产生:即通过检测当前所处环境,自动生成用户期望的值。一个变量可以成为 另一个变量的印像,即该变量追随另一个变量内容的变化。通过光标定位,可方便地 在各个变量位置切换,从而使光标只停留在模板中需要编辑的位置。

    以一个实际例子来说:若在C程序中定义一个结构体,可先输入struct(struct被 yasnippet定义为一个模板),按下TAB键后,则struct将被扩展为以下内容:

    struct Name {

    }

    同时光标停留在“Name”处。“Name”处存在一个变量,“Name”为该变量的默认值(此处仅 仅用于提示用户输入结构体名),此时可直接输入结构体名(“Name”会自动消失, 但 若直接按下TAB键,则“Name”将被保留,光标跳转至下一变量处),然后按下TAB键,则 光标跳转到结构体内的空行,此时便可进行后续的输入工作。这个例子比较简单,但较 好的表现了yasnippet模板的基本特性。利用这些特性,便可以完成非常多的任务。

    关于yasnippet的其它细节功能可以通过查看模板源文件得到了解。可以编写自己的模 板(实际中总需要如此),并且并不困难。对照已有模板及手册,几分钟便可以编写 一个自己的模板。一个比较实用的需要自己编写的模板为(针对C程序):大多数常用 函数的模板(默认仅提供printf和fopen两个函数的模板)。

    对于yasnippet,还没有发现有什么明显的不足,实际上,个人觉得这个插件实在是太 棒了,太实用了,因为它可能将是所用补全功能中最常用的功能。有了这个补全插件,默 认的模板补全可以丢掉了。

  3. gccsense插件和semantic插件——语义补全

    这两个插件均用于语义补全,该要用于编程语言中结构体或类变量的成员的补全。二 者实现的效果非常接近,因此可以任选其一。但gccsense只支持C、C++两种语言,因 此对于其它语言,只能选择semantic。这两个插件的安装、配置均不简单。gccsense 的安装比较复杂,需要安装多个程序,安装过程需要将近半个小时,但配置较简 单;semantic的安装不算简单,但配置困难,很可能发生配置完后却无法完成补全的 情况。另外,gccsense需要使用其提供的包装程序gccrec预编译一次源程序,才能获 得补全信息,semantic则可自动检测到补全信息(但经过实际使用,gccsense的预编
    译并不是必须的,不知是否是由于版本提升的原因)。

    这两个插件对于补全功能的贡献并不大,但却要耗费较多的精力去安装、配置它们, 性价比不高。此外,它们均与auto-complete插件配合使用更有威力。

  4. auto-complete插件

    auto-complete(以下简称为AC)是一个“全能”的补全插件,其可完成的补全功能涵盖 了以上所述的所有功能。当然,这些功能并不完全是由它单独完成的,而是通过调用 以上所述的三个插件:yasnippet、gccsense和semantic,作为它们的前端完成相应的 补全功能。此时这三个插件的补全方式将呈现基本相同的方式,这将给实际的补全操 作带来便利,因为所有操作都将是统一的。此外,AC还提供自己独有的补全功能,这 些包括:

    • 字典补全。即通过查字典实现单词的补全,而非仅仅查询当前缓冲区中单词。AC预 置了一些字典,主要为编程语言的关键字、大量elisp函数名。用户也可定义自己的 字典,只需将字典条目保存在 "~/.dict"文件中即可。
    • 文件目录补全。当输入字符“/”或“~/”时,AC将尝试对其进行目录补全。

    AC的运行机制是:将缓冲区、字典中所有单词、yesnippet的所有模板名以及gccsense 或semantic的所有可能补全项均作为补全对象。按上TAB键可在这些候选补全对象间切 换(同时提供两个快捷键 M-p和M-n,用于选择前一个或下一个候选对象),按下 ENTER键确认补全。补全完成后,若该补全对象为yasnippet的模板名,则进一步触发 模板的替换。对于gccsense或semantic的语义补全的处理略有不同,该补全均在输入 “.”或“->”后被触发。因此,AC无法直接在输入以上字符后触发gccsense和semantic的
    语义补全。但这可通过编写一个函数实现,即将“.”和“>”绑定到AC的相应触发函数上。 对应的代码如下:

    对于gccsense:

    (defun ac-complete-gccsense-self-insert (arg) (interactive "p") (self-insert-command arg) (ac-complete-gccsense))

    (defun my-c-mode-ac-complete-hook () (local-set-key "." 'ac-complete-gccsense-self-insert) (local-set-key ">" 'ac-complete-gccsense-self-insert))

    (add-hook 'c-mode-common-hook 'my-c-mode-ac-complete-hook)

    对于semantic:

    与gccsense基本相同,只需将第一个函数中的(ac-complete-gccsense)换为 (ac-complete-semantic)即可。

    AC非常强大,它使所有的补全功能的实现方式得到统一,同时额外提供一些实用的补 全功能。

  5. 总结

    在yasnippet、gccsense/semantic和auto-complete三大插件的辅助下,emacs将具有 非常强悍的补全能力。尽情享受吧!

抱歉!评论已关闭.