1 Star 0 Fork 0

Ray Yu/nvim-ts-context-commentstring

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

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 are ways to make this plugin more efficient with some commenting plugins. See the Integrations section for more information.

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
  • vue
  • handlebars
  • glimmer
  • graphql
  • lua

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.

Additionally, it is possible to have each commentstring configuration be a table with custom keys. This can be used to configure separate single and multi-line comment styles (useful when integrating with a commenting plugin):

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true,
    config = {
      typescript = { __default = '// %s', __multiline = '/* %s */' }
    }
  }
}

Then, the custom key can be passed to update_commentstring:

require('ts_context_commentstring.internal').update_commentstring({
  key = '__multiline',
})

Finally, it is possible to customize the tree traversal start location when calling update_commentstring, this is useful in commenting plugin integrations. There are some useful helper functions exported from ts_context_commentstring.utils:

require('ts_context_commentstring.internal').calculate_commentstring {
  location = require('ts_context_commentstring.utils').get_cursor_location(),
}

If you want to calculate your own commentstring you are able to do so with the custom_calculation option:

require'nvim-treesitter.configs'.setup {
  context_commentstring = {
    enable = true,
    custom_calculation = function(node, language_tree)
        ...
    end
  }
}

This is a function that takes in the current node and the language tree which could be used for context like figuring out which language you should use a commentstring for. You can also for example figure out which type the current node is. You need to return a commentstring in the custom_calculation if you want it to be set.

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.

Integrations

For some commenting plugins, it's possible to trigger the commentstring calculation only when it is actually needed. Some commenting plugins require more configuration than others.

Let me know if you'd like to see more integrations for other commenting plugins. A PR is always appreciated

vim-commentary

There is an existing integration with vim-commentary, which triggers the commentstring updating logic only when needed (before commenting with gc). If vim-commentary is detected, then this plugin automatically sets up vim-commentary mappings to first update the commentstring, and then trigger vim-commentary.

kommentary

kommentary can also trigger the commentstring updating logic before commenting. However, it requires some configuration to set up.

First, disable the CursorHold autocommand of this plugin:

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

Then, configure kommentary to trigger the commentstring updating logic with its hook_function configuration:

require('kommentary.config').configure_language('typescriptreact', {
  single_line_comment_string = 'auto',
  multi_line_comment_strings = 'auto',
  hook_function = function()
    require('ts_context_commentstring.internal').update_commentstring()
  end,
})

Note that currently the 'default' language configuration does not run hook_function, so explicit language configurations will need to be supplied as shown above. See issue #19.

nvim-comment

nvim-comment can easily be configured to trigger the commentstring updating logic before commenting.

First, disable the CursorHold autocommand of this plugin:

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

Then, configure nvim_comment to trigger the commentstring updating logic with its hook configuration:

require("nvim_comment").setup({
  hook = function()
    require("ts_context_commentstring.internal").update_commentstring()
  end,
})

Comment.nvim

First, disable the CursorHold autocommand of this plugin:

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

Then, configure Comment.nvim to trigger the commentstring updating logic with its pre_hook configuration (note that we can add some extra logic to improve the integration granularity):

require('Comment').setup {
  pre_hook = function(ctx)
    local U = require 'Comment.utils'

    local location = nil
    if ctx.ctype == U.ctype.block then
      location = require('ts_context_commentstring.utils').get_cursor_location()
    elseif ctx.cmotion == U.cmotion.v or ctx.cmotion == U.cmotion.V then
      location = require('ts_context_commentstring.utils').get_visual_start_location()
    end

    return require('ts_context_commentstring.internal').calculate_commentstring {
      key = ctx.ctype == U.ctype.line and '__default' or '__multiline',
      location = location,
    }
  end,
}

mini.comment

mini.comment also relies on commentstring option and implements hook functionality. It can be used to configure updating commentstring before commenting.

First, disable the CursorHold autocommand of this plugin:

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

Then, configure mini.comment to trigger the commentstring updating logic by supplying custom config.hooks.pre:

require('mini.comment').setup({
  hooks = {
    pre = function()
      require('ts_context_commentstring.internal').update_commentstring()
    end,
  },
})

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

MIT License Copyright (c) 2021 Joosep Alviste Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

暂无描述 展开 收起
README
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/rayycl/nvim-ts-context-commentstring.git
git@gitee.com:rayycl/nvim-ts-context-commentstring.git
rayycl
nvim-ts-context-commentstring
nvim-ts-context-commentstring
main

搜索帮助