mickeynp / combobulate

Structured Editing and Navigation in Emacs with Tree-Sitter
GNU General Public License v3.0
918 stars 53 forks source link

Python annotation navigation behaviors #92

Open 2kays opened 6 months ago

2kays commented 6 months ago

In Python, hierarchical navigations behave unexpectedly (to me) with annotations and function definitions (in master).

Example code:

@|annot # descending from here takes me to the function arglist
def fun1(): return 1
| # can't prev/up navigate

|@|annot() # hierarchical nav can never enter function definition for these cursors
def fun2(): return 2
| # can't up/prev navigate 
(decorated_definition
 (decorator @ (identifier))
 definition: 
  (function_definition def name: (identifier)
   parameters: (parameters ( ))
   :
   body: 
    (block
     (return_statement return (integer)))))

Something similar may also be happening with try-except; I'm struggling to get into the except handler.

mickeynp commented 6 months ago

Getting into except from 'try' is not easy because it's a child of the whole try_statement, so sibling navigation from try to except is not possible.

Well, it is, and I did try it for a while, but changing the sibling procedure to handle it breaks in other weird ways: you'd be able to drag an except clause out of a try statement, which makes no sense. This is one of those quirks of how our perception of code does not match the grammar.

You're definitely right that decorators do not behave well at all. That's a bug :)

2kays commented 6 months ago

I can confirm there is no hierarchical nav tool that can get me into except:

|try:| # nope, nope
    |pass| # nope, nope
except KeyError:
    pass

I see a double body: in the explorer:

(try_statement try :
  body: 
   (block
    (pass_statement pass))
  body: 
   (except_clause except (identifier) :
    (block
     (pass_statement pass))))