Package: emacs;
Reported by: Eli Zaretskii <eliz <at> gnu.org>
Date: Sun, 2 Mar 2025 08:55:02 UTC
Severity: normal
Found in version 30.1.50
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Message #31 received at 76676 <at> debbugs.gnu.org (full text, mbox):
From: Juri Linkov <juri <at> linkov.net> To: Yuan Fu <casouri <at> gmail.com> Cc: Eli Zaretskii <eliz <at> gnu.org>, 76676 <at> debbugs.gnu.org Subject: Re: bug#76676: 30.1.50; C-M-b in c-ts-mode moves too far Date: Tue, 18 Mar 2025 19:49:01 +0200
[Message part 1 (text/plain, inline)]
> The only ts-mode where the 'sexp' thing is well defined is c-ts-mode with > > (sexp (not ,(rx (or "{" "}" "[" "]" "(" ")" ",")))) > > All other ts-modes contain desperate attempts to emulate the > traditional behavior to navigate symbols with the 'sexp' thing. > But symbol navigation is now implemented as the default behavior. > > So these ts-modes should be fixed based on the pattern in c-ts-mode. > Then after toggling to the sexp mode they will navigate all ts nodes > except nodes that define boundaries. Ok, here is more complete patch with a small improvement in c-ts-mode, and using the same pattern in java/css/ruby-ts-mode:
[treesit-toggle-sexp-mode.patch (text/x-diff, inline)]
diff --git a/lisp/treesit.el b/lisp/treesit.el index 46332cb1e4b..f5cd3f2067c 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3310,6 +3317,24 @@ treesit-end-of-thing (when dest (goto-char dest)))) +(defun treesit-toggle-sexp-mode () + "Toggle the mode of navigation for sexp commands." + (interactive) + (when (treesit-thing-defined-p 'list nil) + (setq-local treesit-sexp-type-regexp + (unless treesit-sexp-type-regexp + (if (treesit-thing-defined-p 'sexp nil) + 'sexp + #'treesit-node-named)) + forward-sexp-function + (if treesit-sexp-type-regexp + #'treesit-forward-sexp + #'treesit-forward-sexp-list)) + (message "Toggle to mode where sexp commands navigate %s" + (or (and treesit-sexp-type-regexp + "treesit nodes") + "syntax symbols and treesit lists")))) + (defun treesit-beginning-of-defun (&optional arg) "Move backward to the beginning of a defun. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index fa5f8567b60..285d38e6411 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -1194,7 +1194,11 @@ c-ts-mode--emacs-current-defun-name (defvar c-ts-mode--thing-settings `(;; It's more useful to include semicolons as sexp so ;; that users can move to the end of a statement. - (sexp (not ,(rx (or "{" "}" "[" "]" "(" ")" ",")))) + (sexp (not (or (and named + ,(rx bos (or "translation_unit") eos)) + (and anonymous + ,(rx (or "{" "}" "[" "]" "(" ")" + "," ";")))))) (list ,(regexp-opt '("preproc_params" "preproc_if" diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index c4b2282b574..cd18d6d1e28 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -436,19 +436,12 @@ java-ts-mode (setq-local treesit-thing-settings `((java - (sexp ,(rx (or "annotation" - "parenthesized_expression" - "argument_list" - "identifier" - "modifiers" - "block" - "body" - "literal" - "access" - "reference" - "_type" - "true" - "false"))) + (sexp (not (or (and named + ,(rx bos (or "program") eos)) + (and anonymous + ,(rx (or "{" "}" "[" "]" + "(" ")" "<" ">" + "," ";")))))) (list ,(rx bos (or "inferred_parameters" "parenthesized_expression" "argument_list" diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 1594f301641..e8fb0f62d46 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el @@ -1167,52 +1167,17 @@ ruby-ts-mode (setq-local treesit-thing-settings `((ruby - (sexp ,(cons (rx - bos - (or - "class" - "singleton_class" - "module" - "method" - "singleton_method" - "array" - "hash" - "parenthesized_statements" - "method_parameters" - "array_pattern" - "hash_pattern" - "if" - "else" - "then" - "unless" - "case" - "case_match" - "when" - "while" - "until" - "for" - "block" - "do_block" - "begin" - "integer" - "identifier" - "self" - "super" - "constant" - "simple_symbol" - "hash_key_symbol" - "symbol_array" - "string" - "string_array" - "heredoc_body" - "regex" - "argument_list" - "interpolation" - "instance_variable" - "global_variable" - ) - eos) - #'ruby-ts--sexp-p)) + (sexp (not (or (and named + ,(rx bos (or "program" + "body_statement" + "then") + eos)) + (and anonymous + ,(rx (or "do" "begin" + "if" "unless" + "def" "end" + "{" "}" "[" "]" + "(" ")" "[" "]" "|")))))) (list ,(cons (rx bos (or diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 02c3618d281..9d063646184 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1781,7 +1781,13 @@ css--extract-index-name res))))))) (defvar css--treesit-thing-settings - `((css (list + `((css (sexp + (not (or (and named + ,(rx bos (or "stylesheet") eos)) + (and anonymous + ,(rx (or "{" "}" "[" "]" "(" ")" + "," ";")))))) + (list ,(rx bos (or "keyframe_block_list" "block" "pseudo_class_arguments"
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.