Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

neovim + treesitter + vue.js + tcomment_vim not working in JS section #284

Closed
eduardoarandah opened this issue Mar 22, 2021 · 18 comments
Closed

Comments

@eduardoarandah
Copy link

Comments aren't working fine with treesitter

I'm not sure if this is an issue to be reported here or in https://github.com/ikatyang/tree-sitter-vue
so I'll post in both sites

neovim + treesitter commenting the same in html, js

image

Debug info:

:echo tcomment#debug#CollectInfo()

on template section:

TCOMMENT: &ft = vue => vue
TCOMMENT: stx =  => 
TCOMMENT: ct  = {'_args': {'beg': 98, 'fallbackFiletype': '', 'end': 98, 'filetype': 'vue', 'comment_mode': ''}, 'commentstring': '/*%s*/', 'mode': '', 'whitespace': 'both'}

on js section:


TCOMMENT: &ft = vue => vue
TCOMMENT: stx =  => 
TCOMMENT: ct  = {'_args': {'beg': 115, 'fallbackFiletype': '', 'end': 115, 'filetype': 'vue', 'comment_mode': ''}, 'commentstring': '/*%s*/', 'mode': '', 'whitespace': 'both'}

vim + polyglot works fine!

image

on template part:

TCOMMENT: &ft = vue => vue
TCOMMENT: stx = htmlTag => htmlTag
TCOMMENT: ct  = {'_args': {'beg': 55, 'fallbackFiletype': '', 'end': 55, 'filetype': 'vue', 'comment_mode': ''}, 'commentstring': '<!-- %s -->', 'replacements': {'&': '&#38;', '-': '&#45;'}, 'mode': '', 'filetype': 'html'}

on js part:

TCOMMENT: &ft = vue => vue
TCOMMENT: stx = jsObjectSeparator => javascriptObjectSeparator
TCOMMENT: ct  = {'rxmid': '', 'rxend': '', '_args': {'beg': 76, 'fallbackFiletype': '', 'end': 76, 'filetype': 'vue', 'comment_mode': ''}, 'commentstring': '// %s', 'commentstring_rx': '\%%(// %s\|/* %s */\)', 'mode': '', 'filetype': 'javascript', 'replacements': {'*/': {'subst': '|)}>#', 'guard_rx': '^\s*/\?\*'}, '/*': {'subst': '#<{(|', 'guard_rx': '^\s*/\?\*'}}, 'rxbeg': '\*\+'}
@eduardoarandah
Copy link
Author

issue also reported in ikatyang/tree-sitter-vue#8

@eduardoarandah
Copy link
Author

If you're here with same issue, you can use non-treesitter syntax with:

if (has("nvim"))
  " Treesitter
  Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}  " We recommend updating the parsers on update
endif

" also install Vue syntax
Plug 'posva/vim-vue', { 'for': ['vue' ] }

and later, add disable to vue

" treesitter enable
if (has("nvim"))
lua <<EOF
require'nvim-treesitter.configs'.setup {
  ensure_installed ={ "javascript", "json", "css", .... here others....  }, -- one of "all", "maintained" (parsers with maintainers), or a list of languages
  highlight = {
    enable = true,
    disable = { "vue" }
  },
  indent = {
    enable = false
  },
}
EOF
endif

@gegoune
Copy link

gegoune commented Mar 22, 2021

Not sure that disabling treesitter should be an acceptable solution here.

@eduardoarandah
Copy link
Author

Not sure that disabling treesitter should be an acceptable solution here.

@cloggier Agree. It's just a temporary workaround.
In debug info there's some clues on what might be happening: 'posva/vim-vue' reports filetype: html and javascript.
treesitter reports "vue" everywhere

I'd be glad to help but I've no idea how treesitter-vue works

@gegoune
Copy link

gegoune commented Mar 22, 2021

treesitter-vue does very little actually, it only injects other languages for each block (js, css, html). It shouldn't be over complicated to retrieve what parser/grammar is used in a block under cursor and set comment string accordingly.

@gegoune
Copy link

gegoune commented Mar 26, 2021

And @JoosepAlviste did just that in amazing https://github.com/JoosepAlviste/nvim-ts-context-commentstring, which works with any commentstringbased commenting plugin.

@eduardoarandah
Copy link
Author

@cloggier thanks for the tip!

Installed that plugin and is setting up comment string correctly https://github.com/JoosepAlviste/nvim-ts-context-commentstring

However, tcomment is not commenting based on that info.

