Skip to content

Commit

Permalink
refactor!: hooks to handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
bennypowers committed Feb 23, 2023
1 parent b0b5c95 commit cd3fe34
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 119 deletions.
21 changes: 5 additions & 16 deletions lua/splitjoin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ local function get_node(bufnr, winnr)

local node = nodes[#nodes]
if node then
local getter = U.get_config_operative_node(lang, node:type())
if getter then
node = getter(node) or node
end
local start_row, start_col, end_row, end_col = node:range()
local range = { start_row, start_col, end_row, end_col }
local source = vim.treesitter.get_node_text(node, bufnr)
Expand Down Expand Up @@ -92,13 +88,11 @@ local function splitjoin(op)
local type = node:type()
local handler = U.get_config_handlers(lang, type, op)
if handler then return handler(node) end
local after = U.get_config_after(lang, type)
local before = U.get_config_before(lang, type)
local indent = U.get_config_indent(lang, type) or ' '
local sep = U.get_config_separators(lang, type) or ','
local open, close = U.get_config_surrounds(lang, type, source)
local row, col, end_row, end_col = unpack(range)
local base_indent = U.get_base_indent(node)
local base_indent = U.node_get_base_indent(node)

local lines = flatten(operation(source,
lang,
Expand All @@ -109,24 +103,19 @@ local function splitjoin(op)
indent,
base_indent))

local final = before(op,
node,
base_indent,
lines) or lines

vim.api.nvim_buf_set_text(bufnr,
row,
col,
end_row,
end_col,
final)
lines)

after(op, node, bufnr, winnr, row, col)
U.node_cursor_to_end(node)

