使用Emacs作为IDE

使用Emacs作为IDE

Using Emacs as an IDE

目前,当我用C或C ++进行编码时,我在Emacs上的工作流程涉及三个窗口。右侧最大的包含我正在使用的文件。左侧分为两部分,底部是我用来键入编译或制作命令的外壳,顶部通常是我在工作时想查阅的某种文档或自述文件。现在我知道那里有一些相当专业的Emacs用户,并且我很好奇如果打算将其用作完整的IDE,那么其他Emacs在功能上还有什么用处。具体来说,大多数IDE通常以某种形式或其他形式实现这些功能:

  • 源代码编辑器
  • 编译器
  • 调试
  • 文档查询
  • 版本控制
  • OO功能,例如类查找和对象检查器

对于其中的一些,很明显Emacs如何适合这些功能,但是其余的呢?另外,如果必须专注于特定语言,那我应该说它应该是C ++。

编辑:一位用户指出,当我说"其余的内容"时,我应该更加具体。通常,我对高效的版本控制以及文档查找感到好奇。例如,在SLIME中,对Lisp函数进行快速的超规格查找非常容易。有没有一种快速的方法可以在C ++ STL文档中查找内容(例如,如果我忘记了hash_map的确切语法)?


您必须具体说明"其余"的含义。除了对象检查器(我知道)之外,emacs非常容易完成上述所有操作:

  • 编辑器(明显)
  • 编译器-只需运行M-x compile并输入您的编译命令。从那里开始,您只需M-x compile并使用默认值。 Emacs将捕获C / C ++编译器错误(与GCC配合使用效果最好),并帮助您导航到带有警告或错误的行。
  • 调试-类似地,当您要调试时,键入M-x gdb,它将创建带有特殊绑定的gdb缓冲区
  • 文档查找-emacs具有出色的CScope绑定,可用于代码导航。对于其他文档:Emacs也有一个联机帮助阅读器,对于其他所有内容,都有网络和书籍。
  • 版本控制-各种VCS后端都有很多Emacs绑定(CVS,SCCS,RCS,SVN,GIT都可以想到)

编辑:我意识到我有关文档查找的答案确实与代码导航有关。这里是一些更重要的信息:

  • 从emacs中查找手册页,信息手册和Elisp文档
  • 从Emacs中查找Python文档。

毫无疑问,Google搜索将揭示更多示例。

如第二个链接所示,即使不支持现成的功能,也可以在其他文档中查找功能(及其他功能)。


我必须推荐Emacs代码浏览器作为emacs的"传统" IDE风格环境。

编辑:我现在也强烈建议在emacs中的标准VCS接口上使用Magit。


您是否尝试过M-x编译,而不是在shell窗口中运行make命令?它将运行您的make命令,显示错误,并且在许多情况下,如果输出包含文件名和行号,则很容易跳转到导致错误的代码行。

如果您是IDE的狂热者,则可能还需要查看emacs的speedbar软件包(M-x speedbar)。并且,如果您还没有,请学习如何使用标签表浏览代码。


一旦发现了emacs的各个角落,您就会以从未想到的方式提高工作效率。就像其他人提到的那样,使用标签是一种缩放源代码的绝佳方法,而使用M-/(dabbrev-expand)通常可以完全满足您在完成变量名时的期望。

如果要使用一个正则表达式所有出现在缓冲区中的缓冲区,则使用begin很有用。在重构代码,查找代码片段或使用变量时,或者在源文件中使用TODO标记并希望全部访问它们时,这非常方便。

刷新线,排序数字字段,replace-regexp和矩形函数对于从某些工具中进行转储并将其转换为有用数据(例如elisp程序或逗号分隔的电子表格)非常有用。

我写了一篇有关IDE的页面,例如可以使用emacs进行的操作

http://justinsboringpage.blogspot.com/2007/09/11-visual-studio-tricks-in-emacs.html

学习elisp是为自己回答emacs可以完成的另一种绝佳方法,而emacs不能完成典型的IDE可以完成的工作。

例如,我写过关于写Perforce助手功能(如怪怪)的博客(写自己的意思是可以使其表现完全如您所愿)...

