Improve word creation

This commit is contained in:
hrsh7th
2022-01-12 01:19:01 +09:00
parent 5ddf3732c5
commit ce0a3581e0
2 changed files with 56 additions and 28 deletions

View File

@@ -3,24 +3,29 @@ local pattern = require('cmp.utils.pattern')
local str = {} local str = {}
local INVALID_CHARS = {} local INVALIDS = {}
INVALID_CHARS[string.byte("'")] = true INVALIDS[string.byte("'")] = true
INVALID_CHARS[string.byte('"')] = true INVALIDS[string.byte('"')] = true
INVALID_CHARS[string.byte('=')] = true INVALIDS[string.byte('=')] = true
INVALID_CHARS[string.byte('$')] = true INVALIDS[string.byte('$')] = true
INVALID_CHARS[string.byte('(')] = true INVALIDS[string.byte('(')] = true
INVALID_CHARS[string.byte('[')] = true INVALIDS[string.byte('[')] = true
INVALID_CHARS[string.byte(' ')] = true INVALIDS[string.byte('<')] = true
INVALID_CHARS[string.byte('\t')] = true INVALIDS[string.byte('{')] = true
INVALID_CHARS[string.byte('\n')] = true INVALIDS[string.byte(' ')] = true
INVALID_CHARS[string.byte('\r')] = true INVALIDS[string.byte('\t')] = true
INVALIDS[string.byte('\n')] = true
INVALIDS[string.byte('\r')] = true
local NR_BYTE = string.byte('\n') local NR_BYTE = string.byte('\n')
local PAIR_CHARS = {} local PAIRS = {}
PAIR_CHARS[string.byte('[')] = string.byte(']') PAIRS[string.byte('<')] = string.byte('>')
PAIR_CHARS[string.byte('(')] = string.byte(')') PAIRS[string.byte('[')] = string.byte(']')
PAIR_CHARS[string.byte('<')] = string.byte('>') PAIRS[string.byte('(')] = string.byte(')')
PAIRS[string.byte('{')] = string.byte('}')
PAIRS[string.byte('"')] = string.byte('"')
PAIRS[string.byte("'")] = string.byte("'")
---Return if specified text has prefix or not ---Return if specified text has prefix or not
---@param text string ---@param text string
@@ -103,21 +108,42 @@ end
---@param text string ---@param text string
---@return string ---@return string
str.get_word = function(text, stop_char) str.get_word = function(text, stop_char)
local valids = {} local has_alnum = false
local has_valid = false local stack = {}
for idx = 1, #text do local word = {}
local c = string.byte(text, idx) for i = 1, #text do
local invalid = INVALID_CHARS[c] and not (valids[c] and stop_char ~= c) local c = string.byte(text, i, i)
if has_valid and invalid then if not INVALIDS[c] then
return string.sub(text, 1, idx - 1) if PAIRS[c] then
table.insert(stack, c)
end end
valids[c] = true table.insert(word, string.char(c))
if PAIR_CHARS[c] then has_alnum = has_alnum or char.is_alnum(c)
valids[PAIR_CHARS[c]] = true elseif not has_alnum then
if PAIRS[c] then
table.insert(stack, c)
end end
has_valid = has_valid or not invalid table.insert(word, string.char(c))
elseif #stack ~= 0 then
table.insert(word, string.char(c))
if stack[#stack] == c then
table.remove(stack, #stack)
else
if PAIRS[c] then
table.insert(stack, c)
end end
return text end
if has_alnum and #stack == 0 then
break
end
else
break
end
end
if stop_char and word[#word] == string.char(stop_char) then
table.remove(word, #word)
end
return table.concat(word, '')
end end
---Oneline ---Oneline

View File

@@ -7,6 +7,8 @@ describe('utils.str', function()
assert.are.equal(str.get_word('print()'), 'print') assert.are.equal(str.get_word('print()'), 'print')
assert.are.equal(str.get_word('["cmp#confirm"]'), '["cmp#confirm"]') assert.are.equal(str.get_word('["cmp#confirm"]'), '["cmp#confirm"]')
assert.are.equal(str.get_word('"devDependencies":', string.byte('"')), '"devDependencies') assert.are.equal(str.get_word('"devDependencies":', string.byte('"')), '"devDependencies')
assert.are.equal(str.get_word('"devDependencies": ${1},', string.byte('"')), '"devDependencies')
assert.are.equal(str.get_word('#[cfg(test)]'), '#[cfg(test)]')
end) end)
it('strikethrough', function() it('strikethrough', function()