Add c-or-c++-ts-mode (bug#59613)

* lisp/progmodes/c-ts-mode.el
(c-ts-mode--c-or-c++-regexp): New variable.
(c-or-c++-ts-mode): New mode.
* etc/NEWS: Mention c-or-c++-ts-mode.
This commit is contained in:
Yuan Fu 2023-01-07 14:58:37 -08:00
parent 0cb686ffb6
commit 1df2826639
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
2 changed files with 49 additions and 0 deletions

View file

@ -3210,6 +3210,11 @@ programs in the C language.
An optional major mode based on the tree-sitter library for editing An optional major mode based on the tree-sitter library for editing
programs in the C++ language. programs in the C++ language.
+++
*** New major mode 'c-or-c++-ts-mode'.
A function that automatically guesses the language of a header file,
and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly.
+++ +++
*** New major mode 'java-ts-mode'. *** New major mode 'java-ts-mode'.
An optional major mode based on the tree-sitter library for editing An optional major mode based on the tree-sitter library for editing

View file

@ -822,6 +822,50 @@ Set up:
(treesit-major-mode-setup)) (treesit-major-mode-setup))
;; We could alternatively use parsers, but if this works well, I don't
;; see the need to change. This is copied verbatim from cc-guess.el.
(defconst c-ts-mode--c-or-c++-regexp
(eval-when-compile
(let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t]+") (ws-maybe "[ \t]*")
(headers '("string" "string_view" "iostream" "map" "unordered_map"
"set" "unordered_set" "vector" "tuple")))
(concat "^" ws-maybe "\\(?:"
"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++.")
;;;###autoload
(defun c-or-c++-ts-mode ()
"Analyze buffer and enable either C or C++ mode.
Some people and projects use .h extension for C++ header files
which is also the one used for C header files. This makes
matching on file name insufficient for detecting major mode that
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-ts-mode' or `c++-ts-mode'."
(interactive)
(if (save-excursion
(save-restriction
(save-match-data ; Why `save-match-data'?
(widen)
(goto-char (point-min))
(re-search-forward c-ts-mode--c-or-c++-regexp nil t))))
(c++-ts-mode)
(c-ts-mode)))
(provide 'c-ts-mode) (provide 'c-ts-mode)
;;; c-ts-mode.el ends here ;;; c-ts-mode.el ends here