Emacs模式问题

8
我开始使用objective C,而且objective C模式运行得非常好。然而,ObjC使用.h文件,就像C和C++一样。我需要能够同时使用所有三种语言。有人知道如何让Emacs区分是应该使用objC模式还是C/C++模式吗?
编辑:似乎有些人对我的问题存在一些误解。问题在于我有一些与.m文件相关联的.h文件,还有一些与.c文件和.cpp文件相关联的.h文件。我想要的是一个能够放在c-mode-common-hook里面或其他地方的东西,它可以检查是否是objective C .h文件,然后强制它进入objective C模式或其他模式。这样,我只需要打开一个.h文件,它就会自动处于正确的模式。
显然,当我在文件中时,我可以手动更改模式,但那很麻烦,而且我经常忘记,直到按下tab键出现奇怪的事情。这是我目前正在使用的解决方案。
我认为头部注释可能是正确的解决方法,但为了使其真正有用,我需要找出如何让XCode在为我创建文件时将注释放在那里...
编辑2:
我目前正在使用头部注释解决方案。在我能够找出如何让XCode自动添加注释之前,我使用以下elisp函数:
(defun bp-add-objC-comment ()
  "Adds the /* -*- mode: objc -*- */ line at the top of the file"
  (interactive)
  (objc-mode)
  (let((p (point)))
    (goto-char 0)
    (insert "/* -*- mode: objc -*- */\n")
    (goto-char (+ p  (length "/* -*- mode: objc -*- */\n")))))

1
我不明白你的反对意见?Objective-C的.h文件与C++的.h文件是不同的。我想使用正确的模式。 - Brian Postow
你可以使用标记代替手动计算返回位置:(let ((m (point-marker))) (goto-char 0) (insert "...") (goto-char (marker-position m))) - Svante
3个回答

15

你可以在文件的第一行加入类似以下的注释:

/* -*- mode: objc -*- */
或者
// -*- mode: c++ -*-

根据需要。有关更多详细信息,请参见Emacs手册中的指定文件变量


可以,那样可以工作。我本来想要更少的努力,但我可以编写一个脚本来完成这个任务... - Brian Postow
@legoscia,这在我的情况下不起作用,你能建议一下如何让它工作吗? - Dinesh Kachhot
@Dinesh_Kachhot 请尝试提供最小的可重现问题文件,并在https://emacs.stackexchange.com/上发布问题。 - legoscia

6
好的,那么有没有不需要在文件中添加特殊注释的解决方案呢?
看看这个:
;; need find-file to do this
(require 'find-file)
;; find-file doesn't grok objc files for some reason, add that
(push ".m" (cadr (assoc "\\.h\\'" cc-other-file-alist)))

(defun my-find-proper-mode ()
  (interactive)
  ;; only run on .h files
  (when (string-match "\\.h\\'" (buffer-file-name))
    (save-window-excursion
      (save-excursion
        (let* ((alist (append auto-mode-alist nil))  ;; use whatever auto-mode-alist has
               (ff-ignore-include t)                 ;; operate on buffer name only
               (src (ff-other-file-name))            ;; find the src file corresponding to .h
               re mode)
          ;; go through the association list
          ;; and find the mode associated with the source file
          ;; that is the mode we want to use for the .h file
          (while (and alist
                      (setq mode (cdar alist))
                      (setq re (caar alist))
                      (not (string-match re src)))
            (setq alist (cdr alist)))
          (when mode (funcall mode)))))))

(add-hook 'find-file-hook 'my-find-proper-mode)

这使用Emacs内置的包来查找相应的.h/.cc文件。因此,如果您刚打开的头文件对应于c++-mode中的文件,则.h文件将放在该模式中,如果源是objc-mode文件,则头文件将放在该模式中。

注释中不需要特殊的Emacs变量。


有趣。我得更仔细地看看它是如何工作的。非常好! - Brian Postow

1

我会使用eproject来帮助我处理这个问题。假设我不会在同一个项目中混合使用不同的语言,我可以在项目根目录下创建一个.eproject文件,其中包含以下文本:

:cc-header-type :objc

然后,我会为.h文件设置某种默认模式:

(add-to-list 'auto-mode-alist '("[.]h$" . c-mode))

然后,为该模式添加一个钩子:

(add-hook 'c-mode-hook (lambda ()
    (let ((header-style (eproject-attribute :cc-header-type)))
        (when (and header-style
                   (string-match "[.]h$" (buffer-file-name)))
            (case header-style
                (:objc (objc-mode))
                (:c++  (c++-mode))
                (:c    (c-mode))))))

现在,模式将根据您在.eproject文件中进行的设置自动更改。(请注意,.eproject文件不是为eproject设置变量的唯一方法;如果您有一种启发式方法来检测Objective C项目,则eproject也可以通过该方式获取变量。)

无论如何,如果这对您有用,请告诉我,以便我可以将其添加到eproject wiki中。


ObjC项目经常包含C++。甚至有ObjC ++方言。 - Arafangion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接