http://justinsboringpage.blogspot.com/2009/01/who-changed-line-your-working-on-last.html

我还编写了可以动态地为函数创建注释的代码,该注释与我正在使用的编码标准相匹配。

我的elisp代码都不是特别出色的代码,并且大多数代码已经存在于库中,但是使emacs执行工作日内出现的自定义内容确实很有用。


您可以在我的网站上找到有关emacs和版本控制集成的详细说明。我也在撰写有关将Emacs用作多种语言的开发环境的文章-C / C ++,Java,Perl,Lisp / Scheme,Erlang等...


好的,这里的每个人都给出了使emacs成为出色的IDE的完美提示。

但是任何人都应该记住,当您自定义具有大量扩展名的emacs(尤其是用于动态类型检查,功能定义查找等)时,您的emacs对于编辑器的加载将非常非常缓慢。

要解决此问题,我强烈建议在server mode中使用emacs。

它非常简单易用,无需自定义您的init文件。
您只需要在守护程序模式下启动emacs即可;

1
emacs --daemon

这将创建一个emacs服务器,然后您可以从终端或gui连接它。我还建议创建一些别名以使其易于调用。

1
2
3
4
alias ec="emacsclient -t"
alias ecc="emacsclient -c &"
# some people also prefer this but no need to fight here;
alias vi="emacsclient -t"

这样,emacs的启动速度将比gedit更快。

这里一个可能的问题是,如果您是由临时用户运行emacs守护程序,则可能无法将emacs服务器作为root连接。

因此,如果您需要打开一个具有root用户访问权限的文件;使用tramp代替。只需以普通用户身份运行emacs客户端并打开文件即可;

1
2
3
C-x C-f
/sudo:root@localhost/some/file/that/has/root/access/permissions
# on some linux distro it might be `/su:root@...`

