feat(lsp)!: replace snippet parser by lpeg grammar

This commit is contained in:
Maria José Solano
2023-10-01 09:54:04 -07:00
committed by Christian Clason
parent f736b075d3
commit eb1f0e8fcc
5 changed files with 122 additions and 672 deletions

View File

@@ -1,130 +1,70 @@
local helpers = require('test.functional.helpers')(after_each)
local snippet = require('vim.lsp._snippet')
local snippet = require('vim.lsp._snippet_grammar')
local eq = helpers.eq
local exec_lua = helpers.exec_lua
describe('vim.lsp._snippet', function()
describe('vim.lsp._snippet_grammar', function()
before_each(helpers.clear)
after_each(helpers.clear)
local parse = function(...)
return exec_lua('return require("vim.lsp._snippet").parse(...)', ...)
local res = exec_lua('return require("vim.lsp._snippet_grammar").parse(...)', ...)
return res.data.children
end
it('should parse only text', function()
it('parses only text', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
{
type = snippet.NodeType.TEXT,
raw = 'TE\\$\\}XT',
esc = 'TE$}XT',
},
},
{ type = snippet.NodeType.Text, data = { text = 'TE$}XT' } },
}, parse('TE\\$\\}XT'))
end)
it('should parse tabstop', function()
it('parses tabstops', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
{
type = snippet.NodeType.TABSTOP,
tabstop = 1,
},
{
type = snippet.NodeType.TABSTOP,
tabstop = 2,
},
},
{ type = snippet.NodeType.Tabstop, data = { tabstop = 1 } },
{ type = snippet.NodeType.Tabstop, data = { tabstop = 2 } },
}, parse('$1${2}'))
end)
it('should parse placeholders', function()
it('parses nested placeholders', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
{
type = snippet.NodeType.PLACEHOLDER,
{
type = snippet.NodeType.Placeholder,
data = {
tabstop = 1,
children = {
{
type = snippet.NodeType.PLACEHOLDER,
value = {
type = snippet.NodeType.Placeholder,
data = {
tabstop = 2,
children = {
{
type = snippet.NodeType.TEXT,
raw = 'TE\\$\\}XT',
esc = 'TE$}XT',
},
{
type = snippet.NodeType.TABSTOP,
tabstop = 3,
},
{
type = snippet.NodeType.TABSTOP,
tabstop = 1,
transform = {
type = snippet.NodeType.TRANSFORM,
pattern = 'regex',
option = 'i',
format = {
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
modifier = 'upcase',
},
},
},
},
{
type = snippet.NodeType.TEXT,
raw = 'TE\\$\\}XT',
esc = 'TE$}XT',
},
},
value = { type = snippet.NodeType.Tabstop, data = { tabstop = 3 } },
},
},
},
},
}, parse('${1:${2:TE\\$\\}XT$3${1/regex/${1:/upcase}/i}TE\\$\\}XT}}'))
}, parse('${1:${2:${3}}}'))
end)
it('should parse variables', function()
it('parses variables', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
{
type = snippet.NodeType.VARIABLE,
{ type = snippet.NodeType.Variable, data = { name = 'VAR' } },
{ type = snippet.NodeType.Variable, data = { name = 'VAR' } },
{
type = snippet.NodeType.Variable,
data = {
name = 'VAR',
default = { type = snippet.NodeType.Tabstop, data = { tabstop = 1 } },
},
{
type = snippet.NodeType.VARIABLE,
},
{
type = snippet.NodeType.Variable,
data = {
name = 'VAR',
},
{
type = snippet.NodeType.VARIABLE,
name = 'VAR',
children = {
regex = 'regex',
options = '',
format = {
{
type = snippet.NodeType.TABSTOP,
tabstop = 1,
},
},
},
{
type = snippet.NodeType.VARIABLE,
name = 'VAR',
transform = {
type = snippet.NodeType.TRANSFORM,
pattern = 'regex',
format = {
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
modifier = 'upcase',
},
type = snippet.NodeType.Format,
data = { capture = 1, modifier = 'upcase' },
},
},
},
@@ -132,105 +72,82 @@ describe('vim.lsp._snippet', function()
}, parse('$VAR${VAR}${VAR:$1}${VAR/regex/${1:/upcase}/}'))
end)
it('should parse choice', function()
it('parses choice', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
{
type = snippet.NodeType.CHOICE,
tabstop = 1,
items = {
',',
'|',
},
},
{
type = snippet.NodeType.Choice,
data = { tabstop = 1, values = { ',', '|' } },
},
}, parse('${1|\\,,\\||}'))
end)
it('should parse format', function()
eq({
type = snippet.NodeType.SNIPPET,
children = {
it('parses format', function()
eq(
{
{
type = snippet.NodeType.VARIABLE,
name = 'VAR',
transform = {
type = snippet.NodeType.TRANSFORM,
pattern = 'regex',
type = snippet.NodeType.Variable,
data = {
name = 'VAR',
regex = 'regex',
options = '',
format = {
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
modifier = 'upcase',
type = snippet.NodeType.Format,
data = { capture = 1, modifier = 'upcase' },
},
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
if_text = 'if_text',
else_text = '',
type = snippet.NodeType.Format,
data = { capture = 1, if_text = 'if_text' },
},
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
if_text = '',
else_text = 'else_text',
type = snippet.NodeType.Format,
data = { capture = 1, else_text = 'else_text' },
},
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
else_text = 'else_text',
if_text = 'if_text',
type = snippet.NodeType.Format,
data = { capture = 1, if_text = 'if_text', else_text = 'else_text' },
},
{
type = snippet.NodeType.FORMAT,
capture_index = 1,
if_text = '',
else_text = 'else_text',
type = snippet.NodeType.Format,
data = { capture = 1, else_text = 'else_text' },
},
},
},
},
},
}, parse('${VAR/regex/${1:/upcase}${1:+if_text}${1:-else_text}${1:?if_text:else_text}${1:else_text}/}'))
parse(
'${VAR/regex/${1:/upcase}${1:+if_text}${1:-else_text}${1:?if_text:else_text}${1:else_text}/}'
)
)
end)
it('should parse empty strings', function()
it('parses empty strings', function()
eq({
children = {
{
children = { {
esc = '',
raw = '',
type = 7,
} },
{
type = snippet.NodeType.Placeholder,
data = {
tabstop = 1,
type = 2,
},
{
esc = ' ',
raw = ' ',
type = 7,
},
{
name = 'VAR',
transform = {
format = {
{
capture_index = 1,
else_text = '',
if_text = '',
type = 6,
},
},
option = 'g',
pattern = 'erg',
type = 5,
},
type = 3,
value = { type = snippet.NodeType.Text, data = { text = '' } },
},
},
type = 0,
}, parse('${1:} ${VAR/erg/${1:?:}/g}'))
{
type = snippet.NodeType.Text,
data = { text = ' ' },
},
{
type = snippet.NodeType.Variable,
data = {
name = 'VAR',
regex = 'erg',
format = {
{
type = snippet.NodeType.Format,
data = { capture = 1, if_text = '' },
},
},
options = 'g',
},
},
}, parse('${1:} ${VAR/erg/${1:+}/g}'))
end)
end)