>> export const add = (a, b) -!- => a + b; >> >> typing 'C-M-f' should jump to the end of the next sexp >> (to the end of whole "binary_expression"): >> >> export const add = (a, b) => a + b-!-; >> >> since only tree-sitter knows about "binary_expression", >> so 'forward-sexp-default-function' can't be used here. > > Actually, I have one idea of possible heuristics: > > 1. first try 'forward-sexp-default-function' > 2. if it crosses the boundary of sexp defined by 'treesit-thing-settings' > then use 'treesit-end-of-thing' instead > > This should work. Ok, will try. This is implemented now in the attached patch, and it works nicely. The main rule is the following: 'forward-sexp-default-function' should not go out of the current thing, neither go inside a sibling. So we use 'treesit-end-of-thing' in such cases. But when inside a thing or outside a thing, use the default function. This supposes that such things as "identifier" in js should be removed from 'treesit-thing-settings' since identifiers should be navigated the same way as such keywords as "export" and "const" using 'forward-sexp-default-function'. What should remain in 'treesit-thing-settings' are only grouping constructs such as "parenthesized_expression" and "statement_block". Removing "identifier" from 'treesit-thing-settings' exposed a problem in 'treesit-navigate-thing'. This line ((and (null next) (null prev)) parent) tries to go out of the current thing to its parent, thus breaking the main principle that 'forward-sexp' should move forward across siblings only. But removing this line fixed the problem: