tree-sitter-grammars / tree-sitter-markdown

Markdown grammar for tree-sitter
MIT License
427 stars 56 forks source link

bug: a `list_item` does not work well as a textobject #154

Open oblitzitate opened 5 months ago

oblitzitate commented 5 months ago

Did you check existing issues?

Tree-Sitter CLI Version, if relevant (output of tree-sitter --version)

tree-sitter 0.22.6 (b40f342067a89cd6331bf4c27407588320f3c263)

Describe the bug

When you operate on list_item as a text object (e.g. in neovim), it will not manipulate the document as expected. The issue arises because it contains block_continuation at its last part. See examples below.

Steps To Reproduce/Bad Parse Tree

I set a query for the list item:

;; queries/markdown/textobjects.scm
(list_item) @list_item.outer

Then I set it as a textobject:

-- lua/plugins/mini-ai.lua
local mini_ai = require("mini.ai")
local gen_spec = mini_ai.gen_spec
return mini_ai.setup({
    custom_textobjects = {
        u = gen_spec.treesitter({
            a = "@list_item.outer",
            i = "@list_item.outer"
        })
    }
})

Given the following markdown document (with the cursor represented as |)...

- Elements
 |  - Water
    - Earth

A paragraph.
;; Syntax tree for reference
(list
  (list_item
    (list_marker_minus)
    (paragraph
      (inline
        (inline))
      (block_continuation))
    (list
      (list_item
        (list_marker_minus)
        (paragraph
          (inline
            (inline))
          (block_continuation)))
      (list_item
        (list_marker_minus)
        (paragraph
          (inline
            (inline))
          (block_continuation))))))
(paragraph
  (inline
    (inline))))))

... if I apply "delete around/inside the list item textobject" at the cursor, I expect it to delete the - Water line, but instead it deletes the entire list:

A paragraph.

And if I apply it when the cursor is at the following...

- Elements
    - Water
    - Earth|

A paragraph.

...it will delete not just the - Earth part, but also the line under it, which is unexpected:

- Elements
    - Water
A paragraph.

The issue occurs because list_item encapsulates the block_continuation as the last part of its node.

Expected Behavior/Parse Tree

I expected the first example to result in:

- Elements
    - Earth

A paragraph.

And I expected the second example to result in:

- Elements
    - Water

A paragraph.

Repro

No response

mawkler commented 3 months ago

I was just about to create the same issue! Perhaps this could be solved by including leading block_continuation in list_item, instead of using the trailing one (i.e. the one on the next line)?

Here's an example of what I mean. The characters above the ^^ mark the captured block_continuation and the ones above ~~~ the rest of the list_item capture for the - Water line.

Current behaviour where trailing block_continuation is used:

- Elements
  - Water
  ~~~~~~~
  - Earth
^^

Desired behaviour where the leading block_continuation is used:

- Elements
  - Water
^^~~~~~~~
  - Earth