Regenerate nvim config
This commit is contained in:
@ -0,0 +1,27 @@
|
||||
local M = {}
|
||||
|
||||
---Set up non-default configuration
|
||||
---@param config ts_context_commentstring.Config
|
||||
function M.setup(config)
|
||||
require('ts_context_commentstring.config').update(config)
|
||||
end
|
||||
|
||||
---Calculate the commentstring based on the current location of the cursor.
|
||||
---
|
||||
---@param args? ts_context_commentstring.Args
|
||||
---
|
||||
---@return string | nil commentstring If found, otherwise `nil`
|
||||
function M.calculate_commentstring(args)
|
||||
return require('ts_context_commentstring.internal').calculate_commentstring(args)
|
||||
end
|
||||
|
||||
---Update the `commentstring` setting based on the current location of the
|
||||
---cursor. If no `commentstring` can be calculated, will revert to the ofiginal
|
||||
---`commentstring` for the current file.
|
||||
---
|
||||
---@param args? ts_context_commentstring.Args
|
||||
function M.update_commentstring(args)
|
||||
return require('ts_context_commentstring.internal').update_commentstring(args)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,137 @@
|
||||
local M = {}
|
||||
|
||||
---A commentstring configuration that includes both single and multi-line
|
||||
---comments. The fields can be anything and they will be retrievable with the
|
||||
---`key` option to `update_commentstring`.
|
||||
---@class ts_context_commentstring.CommentConfigMultiple
|
||||
---@field __default string Single-line commentstring
|
||||
---@field __multiline string Multi-line commentstring
|
||||
|
||||
---Commentstring configuration can either be a string (a single commenting
|
||||
---style) or a table specifying multiple styles.
|
||||
---@alias ts_context_commentstring.CommentConfig string | ts_context_commentstring.CommentConfigMultiple
|
||||
|
||||
---The comment configuration for a language.
|
||||
---@alias ts_context_commentstring.LanguageConfig ts_context_commentstring.CommentConfig | table<string, ts_context_commentstring.CommentConfig>
|
||||
|
||||
---Configuration of the languages to commentstring configs.
|
||||
---
|
||||
---The configuration object keys should be **treesitter** languages, NOT
|
||||
---filetypes or file extensions.
|
||||
---
|
||||
---You can get the treesitter language for the current file by running this
|
||||
---command:
|
||||
---`:=vim.treesitter.get_parser():lang()`
|
||||
---
|
||||
---Or the injected language for a specific location:
|
||||
---`:=vim.treesitter.get_parser():language_for_range({ line, col, line, col }):lang())`
|
||||
---
|
||||
---@alias ts_context_commentstring.LanguagesConfig table<string, ts_context_commentstring.LanguageConfig>
|
||||
|
||||
---@class ts_context_commentstring.CommentaryConfig
|
||||
---@field Commentary string | false | nil
|
||||
---@field CommentaryLine string | false | nil
|
||||
---@field ChangeCommentary string | false | nil
|
||||
---@field CommentaryUndo string | false | nil
|
||||
|
||||
---@class ts_context_commentstring.Config
|
||||
---@field enable_autocmd boolean
|
||||
---@field custom_calculation? fun(node: TSNode, language_tree: LanguageTree): string
|
||||
---@field languages ts_context_commentstring.LanguagesConfig
|
||||
---@field config ts_context_commentstring.LanguagesConfig
|
||||
---@field commentary_integration ts_context_commentstring.CommentaryConfig
|
||||
|
||||
---@type ts_context_commentstring.Config
|
||||
M.config = {
|
||||
-- Whether to update the `commentstring` on the `CursorHold` autocmd
|
||||
enable_autocmd = true,
|
||||
|
||||
-- Custom logic for calculating the commentstring.
|
||||
custom_calculation = nil,
|
||||
|
||||
-- Keybindings to use for the commentary.nvim integration
|
||||
commentary_integration = {
|
||||
Commentary = 'gc',
|
||||
CommentaryLine = 'gcc',
|
||||
ChangeCommentary = 'cgc',
|
||||
CommentaryUndo = 'gcu',
|
||||
},
|
||||
|
||||
languages = {
|
||||
-- Languages that have a single comment style
|
||||
astro = '<!-- %s -->',
|
||||
c = { __default = '// %s', __multiline = '/* %s */' },
|
||||
cpp = { __default = '// %s', __multiline = '/* %s */' },
|
||||
css = '/* %s */',
|
||||
cue = '// %s',
|
||||
gleam = '// %s',
|
||||
glimmer = '{{! %s }}',
|
||||
go = { __default = '// %s', __multiline = '/* %s */' },
|
||||
graphql = '# %s',
|
||||
haskell = '-- %s',
|
||||
handlebars = '{{! %s }}',
|
||||
hcl = { __default = '# %s', __multiline = '/* %s */' },
|
||||
html = '<!-- %s -->',
|
||||
ini = '; %s',
|
||||
lua = { __default = '-- %s', __multiline = '--[[ %s ]]' },
|
||||
nix = { __default = '# %s', __multiline = '/* %s */' },
|
||||
php = { __default = '// %s', __multiline = '/* %s */' },
|
||||
python = { __default = '# %s', __multiline = '""" %s """' },
|
||||
rego = '# %s',
|
||||
rescript = { __default = '// %s', __multiline = '/* %s */' },
|
||||
scss = { __default = '// %s', __multiline = '/* %s */' },
|
||||
sh = '# %s',
|
||||
bash = '# %s',
|
||||
solidity = { __default = '// %s', __multiline = '/* %s */' },
|
||||
sql = '-- %s',
|
||||
svelte = '<!-- %s -->',
|
||||
terraform = { __default = '# %s', __multiline = '/* %s */' },
|
||||
twig = '{# %s #}',
|
||||
typescript = { __default = '// %s', __multiline = '/* %s */' },
|
||||
vim = '" %s',
|
||||
vue = '<!-- %s -->',
|
||||
zsh = '# %s',
|
||||
kotlin = { __default = '// %s', __multiline = '/* %s */' },
|
||||
roc = '# %s',
|
||||
|
||||
-- Languages that can have multiple types of comments
|
||||
tsx = {
|
||||
__default = '// %s',
|
||||
__multiline = '/* %s */',
|
||||
jsx_element = '{/* %s */}',
|
||||
jsx_fragment = '{/* %s */}',
|
||||
jsx_attribute = { __default = '// %s', __multiline = '/* %s */' },
|
||||
comment = { __default = '// %s', __multiline = '/* %s */' },
|
||||
call_expression = { __default = '// %s', __multiline = '/* %s */' },
|
||||
statement_block = { __default = '// %s', __multiline = '/* %s */' },
|
||||
spread_element = { __default = '// %s', __multiline = '/* %s */' },
|
||||
},
|
||||
},
|
||||
|
||||
---@deprecated Use the languages configuration instead!
|
||||
config = {},
|
||||
}
|
||||
|
||||
M.config.languages.javascript = M.config.languages.tsx
|
||||
|
||||
---@param config? ts_context_commentstring.Config
|
||||
function M.update(config)
|
||||
M.config = vim.tbl_deep_extend('force', M.config, config or {})
|
||||
end
|
||||
|
||||
---@return boolean
|
||||
function M.is_autocmd_enabled()
|
||||
if vim.g.loaded_commentary == 1 then
|
||||
return false
|
||||
end
|
||||
|
||||
local enable_autocmd = M.config.enable_autocmd
|
||||
return enable_autocmd == nil and true or enable_autocmd
|
||||
end
|
||||
|
||||
---@return ts_context_commentstring.LanguagesConfig
|
||||
function M.get_languages_config()
|
||||
return vim.tbl_deep_extend('force', M.config.languages, M.config.config)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,48 @@
|
||||
local M = {}
|
||||
|
||||
---Use this function to get a pre_hook function that can be used when
|
||||
---configuring Comment.nvim.
|
||||
---https://github.com/numToStr/Comment.nvim/
|
||||
---
|
||||
---Example usage:
|
||||
---```lua
|
||||
---require('Comment').setup {
|
||||
--- pre_hook = require('ts_context_commentstring.integrations.comment_nvim').create_pre_hook(),
|
||||
---}
|
||||
---```
|
||||
---
|
||||
---Feel free to copy this function into your own configuration if you need to
|
||||
---make any changes (or contribute the improvements back into this plugin).
|
||||
---
|
||||
---This is a higher order function in case we want to add any extra
|
||||
---configuration for the hook in the future.
|
||||
---
|
||||
---@return fun(ctx: CommentCtx): string|nil
|
||||
function M.create_pre_hook()
|
||||
---@param ctx CommentCtx
|
||||
---@return string|nil
|
||||
return function(ctx)
|
||||
local U = require 'Comment.utils'
|
||||
|
||||
-- Determine whether to use linewise or blockwise commentstring
|
||||
local type = ctx.ctype == U.ctype.linewise and '__default' or '__multiline'
|
||||
|
||||
-- Determine the location where to calculate commentstring from
|
||||
local location = nil
|
||||
if ctx.ctype == U.ctype.blockwise then
|
||||
location = {
|
||||
ctx.range.srow - 1,
|
||||
ctx.range.scol,
|
||||
}
|
||||
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').calculate_commentstring {
|
||||
key = type,
|
||||
location = location,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,47 @@
|
||||
local gmap = vim.api.nvim_set_keymap
|
||||
local bmap = vim.api.nvim_buf_set_keymap
|
||||
|
||||
for _, mode in ipairs { 'n', 'x', 'o' } do
|
||||
gmap(
|
||||
mode,
|
||||
'<Plug>ContextCommentary',
|
||||
[[v:lua.context_commentstring.update_commentstring_and_run('Commentary')]],
|
||||
{ expr = true }
|
||||
)
|
||||
end
|
||||
gmap(
|
||||
'n',
|
||||
'<Plug>ContextCommentaryLine',
|
||||
[[v:lua.context_commentstring.update_commentstring_and_run('CommentaryLine')]],
|
||||
{ expr = true }
|
||||
)
|
||||
gmap(
|
||||
'n',
|
||||
'<Plug>ContextChangeCommentary',
|
||||
[[v:lua.context_commentstring.update_commentstring_and_run('ChangeCommentary')]],
|
||||
{ expr = true }
|
||||
)
|
||||
|
||||
local M = {}
|
||||
|
||||
---Set up vim-commentary mappings to first update the commentstring, and then
|
||||
---run vim-commentary
|
||||
---@param maps ts_context_commentstring.CommentaryConfig
|
||||
function M.set_up_maps(maps)
|
||||
if maps.Commentary then
|
||||
for _, mode in ipairs { 'n', 'x', 'o' } do
|
||||
bmap(0, mode, maps.Commentary, '<Plug>ContextCommentary', {})
|
||||
end
|
||||
end
|
||||
if maps.CommentaryLine then
|
||||
bmap(0, 'n', maps.CommentaryLine, '<Plug>ContextCommentaryLine', {})
|
||||
end
|
||||
if maps.ChangeCommentary then
|
||||
bmap(0, 'n', maps.ChangeCommentary, '<Plug>ContextChangeCommentary', {})
|
||||
end
|
||||
if maps.CommentaryUndo then
|
||||
bmap(0, 'n', maps.CommentaryUndo, '<Plug>ContextCommentary<Plug>Commentary', {})
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,163 @@
|
||||
local api = vim.api
|
||||
|
||||
local utils = require 'ts_context_commentstring.utils'
|
||||
local config = require 'ts_context_commentstring.config'
|
||||
|
||||
local M = {}
|
||||
|
||||
---Initialize the plugin in the buffer
|
||||
---@param bufnr number
|
||||
function M.setup_buffer(bufnr)
|
||||
if not utils.is_treesitter_active(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Save the original commentstring so that it can be restored later if there
|
||||
-- is no match
|
||||
api.nvim_buf_set_var(bufnr, 'ts_original_commentstring', api.nvim_buf_get_option(bufnr, 'commentstring'))
|
||||
|
||||
local enable_autocmd = config.is_autocmd_enabled()
|
||||
|
||||
-- If vim-commentary is installed, set up mappings for it
|
||||
if vim.g.loaded_commentary == 1 then
|
||||
require('ts_context_commentstring.integrations.vim_commentary').set_up_maps(config.config.commentary_integration)
|
||||
end
|
||||
|
||||
if enable_autocmd then
|
||||
local group = api.nvim_create_augroup('context_commentstring_ft', { clear = true })
|
||||
api.nvim_create_autocmd('CursorHold', {
|
||||
buffer = bufnr,
|
||||
group = group,
|
||||
desc = 'Change the commentstring on cursor hold using Treesitter',
|
||||
callback = function()
|
||||
require('ts_context_commentstring').update_commentstring()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
---@class ts_context_commentstring.Args
|
||||
---@field key string Key to prefer to be returned from ts_context_commentstring.CommentConfigMultiple
|
||||
---@field location ts_context_commentstring.Location
|
||||
|
||||
---Calculate the commentstring based on the current location of the cursor.
|
||||
---
|
||||
---**Note:** We should treat this function like a public API, try not to break
|
||||
---it!
|
||||
---
|
||||
---@param args? ts_context_commentstring.Args
|
||||
---
|
||||
---@return string | nil commentstring If found, otherwise `nil`
|
||||
function M.calculate_commentstring(args)
|
||||
args = args or {}
|
||||
local key = args.key or '__default'
|
||||
local location = args.location or nil
|
||||
|
||||
local node, language_tree =
|
||||
utils.get_node_at_cursor_start_of_line(vim.tbl_keys(config.get_languages_config()), location)
|
||||
|
||||
if not node and not language_tree then
|
||||
return nil
|
||||
end
|
||||
|
||||
local custom_calculation = config.config.custom_calculation
|
||||
if custom_calculation then
|
||||
local commentstring = custom_calculation(node, language_tree)
|
||||
if commentstring then
|
||||
return commentstring
|
||||
end
|
||||
end
|
||||
|
||||
local language = language_tree:lang()
|
||||
local language_config = config.get_languages_config()[language]
|
||||
|
||||
return M.check_node(node, language_config, key)
|
||||
end
|
||||
|
||||
---Update the `commentstring` setting based on the current location of the
|
||||
---cursor. If no `commentstring` can be calculated, will revert to the ofiginal
|
||||
---`commentstring` for the current file.
|
||||
---
|
||||
---**Note:** We should treat this function like a public API, try not to break
|
||||
---it!
|
||||
---
|
||||
---@param args? ts_context_commentstring.Args
|
||||
function M.update_commentstring(args)
|
||||
local found_commentstring = M.calculate_commentstring(args)
|
||||
|
||||
if found_commentstring then
|
||||
api.nvim_buf_set_option(0, 'commentstring', found_commentstring)
|
||||
else
|
||||
-- No commentstring was found, default to the default for this buffer
|
||||
local original_commentstring = vim.b.ts_original_commentstring
|
||||
if original_commentstring then
|
||||
api.nvim_buf_set_option(0, 'commentstring', vim.b.ts_original_commentstring)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Check if the given node matches any of the given types. If not, recursively
|
||||
---check its parent node.
|
||||
---
|
||||
---@param node table
|
||||
---@param language_config ts_context_commentstring.LanguageConfig
|
||||
---@param commentstring_key string
|
||||
---
|
||||
---@return string | nil
|
||||
function M.check_node(node, language_config, commentstring_key)
|
||||
commentstring_key = commentstring_key or '__default'
|
||||
|
||||
-- There is no commentstring configuration for this language, use the
|
||||
-- `ts_original_commentstring`
|
||||
if not language_config then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- There is no node, we have reached the top-most node, use the default
|
||||
-- commentstring from language config
|
||||
if not node then
|
||||
return language_config[commentstring_key] or language_config.__default or language_config
|
||||
end
|
||||
|
||||
local node_type = node:type()
|
||||
local match = language_config[node_type]
|
||||
|
||||
if match then
|
||||
return match[commentstring_key] or match.__default or match
|
||||
end
|
||||
|
||||
-- Recursively check the parent node
|
||||
return M.check_node(node:parent(), language_config, commentstring_key)
|
||||
end
|
||||
|
||||
---@deprecated
|
||||
function M.attach()
|
||||
vim.deprecate(
|
||||
'context_commentstring nvim-treesitter module',
|
||||
"require('ts_context_commentstring').setup {} and set vim.g.skip_ts_context_commentstring_module = true to speed up loading",
|
||||
'in the future (see https://github.com/JoosepAlviste/nvim-ts-context-commentstring/issues/82 for more info)',
|
||||
'ts_context_commentstring'
|
||||
)
|
||||
config.update(require('nvim-treesitter.configs').get_module 'context_commentstring')
|
||||
end
|
||||
|
||||
---@deprecated
|
||||
function M.detach() end
|
||||
|
||||
_G.context_commentstring = {}
|
||||
|
||||
---Trigger re-calculation of the `commentstring` and trigger the given <Plug>
|
||||
---mapping right after that.
|
||||
---
|
||||
---This is in the global scope because
|
||||
---`v:lua.require('ts_context_commentstring')` does not work for some reason.
|
||||
---
|
||||
---@param mapping string The Plug mapping to execute
|
||||
---
|
||||
---@return string
|
||||
function _G.context_commentstring.update_commentstring_and_run(mapping)
|
||||
M.update_commentstring()
|
||||
return api.nvim_replace_termcodes('<Plug>' .. mapping, true, true, true)
|
||||
end
|
||||
|
||||
return M
|
||||
@ -0,0 +1,111 @@
|
||||
local api = vim.api
|
||||
local fn = vim.fn
|
||||
|
||||
---Coordinates for a location. Both the line and the column are 0-indexed (e.g.,
|
||||
---line nr 10 is line 9, the first column is 0).
|
||||
---@alias ts_context_commentstring.Location number[] 2-tuple of (line, column)
|
||||
|
||||
local M = {}
|
||||
|
||||
---Get the location of the cursor to be used to get the treesitter node
|
||||
---function.
|
||||
---
|
||||
---@return ts_context_commentstring.Location
|
||||
function M.get_cursor_location()
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
return { cursor[1] - 1, cursor[2] }
|
||||
end
|
||||
|
||||
---Get the location of the cursor line first non-blank character.
|
||||
---
|
||||
---@return ts_context_commentstring.Location
|
||||
function M.get_cursor_line_non_whitespace_col_location()
|
||||
local cursor = api.nvim_win_get_cursor(0)
|
||||
local first_non_whitespace_col = fn.match(fn.getline '.', '\\S')
|
||||
|
||||
return {
|
||||
cursor[1] - 1,
|
||||
first_non_whitespace_col,
|
||||
}
|
||||
end
|
||||
|
||||
---Get the location of the visual selection start.
|
||||
---
|
||||
---@return ts_context_commentstring.Location
|
||||
function M.get_visual_start_location()
|
||||
local first_non_whitespace_col = fn.match(fn.getline '.', '\\S')
|
||||
|
||||
return {
|
||||
vim.fn.getpos("'<")[2] - 1,
|
||||
first_non_whitespace_col,
|
||||
}
|
||||
end
|
||||
|
||||
---Get the location of the visual selection end.
|
||||
---
|
||||
---@return ts_context_commentstring.Location
|
||||
function M.get_visual_end_location()
|
||||
return {
|
||||
vim.fn.getpos("'>")[2] - 1,
|
||||
vim.fn.getpos("'>")[3] - 1,
|
||||
}
|
||||
end
|
||||
|
||||
---@return boolean
|
||||
---@param bufnr? number
|
||||
function M.is_treesitter_active(bufnr)
|
||||
bufnr = bufnr or 0
|
||||
|
||||
-- get_parser will throw an error if Treesitter is not set up for the buffer
|
||||
local ok, _ = pcall(vim.treesitter.get_parser, bufnr)
|
||||
|
||||
return ok
|
||||
end
|
||||
|
||||
---Get the node that is on the given location (default first non-whitespace
|
||||
---character of the cursor line). This also handles injected languages via
|
||||
---language tree.
|
||||
---
|
||||
---For example, if the cursor is at "|":
|
||||
--- | <div>
|
||||
---
|
||||
---then will return the <div> node, even though it isn't at the cursor position
|
||||
---
|
||||
---Returns the node at the cursor's line and the language tree for that
|
||||
---injection.
|
||||
---
|
||||
---@param only_languages string[] List of languages to filter for, all
|
||||
--- other languages will be ignored.
|
||||
---@param location? ts_context_commentstring.Location location Line, column
|
||||
--- where to start traversing the tree. Defaults to cursor start of line.
|
||||
--- This usually makes the most sense when commenting the whole line.
|
||||
---
|
||||
---@return table|nil node, table|nil language_tree Node and language tree for the
|
||||
--- location
|
||||
function M.get_node_at_cursor_start_of_line(only_languages, location)
|
||||
if not M.is_treesitter_active() then
|
||||
return
|
||||
end
|
||||
|
||||
location = location or M.get_cursor_line_non_whitespace_col_location()
|
||||
local range = {
|
||||
location[1],
|
||||
location[2],
|
||||
location[1],
|
||||
location[2],
|
||||
}
|
||||
|
||||
-- default to top level language tree
|
||||
local language_tree = vim.treesitter.get_parser()
|
||||
-- Get the smallest supported language's tree with nodes inside the given range
|
||||
language_tree:for_each_tree(function(_, ltree)
|
||||
if ltree:contains(range) and vim.tbl_contains(only_languages, ltree:lang()) then
|
||||
language_tree = ltree
|
||||
end
|
||||
end)
|
||||
|
||||
local node = language_tree:named_node_for_range(range)
|
||||
return node, language_tree
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user