这使我的生活更加轻松,我可以通过这种方式在几毫秒内打开大量定制的python IDE。您可能还希望将emacs --daemon添加到系统启动中,或为emacsclient创建桌面文件。随你(由你决定。

有关emacs守护程序和emacs客户端的更多信息,请参见wiki;

http://www.emacswiki.org/emacs/EmacsAsDaemon

http://www.emacswiki.org/emacs/EmacsClient


对于版本控制,您可以使用几项内容,具体取决于您使用的版本控制系统。但是其中一些功能是所有用户共有的。

vc.el是在文件级别处理版本控制的内置方法。它具有大多数版本控制系统的后端。例如,Subversion后端随Emacs一起提供,还有git后端和其他可从其他来源获得的后端。

最有用的命令是C-x v v(vc-next-action),它对要访问的文件执行适当的下一步操作。这可能意味着从存储库进行更新或提交更改,如果使用的系统(例如RCS),vc.el还会重新绑定C-x C-q以检入和检出文件。

其他非常有用的命令是C-x v l和C-x v =,它们向您显示正在使用的文件的日志和当前差异。

但是,为了提高工作效率,除了简单起见,您应该避免使用单文件vc.el命令。有几个软件包可以概述整个树的状态,并为您提供更多功能,更不用说能够创建跨越多个文件的一致提交的功能。

其中大多数受到严重影响,或基于CVS的原始pcl-cvs / pcvs。甚至有两个附带的子版本psvn.el和dsvn.el。有用于git等的软件包。


我同意您应该了解M-x编译(将其与M-x next-error绑定到短键序列)。

了解有关版本控制的绑定(例如vc-diff,vc-next-action等)

查看寄存器。您不仅可以记住缓冲区中的位置,还可以记住整个窗口配置(C-x r w-窗口配置到注册)。


M-x vc-next-action是探索Emacs VC功能的起点(可能并不明显)。

根据文件的状态和VC后端,它对当前文件执行"下一个逻辑版本控制操作"。因此,如果文件不受版本控制,它将对其进行注册;如果文件已更改,则提交更改等。

这需要一点时间来适应,但是我发现它非常有用。

默认的键盘绑定是C-x v v


有一个用于emacs集成到Microsoft TFS中的TFS.el。它适用于任何TFS,包括运行Codeplex.com的TFS。

设置的基本步骤:

  • 将tfs.el放在您的加载路径中。

  • 在您的.emacs文件中:

    1
    2
    3
    4
    5
    (require 'tfs)
    (setq tfs/tf-exe "c:\\vs2008\\common7\\ide\\tf.exe")
    (setq tfs/login"/login:domain\\userid,password")
          -or-
    (setq tfs/login (getenv"TFSLOGIN"))  ;; if you have this set
  • 还要在.emacs文件中,为tfs命令设置本地或全局键绑定。像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    (global-set-key "\C-xvo" 'tfs/checkout)
    (global-set-key "\C-xvi" 'tfs/checkin)
    (global-set-key "\C-xvp" 'tfs/properties)
    (global-set-key "\C-xvr" 'tfs/rename)
    (global-set-key "\C-xvg" 'tfs/get)
    (global-set-key "\C-xvh" 'tfs/history)
    (global-set-key "\C-xvu" 'tfs/undo)
    (global-set-key "\C-xvd" 'tfs/diff)
    (global-set-key "\C-xv-" 'tfs/delete)
    (global-set-key "\C-xv+" 'tfs/add)
    (global-set-key "\C-xvs" 'tfs/status)
    (global-set-key "\C-xva" 'tfs/annotate)
    (global-set-key "\C-xvw" 'tfs/workitem)

  • 您可能还会发现标签栏很有用。它模拟了我从Eclipse迁移到Emacs时遗漏的唯一行为。绑定到","和"。"要移至上一个和下一个选项卡栏,它使您无需一直按Ctrl-x b切换缓冲区。

    不幸的是,提到的网页没有提供正确的版本供下载。但是,大多数Ubuntu版本都是通过emacs-goodies软件包提供它的。


    我在Windows上使用emacs。编译模块很好,但是我希望编译对它建议的编译命令行更加智能。可以使用"文件变量"来指定compile-command,但是我想要比这更聪明的东西。所以我写了一个小函数来帮忙。运行compile时,它将猜测要使用的compile命令来提示用户。

    猜测函数查找vbproj或csproj或sln文件,如果找到,则建议使用msbuild。然后,它查看缓冲区文件名,并根据该文件名提出不同的建议。 .wxs文件表示它是WIX项目,您可能想要构建MSI,因此猜测逻辑建议为MSI使用nmake命令。如果是Javascript模块,则建议运行jslint-for-wsh.js来整理.js文件。作为后备,它建议使用nmake。

    我使用的代码如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    (defun cheeso-guess-compile-command ()
     "set `compile-command' intelligently depending on the
    current buffer, or the contents of the current directory."
      (interactive)
      (set (make-local-variable 'compile-command)
           (cond
            ((or (file-expand-wildcards"*.csproj" t)
                 (file-expand-wildcards"*.vcproj" t)
                 (file-expand-wildcards"*.vbproj" t)
                 (file-expand-wildcards"*.shfbproj" t)
                 (file-expand-wildcards"*.sln" t))
            "msbuild")

            ;; sometimes, not sure why, the buffer-file-name is
            ;; not set.  Can use it only if set.
            (buffer-file-name
             (let ((filename (file-name-nondirectory buffer-file-name)))
               (cond

                ;; editing a .wxs (WIX Soluition) file
                ((string-equal (substring buffer-file-name -4)".wxs")
                 (concat"nmake"
                         ;; (substring buffer-file-name 0 -4) ;; includes full path
                         (file-name-sans-extension filename)
                        ".msi" ))

                ;; a javascript file - run jslint
                ((string-equal (substring buffer-file-name -3)".js")
                 (concat (getenv"windir")
                        "\\system32\\cscript.exe c:\\users\\cheeso\\bin\\jslint-for-wsh.js"
                         filename))

                ;; something else - do a typical .exe build
                (t
                 (concat"nmake"
                         (file-name-sans-extension filename)
                        ".exe")))))
            (t
            "nmake"))))


    (defun cheeso-invoke-compile-interactively ()
     "fn to wrap the `compile' function.  This simply
    checks to see if `compile-command' has been previously set, and
    if not, invokes `cheeso-guess-compile-command' to set the value.
    Then it invokes the `compile' function, interactively."
      (interactive)
      (cond
       ((not (boundp 'cheeso-local-compile-command-has-been-set))
        (cheeso-guess-compile-command)
        (set (make-local-variable 'cheeso-local-compile-command-has-been-set) t)))
      ;; local compile command has now been set
      (call-interactively 'compile))

    ;; in lieu of binding to `compile', bind to my monkeypatched function
    (global-set-key"\C-x\C-e"  'cheeso-invoke-compile-interactively)

    我尝试将其作为"建议之前"的编译功能,但无法令人满意地工作。因此,我定义了一个新函数并将其绑定到与compile相同的击键组合。

    EDIT there is now"smarter-compile.el" which takes this idea one step further.


    编译,下一个错误和上一个错误都是Emacs中C ++开发的非常重要的命令(在grep输出上也很有效)。 Etag,访问标签表和查找标签也很重要。 complete.el是20世纪最伟大的无名黑客之一,可以将您的C ++黑客速度提高一个数量级。哦,别忘了ediff。

    我还没有学习如何在不访问shell的情况下使用版本控制,但是现在我运行git的频率越来越高,我可能不得不这样做。


    我知道这是很老的帖子。但是这个问题对emacs初学者是有效的。

    IMO将emacs用作ide的最佳方法是在emacs中使用语言服务器协议。您可以在链接的网站中找到有关语言服务器的所有信息。

    为了快速设置,我建议您转到此页面eglot。 IMO eglot做得很好。它与公司等自动完成程序包很好地集成在一起。提供查找参考,以及更多。

    同样对于调试器,您可能需要用于特定语言的特定调试器。您可以在emacs中使用gdb。只需键入M-x gdb

    为了编译代码,最好使用shell命令。我正在从事eproj项目。需要一段时间才能完成。但是它所做的只是将shell命令映射到项目类型。并通过外壳构建项目。执行命令的方法相同。我可能需要帮助来完成这个项目。它尚未准备好使用,但是如果您了解一些elisp,则可以遍历代码。

    除此之外,始终最好使用emacs compile命令。

    对于版本控制,我还没有看到其他任何可以匹配magit功能的软件包。它特定于git。另外对于git还有另一个软件包git-timemachine,我觉得它非常有用。

    语言服务器协议提供了对象查找和类查找。

    项目树可用于与treemacs的IDE之类的接口。

    还有一个名为Projectile的项目交互库。

    对于自动完成,我发现公司模式非常有用。

    真正的emacs可以做任何事情。


    关于文档查找:这取决于您的编程语言。

    C库和系统调用通常记录在手册页中。为此,您可以使用M-x man。在信息页面上可能会更好地记录一些事情;使用M-x info

    对于elisp本身,请使用C-h f。对于python,在解释器中使用>>> help()

    我发现大多数其他语言都以html形式提供文档。为此,请尝试使用嵌入式浏览器(我使用w3m)。将BROWSER环境变量设置为emacsclient -e"(w3m-goto-url-new-session \"$@\")"周围的包装器脚本(在* nix上),以防可能打开浏览器并且您希望在emacs中打开它。


    近年来,Clang成为Emacs C ++支持的重要组成部分。 Atila Neves在CppCon 2015上发表了演讲:
    " Emacs作为C ++ IDE"

    这是一个16分钟的演讲,他将展示以下主题的解决方案:

    • 跳转到定义
    • 自动补全
    • 动态语法高亮显示
    • 在项目中查找文件

    幻灯片可以在这里找到。


    在Unix或X Windows风格中,我不知道有一个集成的IDE可以适用于所有情况。

    为了与调试器进行交互(仅是IDE的一个组件),请考虑使用realgud。我发现有用的另一件事是位置消息的解析器,因此,如果您具有调用堆栈跟踪,并且想要在调用堆栈中的特定位置进行编辑,则此前端接口可以做到这一点。

    到目前为止,该程序可以使用改进。但是随后,它也可能需要人们对其进行改进。

    免责声明:我从事realgud


    推荐阅读