Вопрос по режиму Emacs

Я начинаю использовать Objective C, и режим Objective C работает отлично. Однако ObjC использует файлы .h, как C и C++. Мне нужно уметь пользоваться всеми тремя. Кто-нибудь знает, как заставить emacs сказать, должен ли он быть в режиме objC или в режиме C/C++?

РЕДАКТИРОВАТЬ: Кажется, есть некоторая путаница в том, что я прошу. Проблема в том, что у меня есть некоторые файлы .h, связанные с файлами .m, и некоторые файлы .h, связанные с файлами .c, и некоторые, связанные с файлами .cpp. Что я ХОЧУ, так это что-то, что я могу вставить в свой c-mode-common-hook или куда-нибудь, что проверит, является ли это объективным файлом C .h, а затем принудительно переведет его в объективный C-режим. , или что-то. Идея в том, что тогда я могу просто открыть файл .h, и он автоматически будет в правильном режиме.

Очевидно, я могу вручную изменить режим, когда я в файле, но это боль, и я часто забываю, пока не нажму вкладку и не произойдет что-то странное. Это решение, которое я использую сейчас.

Я думаю, что комментарий заголовка, вероятно, является правильным способом сделать это, но для того, чтобы он был ДЕЙСТВИТЕЛЬНО полезным, мне нужно выяснить, как заставить 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")))))

person Brian Postow    schedule 18.06.2009    source источник
comment
Я не понимаю вашего возражения? объективные файлы C .h отличаются от файлов C++ .h. Я хочу использовать правильный режим.   -  person Brian Postow    schedule 18.06.2009
comment
Вы можете использовать маркер вместо того, чтобы самостоятельно вычислять позицию возврата: (let ((m (точка-маркер))) (goto-char 0) (insert...) (goto-char (marker-position m)))   -  person Svante    schedule 19.06.2009


Ответы (3)


Вы можете поместить такой комментарий в первую строку файла:

/* -*- mode: objc -*- */

or

// -*- mode: c++ -*-

по мере необходимости. Дополнительные сведения см. в разделе Указание переменных файла. в руководстве по Emacs.

person legoscia    schedule 18.06.2009
comment
это сработает, да. Я искал НЕМНОГО меньше усилий, но я могу сделать скрипт для этого... - person Brian Postow; 18.06.2009
comment
@legoscia В моем случае это не работает, не могли бы вы подсказать, как это будет работать? - person Dinesh Kachhot; 11.06.2019
comment
@Dinesh_Kachhot Попробуйте придумать файл наименьшего размера, который воспроизводит проблему, и опубликуйте его как вопрос на emacs.stackexchange.com. . - person legoscia; 11.06.2019

Хорошо, а как насчет решения, которое не требует добавления специального комментария в файл?

Проверь это:

;; 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++, файл .h помещается в этот режим, если исходный файл является файлом в режиме objc, заголовок помещается в этот режим.

Никаких специальных переменных Emacs в комментариях не требуется.

person Trey Jackson    schedule 19.06.2009
comment
Интересный. Я должен посмотреть на это более внимательно, чтобы увидеть, как именно это работает. Очень хорошо! - person Brian Postow; 19.06.2009

Я бы использовал 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; если у вас есть эвристика для обнаружения объективных проектов c, eproject также может получить переменную таким образом.)

В любом случае, если это работает для вас, дайте мне знать, чтобы я мог добавить его в вики eproject.

person jrockway    schedule 18.06.2009
comment
Проекты ObjC часто содержат C++. Есть даже диалекты ObjC++. - person Arafangion; 28.07.2011