diff options
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim-treesitter/indent.lua | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lua/nvim-treesitter/indent.lua b/lua/nvim-treesitter/indent.lua index 153c6a827..92dab1587 100644 --- a/lua/nvim-treesitter/indent.lua +++ b/lua/nvim-treesitter/indent.lua @@ -12,6 +12,19 @@ local function get_last_node_at_line(root, lnum) return root:descendant_for_range(lnum - 1, col, lnum - 1, col) end +local function get_matching_prev_sibling(anchor, start, matcher) + local start_row, start_col = start[1], start[2] + local node = anchor:descendant_for_range(start_row, start_col, start_row, start_col) + local pos = 1 + -- TODO: reconsider this 999 limit or do something differently in future. + -- if anchor has more than 999 children, this would not work. + while pos < 999 and node and not matcher(node) do + node = node:prev_sibling() + pos = pos + 1 + end + return node, pos +end + local M = {} local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang) @@ -21,6 +34,7 @@ local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang) dedent = {}, branch = {}, ignore = {}, + aligned_indent = {}, } for name, node, metadata in queries.iter_captures(bufnr, "indents", root, lang) do @@ -101,6 +115,30 @@ function M.get_indent(lnum) is_processed = true end + if q.aligned_indent[node:id()] and srow ~= erow then + local metadata = q.aligned_indent[node:id()] + local opening_delimiter = metadata.delimiter:sub(1, 1) + local o_delim_node, pos = get_matching_prev_sibling(node, { srow, #vim.fn.getline(srow + 1) - 1 }, function(n) + return n:type() == opening_delimiter + end) + + if o_delim_node then + if pos == 1 then + -- hanging indent (previous line ended with starting delimiter) + indent = indent + indent_size * 1 + else + local _, o_scol = o_delim_node:start() + local aligned_indent = math.max(indent, 0) + o_scol + if indent > 0 then + indent = aligned_indent + else + indent = aligned_indent + 1 -- extra space for starting delimiter + end + is_processed = true + end + end + end + is_processed_by_row[srow] = is_processed_by_row[srow] or is_processed node = node:parent() |
