Subject: bug#78503: 30.0.92; tree-sitter elixir-ts-mode structural movement broken

From: Juri Linkov <[email-masked]>
Date: Tue, 20 May 2025 19:46:02 +0300

>>> 1.) `defmodule` is considered a function definition and so moving up from the first
>>> actual function definition `def my_fun do` causes the point to jump to
>>> 'defmodule my_mod do'. Invoking `end-of-defun` jumps to the end of the defmodule block.
>>> Effectively, you have been ejected from the module body.
>>>
>>
>> This behavior may look logically flawed,
>> but still it makes sense for user convenience:
>> while navigating with 'C-M-a' it's handy
>> to use the same key to move over modules too.
>
> This would be convenient if list-down would make you jump into the
> module body, ready for a jump to the next defun. But currently it does
> not.

This is exactly what 'down-list' does after removing
'treesit-cycle-sexp-type' from 'elixir-ts-mode'.  (You can use
the command 'M-x treesit-cycle-sexp-type RET' to toggle interactively.)

So 'C-M-f' navigation should use the 'sexp' thing
while 'C-M-d' should use 'list' thing.

Then let's add a new variable like 'treesit-sexp-type-regexp'
e.g. named 'treesit-down-list-regexp' (maybe without a command
to toggle it).

> Also Elixir files usually have only one module, so the optimalization
> to move to other modules might have more downsides than advantages.

Agreed.

>>> 2.) When you use `down-list` while on a function definition line,
>>> nothing happens. I tried to fix it, ony to find out that
>>> `backward-up-list` will jump to `defmodule` when invoked while point is at a
>>> function argument, instead of navigating out of the argument list only.  
>>>
>>> Structural movement might need some extra love.
>>
>> This part is not reproducible.  Do you use the latest master?
>
> Now I do. The issue does not replicate in the same way, but still the
> behavior is unextected to me and less convienient than hoped for.
>
> ```
> def foo(arg) do
>    IO.inspect("some")
> end
> ```
>
> Expected:
> - into args
> - nice to have: into do block (after do)
> - into argument list
> - into quoted string

This is exactly how 'C-M-d' already works when you toggle
'M-x treesit-cycle-sexp-type RET'.

> Actual:
> - after def
> - after closing paren
> - after do
> - onto opening paren
> - into argument list
> - into quoted string
>
> ```
> defmodule Foo do
>    def my_fun(), do: :bar
> end
> ```
>
> Expected:
> - into module body (after do)

This is what 'C-M-d' already does after 'M-x treesit-cycle-sexp-type RET'.
So let's enable 'treesit-cycle-sexp-type' by default, but only for 'down-list'.

> Actual:
> - after defmodule
> - after Foo
> - into module body (after do)

Ok, I will create a new variable 'treesit-down-list-regexp' for 'down-list'.