diff --git a/lua/splitjoin/languages/html/functions.lua b/lua/splitjoin/languages/html/functions.lua
index 35a0610..95d2990 100644
--- a/lua/splitjoin/languages/html/functions.lua
+++ b/lua/splitjoin/languages/html/functions.lua
@@ -12,17 +12,46 @@ local function get_element(node)
return element
end
+local function join_attrs(parent, options)
+ local append, get = String.append('')
+
+ append('<')
+
+ for child in parent:iter_children() do
+ local type = child:type()
+ if type == 'tag_name' then
+ append(Node.get_text(child))
+ elseif type == 'attribute' then
+ append(' ', vim.trim(Node.get_text(child)))
+ end
+ end
+
+ append('>')
+
+ Node.replace(parent, get())
+end
+
+local function is_lengthy(str)
+ return str:len() > 0
+end
+
+local function trace(tag)
+ return function(x)
+ vim.notify(tag.. ':'..vim.inspect(x))
+ return x
+ end
+end
+
---@param node TSNode
local function split_attrs(node, options)
- local element = node:parent()
- if element then
- local original_text = Node.get_text(element)
- local base_indent = Node.get_base_indent(element)
+ local open_tag = node:parent()
+ if open_tag then
+ local base_indent = Node.get_base_indent(open_tag)
local indent = base_indent .. (options.default_indent or ' ')
if options.aligned then
- indent = base_indent .. vim.split(Node.get_text(element), '%s')[1]:gsub('.', ' ') .. ' '
+ indent = base_indent .. vim.split(Node.get_text(open_tag), '%s')[1]:gsub('.', ' ') .. ' '
end
- for child in element:iter_children() do
+ for child in open_tag:iter_children() do
if child:type() == 'attribute' then
local attr = child
local first_attr_child = attr:parent():child(2)
@@ -30,14 +59,27 @@ local function split_attrs(node, options)
if first_attr_child ~= child then
prefix = '\n'..indent
end
+
local new_text = prefix..Node.get_text(attr)
-- TODO: this fails when successfully splitting, then moving the cursor to a separate parent
pcall(Node.replace, attr, new_text)
end
end
- for child in element:iter_children() do
- pcall(Node.trim_line_end,child)
+
+ local function trim_end(s)
+ return select(1, s:gsub('%s*$', '')) or ''
+ end
+
+ local function trim_one_start_indent(s)
+ return select(1, s:gsub('^'..base_indent, '')) or ''
end
+
+ Node.replace(open_tag, vim.iter(vim.split(Node.get_text(open_tag), '\n'))
+ :map(trim_end)
+ :filter(is_lengthy)
+ :map(trim_one_start_indent)
+ :join('\n'))
+
Node.goto_node(node, 'start', 1)
vim.treesitter.get_parser(0, 'html'):invalidate(true)
vim.treesitter.get_parser(0, 'html'):invalidate(true)
@@ -60,25 +102,6 @@ local function split_children(node, options)
Node.goto_node(node, 'start', -1)
end
-local function join_attrs(parent, options)
- local append, get = String.append('')
-
- append('<')
-
- for child in parent:iter_children() do
- local type = child:type()
- if type == 'tag_name' then
- append(Node.get_text(child))
- elseif type == 'attribute' then
- append(' ', vim.trim(Node.get_text(child)))
- end
- end
-
- append('>')
-
- Node.replace(parent, get())
-end
-
local function join_children(node, options)
local element = get_element(node)
local append, get = String.append('')