(Moved to https://github.com/tpope/vim-commentary/ and it works fine)

Cursor in JS part:

image

Cursor in HTML part:

image

@tomtom
Copy link
Owner

tomtom commented Mar 28, 2021

tcomment also uses commentstring if no special comment definition is defined. If tcomment doesn't use commentstring, then something in autoload/tcomment/types/default.vim or maybe syntax based syntax definition interferes with it.

I don't do JS/JSX/etc myself so I have to rely on pull requests from users. My main problem with these bug reports is that they are selfcontradictory and inconsistent to some extent -- at least that what it appears to me.

I a simpler comment plugin suffices for you needs please use that one.

If you want to continue using tcomment, please tell me exactly what kind of behaviour you observe under exacly which conditions and what behaviour you expect. Just telling me "Comments aren't working fine with treesitter" isn't exactly useful because I have no idea what treesitter is and I don't have the time to look it up.

@eduardoarandah
Copy link
Author

@tomtom neovim 0.5 (not released yet, stable is 0.4.4) is promoting treesitter as an alternative to vim regex-based syntax.

Treesitter is a parsing library (builds a syntax tree) and is supposed to have advantages over regex.

Is there a list of variables that I can dump to make this issue productive? this might be an issue with the other plugin (treesitter) not this one, of course!

Links:

https://github.com/nvim-treesitter/nvim-treesitter

https://github.com/tree-sitter/tree-sitter

@tomtom
Copy link
Owner

tomtom commented Mar 29, 2021 via email

@eduardoarandah
Copy link
Author

I've little experience with this, if you want to play with treesitter parsing, you can do this:

  1. install neovim nightly https://gist.github.com/eduardoarandah/40e18928363d0462b30aa18ffe2e1fbe

  2. In your .vimrc add treesitter and the playground. Example with VimPlug:

if (has("nvim"))
  " Treesitter
  Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}  " We recommend updating the parsers on update
  Plug 'nvim-treesitter/playground' 
endif

  1. After call plug#end() configure treesitter, example:
" treesitter enable
if (has("nvim"))
lua <<EOF
require'nvim-treesitter.configs'.setup {
  ensure_installed ={ "javascript", "json", "css", "php", "html", "python", "bash", "regex", "ruby", "yaml", "jsonc", "tsx", "lua", "vue" }, -- one of "all", "maintained" (parsers with maintainers), or a list of languages
  highlight = {
    enable = true,
    disable = { "php" },  -- list of language that will be disabled
  },
  indent = {
    enable = false
  },
}
EOF
endif

  1. Now you can see treesitter parsing with TSPlayground check video:
Grabacion.de.pantalla.2021-03-29.a.la.s.14.15.02.mov.mp4

I don't know much more about how to query the parser to get the exact syntax info.
This plugin code might be helpful: https://github.com/JoosepAlviste/nvim-ts-context-commentstring

@tomtom
Copy link
Owner

tomtom commented Mar 30, 2021 via email

@WhyNotHugo
Copy link

I'm having the same issue too (pretty much same setup: nvim + treesitter).

The issue is just with vuejs files (which embed multiple languages into different blocks). No matter where I comment, this plugin always uses <-- %s --> to comment -- which is not valid in javascript blocks.

In other words, it seems that the plugin won't properly detect which language is the one under the cursor.

I hacked around this for a while (this was challenging, but I'm happy with the solution I've found), and managed to write this snippet to determine the language at the cursor's current position. It works with just one level of nested languages, which I think is a reasonable limitation:

local function print_language_at_cursor()
  local parsers = require("nvim-treesitter.parsers")

  local root = parsers.get_parser()
  local cursor = vim.api.nvim_win_get_cursor(0)

  local range = { cursor[1], cursor[2], cursor[1], cursor[2] }
  local node_lang = root

  -- TODO: Should be able to use `root:for_each_tree()` with a callback to get
  -- the last leaf language that contains this range.
  for _, child in pairs(root:children()) do
    if child:contains(range) then
      node_lang = child
    end
  end

  print(vim.inspect(node_lang:lang()))
end
-- Mapping I used to test this:
vim.keymap.set("n", "<Leader>I", print_language_at_cursor)

I tested this with vue files, and it recognises typescript and css just fine. The HTML portion is recognised as vue, but that's kind find, since both vue and html use the same comment format (this is also the correct language, since them template portion of vue files has special syntax that's not strictly HTML).

@WhyNotHugo
Copy link

WhyNotHugo commented Apr 23, 2022

Oh, this is actually pretty close to what Comment.nvim does, so I think I'll just use that (it seems like a better fit for neovim+treesitter) never mind, it has all kind of quirky bugs.

Thanks for this plugin; it's served me well many many years! 🍻

@WhyNotHugo
Copy link

So I guess that including a bunch of lua code inside this plugin is too out-of-scope, and explicit tree-sitter support might be too invasive.

As a less invasive approach, I wonder if a new setting could be added (something like tcomment#commentstringFunc) which is a function that one can provide and returns the commentstring that should be used.

So basically, if this is set try and use it to determine commentstring, otherwise, use commentstring normally.

The key details her is that since this is a function, it can return a new value for commentstring depending on the current cursor position.

Thoughts?

@tomtom tomtom closed this as completed in 7fb091a Apr 24, 2022
@tomtom
Copy link
Owner

tomtom commented Apr 24, 2022 via email

@WhyNotHugo
Copy link

Yup, I noticed that some plugins do that, but it seems inefficient, there's a lot of parsing and work getting done on each CursorHold. I'd rather the work be done only when needed (e.g.: when actually commenting a line).

Thanks for the change, I'll figure out the rest and leave the result for reference in case anyone else is interested.

@tomtom
Copy link
Owner

tomtom commented Oct 11, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants