diff options
| author | Vincenzo Pupillo | 2024-07-01 12:34:01 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2024-07-13 13:07:18 +0300 |
| commit | c77a9b934bc1120c7726d271bbd4ada178cf8c2d (patch) | |
| tree | 44a4a45c8ebb00a8d6567357f4ceb93ab18df17c | |
| parent | b23ab371756b5f77f62020cdfda5fe7b6fb04470 (diff) | |
| download | emacs-c77a9b934bc1120c7726d271bbd4ada178cf8c2d.tar.gz emacs-c77a9b934bc1120c7726d271bbd4ada178cf8c2d.zip | |
Fontify doxygen support to 'c-ts-mode', 'c++-ts-mode' and 'java-ts-mode'
Add doxygen support to 'c-ts-mode', 'c++-ts-mode' and
'java-ts-mode' using tree-sitter-doxygen from
github.com/tree-sitter-grammars.
* lisp/progmodes/c-ts-common.el
(c-ts-mode-doxygen-comment-font-lock-settings): Add font locking
rules for doxygen comment.
* lisp/progmodes/c-ts-mode.el (c-ts-mode--feature-list): Add
'document' feature.
(c-ts-mode--doxygen-comment-regex): New regular expression for
doxygen comments.
(c-ts-mode, c++-ts-mode): Add support for doxygen parser.
* lisp/progmodes/java-ts-mode.el (java-ts-mode): Add support for
doxygen parser. (Bug#71874)
| -rw-r--r-- | lisp/progmodes/c-ts-common.el | 22 | ||||
| -rw-r--r-- | lisp/progmodes/c-ts-mode.el | 126 | ||||
| -rw-r--r-- | lisp/progmodes/java-ts-mode.el | 159 |
3 files changed, 193 insertions, 114 deletions
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el index 3882a697c48..a1f257ee09a 100644 --- a/lisp/progmodes/c-ts-common.el +++ b/lisp/progmodes/c-ts-common.el | |||
| @@ -348,6 +348,28 @@ and /* */ comments. SOFT works the same as in | |||
| 348 | (delete-region (line-beginning-position) (point)) | 348 | (delete-region (line-beginning-position) (point)) |
| 349 | (insert whitespaces))))) | 349 | (insert whitespaces))))) |
| 350 | 350 | ||
| 351 | ;; Font locking using doxygen parser | ||
| 352 | (defvar c-ts-mode-doxygen-comment-font-lock-settings | ||
| 353 | (treesit-font-lock-rules | ||
| 354 | :language 'doxygen | ||
| 355 | :feature 'document | ||
| 356 | :override t | ||
| 357 | '((document) @font-lock-doc-face) | ||
| 358 | |||
| 359 | :language 'doxygen | ||
| 360 | :override t | ||
| 361 | :feature 'keyword | ||
| 362 | '((tag_name) @font-lock-constant-face | ||
| 363 | (storageclass) @font-lock-constant-face) | ||
| 364 | |||
| 365 | :language 'doxygen | ||
| 366 | :override t | ||
| 367 | :feature 'definition | ||
| 368 | '((tag (identifier) @font-lock-variable-name-face) | ||
| 369 | (function (identifier) @font-lock-function-name-face) | ||
| 370 | (function_link) @font-lock-function-name-face)) | ||
| 371 | "Tree-sitter font lock rules for doxygen like comment styles.") | ||
| 372 | |||
| 351 | ;;; Statement indent | 373 | ;;; Statement indent |
| 352 | 374 | ||
| 353 | (defvar c-ts-common-indent-offset nil | 375 | (defvar c-ts-common-indent-offset nil |
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index e7f74fc53f2..a0f2bc33963 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el | |||
| @@ -63,6 +63,9 @@ | |||
| 63 | ;; will set up Emacs to use the C/C++ modes defined here for other | 63 | ;; will set up Emacs to use the C/C++ modes defined here for other |
| 64 | ;; files, provided that you have the corresponding parser grammar | 64 | ;; files, provided that you have the corresponding parser grammar |
| 65 | ;; libraries installed. | 65 | ;; libraries installed. |
| 66 | ;; | ||
| 67 | ;; If the tree-sitter doxygen grammar is available, then the comment | ||
| 68 | ;; blocks will be highlighted according to this grammar. | ||
| 66 | 69 | ||
| 67 | ;;; Code: | 70 | ;;; Code: |
| 68 | 71 | ||
| @@ -539,7 +542,7 @@ NODE should be a labeled_statement. PARENT is its parent." | |||
| 539 | ;;; Font-lock | 542 | ;;; Font-lock |
| 540 | 543 | ||
| 541 | (defvar c-ts-mode--feature-list | 544 | (defvar c-ts-mode--feature-list |
| 542 | '(( comment definition) | 545 | '(( comment document definition) |
| 543 | ( keyword preprocessor string type) | 546 | ( keyword preprocessor string type) |
| 544 | ( assignment constant escape-sequence label literal) | 547 | ( assignment constant escape-sequence label literal) |
| 545 | ( bracket delimiter error function operator property variable)) | 548 | ( bracket delimiter error function operator property variable)) |
| @@ -591,6 +594,10 @@ MODE is either `c' or `cpp'." | |||
| 591 | "LIVE_BUFFER" "FRAME")) | 594 | "LIVE_BUFFER" "FRAME")) |
| 592 | "A regexp matching all the variants of the FOR_EACH_* macro.") | 595 | "A regexp matching all the variants of the FOR_EACH_* macro.") |
| 593 | 596 | ||
| 597 | (defvar c-ts-mode--doxygen-comment-regex | ||
| 598 | (rx (| "/**" "/*!" "//!" "///")) | ||
| 599 | "A regexp that matches all doxygen comment styles.") | ||
| 600 | |||
| 594 | (defun c-ts-mode--font-lock-settings (mode) | 601 | (defun c-ts-mode--font-lock-settings (mode) |
| 595 | "Tree-sitter font-lock settings. | 602 | "Tree-sitter font-lock settings. |
| 596 | MODE is either `c' or `cpp'." | 603 | MODE is either `c' or `cpp'." |
| @@ -1317,30 +1324,47 @@ in your init files." | |||
| 1317 | (when c-ts-mode-emacs-sources-support | 1324 | (when c-ts-mode-emacs-sources-support |
| 1318 | (treesit-parser-create 'c nil nil 'for-each)) | 1325 | (treesit-parser-create 'c nil nil 'for-each)) |
| 1319 | 1326 | ||
| 1320 | (treesit-parser-create 'c) | 1327 | (let ((primary-parser (treesit-parser-create 'c))) |
| 1321 | ;; Comments. | 1328 | ;; Comments. |
| 1322 | (setq-local comment-start "/* ") | 1329 | (setq-local comment-start "/* ") |
| 1323 | (setq-local comment-end " */") | 1330 | (setq-local comment-end " */") |
| 1324 | ;; Indent. | 1331 | ;; Indent. |
| 1325 | (setq-local treesit-simple-indent-rules | 1332 | (setq-local treesit-simple-indent-rules |
| 1326 | (c-ts-mode--get-indent-style 'c)) | 1333 | (c-ts-mode--get-indent-style 'c)) |
| 1327 | ;; Font-lock. | 1334 | ;; Font-lock. |
| 1328 | (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) | 1335 | (setq-local treesit-font-lock-settings |
| 1329 | ;; Navigation. | 1336 | (c-ts-mode--font-lock-settings 'c)) |
| 1330 | (setq-local treesit-defun-tactic 'top-level) | 1337 | ;; Navigation. |
| 1331 | (treesit-major-mode-setup) | 1338 | (setq-local treesit-defun-tactic 'top-level) |
| 1332 | 1339 | (treesit-major-mode-setup) | |
| 1333 | ;; Emacs source support: handle DEFUN and FOR_EACH_* gracefully. | 1340 | |
| 1334 | (when c-ts-mode-emacs-sources-support | 1341 | ;; Emacs source support: handle DEFUN and FOR_EACH_* gracefully. |
| 1335 | (setq-local add-log-current-defun-function | 1342 | (when c-ts-mode-emacs-sources-support |
| 1336 | #'c-ts-mode--emacs-current-defun-name) | 1343 | (setq-local add-log-current-defun-function |
| 1337 | 1344 | #'c-ts-mode--emacs-current-defun-name) | |
| 1338 | (setq-local treesit-range-settings | 1345 | |
| 1339 | (treesit-range-rules 'c-ts-mode--emacs-set-ranges)) | 1346 | (setq-local treesit-range-settings |
| 1340 | 1347 | (treesit-range-rules 'c-ts-mode--emacs-set-ranges)) | |
| 1341 | (setq-local treesit-language-at-point-function | 1348 | |
| 1342 | (lambda (_pos) 'c)) | 1349 | (setq-local treesit-language-at-point-function |
| 1343 | (treesit-font-lock-recompute-features '(emacs-devel))))) | 1350 | (lambda (_pos) 'c)) |
| 1351 | (treesit-font-lock-recompute-features '(emacs-devel))) | ||
| 1352 | |||
| 1353 | ;; Inject doxygen parser for comment. | ||
| 1354 | (when (treesit-ready-p 'doxygen) | ||
| 1355 | (setq-local treesit-primary-parser primary-parser) | ||
| 1356 | (setq-local treesit-font-lock-settings | ||
| 1357 | (append | ||
| 1358 | treesit-font-lock-settings | ||
| 1359 | c-ts-mode-doxygen-comment-font-lock-settings)) | ||
| 1360 | (setq-local treesit-range-settings | ||
| 1361 | (treesit-range-rules | ||
| 1362 | :embed 'doxygen | ||
| 1363 | :host 'c | ||
| 1364 | :local t | ||
| 1365 | `(((comment) @cap | ||
| 1366 | (:match | ||
| 1367 | ,c-ts-mode--doxygen-comment-regex @cap))))))))) | ||
| 1344 | 1368 | ||
| 1345 | (derived-mode-add-parents 'c-ts-mode '(c-mode)) | 1369 | (derived-mode-add-parents 'c-ts-mode '(c-mode)) |
| 1346 | 1370 | ||
| @@ -1368,24 +1392,40 @@ recommended to enable `electric-pair-mode' with this mode." | |||
| 1368 | :after-hook (c-ts-mode-set-modeline) | 1392 | :after-hook (c-ts-mode-set-modeline) |
| 1369 | 1393 | ||
| 1370 | (when (treesit-ready-p 'cpp) | 1394 | (when (treesit-ready-p 'cpp) |
| 1371 | 1395 | (let ((primary-parser (treesit-parser-create 'cpp))) | |
| 1372 | (treesit-parser-create 'cpp) | 1396 | |
| 1373 | 1397 | ;; Syntax. | |
| 1374 | ;; Syntax. | 1398 | (setq-local syntax-propertize-function |
| 1375 | (setq-local syntax-propertize-function | 1399 | #'c-ts-mode--syntax-propertize) |
| 1376 | #'c-ts-mode--syntax-propertize) | 1400 | |
| 1377 | 1401 | ;; Indent. | |
| 1378 | ;; Indent. | 1402 | (setq-local treesit-simple-indent-rules |
| 1379 | (setq-local treesit-simple-indent-rules | 1403 | (c-ts-mode--get-indent-style 'cpp)) |
| 1380 | (c-ts-mode--get-indent-style 'cpp)) | 1404 | |
| 1381 | 1405 | ;; Font-lock. | |
| 1382 | ;; Font-lock. | 1406 | (setq-local treesit-font-lock-settings |
| 1383 | (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) | 1407 | (c-ts-mode--font-lock-settings 'cpp)) |
| 1384 | (treesit-major-mode-setup) | 1408 | (treesit-major-mode-setup) |
| 1385 | 1409 | ||
| 1386 | (when c-ts-mode-emacs-sources-support | 1410 | (when c-ts-mode-emacs-sources-support |
| 1387 | (setq-local add-log-current-defun-function | 1411 | (setq-local add-log-current-defun-function |
| 1388 | #'c-ts-mode--emacs-current-defun-name)))) | 1412 | #'c-ts-mode--emacs-current-defun-name)) |
| 1413 | |||
| 1414 | ;; Inject doxygen parser for comment. | ||
| 1415 | (when (treesit-ready-p 'doxygen) | ||
| 1416 | (setq-local treesit-primary-parser primary-parser) | ||
| 1417 | (setq-local treesit-font-lock-settings | ||
| 1418 | (append | ||
| 1419 | treesit-font-lock-settings | ||
| 1420 | c-ts-mode-doxygen-comment-font-lock-settings)) | ||
| 1421 | (setq-local treesit-range-settings | ||
| 1422 | (treesit-range-rules | ||
| 1423 | :embed 'doxygen | ||
| 1424 | :host 'cpp | ||
| 1425 | :local t | ||
| 1426 | `(((comment) @cap | ||
| 1427 | (:match | ||
| 1428 | ,c-ts-mode--doxygen-comment-regex @cap))))))))) | ||
| 1389 | 1429 | ||
| 1390 | (derived-mode-add-parents 'c++-ts-mode '(c++-mode)) | 1430 | (derived-mode-add-parents 'c++-ts-mode '(c++-mode)) |
| 1391 | 1431 | ||
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 4ceb211ade1..68ead567632 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | ;; | 26 | ;; |
| 27 | ;; If the tree-sitter doxygen grammar is available, then the comment | ||
| 28 | ;; blocks will be highlighted according to this grammar. | ||
| 27 | 29 | ||
| 28 | ;;; Code: | 30 | ;;; Code: |
| 29 | 31 | ||
| @@ -312,7 +314,7 @@ Return nil if there is no name or if NODE is not a defun node." | |||
| 312 | 314 | ||
| 313 | 315 | ||
| 314 | (defvar java-ts-mode--feature-list | 316 | (defvar java-ts-mode--feature-list |
| 315 | '(( comment definition ) | 317 | '(( comment document definition ) |
| 316 | ( constant keyword string type) | 318 | ( constant keyword string type) |
| 317 | ( annotation expression literal) | 319 | ( annotation expression literal) |
| 318 | ( bracket delimiter operator))) | 320 | ( bracket delimiter operator))) |
| @@ -326,76 +328,91 @@ Return nil if there is no name or if NODE is not a defun node." | |||
| 326 | (unless (treesit-ready-p 'java) | 328 | (unless (treesit-ready-p 'java) |
| 327 | (error "Tree-sitter for Java isn't available")) | 329 | (error "Tree-sitter for Java isn't available")) |
| 328 | 330 | ||
| 329 | (treesit-parser-create 'java) | 331 | (let ((primary-parser (treesit-parser-create 'java))) |
| 330 | 332 | ||
| 331 | ;; Comments. | 333 | ;; Comments. |
| 332 | (c-ts-common-comment-setup) | 334 | (c-ts-common-comment-setup) |
| 333 | 335 | ||
| 334 | ;; Indent. | 336 | ;; Indent. |
| 335 | (setq-local c-ts-common-indent-type-regexp-alist | 337 | (setq-local c-ts-common-indent-type-regexp-alist |
| 336 | `((block . ,(rx (or "class_body" | 338 | `((block . ,(rx (or "class_body" |
| 337 | "array_initializer" | 339 | "array_initializer" |
| 338 | "constructor_body" | 340 | "constructor_body" |
| 339 | "annotation_type_body" | 341 | "annotation_type_body" |
| 340 | "interface_body" | 342 | "interface_body" |
| 341 | "lambda_expression" | 343 | "lambda_expression" |
| 342 | "enum_body" | 344 | "enum_body" |
| 343 | "switch_block" | 345 | "switch_block" |
| 344 | "record_declaration_body" | 346 | "record_declaration_body" |
| 345 | "block"))) | 347 | "block"))) |
| 346 | (close-bracket . "}") | 348 | (close-bracket . "}") |
| 347 | (if . "if_statement") | 349 | (if . "if_statement") |
| 348 | (else . ("if_statement" . "alternative")) | 350 | (else . ("if_statement" . "alternative")) |
| 349 | (for . "for_statement") | 351 | (for . "for_statement") |
| 350 | (while . "while_statement") | 352 | (while . "while_statement") |
| 351 | (do . "do_statement"))) | 353 | (do . "do_statement"))) |
| 352 | (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset) | 354 | (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset) |
| 353 | (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules) | 355 | (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules) |
| 354 | 356 | ||
| 355 | ;; Electric | 357 | ;; Electric |
| 356 | (setq-local electric-indent-chars | 358 | (setq-local electric-indent-chars |
| 357 | (append "{}():;," electric-indent-chars)) | 359 | (append "{}():;," electric-indent-chars)) |
| 358 | 360 | ||
| 359 | ;; Navigation. | 361 | ;; Navigation. |
| 360 | (setq-local treesit-defun-type-regexp | 362 | (setq-local treesit-defun-type-regexp |
| 361 | (regexp-opt '("method_declaration" | 363 | (regexp-opt '("method_declaration" |
| 362 | "class_declaration" | 364 | "class_declaration" |
| 363 | "record_declaration" | 365 | "record_declaration" |
| 364 | "interface_declaration" | 366 | "interface_declaration" |
| 365 | "enum_declaration" | 367 | "enum_declaration" |
| 366 | "import_declaration" | 368 | "import_declaration" |
| 367 | "package_declaration" | 369 | "package_declaration" |
| 368 | "module_declaration" | 370 | "module_declaration" |
| 369 | "constructor_declaration"))) | 371 | "constructor_declaration"))) |
| 370 | (setq-local treesit-defun-name-function #'java-ts-mode--defun-name) | 372 | (setq-local treesit-defun-name-function #'java-ts-mode--defun-name) |
| 371 | 373 | ||
| 372 | (setq-local treesit-thing-settings | 374 | (setq-local treesit-thing-settings |
| 373 | `((java | 375 | `((java |
| 374 | (sexp ,(rx (or "annotation" | 376 | (sexp ,(rx (or "annotation" |
| 375 | "parenthesized_expression" | 377 | "parenthesized_expression" |
| 376 | "argument_list" | 378 | "argument_list" |
| 377 | "identifier" | 379 | "identifier" |
| 378 | "modifiers" | 380 | "modifiers" |
| 379 | "block" | 381 | "block" |
| 380 | "body" | 382 | "body" |
| 381 | "literal" | 383 | "literal" |
| 382 | "access" | 384 | "access" |
| 383 | "reference" | 385 | "reference" |
| 384 | "_type" | 386 | "_type" |
| 385 | "true" | 387 | "true" |
| 386 | "false"))) | 388 | "false"))) |
| 387 | (sentence ,(rx (or "statement" | 389 | (sentence ,(rx (or "statement" |
| 388 | "local_variable_declaration" | 390 | "local_variable_declaration" |
| 389 | "field_declaration" | 391 | "field_declaration" |
| 390 | "module_declaration" | 392 | "module_declaration" |
| 391 | "package_declaration" | 393 | "package_declaration" |
| 392 | "import_declaration"))) | 394 | "import_declaration"))) |
| 393 | (text ,(regexp-opt '("line_comment" | 395 | (text ,(regexp-opt '("line_comment" |
| 394 | "block_comment" | 396 | "block_comment" |
| 395 | "text_block")))))) | 397 | "text_block")))))) |
| 396 | 398 | ||
| 397 | ;; Font-lock. | 399 | ;; Font-lock. |
| 398 | (setq-local treesit-font-lock-settings java-ts-mode--font-lock-settings) | 400 | (setq-local treesit-font-lock-settings |
| 401 | java-ts-mode--font-lock-settings) | ||
| 402 | |||
| 403 | ;; Inject doxygen parser for comment. | ||
| 404 | (when (treesit-ready-p 'doxygen) | ||
| 405 | (setq-local treesit-primary-parser primary-parser) | ||
| 406 | (setq-local treesit-font-lock-settings | ||
| 407 | (append treesit-font-lock-settings | ||
| 408 | c-ts-mode-doxygen-comment-font-lock-settings)) | ||
| 409 | (setq-local treesit-range-settings | ||
| 410 | (treesit-range-rules | ||
| 411 | :embed 'doxygen | ||
| 412 | :host 'java | ||
| 413 | :local t | ||
| 414 | `(((block_comment) @cap (:match "/\\*\\*" @cap))))))) | ||
| 415 | |||
| 399 | (setq-local treesit-font-lock-feature-list java-ts-mode--feature-list) | 416 | (setq-local treesit-font-lock-feature-list java-ts-mode--feature-list) |
| 400 | 417 | ||
| 401 | ;; Imenu. | 418 | ;; Imenu. |