use endwise

This commit is contained in:
windwp 2021-04-18 22:06:11 +07:00 committed by windwp
parent 3b2fba3ac5
commit 460cdfce42
11 changed files with 309 additions and 12 deletions

View File

@ -27,6 +27,15 @@ M.add_rule = function (rule)
table.insert(M.config.rules, rule)
end
M.add_rules = function (rules)
for _, rule in pairs(rules) do
table.insert(M.config.rules, rule)
end
end
M.clear_rules = function()
M.config.rules = {}
end
M.disable=function()
state.disabled = true
@ -36,12 +45,6 @@ M.enable = function()
state.disabled = false
end
M.add_rules = function (rules)
for _, rule in pairs(rules) do
table.insert(M.config.rules, rule)
end
end
M.on_attach = function(bufnr)
if state.disabled then return end
bufnr = bufnr or api.nvim_get_current_buf()
@ -160,6 +163,7 @@ M.autopairs_insert = function(bufnr, char)
end
M.autopairs_cr = function(bufnr)
log.debug("on_cr")
if state.disabled then return end
bufnr = bufnr or api.nvim_get_current_buf()
local line = utils.text_get_current_line(bufnr)
@ -167,20 +171,48 @@ M.autopairs_cr = function(bufnr)
local filetype = vim.bo.filetype
for _, rule in pairs(state.rules) do
if rule.start_pair and utils.check_filetype(rule.filetypes, filetype) then
local prev_char = utils.text_sub_char(line, col,-#rule.start_pair)
local next_char = utils.text_sub_char(line, col+1,#rule.end_pair)
local prev_char, next_char = utils.text_cusor_line(
line,
col,
#rule.start_pair,
#rule.end_pair, rule.is_regex
)
log.debug(vim.inspect( prev_char))
if
rule.start_pair == prev_char
and rule.end_pair == next_char
rule.is_endwise
and utils.is_equal(rule.start_pair, prev_char, rule.is_regex)
and rule:can_cr({
check_ts = true,
bufnr = bufnr,
rule = rule,
prev_char = prev_char,
next_char = next_char,
line = line
})
then
log.debug('correct_endwise')
return utils.esc(
rule.end_pair
.. utils.repeat_key(utils.key.left, 3)
.."<cr><esc><<O"
)
end
if
rule.start_pair == prev_char
and rule.end_pair == next_char
and rule:can_cr({
check_ts = false,
bufnr = bufnr,
rule = rule,
prev_char = prev_char,
next_char = next_char,
line = line
})
then
log.debug('map _cr')
return utils.esc("<cr><c-o>O")
end
log.debug("end_cr")
end
end
return utils.esc("<cr>")

View File

@ -26,10 +26,19 @@ function Rule.new(...)
del_cond = {},
cr_cond = {},
pair_cond = {},
-- only use on end_wise
is_endwise = false,
-- use regex to compalre
is_regex = false
},opt)
return setmetatable(opt, {__index = Rule})
end
function Rule:use_regex(value)
self.is_regex = value
return self
end
function Rule:with_move(cond)
if self.move_cond == nil then self.move_cond = {}end
table.insert(self.move_cond, cond)
@ -56,7 +65,7 @@ function Rule:with_pair(cond)
end
function Rule:end_wise()
self.is_endwise = true
return self
end

View File

@ -0,0 +1,8 @@
local endwise = require('nvim-autopairs.ts-rule').endwise
local rules = {
endwise('then$', 'end', 'lua', 'if_statement')
}
return rules

View File

