aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2023-04-10 02:58:46 +0300
committerDmitry Gutov2023-04-10 02:58:46 +0300
commitdb8f207e52fc969e0dcf30e197bcfaa4fa1d2b6e (patch)
tree49cb24a387626ba9d8592d999933700317517607
parent589959fb09d8a8f60179e1cceca4c3777b8c7719 (diff)
downloademacs-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.el17
-rw-r--r--test/lisp/progmodes/c-ts-mode-resources/indent.erts14
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
468Name: Empty Line (Block Start)
469
470=-=
471int
472main (void)
473{
474|
475=-=
476int
477main (void)
478{
479 |
480=-=-=