1

Compare commits

..

6 Commits

Author SHA1 Message Date
09db9fb7aa Update config for VIM 2024-04-28 19:28:48 -07:00
cc77c17478 Cleanup 2024-04-28 19:26:32 -07:00
3959c28d9f Improvements 2024-04-28 19:14:07 -07:00
3d60efb9f5 Unwrapping 2024-04-28 11:28:38 -07:00
987783e973 Improved wrapping 2024-04-28 11:16:30 -07:00
a027e9c16e Include brace range inside of ParamList 2024-04-27 11:51:43 -07:00
2 changed files with 134 additions and 62 deletions

View File

@ -11,6 +11,10 @@ local configs = {
go = { go = {
comma_last = true, comma_last = true,
}, },
vim = {
brace_last_wrap = false,
line_prefix = '\\ ',
}
} }
local function set(opts, filetypes) local function set(opts, filetypes)

View File

@ -262,8 +262,9 @@ end
local ParamList = {} local ParamList = {}
ParamList.__index = ParamList ParamList.__index = ParamList
function ParamList.new() function ParamList.new(range)
local params = { local params = {
range = range,
current = nil, current = nil,
parsed = {}, parsed = {},
} }
@ -280,7 +281,7 @@ function ParamList:flush()
end end
end end
function ParamList:update(char, brace_stack, range, cursor) function ParamList:update(char, brace_stack, cursor)
if not cursor:is_string() then if not cursor:is_string() then
brace_stack:update(char) brace_stack:update(char)
if brace_stack:empty() and char == ',' then if brace_stack:empty() and char == ',' then
@ -292,7 +293,7 @@ function ParamList:update(char, brace_stack, range, cursor)
if self.current then if self.current then
self.current:append(char) self.current:append(char)
else else
self.current = Param.new(char, range) self.current = Param.new(char, self.range)
end end
if cursor == Cursor.get_current() then if cursor == Cursor.get_current() then
@ -300,30 +301,72 @@ function ParamList:update(char, brace_stack, range, cursor)
end end
end end
function ParamList:parse(range) function ParamList:parse()
local brace_stack = BraceStack:new() local brace_stack = BraceStack:new()
for row = range.start.row, range.stop.row do for row = self.range.start.row, self.range.stop.row do
local line = vim.fn.getline(row) local line = vim.fn.getline(row)
local start_col = 1 local start_col = 1
if row == range.start.row then if row == self.range.start.row then
start_col = range.start.col + 1 start_col = self.range.start.col + 1
end end
local stop_col = #line local stop_col = #line
if row == range.stop.row then if row == self.range.stop.row then
stop_col = range.stop.col - 1 stop_col = self.range.stop.col - 1
end end
for col = start_col, stop_col do for col = start_col, stop_col do
self:update(line:sub(col, col), brace_stack, range, Cursor.new(row, col)) self:update(line:sub(col, col), brace_stack, Cursor.new(row, col))
end end
end end
self:flush() self:flush()
end end
--
-- Builder
--
local Builder = {}
Builder.__index = Builder
function Builder.new(indent_level, indent_block)
local builder = {
lines = {},
line = '',
indent_level = indent_level,
indent_block = indent_block,
}
return setmetatable(builder, Builder)
end
function Builder:indent()
self.indent_level = self.indent_level + 1
end
function Builder:unindent()
assert(self.indent_level > 0)
self.indent_level = self.indent_level - 1
end
function Builder:update(text)
self.line = self.line .. text
end
function Builder:flush()
local indent = string.rep(self.indent_block, self.indent_level)
table.insert(self.lines, indent .. self.line)
self.line = ''
end
function Builder:get_offset()
local indent = string.rep(self.indent_block, self.indent_level)
return Cursor.new(#self.lines, #self.line + #indent)
end
-- --
-- WrapContext -- WrapContext
-- --
@ -351,67 +394,94 @@ function WrapContext:parse()
end end
local first_line = vim.fn.getline(self.range.start.row) local first_line = vim.fn.getline(self.range.start.row)
self.indent = first_line:match('^(%s*)') local indent = #first_line:match('^(%s*)')
self.prefix = first_line:sub(#self.indent + 1, self.range.start.col) self.prefix = first_line:sub(indent + 1, self.range.start.col)
if vim.o.expandtab then
self.indent_level = indent / vim.o.shiftwidth
self.indent_block = string.rep(' ', vim.o.shiftwidth)
else
self.indent_level = indent
self.indent_block = '\t'
end
local last_line = vim.fn.getline(self.range.stop.row) local last_line = vim.fn.getline(self.range.stop.row)
self.suffix = last_line:sub(self.range.stop.col) self.suffix = last_line:sub(self.range.stop.col)
self.params = ParamList.new() self.params = ParamList.new(self.range)
self.params:parse(self.range) self.params:parse()
return true return true
end end
function WrapContext:wrap(opt) function WrapContext:update_builder_param(builder, param, opt)
vim.fn.setline(self.range.start.row, self.indent .. self.prefix) local text = param.text
if #opt.line_prefix > 0 then
text = param.text:match('^%s*[' .. opt.line_prefix .. ']?%s*(.*)')
end
local cursor = nil local cursor = nil
local row = self.range.start.row
for i, param in ipairs(self.params.parsed) do
local first_param = i == 1
local last_param = i == #self.params.parsed
local line = ''
if opt.comma_prefix then
line = line .. self.indent .. opt.line_prefix
if not first_param then
line = line .. ', '
end
line = line .. param.text
else
line = line .. self.indent .. opt.line_prefix .. param.text
if not last_param or opt.comma_last then
line = line .. ','
end
end
if last_param and not opt.brace_last_wrap then
line = line .. self.suffix
end
vim.fn.append(row, line)
row = row + 1
vim.fn.execute(string.format('%d>', row))
if first_param and opt.comma_prefix_indent then
local prev_shiftwidth = vim.o.shiftwidth
vim.o.shiftwidth = prev_shiftwidth - 2
vim.fn.execute(string.format('%d>', row))
vim.o.shiftwidth = prev_shiftwidth
end
if param:is_active() then if param:is_active() then
cursor = Cursor.get_current() cursor = builder:get_offset()
cursor.col = #vim.fn.getline(cursor.row):match('^%s*') + param.offset cursor.row = cursor.row + self.range.start.row
cursor.col = cursor.col + param.offset - (#param.text - #text)
end end
builder:update(text)
return cursor
end
function WrapContext:wrap(opt)
local builder = Builder.new(self.indent_level, self.indent_block)
builder:update(self.prefix)
builder:flush()
builder:indent()
local cursor = nil
for i, param in ipairs(self.params.parsed) do
local is_first_param = i == 1
local is_last_param = i == #self.params.parsed
if opt.comma_prefix then
builder:update(opt.line_prefix)
if not is_first_param then
builder:update(', ')
elseif opt.comma_prefix_indent and not is_last_param then
builder:update(' ')
end
cursor = self:update_builder_param(builder, param, opt) or cursor
else
builder:update(opt.line_prefix)
cursor = self:update_builder_param(builder, param, opt) or cursor
if not is_last_param or opt.comma_last then
builder:update(',')
end
end
if is_last_param and not opt.brace_last_wrap then
builder:update(self.suffix)
end
builder:flush()
end
if not opt.brace_last_indent then
builder:unindent()
end end
if opt.brace_last_wrap then if opt.brace_last_wrap then
vim.fn.append(row, self.indent .. self.suffix) builder:update(self.suffix)
if opt.brace_last_indent then builder:flush()
vim.fn.execute(string.format('%d>', row + 1)) end
local row = self.range.start.row
for i, line in ipairs(builder.lines) do
if i == 1 then
vim.fn.setline(row, line)
else
vim.fn.append(row, line)
row = row + 1
end end
end end
@ -426,30 +496,28 @@ function WrapContext:unwrap(opt)
padding = ' ' padding = ' '
end end
local line = self.indent .. self.prefix .. padding local builder = Builder.new(self.indent_level, self.indent_block)
builder:update(self.prefix)
builder:update(padding)
local cursor = nil local cursor = nil
for i, param in ipairs(self.params.parsed) do for i, param in ipairs(self.params.parsed) do
if param:is_active() then cursor = self:update_builder_param(builder, param, opt) or cursor
cursor = Cursor.new(0, #line + param.offset)
end
line = line .. param.text
if i < #self.params.parsed then if i < #self.params.parsed then
line = line .. ', ' builder:update(', ')
end end
end end
line = line .. padding .. self.suffix builder:update(padding)
builder:update(self.suffix)
builder:flush()
vim.fn.setline(self.range.start.row, line) vim.fn.setline(self.range.start.row, builder.lines[1])
vim.fn.execute(string.format('%d,%dd_', self.range.start.row + 1, self.range.stop.row)) vim.fn.execute(string.format(
'%d,%dd_',
for _, param in ipairs(self.params.parsed) do self.range.start.row + 1,
if param:is_active() then self.range.stop.row
cursor.row = Cursor:get_current().row - 1 ))
end
end
if cursor then if cursor then
cursor:set_current() cursor:set_current()