@ -0,0 +1,34 @@
local conds = {}
local _, ts_utils = pcall(require, 'nvim-treesitter.ts_utils')
local log = require('nvim-autopairs._log')
local ts_lib=require('nvim-autopairs.ts-utils')
local parsers = require'nvim-treesitter.parsers'
conds.is_ts_node = function(nodename)
return function (opts)
if not opts.check_ts then return true end
parsers.get_parser():parse()
local target = ts_utils.get_node_at_cursor()
if target ~= nil and target:type() == nodename then
local text = ts_utils.get_node_text(target)
local last = text[#text]:match(opts.rule.end_pair)
log.debug('last:' .. last)
-- check last character is match with end_pair
if last == nil then
return true
end
-- if match then we need tocheck parent node
local _,_, linenr_target = target:range()
local _,_, linenr_parent = target:parent():range()
log.debug(linenr_target)
log.debug(linenr_parent)
if linenr_parent - linenr_target == 1 then
return true
end
else
end
return false
end
end
return conds

View File

@ -0,0 +1,18 @@
local Rule = require('nvim-autopairs.rule')
local cond = require('nvim-autopairs.conds')
local ts_conds = require('nvim-autopairs.ts-conds')
return {
endwise=function (...)
local params = {...}
assert(type(params[4]) == 'string', 'type ')
return Rule(...)
:with_pair(cond.none())
:with_move(cond.none())
:with_del(cond.none())
:with_cr(ts_conds.is_ts_node(params[4]))
:use_regex(true)
:end_wise()
end
}

View File

@ -0,0 +1,13 @@
local _, ts_utils = pcall(require, 'nvim-treesitter.ts_utils')
local M = {}
function M.get_tag_name(node)
local tag_name = nil
if node ~=nil then
tag_name = ts_utils.get_node_text(node)
end
return tag_name
end
return M

View File

@ -13,6 +13,7 @@ M.reset_vchar = function()
vim.cmd [[let v:char = ""]]
end
M.is_quote = function (char)
return char == "'" or char == '"' or char == '`'
end
@ -26,6 +27,17 @@ M.is_close_bracket = function (char)
return char == ")" or char == ']' or char == '}'
end
M.is_equal = function (value,text, is_regex)
log.debug('value'..value)
if is_regex and string.match(text, value) then
log.debug('match')
return true
elseif text == value then
return true
end
return false
end
M.is_in_quote = function(line, pos, quote)
local cIndex = 0
local result = false
@ -88,6 +100,13 @@ M.text_get_current_line = function(bufnr)
return M.text_get_line(bufnr, row -1)
end
M.repeat_key=function(key,num)
local text=''
for _ = 1, num, 1 do
text=text..key
end
return text
end
-- function M.text_prev_next(line, col, prev_count, next_char)
-- prev_count = prev_count or 1
@ -99,6 +118,15 @@ end
-- return prev, next
-- end
-- end
M.text_cusor_line = function(line, col, prev_count, next_count, is_regex)
if is_regex then
prev_count = col
next_count = #line - col
end
local prev = M.text_sub_char(line, col, -prev_count)
local next = M.text_sub_char(line, col + 1, next_count)
return prev, next
end
M.text_sub_char = function(line, start, num)
local finish = start

24
tests/endwise/init.lua Normal file
View File

@ -0,0 +1,24 @@
local function abc()
if fdasf then
end
return abc

4
tests/endwise/ruby.rb Normal file
View File

@ -0,0 +1,4 @@
module MyFirstModule
end

127
tests/endwise_spec.lua Normal file
View File

@ -0,0 +1,127 @@
local npairs = require('nvim-autopairs')
local ts = require 'nvim-treesitter.configs'
local Rule = require('nvim-autopairs.ts-rule')
local log = require('nvim-autopairs._log')
local helpers = {}
ts.setup {
ensure_installed = 'maintained',
highlight = {enable = true},
}
_G.npairs = npairs;
local eq=_G.eq
vim.api.nvim_set_keymap('i' , '<CR>','v:lua.npairs.check_break_line_char()', {expr = true , noremap = true})
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
ts.setup {
ensure_installed = 'maintained',
highlight = {enable = true},
}
local data = {
{
only = true,
name = "lua if add endwise" ,
filepath = './tests/endwise/init.lua',
filetype = "lua",
linenr = 5,
key = [[<cr>]],
before = [[if data== 'fdsafdsa' then| ]],
after = [[end ]]
},
{
name = "lua if is have endwise" ,
filepath = './tests/endwise/init.lua',
filetype = "lua",
linenr = 5,
key = [[<cr>]],
before = [[if data== 'fdsafdsa' then|end ]],
after = [[end ]]
},
{
name = "don't add endwise on match rule" ,
filepath = './tests/endwise/init.lua',
filetype = "lua",
linenr = 5,
key = [[<cr>]],
before ={
[[if data == 'xdsad' then| ]],
[[ local abde='das' ]],
[[end]]
},
after = [[ local abde='das' ]]
},
}
local run_data = {}
for _, value in pairs(data) do
if value.only == true then
table.insert(run_data, value)
break
end
end
if #run_data == 0 then run_data = data end
local _, ts_utils = pcall(require, 'nvim-treesitter.ts_utils')
_G.TU = ts_utils
local function Test(test_data)
for _, value in pairs(test_data) do
it("test "..value.name, function()
local text_before = {}
local pos_before = {
linenr = value.linenr,
colnr = 0
}
if not vim.tbl_islist(value.before) then
value.before = {value.before}
end
local numlnr = 0
for _, text in pairs(value.before) do
local txt = string.gsub(text, '%|' , "")
table.insert(text_before, txt )
if string.match( text, "%|") then
pos_before.colnr = string.find(text, '%|')
pos_before.linenr = pos_before.linenr + numlnr
end
numlnr = numlnr + 1
end
local after = string.gsub(value.after, '%|' , "")
vim.bo.filetype = value.filetype
if vim.fn.filereadable(vim.fn.expand(value.filepath)) == 1 then
npairs.clear_rules()
npairs.add_rules(require('nvim-autopairs.rules.endwise-'..value.filetype))
vim.cmd(":bd!")
vim.cmd(":e " .. value.filepath)
vim.bo.filetype = value.filetype
vim.api.nvim_buf_set_lines(0, pos_before.linenr -1, pos_before.linenr +#text_before, false, text_before)
vim.fn.cursor(pos_before.linenr, pos_before.colnr)
log.debug("insert:"..value.key)
helpers.insert(value.key)
vim.wait(10)
helpers.feed("<esc>")
local result = vim.fn.getline(pos_before.linenr + 2)
local pos = vim.fn.getpos('.')
eq(pos_before.linenr + 1, pos[2], '\n\n breakline error:' .. value.name .. "\n")
eq(after, result , "\n\n text error: " .. value.name .. "\n")
else
eq(false, true, "\n\n file not exist " .. value.filepath .. "\n")
end
end)
end
end
describe('[endwise tag]', function()
Test(run_data)
end)

View File

@ -18,7 +18,7 @@ set nosmartindent
set indentexpr=
lua << EOF
-- _G.__is_log = true
_G.__is_log = true
require("plenary/busted")
vim.cmd[[luafile ./tests/test_utils.lua]]
require("nvim-autopairs").setup()