>> From: Yang Yingchao >> Date: Wed, 13 Sep 2023 08:41:27 +0800 >> >> >>> Date: Tue, 12 Sep 2023 12:41:32 +0800 >> >>> From: Yang Yingchao via "Bug reports for GNU Emacs, >> >>> the Swiss army knife of text editors" >> >>> >> >>> It seams that there is an issue with the behavior of `treesit-beginning-of-defun` function in >> >>> `c++-ts-mode` when there are static variables present in the source code. For instance, in the >> >>> provided code snippet, if the cursor is initially placed on the line containing `int b`, and the >> >>> "C-M-a" is pressed, the cursor is positioned on line 4 instead of line 1 where the beginning of >> >>> the function is located. >> >>> >> >>> ,---- >> >>> | void func // c-ts-mode: treesit-beginning-of-defun stops in this line, RIGHT >> >>> | { >> >>> | char * msg; >> >>> | static int a; // c++-ts-mode: treesit-beginning-of-defun stops in this line, WRONG >> >>> | int b; // PUT CUSOR HERE >> >>> | } >> >>> `---- >> >>> >> >>> it works in c-ts-mode works normally. >> >> >> >> If you want c++-ts-mode to work like c-ts-mode, set >> >> treesit-defun-tactic to 'top-level'. By default, we try to support >> >> nested defuns in C++, but not in C. >> > >> > >> > I apologize, but I realized that I have already asked this question before. >> > >> > However, setting 'treesit-defun-tactic' to 'top-level' could cause other >> > issues, as seen in the following snippets: >> > >> > >> > ,---- >> > | class Name { >> > | public: >> > | Name() >> > | { >> > | // cursor here >> > | } >> > | >> > | void func() >> > | { >> > | static int a; >> > | } >> > | >> > | }; >> > `---- >> > >> > Suppose the cursor is in line 5, and "C-M-a" is pressed: >> > >> > - In 'c++-mode', the cursor will be moved to the start of the function 'Name()', which is the expected behavior. >> > - In 'c++-ts-mode': >> > - With 'treesit-defun-tactic' set to 'nested', it behaves the same as in 'c++-mode'. >> > - With 'treesit-defun-tactic' set to 'top-level', the cursor is moved to the beginning of >> > the class, i.e., line 1. >> > >> > Is it possible to make 'c++-ts-mode' behave the same as in 'c++-mode'? >> > >> > Regards. >> >> Maybe I'm wrong, but I would like to suggest reconsidering the solution to the >> 'begging-of-defun' issue related to the static *variable*. It feels strange to me to fix this >> issue by changing the 'treesit-defun-tactic', which is meant to apply to a *function* >> literally... > > Yuan, any ideas or suggestions? Just FYI, I made some modifications to 'treesit--navigate-thing' in my own branch to fix this specific issue: ,---- | 1 file changed, 8 insertions(+) | lisp/treesit.el | 8 ++++++++ | | modified lisp/treesit.el | @@ -2092,6 +2092,14 @@ treesit--navigate-thing | (pcase-let | ((`(,prev ,next ,parent) | (treesit--things-around pos regexp pred))) | + | + ;; YYC: Special handling for static variable inside defun... | + (when (and (equal (treesit-node-type prev) | + "storage_class_specifier") | + (equal (treesit-node-type (treesit-node-parent prev)) | + "declaration")) | + (setq prev nil)) | + | ;; When PARENT is nil, nested and top-level are the same, if | ;; there is a PARENT, make PARENT to be the top-level parent | ;; and pretend there is no nested PREV and NEXT. | `----