neovim
neovim copied to clipboard
feat(comment): allow commentstring to be determined from node metadata
Problem: Some weird languages have different comment syntax depending on the location in the code, and we do not have a way to determine the correct commentstring for these special cases.
Solution: Allow queries to specify commentstring values in metadata, allowing users/nvim-treesitter to provide a better commenting experience without hugely increasing the scope of the code in core.
Fixes #28830
Where should this be documented?
I was wondering the same. Maybe in treesitter.txt in a similar section under *treesitter-highlight-priority*? There are a few sections in there related to special metadata stuff
I don't think this should be specific to commentstring, at least at the underlying function level (it's ok at the metadata level for now, unless we can think of a way to generalize this too). Can't this support any vim.filetype.get_option?
Sorry, I don't really understand what this would look like. Are you just saying to modify the helper function the be able to extract any option (not just commentstring)? Also when would it be helpful/make sense to set a different option in the metadata?
Hypothetically, what other options could this potentially be useful for? Are there any options like commentstring where the option may be different line by line?
Some ideas:
expandtabin Makefiles? Recipe lines should have hard tabs, whereas variable logic ~should~ can be indented with spaces.'breakat'(though this is a global option)'equalprg''formatprj','formatexpr''indentexpr''iskeyword''filetype'?
Though I'd imagine in practice most of these would be handled via injections instead of this.
@ribru17, is traversing the output of vim.treesitter.get_captures_at_pos() backwards enough to guarantee that the "most narrow" capture is used? Because skipping manual traversing for this step is a big win. Could you, please, add a test for how it works with separate "conflicting" captures (because right now it looks like traverse forward would also pass the tests).
And if the current implementation is good from tree-sitter POV, it can be visibly simplified. I'll test and post suggestions tomorrow.
@ribru17, is traversing the output of
vim.treesitter.get_captures_at_pos()backwards enough to guarantee that the "most narrow" capture is used?
I am 99% sure it is, though I don't know if we have a test for get_captures_at_pos() ensuring this. That said I've added a test for the inner metadata logic, so I think all functionality is tested now
As for the generic helper function, it sorta depends on another PR I will put out soon (which depends on #30514, due to a small conflict)
I don't think this should be specific to
commentstring, at least at the underlying function level (it's ok at the metadata level for now, unless we can think of a way to generalize this too). Can't this support anyvim.filetype.get_option?
@clason this PR may have changed since your comment, but is this still an open question / blocker? Does the "generalize _get_urls" TODO capture your suggestion?
Hypothetically, what other options could this potentially be useful for? Are there any options like
commentstringwhere the option may be different line by line
@lewis6991 are you suggesting something like:
((list) @_list (#set! @_list option.foo "..."))
or something else?
Yeah something like that. Clason suggested making this more generic, so I was just going through the thought process of any hypothetical benefits if we were to do that. The fact this is done using the #set! directive means we don't need any upstream support or community alignment to implement this.
Yes, I think it should be generic on the level of the queries/metadata, but I have been convinced that it makes sense for the actual feature/Lua implementation to be specific to commentstring.
Idea: Use bo.foo or wo.foo for symmetry with the Lua API (aids discoverability and reinforces domain knowledge)?
Would this look like using wo.foo as a table key or creating a wo table within metadata, then using foo for its key?
I didn't envision any table handling (yet; that can come later under the hood if that makes things easier); I was thinking merely as a namespace (alternative to options.commentstring -> bo.commentstring).
Is it possible to add this to the 0.11 milestone?
If it's done before 0.11 is released (which doesn't look imminent), it'll be included. I don't think it needs to block the release (which is what the milestone is for).
If it's done before 0.11 is released (which doesn't look imminent), it'll be included. I don't think it needs to block the release (which is what the milestone is for).
Is there anything left to do here?
Hypothetically, what other options could this potentially be useful for? Are there any options like commentstring where the option may be different line by line
Could this approach be used to tackle #32129?
No. What's needed is to rewrite that functionality from scratch based on treesitter indentation. (But not node-level metadata.)