Подтвердить что ты не робот

С++ 11 режим или настройки для emacs?

Я запускаю Emacs 23.3.1 (Ubuntu, Oneiric package) и emacs, похоже, не понимает никаких новых ключевых слов С++ 11, constexpr, thread_local и т.д. Также он не понимает, что ' → 'теперь разрешено в параметрах шаблона или в новом синтаксисе "enum class". Есть ли обновленный или альтернативный модуль где-нибудь? Или, если это не так, некоторые настройки, чтобы сделать emacs более дружественным С++ 11 в среднем?

4b9b3361

Ответ 1

Я проверил версию trunk, cc-mode еще не обновлен, и AFAIK нет альтернативы. Если вы действительно этого хотите, но не хотите, чтобы ваши руки были грязными, вы должны заплатить кому-то, чтобы реализовать его для вас...

Ответ 2

Ну, я использую 24.1. Некоторые ключевые слова С++ 98 отсутствуют, и все новые ключевые слова С++ 11. Он даже не индексирует числовые константы. Кажется, что С++ - режим не обновлялся в течение десятилетия.

Я использую следующий код в течение длительного времени и недавно добавил ключевые слова С++ 11. Попробуйте поместить его в свои .emacs; он должен заполнить некоторые отверстия.

(require 'font-lock)

(defun --copy-face (new-face face)
  "Define NEW-FACE from existing FACE."
  (copy-face face new-face)
  (eval `(defvar ,new-face nil))
  (set new-face new-face))

(--copy-face 'font-lock-label-face  ; labels, case, public, private, proteced, namespace-tags
         'font-lock-keyword-face)
(--copy-face 'font-lock-doc-markup-face ; comment markups such as Javadoc-tags
         'font-lock-doc-face)
(--copy-face 'font-lock-doc-string-face ; comment markups
         'font-lock-comment-face)

(global-font-lock-mode t)
(setq font-lock-maximum-decoration t)


(add-hook 'c++-mode-hook
      '(lambda()
        (font-lock-add-keywords
         nil '(;; complete some fundamental keywords
           ("\\<\\(void\\|unsigned\\|signed\\|char\\|short\\|bool\\|int\\|long\\|float\\|double\\)\\>" . font-lock-keyword-face)
           ;; add the new C++11 keywords
           ("\\<\\(alignof\\|alignas\\|constexpr\\|decltype\\|noexcept\\|nullptr\\|static_assert\\|thread_local\\|override\\|final\\)\\>" . font-lock-keyword-face)
           ("\\<\\(char[0-9]+_t\\)\\>" . font-lock-keyword-face)
           ;; PREPROCESSOR_CONSTANT
           ("\\<[A-Z]+[A-Z_]+\\>" . font-lock-constant-face)
           ;; hexadecimal numbers
           ("\\<0[xX][0-9A-Fa-f]+\\>" . font-lock-constant-face)
           ;; integer/float/scientific numbers
           ("\\<[\\-+]*[0-9]*\\.?[0-9]+\\([ulUL]+\\|[eE][\\-+]?[0-9]+\\)?\\>" . font-lock-constant-face)
           ;; user-types (customize!)
           ("\\<[A-Za-z_]+[A-Za-z_0-9]*_\\(t\\|type\\|ptr\\)\\>" . font-lock-type-face)
           ("\\<\\(xstring\\|xchar\\)\\>" . font-lock-type-face)
           ))
        ) t)

Надеюсь, это поможет.

Ответ 3

По просьбе Майка Уэллера здесь представлена ​​обновленная версия для строк С++ 11 строк (включая пользовательские литералы).

(add-hook
 'c++-mode-hook
 '(lambda()
    ;; We could place some regexes into `c-mode-common-hook', but note that their evaluation order
    ;; matters.
    (font-lock-add-keywords
     nil '(;; complete some fundamental keywords
           ("\\<\\(void\\|unsigned\\|signed\\|char\\|short\\|bool\\|int\\|long\\|float\\|double\\)\\>" . font-lock-keyword-face)
           ;; namespace names and tags - these are rendered as constants by cc-mode
           ("\\<\\(\\w+::\\)" . font-lock-function-name-face)
           ;;  new C++11 keywords
           ("\\<\\(alignof\\|alignas\\|constexpr\\|decltype\\|noexcept\\|nullptr\\|static_assert\\|thread_local\\|override\\|final\\)\\>" . font-lock-keyword-face)
           ("\\<\\(char16_t\\|char32_t\\)\\>" . font-lock-keyword-face)
           ;; PREPROCESSOR_CONSTANT, PREPROCESSORCONSTANT
           ("\\<[A-Z]*_[A-Z_]+\\>" . font-lock-constant-face)
           ("\\<[A-Z]\\{3,\\}\\>"  . font-lock-constant-face)
           ;; hexadecimal numbers
           ("\\<0[xX][0-9A-Fa-f]+\\>" . font-lock-constant-face)
           ;; integer/float/scientific numbers
           ("\\<[\\-+]*[0-9]*\\.?[0-9]+\\([ulUL]+\\|[eE][\\-+]?[0-9]+\\)?\\>" . font-lock-constant-face)
           ;; c++11 string literals
           ;;       L"wide string"
           ;;       L"wide string with UNICODE codepoint: \u2018"
           ;;       u8"UTF-8 string", u"UTF-16 string", U"UTF-32 string"
           ("\\<\\([LuU8]+\\)\".*?\"" 1 font-lock-keyword-face)
           ;;       R"(user-defined literal)"
           ;;       R"( a "quot'd" string )"
           ;;       R"delimiter(The String Data" )delimiter"
           ;;       R"delimiter((a-z))delimiter" is equivalent to "(a-z)"
           ("\\(\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\)" 1 font-lock-keyword-face t) ; start delimiter
           (   "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\(.*?\\))[^\\s-\\\\()]\\{0,16\\}\"" 1 font-lock-string-face t)  ; actual string
           (   "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?\\()[^\\s-\\\\()]\\{0,16\\}\"\\)" 1 font-lock-keyword-face t) ; end delimiter

           ;; user-defined types (rather project-specific)
           ("\\<[A-Za-z_]+[A-Za-z_0-9]*_\\(type\\|ptr\\)\\>" . font-lock-type-face)
           ("\\<\\(xstring\\|xchar\\)\\>" . font-lock-type-face)
           ))
    ) t)

