MeanderingProgrammer / markdown.nvim

Plugin to improve viewing Markdown files in Neovim
MIT License
504 stars 20 forks source link

bug: Incorrect language selector for code blocks #44

Closed sergey-tikhonenko closed 2 weeks ago

sergey-tikhonenko commented 2 weeks ago

Neovim version (nvim -v)

NVIM v0.10.0 Build type: Release LuaJIT 2.1.1713484068

Operating system

Linux, Ubuntu 22.04.4 LTS

Terminal emulator / GUI

kitty 0.21.2

Describe the bug

The plugin doesn't support all forms of the language specification for code blocks that are supported by the Markdown Treesitter parser.

изображение

The language selector here should be (info_string (language)) instead of (info_string).

изображение

изображение

The Treesitter markdown parser explicitly identifies the separate language node in the AST, leaving the surroundings unspecified.

See also the snippet below with several options for specifying the code block language:

The ordinary code block with the short form language.

```python
print("Hello")

Code blocks that use braces around the language name (e.g. ```{python}) are executable, and will be run by Quarto during render. Treesitter supports this form.

```{python}
1 + 1

изображение

This is code block with the short form language and separate attributes. Treesitter supports this form.

```python  {.numberLines filename="hello.py"}
print("Hello")

изображение

This code block with the Pandoc form language and attributes. At the moment Treesitter doesn't recognise the language for this form.

```{.python  .numberLines filename="hello.py"}
print("Hello")

изображение

Expected behavior

The plugin for language detection should use the (info_string (language)) selector instead of (info_string).

Additional information

The functionality was added during the "Feature: add language icon for code block" (6eef62c) implementation.

MeanderingProgrammer commented 2 weeks ago

That makes sense, was not even aware of all of these options for code blocks, neat!

Have pushed a fix here: https://github.com/MeanderingProgrammer/markdown.nvim/commit/90072fdbc28042add4cd08bef282df032bf6ac42.

LMK how it works!

sergey-tikhonenko commented 2 weeks ago

Works as expected. Thanks.

изображение

Ideally it might display the filename next to the language, but this requires the Markdown Treesitter parser support for the attribute map.

MeanderingProgrammer commented 2 weeks ago

Do have any special conceal logic removing the attribute map?

For me the attribute map stays in the 3rd example, like in this demo: https://github.com/MeanderingProgrammer/markdown.nvim/blob/main/demo/heading_code.gif

sergey-tikhonenko commented 2 weeks ago

Thanks for the question.

I thought it was your plugin that conceals attributes, but there were my custom Treesitter rules. This was an attempt to conceal the curly braces around the language while there are no other attributes.

; hide curly braces for quatro files
 (fenced_code_block
   (info_string) @label
   (#set! conceal ""))

But this doesn't work if any attributes are specified.

Not sure if conditions are supported in the Treesitter rules. Need to checked, if not, then only a custom handler can help in the case.

изображение

In 4th case I was wrong - Treesitter supports this form too. This highlighting doesn't work.

изображение

Thus to correctly determine the snippet language, you need to take into account that might be the dot in the beginning.

sergey-tikhonenko commented 2 weeks ago

It seems the plugin hides the language name if its symbol is not found.

изображение

Here is the mermaid code block. Both the Treesitter parser and highlighting work correctly, but the language name is disappeared.

flowchart LR
  A[Hard edge] --> B(Round edge)
  B --> C{Decision}
  C --> D[Result one]
  C --> E[Result two]

изображение

sergey-tikhonenko commented 2 weeks ago

LazyVim replaces nvim-tree/nvim-web-devicons with echasnovski/mini.icons. This give better integrations (more languages). There are also defaults for unknown languages, so the language name does not disappear in the above mentioned cases.

image

MeanderingProgrammer commented 2 weeks ago

Thanks for the heads up!

Added support for mini.icons here: https://github.com/MeanderingProgrammer/markdown.nvim/commit/353e4459938dd58873772e27a45c1d92bc83bafc.

Gets used instead of nvim-web-devicons when its available.

sergey-tikhonenko commented 2 weeks ago

Just for a feedback.

Finally, I've got a configuration that satisfy my needs for now. To hide the curly braces, I have to write a small custom handler:

custom_handlers = {
  markdown = {
    -- hides curly braces around the language line for code blocks
    render = function(namespace, root, buf)
      local query = vim.treesitter.query.parse("markdown", "(info_string) @_info")
      for _, node in query:iter_captures(root, buf) do
        local value = vim.treesitter.get_node_text(node, buf)
        local start_row, start_col, end_row, end_col = node:range()
        local start_match, _, start_meta, end_meta = string.find(value, "^%s*{%s*().*()%s*}%s*$")
        if start_match then
          vim.api.nvim_buf_set_extmark(buf, namespace, start_row, start_col, {
            end_row = start_row,
            end_col = start_col + start_meta - 1,
            conceal = "",
          })
          vim.api.nvim_buf_set_extmark(buf, namespace, end_row, start_col + end_meta - 1, {
            end_row = end_row,
            end_col = end_col,
            conceal = "",
          })
        end
      end
    end,
    extends = true,
  },
},

Might be this will be useful for someone.

image

sergey-tikhonenko commented 1 week ago

In 90072fd you use virt_text_pos = 'inline' relying on default highlighting NeoVim configuration for markdown. Where the language node is concealed.

I've faced with an environment where user has his own ~/.config/nvim/queries/markdown/highlights.scm due to conceal directives can't be reverted. And, among other things, concealment of the the language node is not enabled.

Enabling the plugin in such environment results in duplication in the language name.

image

I don't know how it might be fixed without change users highlights.scm. Possible some check for region concealment. Don't have enough experience in Neovim machinery.

MeanderingProgrammer commented 1 week ago

Yeah, that is definitely a growing trend of issues.

I'm going to track that here: https://github.com/MeanderingProgrammer/markdown.nvim/issues/50, see if I can think of a reasonable approach to it.