kyazdani42 / nvim-ts-context-commentstring

Neovim treesitter plugin for setting the commentstring based on the cursor location in a file.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

nvim-ts-context-commentstring

A Neovim plugin for setting the commentstring option based on the cursor location in the file. The location is checked via treesitter queries.

This is useful when there are embedded languages in certain types of files. For example, Vue files can have many different sections, each of which can have a different style for comments.

Note that this plugin only changes the commentstring setting. It does not add any mappings for commenting. It is recommended to use a commenting plugin like vim-commentary alongside this plugin.

Demo gif

Getting started

Requirements:

Installation:

Use your favorite plugin manager. For example, here's how it would look like with Packer:

use 'JoosepAlviste/nvim-ts-context-commentstring'

Setup:

Enable the module from nvim-treesitter setup

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true
  }
}

Don't forget to use lua heredoc if you're using init.vim

Recommended: Using a commenting plugin

It is recommended to use a commenting plugin like vim-commentary together with this plugin. vim-commentary provides the mappings for commenting which use the commentstring setting. This plugin adds to that by correctly setting the commentstring setting so that vim-commentary can do its thing even in more complex filetypes.

There is an additional integration with vim-commentary specifically, which optimizes the commentstring updating logic so that it is not run unnecessarily. If vim-commentary is detected, then this plugin automatically sets up vim-commentary mappings to first update the commentstring, and then trigger vim-commentary.

Let me know if you'd like a similar integration for another commenting plugin.

Configuration

Adding support for more languages

Currently, the following languages are supported when they are injected with language tree (see lua/ts_context_commentstring/internal.lua):

  • javascript
  • typescript
  • tsx
  • css
  • scss
  • php
  • html
  • svelte

This means that in any filetype, if the given languages are injected, this plugin should detect them and correctly set the commentstring. For example, Vue files can be injected with css or javascript. Even though we don't configure anything for Vue explicitly, the commentstring updating logic should still work.

Support for more languages can be added quite easily by passing a config table when configuring the plugin:

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true,
    config = {
      css = '// %s'
    }
  }
}

Additionally, some languages are not injected with language tree, but have multiple commenting styles in the same language. One such example is JavaScript with JSX. The JSX section is not an injected language, but a part of the tree generated by the javascript treesitter parser.

In this more complex case, this plugin supports adding queries for specific treesitter nodes. Each node can have its own unique commenting style. For example, here's how the default configuration for javascript would look like:

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true,
    config = {
      javascript = {
        __default = '// %s',
        jsx_element = '{/* %s */}',
        jsx_fragment = '{/* %s */}',
        jsx_attribute = '// %s',
        comment = '// %s'
      }
    }
  }
}

The __default value is used when none of the other node types are seen. The rest of the keys refer to the type of the treesitter node. In this example, if your cursor is inside a jsx_element, then the {/* %s */} commentstring will be set.

Note that the language refers to the treesitter language, not the filetype or the file extension.

Behavior

The default behavior is to trigger commentstring updating on CursorHold. If your updatetime setting is set to a high value, then the updating might not be triggered. Let me know if you'd like to have this be customized by creating an issue. Another candidate might be the CursorMoved autocommand.

The default CursorHold autocommand can be disabled by passing enable_autocmd = false when setting up the plugin:

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true,
    enable_autocmd = false,
  }
}

Then, you can call the update_commentstring function manually:

nnoremap <leader>c <cmd>lua require('ts_context_commentstring.internal').update_commentstring()<cr>

Note: It is not necessary to use this option if you are using vim-commentary, the integration is set up automatically.

More demos

React:

React demo gif

Svelte:

Svelte demo gif

HTML:

HTML demo gif

Nesting:

I injected HTML into JavaScript strings and created multiple levels of nesting with language tree. This sort of nesting of languages works without any extra configuration in the plugin.

Nesting demo gif

About

Neovim treesitter plugin for setting the commentstring based on the cursor location in a file.

License:MIT License


Languages

Language:Lua 99.4%Language:Vim Script 0.6%