aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2023-01-17 22:30:09 -0800
committerYuan Fu2023-01-17 22:32:40 -0800
commit24f0dfd3731dcbabab0932792462636870b7bcba (patch)
treef04e72a7ad65f03e2c2db6f621f344febf0a3e47
parentac3bc775b6fd934c972d9e2542f384cdc92d2754 (diff)
downloademacs-24f0dfd3731dcbabab0932792462636870b7bcba.tar.gz
emacs-24f0dfd3731dcbabab0932792462636870b7bcba.zip
Revert "Revert "Add c-or-c++-ts-mode (bug#59613)""
This reverts commit d46f7f4edcce14e6cbd8e2d7091dbabbe08defc1. Aaaactually, we need this, otherwise we can't use tree-sitter based C mode for header files.
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/progmodes/c-ts-mode.el44
2 files changed, 49 insertions, 0 deletions
diff --git a/etc/NEWS b/etc/NEWS
index d1ddd0194c1..95dd4a24ec3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3236,6 +3236,11 @@ An optional major mode based on the tree-sitter library for editing
3236programs in the C++ language. 3236programs in the C++ language.
3237 3237
3238+++ 3238+++
3239*** New command 'c-or-c++-ts-mode'.
3240A command that automatically guesses the language of a header file,
3241and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly.
3242
3243+++
3239*** New major mode 'java-ts-mode'. 3244*** New major mode 'java-ts-mode'.
3240An optional major mode based on the tree-sitter library for editing 3245An optional major mode based on the tree-sitter library for editing
3241programs in the Java language. 3246programs in the Java language.
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 89a08a6fa9c..f9f75a0e452 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -972,6 +972,50 @@ This mode is independent from the classic cc-mode.el based
972 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) 972 (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp))
973 (treesit-major-mode-setup))) 973 (treesit-major-mode-setup)))
974 974
975;; We could alternatively use parsers, but if this works well, I don't
976;; see the need to change. This is copied verbatim from cc-guess.el.
977(defconst c-ts-mode--c-or-c++-regexp
978 (eval-when-compile
979 (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t]+") (ws-maybe "[ \t]*")
980 (headers '("string" "string_view" "iostream" "map" "unordered_map"
981 "set" "unordered_set" "vector" "tuple")))
982 (concat "^" ws-maybe "\\(?:"
983 "using" ws "\\(?:namespace" ws
984 "\\|" id "::"
985 "\\|" id ws-maybe "=\\)"
986 "\\|" "\\(?:inline" ws "\\)?namespace"
987 "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{"
988 "\\|" "class" ws id
989 "\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]"
990 "\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]"
991 "\\|" ws-maybe ":\\)"
992 "\\|" "template" ws-maybe "<.*?>"
993 "\\|" "#include" ws-maybe "<" (regexp-opt headers) ">"
994 "\\)")))
995 "A regexp applied to C header files to check if they are really C++.")
996
997;;;###autoload
998(defun c-or-c++-ts-mode ()
999 "Analyze buffer and enable either C or C++ mode.
1000
1001Some people and projects use .h extension for C++ header files
1002which is also the one used for C header files. This makes
1003matching on file name insufficient for detecting major mode that
1004should be used.
1005
1006This function attempts to use file contents to determine whether
1007the code is C or C++ and based on that chooses whether to enable
1008`c-ts-mode' or `c++-ts-mode'."
1009 (interactive)
1010 (if (save-excursion
1011 (save-restriction
1012 (save-match-data ; Why `save-match-data'?
1013 (widen)
1014 (goto-char (point-min))
1015 (re-search-forward c-ts-mode--c-or-c++-regexp nil t))))
1016 (c++-ts-mode)
1017 (c-ts-mode)))
1018
975(provide 'c-ts-mode) 1019(provide 'c-ts-mode)
976 1020
977;;; c-ts-mode.el ends here 1021;;; c-ts-mode.el ends here