mirror of
https://github.com/windwp/nvim-ts-autotag.git
synced 2024-12-29 13:39:15 -06:00
fix bug and update
This commit is contained in:
parent
6be1192965
commit
8515e48a27
@ -23,8 +23,6 @@ M.tbl_skipTag = {
|
||||
'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr', 'menuitem'
|
||||
}
|
||||
|
||||
local ERROR_TAG = "ERROR"
|
||||
|
||||
-- stylua: ignore
|
||||
local HTML_TAG = {
|
||||
filetypes = {
|
||||
@ -35,13 +33,13 @@ local HTML_TAG = {
|
||||
'php',
|
||||
'xml',
|
||||
},
|
||||
start_tag_pattern = 'start_tag',
|
||||
start_name_tag_pattern = 'tag_name',
|
||||
end_tag_pattern = "end_tag",
|
||||
end_name_tag_pattern = "tag_name",
|
||||
close_tag_pattern = 'erroneous_end_tag',
|
||||
close_name_tag_pattern = 'erroneous_end_tag_name',
|
||||
element_tag = 'element',
|
||||
start_tag_pattern = { 'start_tag' },
|
||||
start_name_tag_pattern = { 'tag_name' },
|
||||
end_tag_pattern = { 'end_tag' },
|
||||
end_name_tag_pattern = { 'tag_name' },
|
||||
close_tag_pattern = { 'erroneous_end_tag' },
|
||||
close_name_tag_pattern = { 'erroneous_end_tag_name' },
|
||||
element_tag = { 'element' },
|
||||
skip_tag_pattern = { 'quoted_attribute_value', 'end_tag' },
|
||||
}
|
||||
-- stylua: ignore
|
||||
@ -50,13 +48,13 @@ local JSX_TAG = {
|
||||
'typescriptreact', 'javascriptreact', 'javascript.jsx',
|
||||
'typescript.tsx', 'javascript', 'typescript', 'rescript'
|
||||
},
|
||||
start_tag_pattern = 'jsx_opening_element|start_tag',
|
||||
start_name_tag_pattern = 'identifier|nested_identifier|tag_name|jsx_identifier',
|
||||
end_tag_pattern = 'jsx_closing_element|end_tag',
|
||||
end_name_tag_pattern = 'identifier|tag_name',
|
||||
close_tag_pattern = 'jsx_closing_element|nested_identifier|jsx_identifier|erroneous_end_tag|end_tag',
|
||||
close_name_tag_pattern = 'identifier|nested_identifier|jsx_identifier|erroneous_end_tag_name|tag_name',
|
||||
element_tag = 'jsx_element|element',
|
||||
start_tag_pattern = { 'jsx_opening_element', 'start_tag' },
|
||||
start_name_tag_pattern = { 'identifier', 'nested_identifier', 'tag_name', 'member_expression', 'jsx_identifier' },
|
||||
end_tag_pattern = { 'jsx_closing_element', 'end_tag' },
|
||||
end_name_tag_pattern = { 'identifier', 'tag_name' },
|
||||
close_tag_pattern = { 'jsx_closing_element', 'nested_identifier' },
|
||||
close_name_tag_pattern = { 'member_expression', 'nested_identifier', 'jsx_identifier', 'identifier', '>' },
|
||||
element_tag = { 'jsx_element', 'element' },
|
||||
skip_tag_pattern = {
|
||||
'jsx_closing_element', 'jsx_expression', 'string', 'jsx_attribute', 'end_tag',
|
||||
'string_fragment'
|
||||
@ -68,13 +66,13 @@ local JSX_TAG = {
|
||||
-- stylua: ignore
|
||||
local HBS_TAG = {
|
||||
filetypes = { 'glimmer', 'handlebars', 'hbs', 'htmldjango' },
|
||||
start_tag_pattern = 'element_node_start',
|
||||
start_name_tag_pattern = 'tag_name',
|
||||
end_tag_pattern = 'element_node_end',
|
||||
end_name_tag_pattern = 'tag_name',
|
||||
close_tag_pattern = 'element_node_end',
|
||||
close_name_tag_pattern = 'tag_name',
|
||||
element_tag = 'element_node',
|
||||
start_tag_pattern = { 'element_node_start' },
|
||||
start_name_tag_pattern = { 'tag_name' },
|
||||
end_tag_pattern = { 'element_node_end' },
|
||||
end_name_tag_pattern = { 'tag_name' },
|
||||
close_tag_pattern = { 'element_node_end' },
|
||||
close_name_tag_pattern = { 'tag_name' },
|
||||
element_tag = { 'element_node' },
|
||||
skip_tag_pattern = { 'element_node_end', 'attribute_node', 'concat_statement' },
|
||||
}
|
||||
|
||||
@ -82,13 +80,13 @@ local HBS_TAG = {
|
||||
-- stylua: ignore
|
||||
local SVELTE_TAG = {
|
||||
filetypes = { 'svelte' },
|
||||
start_tag_pattern = 'start_tag',
|
||||
start_name_tag_pattern = 'tag_name',
|
||||
end_tag_pattern = 'end_tag',
|
||||
end_name_tag_pattern = 'tag_name',
|
||||
close_tag_pattern = 'ERROR',
|
||||
close_name_tag_pattern = 'ERROR',
|
||||
element_tag = 'element',
|
||||
start_tag_pattern = { 'start_tag' },
|
||||
start_name_tag_pattern = { 'tag_name' },
|
||||
end_tag_pattern = { 'end_tag' },
|
||||
end_name_tag_pattern = { 'tag_name' },
|
||||
close_tag_pattern = { 'ERROR' },
|
||||
close_name_tag_pattern = { 'ERROR', 'erroneous_end_tag_name' },
|
||||
element_tag = { 'element' },
|
||||
skip_tag_pattern = { 'quoted_attribute_value', 'end_tag' },
|
||||
}
|
||||
|
||||
@ -99,7 +97,7 @@ local all_tag = {
|
||||
}
|
||||
M.enable_rename = true
|
||||
M.enable_close = true
|
||||
M.enable_close_on_slash = true
|
||||
M.enable_close_on_slash = false
|
||||
|
||||
M.setup = function(opts)
|
||||
opts = opts or {}
|
||||
@ -183,8 +181,7 @@ local function find_child_match(opts)
|
||||
if target == nil or pattern == nil then
|
||||
return nil
|
||||
end
|
||||
local tbl_pattern = vim.split(pattern, "|")
|
||||
for _, ptn in pairs(tbl_pattern) do
|
||||
for _, ptn in pairs(pattern) do
|
||||
for node in target:iter_children() do
|
||||
local node_type = node:type()
|
||||
if node_type ~= nil and node_type == ptn and not is_in_table(skip_tag_pattern, node_type) then
|
||||
@ -202,8 +199,7 @@ local function find_parent_match(opts)
|
||||
if target == nil or pattern == nil then
|
||||
return nil
|
||||
end
|
||||
local tbl_pattern = vim.split(pattern, "|")
|
||||
for _, ptn in pairs(tbl_pattern) do
|
||||
for _, ptn in pairs(pattern) do
|
||||
local cur_node = target
|
||||
local cur_depth = 0
|
||||
while cur_node ~= nil do
|
||||
@ -248,6 +244,7 @@ local function find_tag_node(opt)
|
||||
pattern = tag_pattern,
|
||||
skip_tag_pattern = skip_tag_pattern,
|
||||
})
|
||||
|
||||
else
|
||||
node = find_parent_match({
|
||||
target = target,
|
||||
@ -258,31 +255,17 @@ local function find_tag_node(opt)
|
||||
if node == nil then
|
||||
return nil
|
||||
end
|
||||
local name_node = node
|
||||
local tbl_name_pattern = {}
|
||||
if string.match(name_tag_pattern, "%|") then
|
||||
tbl_name_pattern = vim.split(name_tag_pattern, "|")
|
||||
for _, pattern in pairs(tbl_name_pattern) do
|
||||
name_node = find_child_match({
|
||||
target = node,
|
||||
pattern = pattern,
|
||||
})
|
||||
if name_node then
|
||||
return name_node
|
||||
end
|
||||
end
|
||||
local name_node = find_child_match({
|
||||
target = node,
|
||||
pattern = name_tag_pattern,
|
||||
})
|
||||
if name_node then
|
||||
return name_node
|
||||
end
|
||||
|
||||
tbl_name_pattern = vim.split(name_tag_pattern, ">")
|
||||
for _, pattern in pairs(tbl_name_pattern) do
|
||||
name_node = find_child_match({
|
||||
target = name_node,
|
||||
pattern = pattern,
|
||||
})
|
||||
end
|
||||
|
||||
-- check current node is have same name of tag_match
|
||||
if is_in_table(tbl_name_pattern, node:type()) then
|
||||
if is_in_table(name_tag_pattern, node:type()) then
|
||||
return node
|
||||
end
|
||||
return name_node
|
||||
@ -298,11 +281,6 @@ local function find_start_tag(current)
|
||||
if not ts_tag then
|
||||
return nil
|
||||
end
|
||||
|
||||
if current:type() ~= "ERROR" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local target = nil
|
||||
|
||||
target = find_child_match({
|
||||
@ -333,8 +311,9 @@ local function check_close_tag(close_slash_tag)
|
||||
if close_slash_tag then
|
||||
-- Find start node from non closed tag
|
||||
local current = ts_utils.get_node_at_cursor()
|
||||
|
||||
-- log.debug(current)
|
||||
target = find_start_tag(current)
|
||||
-- log.debug(target)
|
||||
end
|
||||
|
||||
local tag_node = find_tag_node({
|
||||
@ -407,7 +386,7 @@ local function replace_text_node(node, tag_name)
|
||||
if start_row == end_row then
|
||||
local line = vim.fn.getline(start_row + 1)
|
||||
local newline = line:sub(0, start_col) .. tag_name .. line:sub(end_col + 1, string.len(line))
|
||||
vim.fn.setline(start_row + 1, { newline })
|
||||
vim.api.nvim_buf_set_lines(0, start_row, start_row + 1, true, { newline })
|
||||
end
|
||||
end
|
||||
|
||||
@ -422,10 +401,6 @@ local function validate_tag_regex(node, start_regex, end_regex)
|
||||
return false
|
||||
end
|
||||
|
||||
-- local function validate_tag(node)
|
||||
-- return validate_tag_regex(node,"^%<","%>$")
|
||||
-- end
|
||||
|
||||
local function validate_start_tag(node)
|
||||
return validate_tag_regex(node, "^%<%w", "%>$")
|
||||
end
|
||||
@ -457,7 +432,7 @@ local function rename_start_tag()
|
||||
|
||||
tag_node = find_parent_match({
|
||||
target = parent_node,
|
||||
pattern = ts_tag.element_tag .. "|" .. ERROR_TAG,
|
||||
pattern = ts_tag.element_tag,
|
||||
max_depth = 2,
|
||||
})
|
||||
|
||||
@ -471,6 +446,7 @@ local function rename_start_tag()
|
||||
name_tag_pattern = ts_tag.close_name_tag_pattern,
|
||||
})
|
||||
|
||||
|
||||
if close_tag_node == nil then
|
||||
close_tag_node = find_child_tag_node({
|
||||
target = tag_node:parent(),
|
||||
@ -480,38 +456,25 @@ local function rename_start_tag()
|
||||
end
|
||||
|
||||
if close_tag_node ~= nil then
|
||||
local error_node = find_child_match({
|
||||
target = tag_node,
|
||||
pattern = ERROR_TAG,
|
||||
})
|
||||
if error_node == nil then
|
||||
log.debug("do replace")
|
||||
local close_tag_name = get_tag_name(close_tag_node)
|
||||
log.debug(close_tag_name)
|
||||
|
||||
-- verify parent node is same of close_tag_node (test case: 22)
|
||||
if close_tag_node ~= nil and tag_node ~= nil then
|
||||
local tag_parent = get_tag_name(tag_node:parent())
|
||||
-- log.debug(utils.dump_node(tag_node:parent()))
|
||||
if tag_parent == close_tag_name and not utils.verify_node(tag_node:parent(), close_tag_name) then
|
||||
log.debug("skip it have same")
|
||||
return
|
||||
end
|
||||
log.debug(close_tag_node:type())
|
||||
local close_tag_name = get_tag_name(close_tag_node)
|
||||
-- verify parent node is same of close_tag_node (test case: 22)
|
||||
if close_tag_node ~= nil and tag_node ~= nil then
|
||||
local tag_parent = get_tag_name(tag_node:parent())
|
||||
-- log.debug(utils.dump_node(tag_node:parent()))
|
||||
if tag_parent == close_tag_name and not utils.verify_node(tag_node:parent(), close_tag_name) then
|
||||
log.debug("skip it have same")
|
||||
return
|
||||
end
|
||||
|
||||
if tag_name ~= close_tag_name then
|
||||
replace_text_node(close_tag_node, tag_name)
|
||||
end
|
||||
else
|
||||
local error_tag = get_tag_name(error_node)
|
||||
-- tsx node is empty
|
||||
if error_tag == "</>" then
|
||||
replace_text_node(error_node, "</" .. tag_name .. ">")
|
||||
end
|
||||
-- have both parent node and child node is error
|
||||
if close_tag_node:type() == ERROR_TAG then
|
||||
replace_text_node(error_node, "</" .. tag_name .. ">")
|
||||
end
|
||||
if tag_name ~= close_tag_name then
|
||||
-- log.debug("do replace")
|
||||
-- log.debug(tag_name)
|
||||
-- log.debug(close_tag_name)
|
||||
if close_tag_name == '>' then
|
||||
tag_name = tag_name .. '>'
|
||||
end
|
||||
replace_text_node(close_tag_node, tag_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -525,7 +488,6 @@ local function rename_end_tag()
|
||||
tag_pattern = ts_tag.close_tag_pattern,
|
||||
name_tag_pattern = ts_tag.close_name_tag_pattern,
|
||||
})
|
||||
-- log.debug(tag_node:type())
|
||||
if tag_node == nil then
|
||||
return
|
||||
end
|
||||
@ -549,30 +511,36 @@ local function rename_end_tag()
|
||||
tag_pattern = ts_tag.start_tag_pattern,
|
||||
name_tag_pattern = ts_tag.start_name_tag_pattern,
|
||||
})
|
||||
if not validate_start_tag(start_tag_node:parent()) then
|
||||
if start_tag_node and not validate_start_tag(start_tag_node:parent()) then
|
||||
return
|
||||
end
|
||||
if start_tag_node ~= nil then
|
||||
local start_tag_name = get_tag_name(start_tag_node)
|
||||
if tag_name ~= start_tag_name then
|
||||
log.debug('replace end tag')
|
||||
replace_text_node(start_tag_node, tag_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function validate_rename()
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local char = line:sub(cursor[2] + 1, cursor[2] + 1)
|
||||
-- only rename when last character is a word
|
||||
if string.match(char, "%w") then
|
||||
return true
|
||||
local function is_before(regex, range)
|
||||
return function()
|
||||
local cursor = vim.api.nvim_win_get_cursor(0)
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local char = line:sub(cursor[2] + range, cursor[2] + range)
|
||||
-- only rename when last character is a word
|
||||
if string.match(char, regex) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local is_before_word = is_before('%w', 1)
|
||||
local is_before_arrow = is_before('<', 0)
|
||||
|
||||
M.rename_tag = function()
|
||||
if validate_rename() and parsers.has_parser() then
|
||||
if is_before_word() and parsers.has_parser() then
|
||||
parsers.get_parser():parse()
|
||||
rename_start_tag()
|
||||
rename_end_tag()
|
||||
@ -586,6 +554,7 @@ M.attach = function(bufnr, lang)
|
||||
|
||||
if is_in_table(M.tbl_filetypes, vim.bo.filetype) then
|
||||
setup_ts_tag()
|
||||
local group = vim.api.nvim_create_augroup('nvim-ts-autotag', { clear = true })
|
||||
if M.enable_close == true then
|
||||
vim.api.nvim_buf_set_keymap(bufnr or 0, "i", ">", ">", {
|
||||
noremap = true,
|
||||
@ -605,7 +574,10 @@ M.attach = function(bufnr, lang)
|
||||
callback = function()
|
||||
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
vim.api.nvim_buf_set_text(bufnr or 0, row - 1, col, row - 1, col, { "/" })
|
||||
M.close_slash_tag()
|
||||
if is_before_arrow() then
|
||||
log.debug('is_before_arrow')
|
||||
M.close_slash_tag()
|
||||
end
|
||||
local new_row, new_col = unpack(vim.api.nvim_win_get_cursor(0))
|
||||
vim.api.nvim_win_set_cursor(0, { new_row, new_col + 1 })
|
||||
end,
|
||||
@ -614,6 +586,7 @@ M.attach = function(bufnr, lang)
|
||||
if M.enable_rename == true then
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_create_autocmd("InsertLeave", {
|
||||
group = group,
|
||||
buffer = bufnr,
|
||||
callback = M.rename_tag,
|
||||
})
|
||||
|
@ -16,9 +16,6 @@ const SamplePage: React.FC = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,24 +1,8 @@
|
||||
if not _G.test_close then
|
||||
return
|
||||
end
|
||||
|
||||
local ts = require('nvim-treesitter.configs')
|
||||
local helpers = {}
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
highlight = { enable = true },
|
||||
})
|
||||
local eq = assert.are.same
|
||||
|
||||
function helpers.feed(text, feed_opts)
|
||||
feed_opts = feed_opts or 'n'
|
||||
local to_feed = vim.api.nvim_replace_termcodes(text, true, false, true)
|
||||
vim.api.nvim_feedkeys(to_feed, feed_opts, true)
|
||||
end
|
||||
|
||||
function helpers.insert(text)
|
||||
helpers.feed('a' .. text, 'x')
|
||||
end
|
||||
|
||||
local data = {
|
||||
{
|
||||
@ -193,6 +177,5 @@ describe('[close slash tag]', function()
|
||||
_G.Test_withfile(run_data, {
|
||||
mode = 'i',
|
||||
cursor_add = 0,
|
||||
before_each = function(value) end,
|
||||
})
|
||||
end)
|
||||
|
@ -1,24 +1,8 @@
|
||||
if not _G.test_close then
|
||||
return
|
||||
end
|
||||
|
||||
local ts = require('nvim-treesitter.configs')
|
||||
local helpers = {}
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
highlight = { enable = true },
|
||||
})
|
||||
local eq = assert.are.same
|
||||
|
||||
function helpers.feed(text, feed_opts)
|
||||
feed_opts = feed_opts or 'n'
|
||||
local to_feed = vim.api.nvim_replace_termcodes(text, true, false, true)
|
||||
vim.api.nvim_feedkeys(to_feed, feed_opts, true)
|
||||
end
|
||||
|
||||
function helpers.insert(text)
|
||||
helpers.feed('a' .. text, 'x')
|
||||
end
|
||||
|
||||
local data = {
|
||||
{
|
||||
|
@ -26,13 +26,16 @@ set foldlevel=9999
|
||||
|
||||
lua << EOF
|
||||
_G.__is_log=true
|
||||
_G.test_rename = true
|
||||
_G.test_close = true
|
||||
_G.ts_filetypes = {
|
||||
'html', 'javascript', 'typescript', 'svelte', 'vue', 'tsx', 'php', 'glimmer', 'rescript', 'embedded_template'
|
||||
}
|
||||
require("plenary/busted")
|
||||
vim.cmd[[luafile ./tests/test-utils.lua]]
|
||||
require("nvim-ts-autotag").setup()
|
||||
require("nvim-ts-autotag").setup({
|
||||
enable = true,
|
||||
enable_rename = true,
|
||||
enable_close = true,
|
||||
enable_close_on_slash = true,
|
||||
})
|
||||
EOF
|
||||
|
||||
|
@ -1,30 +1,13 @@
|
||||
local ts = require 'nvim-treesitter.configs'
|
||||
|
||||
local log = require('nvim-ts-autotag._log')
|
||||
|
||||
if not _G.test_rename then
|
||||
return
|
||||
end
|
||||
|
||||
local helpers = {}
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
highlight = {
|
||||
use_languagetree = true,
|
||||
use_languagetree = false,
|
||||
enable = true,
|
||||
},
|
||||
fold = { enable = false },
|
||||
})
|
||||
|
||||
function helpers.feed(text, feed_opts)
|
||||
feed_opts = feed_opts or 'n'
|
||||
local to_feed = vim.api.nvim_replace_termcodes(text, true, false, true)
|
||||
vim.api.nvim_feedkeys(to_feed, feed_opts, true)
|
||||
end
|
||||
|
||||
function helpers.insert(text)
|
||||
helpers.feed('i' .. text, 'x')
|
||||
end
|
||||
|
||||
local data = {
|
||||
{
|
||||
|
@ -1,5 +1,4 @@
|
||||
local utils = require('nvim-ts-autotag.utils')
|
||||
local _, ts_utils = pcall(require, 'nvim-treesitter.ts_utils')
|
||||
local log = require('nvim-ts-autotag._log')
|
||||
local api = vim.api
|
||||
|
||||
@ -59,8 +58,7 @@ local compare_text = function(linenr, text_after, name, cursor_add, end_cursor)
|
||||
)
|
||||
for i = 1, #text_after, 1 do
|
||||
local t = string.gsub(text_after[i], '%|', '')
|
||||
if
|
||||
t
|
||||
if t
|
||||
and new_text[i]
|
||||
and t:gsub('%s+$', '') ~= new_text[i]:gsub('%s+$', '')
|
||||
then
|
||||
@ -175,16 +173,16 @@ _G.Test_withfile = function(test_data, cb)
|
||||
end
|
||||
|
||||
_G.dump_node = function(node)
|
||||
local text = ts_utils.get_node_text(node)
|
||||
local text = utils.get_node_text(node)
|
||||
for _, txt in pairs(text) do
|
||||
print(txt)
|
||||
log.debug(txt)
|
||||
end
|
||||
end
|
||||
|
||||
_G.dump_node_text = function(target)
|
||||
for node in target:iter_children() do
|
||||
local node_type = node:type()
|
||||
local text = ts_utils.get_node_text(node)
|
||||
local text = utils.get_node_text(node)
|
||||
log.debug('type:' .. node_type .. ' ')
|
||||
log.debug(text)
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user