if op == 'split' and base_indent:len() > 0 and close then
local last_row = row + #final - 1
local last_row = row + #lines - 1
vim.api.nvim_buf_set_lines(bufnr, last_row, last_row + 1, false, {
base_indent .. U.get_line(bufnr, last_row)
base_indent .. U.buffer_get_line(bufnr, last_row)
})
end
end
Expand Down
7 changes: 0 additions & 7 deletions lua/splitjoin/languages/css.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,4 @@ return {
separators = {
block = ';',
},
before = {
block = function(op, _, _, lines)
if op == 'join' then
-- lines[#lines] = lines[#lines] .. ';'
end
end
}
}
22 changes: 11 additions & 11 deletions lua/splitjoin/languages/lua.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ return {
if_statement = {
split = function(node)
local indent = U.get_config_indent('lua', 'if_statement') or ' '
U.replace_node(node, vim.treesitter.get_node_text(node, 0)
U.node_replace(node, vim.treesitter.get_node_text(node, 0)
:gsub('%s+then%s+', ' then\n'..indent)
:gsub('%s+else%s+', '\nelse\n'..indent)
:gsub('%s+end%s*', '\nend')
:gsub('%s*end%s*', '\nend')
:gsub(
'%s+elseif%s+(.*)then%s+',
function(s)
Expand All @@ -28,34 +28,34 @@ return {
..indent
end
))
U.cursor_to_node_end(node)
U.node_cursor_to_end(node)
end,
join = function(node)
local source = vim.treesitter.get_node_text(node, 0)
U.replace_node(node, source
U.node_replace(node, source
:gsub('if%s+', 'if ')
:gsub('%s*then%s+', ' then ')
:gsub('%s*elseif%s+', ' elseif ')
:gsub('%s*else%s+', ' else ')
:gsub('^%s*end%s*$', ' end'))
:gsub('%s*end%s*', ' end'))
end
},

variable_list = {
split = function(node)
local source = vim.treesitter.get_node_text(node, 0)
local is_variable_decl = U.is_child_of('variable_declaration', node)
local is_variable_decl = U.node_is_child_of('variable_declaration', node)
local indent = is_variable_decl and ' ' or ''
local new = source:gsub(',%s*',',\n'..indent)
U.replace_node(node, new)
U.cursor_to_node_end(node)
if is_variable_decl then U.trim_node_line_end(node) end
U.node_replace(node, new)
U.node_cursor_to_end(node)
if is_variable_decl then U.node_trim_line_end(node) end
end,
join = function(node)
local source = vim.treesitter.get_node_text(node, 0)
local next = source:gsub('%s+', ' ')
U.replace_node(node, next)
U.cursor_to_node_end(node)
U.node_replace(node, next)
U.node_cursor_to_end(node)
end
}
},
Expand Down
51 changes: 27 additions & 24 deletions lua/splitjoin/languages/typescript.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
local U = require'splitjoin.util'

local flatten = vim.tbl_flatten
local map = vim.tbl_map

---@type SplitjoinLanguageConfig
return {
extends = 'ecmascript',
Expand All @@ -16,38 +13,44 @@ return {
separators = {
union_type = '|',
},

surround = {
type_parameters = {'<', '>'},
type_arguments = {'<', '>'},
},

no_trailing_comma = {
type_arguments = true,
},

-- hooks
operative_node = {
union_type = function(node)
local n = node
local p = n:parent()
while p and p:type() == 'union_type' do
n = p
p = n:parent()
end
return n
end,
},
before = {
union_type = function(op, _, _, lines)
if op == 'split' then
handlers = {
union_type = {
split = function(node)
local n = node while U.node_is_child_of('union_type', n) do n = n:parent() end
local sep_first = U.node_is_sep_first('typescript', 'union_type')
local source = vim.treesitter.get_node_text(n, 0)
local base_indent = U.node_get_base_indent(n) or ''
local indent = base_indent -- .. (U.get_config_indent('typescript', 'union_type') or ' ')
local sep = sep_first and ('\n' .. indent .. '| ') or (' |\n'..indent)
local prefix = sep_first and '\n'..indent..indent..'| ' or indent
local replacement = prefix..source:gsub('|', sep)
U.node_replace(n, replacement)
U.node_trim_line_end(node)
U.node_cursor_to_end(node)
vim.cmd.norm'h'
end,
join = function(node)
local n = node while U.node_is_child_of('union_type', n) do n = n:parent() end
local source = vim.treesitter.get_node_text(n, 0)
local row = n:range()
U.node_replace(n, source:gsub('%s*', ''):gsub('^|', ''))
local sep_first = U.node_is_sep_first('typescript', 'union_type')
if sep_first then
table.insert(lines, 1, '')
U.buffer_join_row_below(row - 1)
end
return lines
end
end
},
after = {
union_type = U.trim_end
end,
}
},

}
93 changes: 37 additions & 56 deletions lua/splitjoin/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,6 @@ end

--- OPERATION HELPERS
-- TODO: Remove these in favour of node helpers and default handlers
function M.trim_end(op, node, bufnr, winnr, row, col)
local first_line = M.get_line(bufnr, row)

local trimmed = first_line:gsub('%s+$', '')
vim.api.nvim_buf_set_lines(bufnr,
row,
row + 1,
true,
{ trimmed })
if op == 'join' then
vim.cmd.norm(row..'GJ')
M.jump_to_node_end_at(op, node, bufnr, winnr, row, col + 1, 0, trimmed:len())
else
M.jump_to_node_end_at(op, node, bufnr, winnr, row + 1, col, 1, -1)
end
end

function M.jump_to_node_end_at(op, orig_node, bufnr, winnr, row, col, row_offset, col_offset)
local found, new_node = pcall(get_node_at_pos, bufnr,
row,
col,
{ ignore_injections = false })
if found and new_node then
local _, _, end_row, end_col = new_node:range()

vim.api.nvim_win_set_cursor(winnr, {
end_row + (row_offset or 1),
end_col + (col_offset or -1),
})
end
end

function M.get_joined(lang, type, sep, joined)
if M.node_is_sep_first(lang, type) then
return joined:gsub('%s*%'..sep, sep)
Expand All @@ -86,24 +54,47 @@ function M.add_sep(lang, type, base, indent, sep)
return (base..indent..vim.trim(x)..sep)
end
end

end

function M.get_line(bufnr, row)





-- BUFFER ROW HELPERS
function M.buffer_get_line(bufnr, row)
local line = unpack(vim.api.nvim_buf_get_lines(bufnr,
row,
row + 1,
true))
return line
end

function M.buffer_join_row_below(row)
local fst = M.buffer_get_line(0, row)
local snd = M.buffer_get_line(0, row + 1)
vim.api.nvim_buf_set_lines(0,
row,
row + 2,
true,
{ fst:gsub('%s*$',' ') .. snd:gsub('^%s*', '') })
end














-- NODE HELPERS
function M.cursor_to_node_end(original_node)
function M.node_cursor_to_end(original_node)
local row, col = original_node:range()
local found, node = pcall(vim.treesitter.get_node_at_pos, 0, row, col, { ignore_injections = false })
if found and node then
Expand All @@ -112,23 +103,22 @@ function M.cursor_to_node_end(original_node)
end
end

function M.is_child_of(type, node)
local current = node
function M.node_is_child_of(type, node)
local current = node:parent()
repeat
if current:type() == type then
if current and current:type() == type then
return true
end
current = current:parent()
until not current:parent()
return false
end

function M.replace_node(node, replacement)
function M.node_replace(node, replacement)
local row, col, row_end, col_end = node:range()
local base_indent = M.get_base_indent(node) or ''
local base_indent = M.node_get_base_indent(node) or ''
local starts_newline = replacement:match'^\n'
local lines = M.split(replacement, '\n')
print(vim.inspect(lines))
for i, line in ipairs(lines) do
if i > 1 then
lines[i] = base_indent..line
Expand All @@ -143,30 +133,24 @@ function M.replace_node(node, replacement)
lines)
end

function M.get_base_indent(node)
function M.node_get_base_indent(node)
local row = node:range()
return M.get_line(0, row):match'^%s+' or ''
return M.buffer_get_line(0, row):match'^%s+' or ''
end

function M.trim_node_line_end(node)
function M.node_trim_line_end(node)
local row = node:range()
local trimmed = M.get_line(0, row):gsub('%s*$', '')
local trimmed = M.buffer_get_line(0, row):gsub('%s*$', '')
vim.api.nvim_buf_set_lines(0,
row,
row + 1,
true,
{ trimmed })
end

function M.join_with_previous_line(node)
function M.node_join_to_previous_line(node)
local row = node:range()
local previous = M.get_line(0, row - 1)
local current = M.get_line(0, row)
vim.api.nvim_buf_set_lines(0,
row - 1,
row,
true,
{ previous .. ' ' .. current })
M.buffer_join_row_below(row - 1)
end


Expand Down Expand Up @@ -222,9 +206,6 @@ M.node_is_padded = get_option_for('pad')
M.node_is_no_trailing_comma = get_config_for('no_trailing_comma')

M.get_config_handlers = get_config_for('handlers')
M.get_config_after = get_config_for('after', M.jump_to_node_end_at)
M.get_config_before = get_config_for('before', function(_, _, _, lines) return lines end)
M.get_config_operative_node = get_config_for('operative_node')
M.get_config_separators = get_config_for('separators')
M.get_config_indent = get_config_for('default_indent')

Expand Down
13 changes: 9 additions & 4 deletions test/fixtures/lua.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ local table = { a = 'a', b = 'b', c = 'c' }

local mixed = { 1, 2, 3, a = 'a', b = 'b', c = 'c' }

local function params(a, b, c)
a, b, c = mod(a, b, c)
local this = { 1, 2, 3, a = 'a', b = { d = 'd', e = 'e' }, c = { 4, 5, 6 } }

local function theother(a, b, c)
a, b, c = otherwise(a, b, c)
end

local function that(a, b, c)
local a, b, c = thefirst(a, b, c)
end

local a, b, c = d
Expand All @@ -22,7 +28,6 @@ if this then theother() elseif thefirst() end

if this then that() elseif theother then thefirst() else otherwise() end


function hi()
local function thefirst()
if this then that() elseif theother then thefirst() else otherwise() end
end
Loading

0 comments on commit cd3fe34

Please sign in to comment.