summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Nazarewicz <mina86@mina86.com>2020-05-04 19:08:10 +0100
committerMichal Nazarewicz <mina86@mina86.com>2020-05-09 11:30:32 +0100
commitae3c510696f02f01d03052f070e5ce65b4018a45 (patch)
tree7ffda57aed8788d8b0cbfbb16d486c0d0db15b97
parentfab23328512e47a50caced8d074e86e583cc8a9f (diff)
downloademacs-ae3c510696f02f01d03052f070e5ce65b4018a45.tar.gz
cc-mode: extend regexp used by ‘c-or-c++-mode’
* lisp/progmodes/cc-mode (c-or-c++-mode--regexp): Expand the regexp to match some more C++-only constructs and recognise a few more standard C++ header files. Also make sure identifiers start with non-digit. (c-or-c++-mode): Add ‘(interactive)’ declaration. * test/lisp/progmodes/cc-mode-tests.el (c-or-c++-mode): Add test case for the newly recognised constructs.
-rw-r--r--lisp/progmodes/cc-mode.el21
-rw-r--r--test/lisp/progmodes/cc-mode-tests.el12
2 files changed, 25 insertions, 8 deletions
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index f92d3efdeb7..e3a924efb06 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2541,13 +2541,21 @@ Key bindings:
(defconst c-or-c++-mode--regexp
(eval-when-compile
- (let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*"))
+ (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*")
+ (headers '("string" "string_view" "iostream" "map" "unordered_map"
+ "set" "unordered_set" "vector" "tuple")))
(concat "^" ws-maybe "\\(?:"
- "using" ws "\\(?:namespace" ws "std;\\|std::\\)"
- "\\|" "namespace" "\\(:?" ws id "\\)?" ws-maybe "{"
- "\\|" "class" ws id ws-maybe "[:{\n]"
- "\\|" "template" ws-maybe "<.*>"
- "\\|" "#include" ws-maybe "<\\(?:string\\|iostream\\|map\\)>"
+ "using" ws "\\(?:namespace" ws
+ "\\|" id "::"
+ "\\|" id ws-maybe "=\\)"
+ "\\|" "\\(?:inline" ws "\\)?namespace"
+ "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{"
+ "\\|" "class" ws id
+ "\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]"
+ "\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]"
+ "\\|" ws-maybe ":\\)"
+ "\\|" "template" ws-maybe "<.*?>"
+ "\\|" "#include" ws-maybe "<" (regexp-opt headers) ">"
"\\)")))
"A regexp applied to C header files to check if they are really C++.")
@@ -2563,6 +2571,7 @@ should be used.
This function attempts to use file contents to determine whether
the code is C or C++ and based on that chooses whether to enable
`c-mode' or `c++-mode'."
+ (interactive)
(if (save-excursion
(save-restriction
(save-match-data
diff --git a/test/lisp/progmodes/cc-mode-tests.el b/test/lisp/progmodes/cc-mode-tests.el
index ad7a52b40d9..64d52a952b6 100644
--- a/test/lisp/progmodes/cc-mode-tests.el
+++ b/test/lisp/progmodes/cc-mode-tests.el
@@ -40,7 +40,7 @@
(insert content)
(setq mode nil)
(c-or-c++-mode)
- (unless(eq expected mode)
+ (unless (eq expected mode)
(ert-fail
(format "expected %s but got %s when testing '%s'"
expected mode content)))))
@@ -53,11 +53,18 @@
(funcall do-test (concat " * " content) 'c-mode))
'("using \t namespace \t std;"
"using \t std::string;"
+ "using Foo = Bar;"
"namespace \t {"
"namespace \t foo \t {"
- "class \t Blah_42 \t {"
+ "namespace \t foo::bar \t {"
+ "inline namespace \t foo \t {"
+ "inline namespace \t foo::bar \t {"
"class \t Blah_42 \t \n"
+ "class \t Blah_42;"
+ "class \t Blah_42 \t final {"
+ "struct \t Blah_42 \t final {"
"class \t _42_Blah:public Foo {"
+ "struct \t _42_Blah:public Foo {"
"template \t < class T >"
"template< class T >"
"#include <string>"
@@ -67,6 +74,7 @@
(mapc (lambda (content) (funcall do-test content 'c-mode))
'("struct \t Blah_42 \t {"
"struct template {"
+ "struct Blah;"
"#include <string.h>")))))
(ert-deftest c-mode-macro-comment ()