使用 Emacs 作为 IDE

目前,当我用 C 或 C + + 编写代码时,我使用 Emacs 的工作流程涉及三个窗口。右边最大的包含我正在处理的文件。左边分为两个,底部是一个 shell,我用它来输入编译或者 make 命令,顶部通常是一些文档或者 README 文件,我在工作的时候可以查阅它们。现在我知道有一些相当专业的 Emacs 用户,我很好奇其他 Emacs 在功能上是否有用,如果目的是将其作为一个完整的 IDE 使用的话。具体来说,大多数 IDE 通常以某种形式实现这些功能:

  • 源代码编辑器
  • 编译器
  • 正在调试
  • 文档查找
  • 版本控制
  • OO 特性,如类查找和对象检查器

对于其中的一些函数来说,Emacs 如何适应这些函数显而易见,但是其余的函数呢?另外,如果必须关注某种特定的语言,我会说它应该是 C + + 。

编辑: 一位用户指出,当我说“剩下的怎么办”时,我应该说得更具体一些。我主要对高效的版本控制和文档查找感到好奇。例如,在 SLIME 中,对 Lisp 函数执行快速的 hyperspec 查找是相当容易的。有没有一种快速的方法来查找 C + + STL 文档中的内容(例如,如果我忘记了 Hash _ map的确切语法) ?

79094 次浏览

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

如果您是 IDE 的粉丝,您可能还想查看 emacs 的速度条包(M-x Speedbar)。并且,如果您还没有学习过,请了解如何使用标记表来导航代码。

你必须具体说明“其他”是什么意思。除了对象检查器(我知道) ,emacs 很容易做到以上所有工作:

  • 编辑(显而易见)
  • 编译器-只需运行 M-x compile并输入您的编译命令。从这里开始,您可以只使用 M-x compile并使用默认值。Emacs 将捕获 C/C + + 编译器错误(最适用于 GCC) ,并帮助您导航到带有警告或错误的行。
  • 调试——类似地,当您想要调试时,键入 M-x gdb,它将创建一个带有特殊绑定的 gdb 缓冲区
  • 文档查找 -emacs 具有用于代码导航的优秀 CScope 绑定。对于其他文档: Emacs 还有一个 manpage 阅读器,对于其他所有东西,还有网页和书籍。
  • 版本控制——对于各种 VCS 后端(CVS、 SCCS、 RCS、 SVN、 GIT 都可以想到) ,有很多 Emacs 绑定

编辑: 我意识到我关于文档查找的答案实际上与代码导航有关:

谷歌搜索无疑会揭示更多的例子。

如第二个链接所示,即使不支持开箱即用,也可以在其他文档中查找函数(或其他任何东西)。

我同意您应该学习 M-x 编译(将它和 M-x next-error 绑定到一个简短的键序列)。

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

查查登记簿。您不仅可以记住缓冲区中的位置,还可以记住整个窗口配置(C-x r w —— window-configuration-to-register)。

我必须推荐 Emacs 代码浏览器作为 emacs 的一个更“传统”的 IDE 样式环境。

EDIT : 我现在也高度推荐 马吉特,而不是 emacs 中的标准 VCS 接口。

在 Emacs 中,编译、下一个错误和前一个错误都是 C + + 开发中非常重要的命令(对 grep 输出也很有用)。标签、访问标签表和查找标签也很重要。El 是20世纪最伟大的无名黑客之一,它可以通过一个数量级加速你的 c + + 黑客攻击。别忘了还有艾迪夫。

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

探索 Emacs 的 VC 特性的一个起点(可能不太明显)是 M-x vc-next-action

它对当前文件执行“下一个逻辑版本控制操作”,具体取决于文件的状态和 VC 后端。因此,如果文件不受版本控制,它注册它,如果文件已经更改,更改被提交等。

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

默认的密钥绑定是 C-x v

对于版本控制,根据所使用的版本控制系统,可以使用几种方法。但其中一些功能对所有这些工具都是共同的。

Vc.el 是在文件级别处理版本控制的内置方法。它具有大多数版本控制系统的后端。例如,Subversion 后端附带了 Emacs,还有 git 后端和其他来源的后端。

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

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

但是为了实现真正的生产效率,除了简单的事情之外,您应该避免使用单文件 vc.el 命令。有几个包可以让您对整个树的状态有一个概述,并提供更多的功能,更不用说创建跨多个文件的连贯提交的能力了。

其中大多数受到严重影响或基于 CVS 的原始 Pcl-cvs/PCVs。甚至还有两个是颠覆性的,Psvn.elDsvn.el。有一些用于 git 等的软件包。

你可以在 我的网站上找到 emacs 和版本控制集成的详细描述。我还在写一篇关于使用 Emacs 作为许多语言的开发环境的文章—— C/C + + 、 Java、 Perl、 Lisp/Scheme、 Erlang 等等。.

一旦发现 Emacs 的某些角落,它们会以你从未想过的方式让你更有效率。正如其他人已经提到的,使用标记是一种奇妙而快速的方式来放大您的源代码,并且使用 M-/(dabbrev 扩展)通常可以完成您所期望的变量名。

对于在缓冲区中获取包含正则表达式的所有匹配项的缓冲区来说,使用 comes 非常有用。这对于重构代码和查找代码片段或变量的使用,或者如果您在源文件中使用 TODO 标记并希望访问它们,都非常方便。

对于从某些工具获取转储并将其转换为有用的数据(例如省略号程序或逗号分隔的电子表格)来说,刷新行、 sort-numeric-fields、 place-regexp 和矩形函数非常有用。

