Modo C++ 11 o configuraciones para emacs?
c++11 elisp (6)
Estoy ejecutando Emacs 23.3.1 (Ubuntu, paquete Oneiric) y emacs no parece entender ninguna de las nuevas palabras clave de C ++ 11, constexpr, thread_local, etc. Además, no entiende que ''>>'' es ahora permitido en los parámetros de la plantilla, o la nueva sintaxis de la ''clase enum''. ¿Hay algún módulo actualizado o alternativo en alguna parte? ¿O en su defecto, algunas configuraciones para hacer que emacs sea más amigable con C ++ 11 mientras tanto?
Bueno, estoy usando 24.1. Faltan algunas palabras clave de C ++ 98 y todas las palabras clave nuevas de C ++ 11. Ni siquiera genera las constantes numéricas. Parece como si el modo c ++ no se hubiera actualizado durante una década.
Estoy usando el siguiente código desde hace mucho tiempo y recientemente agregué C ++ 11 palabras clave. Intenta ponerlo en tu .emacs ; debería llenar algunos agujeros.
(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)
Espero que esto ayude.
De acuerdo con una solicitud de Mike Weller aquí una versión actualizada para C ++ 11 cadenas de literales (incluidos literales definidos por el usuario).
(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)
En la implementación anterior de literales de cadenas definidas por el usuario, las etiquetas delimitadoras se marcan por separado como font-lock-keyword-face
; otra opción sería font-lock-constant-face
. Esta implementación no es tan eficiente como podría ser; pero funciona y no ralentiza Emacs. Tenga en cuenta que las expresiones regulares para literales de cadenas definidas por el usuario no han sido "robadas" de alguna parte; así que espero que funcionen. Cualquier comentario es bienvenido
Si le gusta escribir la cadena literal completa como font-lock-string-face
, incluidos los delimitadores, reemplace las tres expresiones regulares por una sola. Como éste:
.
.
("//<//([uU8]*R/"[^//s-////()]//{0,16//}(.*?)[^//s-////()]//{0,16//}/"//)//>" 1 font-lock-string-face t)
Que te diviertas.
Eche un vistazo al paquete: bloque de fuente "Modern C ++" para Emacs . También está disponible en Melpa .
Soporte de resaltado de sintaxis para "C ++ moderno" - hasta C ++ 17 y especificaciones técnicas. Este paquete tiene como objetivo proporcionar un punto culminante simple del lenguaje C ++ sin dependencia.
Se recomienda utilizarlo además del modo principal modo c ++ para resaltar adicionalmente (tipos definidos por el usuario, funciones, etc.) e indentación.
Soy el mantenedor de este modo menor. Cualquier comentario es apreciado.
He comprobado la versión del tronco, cc-mode
no se ha actualizado aún y AFAIK no hay alternativa. Si realmente lo quiere, pero no quiere ensuciarse las manos, debe pagarle a alguien para que lo implemente ...
Para mí, los dos puntos de dolor más apremiantes con el bloqueo de fuente del código C ++ moderno han sido
- el hecho de que
auto
se resalta como una palabra clave (y no un tipo) y, por lo tanto, el siguiente identificador normalmente no se resaltará como una declaración de variable, y - que resaltar simplemente se vuelve loco cuando se le presenta algún código (por ejemplo, pruebe rtags ''
src/ClangIndexer.cpp
) y luego, por ejemplo, no resalta las construcciones de alto nivel como las definiciones de funciones.
Después de un poco de experimentación, llegué a una solución que funciona bien para mí y aborda ambos puntos.
El primero se logra modificando lisp/progmodes/cc-langs.el
(copiar en la load-path
de load-path
de uno y luego modificar también funciona) para eliminar "auto"
de
(c-lang-defconst c-modifier-kwds
"Keywords that can prefix normal declarations of identifiers
y añádalo a c++-font-lock-extra-types
(por ejemplo, a través de Customize).
Para el segundo, vaciar c++-font-lock-extra-types
(excepto para mantener "auto"
) ayuda.
Reemplazar la expresión regular de coma flotante de Andreas con esto mejorará la abundancia de los flotadores.
integer/float/scientific literals
("//<[-+]?[0-9]*//.?[0-9]+//([uUlL]+//|[eE][-+]?[0-9]+//)?[fFlL]?//>" . font-lock-constant-face)
Espero que ayude a alguien.