1
This commit is contained in:
Alex Yatskov 2024-04-28 22:11:34 -07:00
parent 09db9fb7aa
commit 193d7fbd57

View File

@ -376,7 +376,8 @@ WrapContext.__index = WrapContext
function WrapContext.new(opt) function WrapContext.new(opt)
local wrap_context = { local wrap_context = {
opt = opt, opt = nil,
base_opt = opt,
indent = '', indent = '',
prefix = '', prefix = '',
suffix = '', suffix = '',
@ -387,15 +388,25 @@ function WrapContext.new(opt)
return setmetatable(wrap_context, WrapContext) return setmetatable(wrap_context, WrapContext)
end end
function WrapContext:parse() function WrapContext:config_opt()
self.range = BraceRange.find_closest_any() self.opt = {}
if not self.range then for key, value in pairs(self.base_opt) do
return false if type(value) == 'table' then
self.opt[key] = false
for _, brace in ipairs(value) do
if self.range.pair == BracePair.from_brace(brace) then
self.opt[key] = true
break
end
end
else
self.opt[key] = value
end
end
end end
local first_line = vim.fn.getline(self.range.start.row) function WrapContext:config_indent(line)
local indent = #first_line:match('^(%s*)') local indent = #line:match('^(%s*)')
self.prefix = first_line:sub(indent + 1, self.range.start.col)
if vim.o.expandtab then if vim.o.expandtab then
self.indent_level = indent / vim.o.shiftwidth self.indent_level = indent / vim.o.shiftwidth
self.indent_block = string.rep(' ', vim.o.shiftwidth) self.indent_block = string.rep(' ', vim.o.shiftwidth)
@ -403,8 +414,20 @@ function WrapContext:parse()
self.indent_level = indent self.indent_level = indent
self.indent_block = '\t' self.indent_block = '\t'
end end
end
function WrapContext:parse()
self.range = BraceRange.find_closest_any()
if not self.range then
return false
end
self:config_opt()
local first_line = vim.fn.getline(self.range.start.row)
local last_line = vim.fn.getline(self.range.stop.row) local last_line = vim.fn.getline(self.range.stop.row)
self:config_indent(first_line)
self.prefix = first_line:sub(self.indent_level * #self.indent_block + 1, self.range.start.col)
self.suffix = last_line:sub(self.range.stop.col) self.suffix = last_line:sub(self.range.stop.col)
self.params = ParamList.new(self.range) self.params = ParamList.new(self.range)
@ -413,24 +436,25 @@ function WrapContext:parse()
return true return true
end end
function WrapContext:update_builder_param(builder, param, opt) function WrapContext:update_builder_param(builder, param)
local text = param.text local text = param.text
if #opt.line_prefix > 0 then if #self.opt.line_prefix > 0 then
text = param.text:match('^%s*[' .. opt.line_prefix .. ']?%s*(.*)') text = param.text:match('^%s*[' .. self.opt.line_prefix .. ']?%s*(.*)')
end end
local cursor = nil local cursor = nil
if param:is_active() then if param:is_active() then
local offset_delta = #param.text - #text
cursor = builder:get_offset() cursor = builder:get_offset()
cursor.row = cursor.row + self.range.start.row cursor.row = cursor.row + self.range.start.row
cursor.col = cursor.col + param.offset - (#param.text - #text) cursor.col = cursor.col + param.offset - offset_delta
end end
builder:update(text) builder:update(text)
return cursor return cursor
end end
function WrapContext:wrap(opt) function WrapContext:wrap()
local builder = Builder.new(self.indent_level, self.indent_block) local builder = Builder.new(self.indent_level, self.indent_block)
builder:update(self.prefix) builder:update(self.prefix)
builder:flush() builder:flush()
@ -441,36 +465,34 @@ function WrapContext:wrap(opt)
local is_first_param = i == 1 local is_first_param = i == 1
local is_last_param = i == #self.params.parsed local is_last_param = i == #self.params.parsed
if opt.comma_prefix then if self.opt.comma_prefix then
builder:update(opt.line_prefix) builder:update(self.opt.line_prefix)
if not is_first_param then if not is_first_param then
builder:update(', ') builder:update(', ')
elseif opt.comma_prefix_indent and not is_last_param then elseif self.opt.comma_prefix_indent and not is_last_param then
builder:update(' ') builder:update(' ')
end end
cursor = self:update_builder_param(builder, param) or cursor
cursor = self:update_builder_param(builder, param, opt) or cursor
else else
builder:update(opt.line_prefix) builder:update(self.opt.line_prefix)
cursor = self:update_builder_param(builder, param, opt) or cursor cursor = self:update_builder_param(builder, param) or cursor
if not is_last_param or self.opt.comma_last then
if not is_last_param or opt.comma_last then
builder:update(',') builder:update(',')
end end
end end
if is_last_param and not opt.brace_last_wrap then if is_last_param and not self.opt.brace_last_wrap then
builder:update(self.suffix) builder:update(self.suffix)
end end
builder:flush() builder:flush()
end end
if not opt.brace_last_indent then if not self.opt.brace_last_indent then
builder:unindent() builder:unindent()
end end
if opt.brace_last_wrap then if self.opt.brace_last_wrap then
builder:update(self.suffix) builder:update(self.suffix)
builder:flush() builder:flush()
end end
@ -485,24 +507,29 @@ function WrapContext:wrap(opt)
end end
end end
if cursor then if not cursor then
cursor:set_current() cursor = self.range.start
end
end end
function WrapContext:unwrap(opt) cursor:set_current()
end
function WrapContext:unwrap()
local padding = '' local padding = ''
if opt.brace_pad then if self.opt.brace_pad then
padding = ' ' padding = ' '
end end
local builder = Builder.new(self.indent_level, self.indent_block) local builder = Builder.new(
self.indent_level,
self.indent_block
)
builder:update(self.prefix) builder:update(self.prefix)
builder:update(padding) 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
cursor = self:update_builder_param(builder, param, opt) or cursor cursor = self:update_builder_param(builder, param) or cursor
if i < #self.params.parsed then if i < #self.params.parsed then
builder:update(', ') builder:update(', ')
end end
@ -513,45 +540,23 @@ function WrapContext:unwrap(opt)
builder:flush() builder:flush()
vim.fn.setline(self.range.start.row, builder.lines[1]) vim.fn.setline(self.range.start.row, builder.lines[1])
vim.fn.execute(string.format( vim.fn.execute(string.format('%d,%dd_', self.range.start.row + 1, self.range.stop.row))
'%d,%dd_',
self.range.start.row + 1,
self.range.stop.row
))
if cursor then if not cursor then
cursor:set_current() cursor = self.range.start
end end
cursor:set_current()
end end
function WrapContext:toggle() function WrapContext:toggle()
local opt = self:specialize_opt()
if self.range:is_wrapped() then if self.range:is_wrapped() then
self:unwrap(opt) self:unwrap()
else else
self:wrap(opt) self:wrap()
end end
end end
function WrapContext:specialize_opt()
local opt = {}
for key, value in pairs(self.opt) do
if type(value) == 'table' then
opt[key] = false
for _, brace in ipairs(value) do
if self.range.pair == BracePair.from_brace(brace) then
opt[key] = true
break
end
end
else
opt[key] = value
end
end
return opt
end
return { return {
WrapContext = WrapContext, WrapContext = WrapContext,
} }