如何告诉 emacs 在 C++ 模式下打开 .h 文件?

Posted

技术标签:

【中文标题】如何告诉 emacs 在 C++ 模式下打开 .h 文件?【英文标题】:How to tell emacs to open .h file in C++ mode? 【发布时间】:2011-03-19 17:36:29 【问题描述】:

我应该在我的 _emacs(在 Windows 上)文件中添加哪些行以使其以 C++ 模式打开 .h 文件?默认为C模式。

【问题讨论】:

【参考方案1】:

试试这个:

(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

每当您打开 .h 文件时,都会使用 C++ 模式。

【讨论】:

这给了我错误“符号作为变量的值是无效的:\.h\”【参考方案2】:

我可以发誓我已经看到这个问题得到了适当的回答?很奇怪。

你想要这个:

(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

【讨论】:

你做了……作者删了。【参考方案3】:

如果您不希望这适用于每个 .h 文件,您可以将以下内容添加到 C++ 头文件的底部。

// Local Variables:
// mode: c++
// End:

这将适用于您要基于每个文件设置的任何 Emacs 变量。 Emacs 会忽略前导字符,因此请使用适合文件类型的任何注释字符。

【讨论】:

谢谢,没有意识到你可以用 emacs 做到这一点。 不知道在任何文件中都有效。这可能非常有用。谢谢:)【参考方案4】:

由于我经常同时使用 C 和 C++,所以我编写了这个函数来尝试“猜测”一个 .h 文件是 C 还是 C++

;; function decides whether .h file is C or C++ header, sets C++ by
;; default because there's more chance of there being a .h without a
;; .cc than a .h without a .c (ie. for C++ template files)
(defun c-c++-header ()
  "sets either c-mode or c++-mode, whichever is appropriate for
header"
  (interactive)
  (let ((c-file (concat (substring (buffer-file-name) 0 -1) "c")))
    (if (file-exists-p c-file)
        (c-mode)
      (c++-mode))))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c-c++-header))

如果这不起作用,我设置一个在 C 和 C++ 模式之间切换的键

;; and if that doesn't work, a function to toggle between c-mode and
;; c++-mode
(defun c-c++-toggle ()
  "toggles between c-mode and c++-mode"
  (interactive)
  (cond ((string= major-mode "c-mode")
         (c++-mode))
        ((string= major-mode "c++-mode")
         (c-mode))))

这并不完美,可能有更好的启发式方法来确定标头是 C 还是 C++,但它对我有用。

【讨论】:

更好的解决方案可能是对文件中的模式进行编码(请参阅我的答案),然后定义键以将适当的行添加到文件中。唯一的缺点是不使用 emacs 的人也会看到这一点,但由于它位于文件的底部,因此应该不是什么大问题。 这对你自己的项目来说很好,但我的解决方案主要是处理其他人的项目。您可以 cat 将您的局部变量放在第 3 方项目的标题末尾,但 IMO 的工作量太大了。 我实际上非常喜欢这个解决方案,它可以轻松自定义行为而无需修改任何源文件。例如,在我的版本中,我使用 (string-match "llvm" (buffer-file-name)) 之类的东西来确定 .h 文件是否为 c++(llvm 是 c++ 项目)。 我迟到了 7 年,但我认为确定 .h 是否在 c++ 中的更好方法是扫描缓冲区中的类、命名空间、公共、私有等字词。还有避免将 C 标头标记为 c++ 只是因为它们碰巧有一个名为 class 的变量等,您可以检查这些单词是否位于行首(在 c 缩进之后)。【参考方案5】:

另一种同时使用 c-mode 和 c++-mode 的方法是使用directory local variables 来设置模式。

在设置模式后评估目录变量1,因此您实际上可以为您的 C++ 项目编写一个 .dir-locals.el 文件,其中包含以下内容:

((c-mode . ((mode . c++))))

Emacs 将模式更改为 c++-mode,只要它最初将其设置为 c-mode

如果您同时使用 C 和 C++ 项目,这对于每个项目来说都是一个非常简单的解决方案。

当然,如果您的大部分项目都是 C++,您可以将 c++-mode 设置为默认值2,然后您可以反过来使用此方法在适当的情况下切换到 c-mode .


1normal-mode 按此顺序调用(set-auto-mode)(hack-local-variables)。另见:How can I access directory-local variables in my major mode hooks?

2 为此,添加

(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

到您的 .emacs 文件,默认情况下以 C++ 模式打开 .h 文件。

【讨论】:

这是最有用的答案。另外,请注意mode 是文件局部变量列表中的一种特殊形式,仅记录在here 中。 我已添加脚注 (2),因此您的答案是自给自足的,不依赖于其他人。现在,它应该是公认的答案。谢谢。 此解决方案导致 c++-mode 也可用于 .glsl 文件。有什么办法可以强制使用 glsl-mode 吗? (add-to-list 'auto-mode-alist '("\\.glsl\\'" . glsl-mode)) ? 这个解决方案很棒!但是,以这种方式加载的头文件应用通过(c++-mode . 设置的目录本地值(至少在Emacs 25 中),因此您必须通过(nil . 应用这些值。跨度> 【参考方案6】:

显然你也可以把它放在文件的顶部:

// -*-c++-*-

告诉 Emacs 这是一个 C++ 文件。

我之所以使用它,是因为我经常使用普通的 Emacs,它无需以任何方式配置 Emacs 即可工作。

【讨论】:

或也为:// -*- mode: c++ -*-。您还可以在其中添加其他变量,例如-*- coding: utf-8; mode: python; tab-width: 4; -*-

以上是关于如何告诉 emacs 在 C++ 模式下打开 .h 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 emacs 中创建一个空文件?

如何阻止 emacs dired 模式打开这么多缓冲区?

如何在 java 模式下配置 emacs,使其不会自动对齐方法参数

Git 将 Emacs 减慢到死亡 - 如何解决这个问题?

如何在 emacs - haskell 模式下运行 haskell 应用程序?

.emacs 编辑以始终在终端模式下启动 Emacs?