我写了一个关于 IDE 的页面,就像你可以用 emacs 做的事情一样

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

学习省略号是另一个很好的方法,可以帮助您回答除了典型 IDE 之外,emacs 还能做些什么。

例如,我曾经写过一篇关于写 Perforce helper 函数的博文,比如  举(写自己的函数意味着你可以让它按照你想要的方式运行) ..。

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

我还编写了一些代码,动态地为某个函数创建注释,这些注释与我正在使用的编码标准相匹配。

我的省略号都不是特别好,而且大部分已经存在于库中,但是让 emacs 做一些工作日才出现的自定义工作是非常有用的。

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

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

对于 elisp 本身,使用 C-h f.python,在解释器中使用 >>> help(<function, class, module>)

我发现大多数其他语言都提供 html 格式的文档。为此,尝试使用嵌入式浏览器(我使用 w3m)。将你的环境变量设置为围绕 emacsclient -e "(w3m-goto-url-new-session \"$@\")"的包装脚本(on * nix) ,以防有什么东西可能打开浏览器,你想在 emacs 中打开它。

您可能还会发现 Tabbar很有用。它模拟了从 Eclipse 迁移到 Emacs 时遗漏的唯一行为。绑定到“ ,”和“为了移动到前一个和下一个选项卡栏,它使您不必一直通过 Ctrl-xb 切换缓冲区。

遗憾的是,上面提到的网页没有提供正确的下载版本。然而,大多数 Ubuntu 版本都是在他们的 emacs-goodies 包中发布的。

有一个 用于将 emacs 集成到 Microsoft TFS 的 TFS.el,它可以与任何 TFS 一起工作,包括运行 Codebx.com 的 TFS。

设置的基本步骤:

  1. 将 tfs.el 放在加载路径中。

  2. 在.emacs 文件中:

    (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
    
  3. also in your .emacs file, set local or global key bindings for tfs commands. like so:

    (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)
    

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

Guess 函数查找 vbproj、 csproj 或 sln 文件,如果找到,它建议使用 msbuild。然后它查看缓冲区文件名,根据这一点,提出了不同的建议。A.Wxs 文件意味着它是一个 WIX 项目,您可能希望构建一个 MSI,因此猜测逻辑建议为 MSI 使用 nmake 命令。如果它是一个 Javascript 模块,那么建议运行 jslint-for-wsh。Js 的线头。Js 文件。作为备用方案,它建议使用 nmake。

我使用的代码如下:

(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相同的击键组合。


现在有了“ 更聪明-编译 El”,使这个想法更进一步。

好了,这里的每个人都在给出完美的提示,让 emacs 成为一个伟大的 IDE。

但是任何人都应该记住,当你用大量的扩展定制你的 emacs 时(特别是那些用于动态类型检查,函数定义查找等等的扩展) ,你的 emacs 对于编辑器来说加载会非常非常慢。

为了解决这个问题,我强烈建议在 server mode中使用 emacs。

它使用起来非常简单,不需要自定义初始化文件。 您只需要在守护进程模式下启动 emacs;

emacs --daemon

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

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 客户端与您的普通用户和打开文件,像这样;

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

这使我的生活变得更加容易,我可以用这种方式在毫秒内打开我重量级的定制 pythonIDE。您可能还希望在系统启动时添加 emacs —— daemon,或者为 emacsclient 创建一个桌面文件。这取决于你。

更多关于 emacs 守护进程和 emacs 客户端可以在 wiki 找到;

Http://www.emacswiki.org/emacs/emacsasdaemon

Http://www.emacswiki.org/emacs/emacsclient

近年来,Clang 成为 Emacs C + + 支持的重要组成部分。阿提拉•内维斯(Atila Neves)在2015年 CppCon 上发表了讲话: “作为 C + + IDE 的 Emacs”

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

  • 直奔主题
  • 自动完成
  • 飞行语法突显
  • 在项目中查找文件

幻灯片可以找到 给你

在 Unix 或 X 窗口风格中,我不知道是否有一个集成的 IDE 可以满足所有需求。

对于与调试器(IDE 的一个组件)交互,请考虑 Realgud。我发现它的另一个有用之处是用于位置消息的解析器,这样,如果您有一个调用堆栈跟踪并希望在调用堆栈中的特定位置进行编辑,这个前端接口就可以做到这一点。

到目前为止,这个程序可以使用改进。但然后,它也可以利用人们的工作来改进它。

免责声明: 我在 Realgud 工作

我知道这是一个非常老的帖子。但这个问题是有效的 Emacs 初学者。

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

对于一个快速设置,我会敦促你去这个页面 红葡萄酒。我的天哪,红酒真的很不错。它集成了很好的汽车完成包像公司。提供查找引用等。

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

对于编译代码,最好使用 shell 命令。我在这个项目 Eproj工作。完成它需要一段时间。但它所做的只是将 shell 命令映射到项目类型。并通过 shell 构建您的项目。它对执行命令执行相同的操作。我可能需要帮助来完成这个项目。它还没有准备好使用,但是如果您知道一点省略号,就可以查看代码。

除此之外,最好还是使用 emacs 编译命令。

对于版本控制,我还没有看到任何其他软件包可以匹配的力量 Magit。这是针对 Git 的。对于 git,还有另一个包 git-timemachine,我发现它非常有用。

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

项目树可以用于与 Treemacs类似的接口。

还有一个名为 抛射物的项目交互库。

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

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

尝试 lsp-mode。现在您可以在 emacs 中使用其他 IDE 功能连接到服务器。查找更多信息: Lsp 模式