diff options
| author | Yuan Fu | 2025-06-09 22:35:34 -0700 |
|---|---|---|
| committer | Yuan Fu | 2025-06-09 22:55:09 -0700 |
| commit | f904ff5ca2535356e1353e5fc95d9b0643b8570b (patch) | |
| tree | dfaf17ff1ed3c2c22add0d3a5bc7062a77c608a4 | |
| parent | 5390593c42d46942cd4016bf11653db96246986d (diff) | |
| download | emacs-f904ff5ca2535356e1353e5fc95d9b0643b8570b.tar.gz emacs-f904ff5ca2535356e1353e5fc95d9b0643b8570b.zip | |
Add tree-sitter version of prog-fill-reindent-defun (bug#78703)
Add a tree-sitter version of prog-fill-reindent-defun that
indents the defun that encloses point, rather than the sibling
defun after point when there is one.
* lisp/progmodes/prog-mode.el:
(prog-fill-reindent-defun): Turns into a wrapper function.
(prog-fill-reindent-defun-function): New variable.
(prog-fill-reindent-defun-default): Old prog-fill-reindent-defun
becomes this function.
* lisp/treesit.el (treesit-fill-reindent-defun): New function.
(treesit-major-mode-setup): Setup
prog-fill-reindent-defun-function.
| -rw-r--r-- | lisp/progmodes/prog-mode.el | 32 | ||||
| -rw-r--r-- | lisp/treesit.el | 31 |
2 files changed, 51 insertions, 12 deletions
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el index b81ff6ff7a5..50aac95dbc6 100644 --- a/lisp/progmodes/prog-mode.el +++ b/lisp/progmodes/prog-mode.el | |||
| @@ -166,23 +166,37 @@ instead." | |||
| 166 | (and (re-search-forward "\\s-*\\s<" (line-end-position) t) | 166 | (and (re-search-forward "\\s-*\\s<" (line-end-position) t) |
| 167 | (nth 8 (syntax-ppss)))))) | 167 | (nth 8 (syntax-ppss)))))) |
| 168 | 168 | ||
| 169 | (defun prog-fill-reindent-defun (&optional argument) | 169 | (defvar prog-fill-reindent-defun-function |
| 170 | "Refill or reindent the paragraph or defun that contains point. | 170 | #'prog-fill-reindent-defun-default |
| 171 | 171 | "Function called by `prog-fill-reindent-defun' to do the actual work. | |
| 172 | If the point is in a string or a comment, fill the paragraph that | 172 | It should take the same argument as `prog-fill-reindent-defun'.") |
| 173 | contains point or follows point. | 173 | |
| 174 | 174 | (defun prog-fill-reindent-defun-default (&optional justify) | |
| 175 | Otherwise, reindent the function definition that contains point | 175 | "Default implementation of `prog-fill-reindent-defun'. |
| 176 | or follows point." | 176 | JUSTIFY is the same as in `fill-paragraph'." |
| 177 | (interactive "P") | 177 | (interactive "P") |
| 178 | (save-excursion | 178 | (save-excursion |
| 179 | (if (prog--text-at-point-p) | 179 | (if (prog--text-at-point-p) |
| 180 | (fill-paragraph argument (region-active-p)) | 180 | (fill-paragraph justify (region-active-p)) |
| 181 | (beginning-of-defun) | 181 | (beginning-of-defun) |
| 182 | (let ((start (point))) | 182 | (let ((start (point))) |
| 183 | (end-of-defun) | 183 | (end-of-defun) |
| 184 | (indent-region start (point) nil))))) | 184 | (indent-region start (point) nil))))) |
| 185 | 185 | ||
| 186 | (defun prog-fill-reindent-defun (&optional justify) | ||
| 187 | "Refill or reindent the paragraph or defun that contains point. | ||
| 188 | |||
| 189 | If the point is in a string or a comment, fill the paragraph that | ||
| 190 | contains point or follows point. | ||
| 191 | |||
| 192 | Otherwise, reindent the function definition that contains point | ||
| 193 | or follows point. | ||
| 194 | |||
| 195 | If JUSTIFY is non-nil (interactively, with prefix argument), justify as | ||
| 196 | well." | ||
| 197 | (interactive "P") | ||
| 198 | (funcall prog-fill-reindent-defun-function justify)) | ||
| 199 | |||
| 186 | (defun prog-first-column () | 200 | (defun prog-first-column () |
| 187 | "Return the indentation column normally used for top-level constructs." | 201 | "Return the indentation column normally used for top-level constructs." |
| 188 | (or (car prog-indentation-context) 0)) | 202 | (or (car prog-indentation-context) 0)) |
diff --git a/lisp/treesit.el b/lisp/treesit.el index 30f163aa100..bc6b177e25e 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | (require 'cl-lib) | 58 | (require 'cl-lib) |
| 59 | (require 'font-lock) | 59 | (require 'font-lock) |
| 60 | (require 'seq) | 60 | (require 'seq) |
| 61 | (require 'prog-mode) ; For `prog--text-at-point-p'. | ||
| 61 | 62 | ||
| 62 | ;;; Function declarations | 63 | ;;; Function declarations |
| 63 | 64 | ||
| @@ -3861,6 +3862,28 @@ The delimiter between nested defun names is controlled by | |||
| 3861 | (setq node (treesit-node-parent node))) | 3862 | (setq node (treesit-node-parent node))) |
| 3862 | name)) | 3863 | name)) |
| 3863 | 3864 | ||
| 3865 | ;;; Prog mode | ||
| 3866 | |||
| 3867 | (defun treesit-fill-reindent-defun (&optional justify) | ||
| 3868 | "Refill/reindent the paragraph/defun that contains point. | ||
| 3869 | |||
| 3870 | This is a tree-sitter implementation of `prog-fill-reindent-defun'. | ||
| 3871 | |||
| 3872 | `treesit-major-mode-setup' assigns this function to | ||
| 3873 | `prog-fill-reindent-defun-function' if the major mode defines the | ||
| 3874 | `defun' thing. | ||
| 3875 | |||
| 3876 | JUSTIFY is the same as in `fill-paragraph'." | ||
| 3877 | (interactive "P") | ||
| 3878 | (save-excursion | ||
| 3879 | (if (prog--text-at-point-p) | ||
| 3880 | (fill-paragraph justify (region-active-p)) | ||
| 3881 | (let* ((treesit-defun-tactic 'parent-first) | ||
| 3882 | (node (treesit-defun-at-point))) | ||
| 3883 | (indent-region (treesit-node-start node) | ||
| 3884 | (treesit-node-end node) | ||
| 3885 | nil))))) | ||
| 3886 | |||
| 3864 | ;;; Imenu | 3887 | ;;; Imenu |
| 3865 | 3888 | ||
| 3866 | (defvar treesit-simple-imenu-settings nil | 3889 | (defvar treesit-simple-imenu-settings nil |
| @@ -4351,8 +4374,8 @@ and enable `font-lock-mode'. | |||
| 4351 | If `treesit-simple-indent-rules' is non-nil, set up indentation. | 4374 | If `treesit-simple-indent-rules' is non-nil, set up indentation. |
| 4352 | 4375 | ||
| 4353 | If `treesit-defun-type-regexp' is non-nil or `defun' is defined | 4376 | If `treesit-defun-type-regexp' is non-nil or `defun' is defined |
| 4354 | in `treesit-thing-settings', set up `beginning-of-defun-function' | 4377 | in `treesit-thing-settings', set up `beginning-of-defun-function', |
| 4355 | and `end-of-defun-function'. | 4378 | `end-of-defun-function', and `prog-fill-reindent-defun-function'. |
| 4356 | 4379 | ||
| 4357 | If `treesit-defun-name-function' is non-nil, set up | 4380 | If `treesit-defun-name-function' is non-nil, set up |
| 4358 | `add-log-current-defun'. | 4381 | `add-log-current-defun'. |
| @@ -4415,7 +4438,9 @@ before calling this function." | |||
| 4415 | ;; the variables. In future we should update `end-of-defun' to | 4438 | ;; the variables. In future we should update `end-of-defun' to |
| 4416 | ;; work with nested defuns. | 4439 | ;; work with nested defuns. |
| 4417 | (setq-local beginning-of-defun-function #'treesit-beginning-of-defun) | 4440 | (setq-local beginning-of-defun-function #'treesit-beginning-of-defun) |
| 4418 | (setq-local end-of-defun-function #'treesit-end-of-defun)) | 4441 | (setq-local end-of-defun-function #'treesit-end-of-defun) |
| 4442 | (setq-local prog-fill-reindent-defun-function | ||
| 4443 | #'treesit-fill-reindent-defun)) | ||
| 4419 | ;; Defun name. | 4444 | ;; Defun name. |
| 4420 | (when treesit-defun-name-function | 4445 | (when treesit-defun-name-function |
| 4421 | (setq-local add-log-current-defun-function | 4446 | (setq-local add-log-current-defun-function |