diff options
| author | Dmitry Gutov | 2023-04-10 02:58:46 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2023-04-10 02:58:46 +0300 |
| commit | db8f207e52fc969e0dcf30e197bcfaa4fa1d2b6e (patch) | |
| tree | 49cb24a387626ba9d8592d999933700317517607 | |
| parent | 589959fb09d8a8f60179e1cceca4c3777b8c7719 (diff) | |
| download | emacs-db8f207e52fc969e0dcf30e197bcfaa4fa1d2b6e.tar.gz emacs-db8f207e52fc969e0dcf30e197bcfaa4fa1d2b6e.zip | |
Fix some cases of incomplete code's indentation [c/c++-ts-mode]
* lisp/progmodes/c-ts-mode.el (c-ts-base--before-indent): Try to
guess when the parse tree is incomplete, and provide a better node
to indent against (bug#62717).
(c-ts-base-mode): Set up advice for local treesit-indent-function.
| -rw-r--r-- | lisp/progmodes/c-ts-mode.el | 17 | ||||
| -rw-r--r-- | test/lisp/progmodes/c-ts-mode-resources/indent.erts | 14 |
2 files changed, 31 insertions, 0 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 981c7766375..83e89c3a335 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el | |||
| @@ -859,6 +859,18 @@ the semicolon. This function skips the semicolon." | |||
| 859 | (goto-char (match-end 0))) | 859 | (goto-char (match-end 0))) |
| 860 | (treesit-default-defun-skipper)) | 860 | (treesit-default-defun-skipper)) |
| 861 | 861 | ||
| 862 | (defun c-ts-base--before-indent (args) | ||
| 863 | (pcase-let ((`(,node ,parent ,bol) args)) | ||
| 864 | (when (null node) | ||
| 865 | (let ((smallest-node (treesit-node-at (point)))) | ||
| 866 | ;; "Virtual" closer curly added by the | ||
| 867 | ;; parser's error recovery. | ||
| 868 | (when (and (equal (treesit-node-type smallest-node) "}") | ||
| 869 | (equal (treesit-node-end smallest-node) | ||
| 870 | (treesit-node-start smallest-node))) | ||
| 871 | (setq parent (treesit-node-parent smallest-node))))) | ||
| 872 | (list node parent bol))) | ||
| 873 | |||
| 862 | (defun c-ts-mode-indent-defun () | 874 | (defun c-ts-mode-indent-defun () |
| 863 | "Indent the current top-level declaration syntactically. | 875 | "Indent the current top-level declaration syntactically. |
| 864 | 876 | ||
| @@ -904,6 +916,11 @@ the semicolon. This function skips the semicolon." | |||
| 904 | ;; function_definitions, so we need to find the top-level node. | 916 | ;; function_definitions, so we need to find the top-level node. |
| 905 | (setq-local treesit-defun-prefer-top-level t) | 917 | (setq-local treesit-defun-prefer-top-level t) |
| 906 | 918 | ||
| 919 | ;; When the code is in incomplete state, try to make a better guess | ||
| 920 | ;; about which node to indent against. | ||
| 921 | (add-function :filter-args (local 'treesit-indent-function) | ||
| 922 | #'c-ts-base--before-indent) | ||
| 923 | |||
| 907 | ;; Indent. | 924 | ;; Indent. |
| 908 | (when (eq c-ts-mode-indent-style 'linux) | 925 | (when (eq c-ts-mode-indent-style 'linux) |
| 909 | (setq-local indent-tabs-mode t)) | 926 | (setq-local indent-tabs-mode t)) |
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent.erts b/test/lisp/progmodes/c-ts-mode-resources/indent.erts index 5cdefe2122c..221b3d809af 100644 --- a/test/lisp/progmodes/c-ts-mode-resources/indent.erts +++ b/test/lisp/progmodes/c-ts-mode-resources/indent.erts | |||
| @@ -464,3 +464,17 @@ main (void) | |||
| 464 | | | 464 | | |
| 465 | } | 465 | } |
| 466 | =-=-= | 466 | =-=-= |
| 467 | |||
| 468 | Name: Empty Line (Block Start) | ||
| 469 | |||
| 470 | =-= | ||
| 471 | int | ||
| 472 | main (void) | ||
| 473 | { | ||
| 474 | | | ||
| 475 | =-= | ||
| 476 | int | ||
| 477 | main (void) | ||
| 478 | { | ||
| 479 | | | ||
| 480 | =-=-= | ||