В вышеприведенной реализации пользовательских строк литералы теги разделителя отмечены отдельно как font-lock-keyword-face; другой вариант будет font-lock-constant-face. Эта реализация не так эффективна, как могла бы быть; но он работает и не замедляет работу Emacs. Обратите внимание, что регулярные выражения для пользовательских строк литералов не были "украдены" из чего-либо; поэтому я надеюсь, что они сработают. Любые комментарии приветствуются.

Если вы хотите разделить всю литеральную строку как font-lock-string-face - включая разделители - замените три регулярных выражения на один. Как этот:

    .
    .
("\\<\\([uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?)[^\\s-\\\\()]\\{0,16\\}\"\\)\\>" 1 font-lock-string-face t)

Удачи.

Ответ 4

Посмотрите на пакет: "Современный С++" шрифт-замок для Emacs. Он также доступен на Melpa.

Поддержка выделения синтаксиса для "Modern С++" - до С++ 17 и Техническая спецификация. Этот пакет предназначен для обеспечения простого выделение языка С++ без зависимости.

Рекомендуется использовать его в дополнение к основному режиму С++ - mode для дополнительной подсветки (определенные пользователем типы, функции и т.д.) и отступа.

Я поддерживаю этот второстепенный режим. Любые отзывы приветствуются.

Ответ 5

Замена регулярного выражения с плавающей запятой Андреаса с этим улучшит галопирование поплавков.

integer/float/scientific literals
("\\<[-+]?[0-9]*\\.?[0-9]+\\([uUlL]+\\|[eE][-+]?[0-9]+\\)?[fFlL]?\\>" . font-lock-constant-face)

Надеюсь, что это поможет кому-то.

Ответ 6

Для меня две наиболее актуальные точки боли с блокировкой шрифтов современного кода на С++ были

  • тот факт, что auto выделяется как ключевое слово (а не тип), и, таким образом, следующий идентификатор обычно не выделяется как объявление переменной, а
  • что выделение просто сходит с ума, когда представлено некоторым кодом (например, попробуйте rtags 'src/ClangIndexer.cpp), а затем, например, не выделяет конструкции верхнего уровня, такие как определения функций.

После нескольких экспериментов я пришел к решению, которое хорошо работает для меня и адресует обе точки.

Первый из них достигается путем изменения lisp/progmodes/cc-langs.el (копирование на один load-path, а затем изменение также работает) до удалить "auto" из

(c-lang-defconst c-modifier-kwds
  "Keywords that can prefix normal declarations of identifiers

и добавьте к c++-font-lock-extra-types (например, через Customize).

Для второго, помогает освобождение c++-font-lock-extra-types (кроме сохранения "auto").