diff options
| author | George Harker <george@george-graphics.co.uk> | 2023-03-20 14:44:39 -0700 |
|---|---|---|
| committer | Amaan Qureshi <amaanq12@gmail.com> | 2023-03-24 13:07:53 -0400 |
| commit | cb568af5393241e5dbc9c19157c5df5e9ca9af2d (patch) | |
| tree | e3a1848a3f1c7a03a4ecadd14f95022eaeb52f0f /lua | |
| parent | split delimiter into open_delimiter and close_delimiter (diff) | |
| download | nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar.gz nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar.bz2 nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar.lz nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar.xz nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.tar.zst nvim-treesitter-cb568af5393241e5dbc9c19157c5df5e9ca9af2d.zip | |
use indent.X syntax for captures and properties of set directives
update CONTRIBUTING.md
adjust indents for bass
fix doc capture comment
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim-treesitter/indent.lua | 80 | ||||
| -rw-r--r-- | lua/nvim-treesitter/query.lua | 44 |
2 files changed, 71 insertions, 53 deletions
diff --git a/lua/nvim-treesitter/indent.lua b/lua/nvim-treesitter/indent.lua index 932fa17ff..7290b3148 100644 --- a/lua/nvim-treesitter/indent.lua +++ b/lua/nvim-treesitter/indent.lua @@ -52,18 +52,31 @@ end local get_indents = tsutils.memoize_by_buf_tick(function(bufnr, root, lang) local map = { - auto = {}, - indent = {}, - indent_end = {}, - dedent = {}, - branch = {}, - ignore = {}, - aligned_indent = {}, - zero_indent = {}, + indent = { + auto = {}, + begin = {}, + ["end"] = {}, + dedent = {}, + branch = {}, + ignore = {}, + align = {}, + zero = {}, + }, } + local function split(to_split) + local t = {} + for str in string.gmatch(to_split, "([^.]+)") do + table.insert(t, str) + end + return t + end + for name, node, metadata in queries.iter_captures(bufnr, "indents", root, lang) do - map[name][node:id()] = metadata or {} + local path = split(name) + -- node may contain a period so append directly. + table.insert(path, node:id()) + queries.insert_to_path(map, path, metadata or {}) end return map @@ -116,7 +129,7 @@ function M.get_indent(lnum) if is_empty_line then local prevlnum = vim.fn.prevnonblank(lnum) node = get_last_node_at_line(root, prevlnum) - if q.indent_end[node:id()] then + if q.indent["end"][node:id()] then node = get_first_node_at_line(root, lnum) end else @@ -134,16 +147,16 @@ function M.get_indent(lnum) -- tracks to ensure multiple indent levels are not applied for same line local is_processed_by_row = {} - if q.zero_indent[node:id()] then + if q.indent.zero[node:id()] then return 0 end while node do -- do 'autoindent' if not marked as @indent if - not q.indent[node:id()] - and not q.aligned_indent[node:id()] - and q.auto[node:id()] + not q.indent.begin[node:id()] + and not q.indent.align[node:id()] + and q.indent.auto[node:id()] and node:start() < lnum - 1 and lnum - 1 <= node:end_() then @@ -153,7 +166,12 @@ function M.get_indent(lnum) -- Do not indent if we are inside an @ignore block. -- If a node spans from L1,C1 to L2,C2, we know that lines where L1 < line <= L2 would -- have their indentations contained by the node. - if not q.indent[node:id()] and q.ignore[node:id()] and node:start() < lnum - 1 and lnum - 1 <= node:end_() then + if + not q.indent.begin[node:id()] + and q.indent.ignore[node:id()] + and node:start() < lnum - 1 + and lnum - 1 <= node:end_() + then return 0 end @@ -163,7 +181,7 @@ function M.get_indent(lnum) if not is_processed_by_row[srow] - and ((q.branch[node:id()] and srow == lnum - 1) or (q.dedent[node:id()] and srow ~= lnum - 1)) + and ((q.indent.branch[node:id()] and srow == lnum - 1) or (q.indent.dedent[node:id()] and srow ~= lnum - 1)) then indent = indent - indent_size is_processed = true @@ -179,16 +197,16 @@ function M.get_indent(lnum) if should_process and ( - q.indent[node:id()] - and (srow ~= erow or is_in_err or q.indent[node:id()].immediate_indent) - and (srow ~= lnum - 1 or q.indent[node:id()].start_at_same_line) + q.indent.begin[node:id()] + and (srow ~= erow or is_in_err or q.indent.begin[node:id()]["indent.immediate"]) + and (srow ~= lnum - 1 or q.indent.begin[node:id()]["indent.start_at_same_line"]) ) then indent = indent + indent_size is_processed = true end - if is_in_err and not q.aligned_indent[node:id()] then + if is_in_err and not q.indent.align[node:id()] then -- only when the node is in error, promote the -- first child's aligned indent to the error node -- to work around ((ERROR "X" . (_)) @aligned_indent (#set! "delimeter" "AB")) @@ -196,25 +214,25 @@ function M.get_indent(lnum) -- (ERROR "X" @aligned_indent (#set! "delimeter" "AB") . (_)) -- and we will fish it out here. for c in node:iter_children() do - if q.aligned_indent[c:id()] then - q.aligned_indent[node:id()] = q.aligned_indent[c:id()] + if q.indent.align[c:id()] then + q.indent.align[node:id()] = q.indent.align[c:id()] break end end end -- do not indent for nodes that starts-and-ends on same line and starts on target line (lnum) - if should_process and q.aligned_indent[node:id()] and (srow ~= erow or is_in_err) and (srow ~= lnum - 1) then - local metadata = q.aligned_indent[node:id()] + if should_process and q.indent.align[node:id()] and (srow ~= erow or is_in_err) and (srow ~= lnum - 1) then + local metadata = q.indent.align[node:id()] local o_delim_node, o_is_last_in_line ---@type TSNode|nil, boolean|nil local c_delim_node, c_is_last_in_line ---@type TSNode|nil, boolean|nil, boolean|nil local indent_is_absolute = false - if metadata.open_delimiter then - o_delim_node, o_is_last_in_line = find_delimiter(bufnr, node, metadata.open_delimiter) + if metadata["indent.open_delimiter"] then + o_delim_node, o_is_last_in_line = find_delimiter(bufnr, node, metadata["indent.open_delimiter"]) else o_delim_node = node end - if metadata.close_delimiter then - c_delim_node, c_is_last_in_line = find_delimiter(bufnr, node, metadata.close_delimiter) + if metadata["indent.close_delimiter"] then + c_delim_node, c_is_last_in_line = find_delimiter(bufnr, node, metadata["indent.close_delimiter"]) else c_delim_node = node end @@ -245,7 +263,7 @@ function M.get_indent(lnum) -- Then its indent level shouldn't be affected by `@aligned_indent` node indent = math.max(indent - indent_size, 0) else - indent = o_scol + (metadata.increment or 1) + indent = o_scol + (metadata["indent.increment"] or 1) indent_is_absolute = true end end @@ -254,9 +272,9 @@ function M.get_indent(lnum) if c_srow and c_srow ~= o_srow and c_srow == lnum - 1 then -- delims end on current line, and are not open and closed same line. -- then this last line may need additional indent to avoid clashes - -- with the next. `avoid_last_matching_next` controls this behavior, + -- with the next. `indent.avoid_last_matching_next` controls this behavior, -- for example this is needed for function parameters. - avoid_last_matching_next = metadata.avoid_last_matching_next or false + avoid_last_matching_next = metadata["indent.avoid_last_matching_next"] or false end if avoid_last_matching_next then -- last line must be indented more in cases where diff --git a/lua/nvim-treesitter/query.lua b/lua/nvim-treesitter/query.lua index 18c416a38..51310545b 100644 --- a/lua/nvim-treesitter/query.lua +++ b/lua/nvim-treesitter/query.lua @@ -213,6 +213,24 @@ local function prepare_query(bufnr, query_name, root, root_lang) } end +-- Given a path (i.e. a List(String)) this functions inserts value at path +---@param object any +---@param path string[] +---@param value any +function M.insert_to_path(object, path, value) + local curr_obj = object + + for index = 1, (#path - 1) do + if curr_obj[path[index]] == nil then + curr_obj[path[index]] = {} + end + + curr_obj = curr_obj[path[index]] + end + + curr_obj[path[#path]] = value +end + ---@param query Query ---@param bufnr integer ---@param start_row integer @@ -230,24 +248,6 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row) return t end - -- Given a path (i.e. a List(String)) this functions inserts value at path - ---@param object any - ---@param path string[] - ---@param value any - local function insert_to_path(object, path, value) - local curr_obj = object - - for index = 1, (#path - 1) do - if curr_obj[path[index]] == nil then - curr_obj[path[index]] = {} - end - - curr_obj = curr_obj[path[index]] - end - - curr_obj[path[#path]] = value - end - local matches = query:iter_matches(qnode, bufnr, start_row, end_row) local function iterator() @@ -260,9 +260,9 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row) local name = query.captures[id] -- name of the capture in the query if name ~= nil then local path = split(name .. ".node") - insert_to_path(prepared_match, path, node) + M.insert_to_path(prepared_match, path, node) local metadata_path = split(name .. ".metadata") - insert_to_path(prepared_match, metadata_path, metadata[id]) + M.insert_to_path(prepared_match, metadata_path, metadata[id]) end end @@ -273,10 +273,10 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row) for _, pred in pairs(preds) do -- functions if pred[1] == "set!" and type(pred[2]) == "string" then - insert_to_path(prepared_match, split(pred[2]), pred[3]) + M.insert_to_path(prepared_match, split(pred[2]), pred[3]) end if pred[1] == "make-range!" and type(pred[2]) == "string" and #pred == 4 then - insert_to_path( + M.insert_to_path( prepared_match, split(pred[2] .. ".node"), tsrange.TSRange.from_nodes(bufnr, match[pred[3]], match[pred[4]]) |
