🪴 my neovim config:)
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

plugin: vendor treesitter indent

robin 6a60df29 b7d5e909

+546 -2
+201
LICENSE-APACHE-2.0
··· 1 + Apache License 2 + Version 2.0, January 2004 3 + http://www.apache.org/licenses/ 4 + 5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 + 7 + 1. Definitions. 8 + 9 + "License" shall mean the terms and conditions for use, reproduction, 10 + and distribution as defined by Sections 1 through 9 of this document. 11 + 12 + "Licensor" shall mean the copyright owner or entity authorized by 13 + the copyright owner that is granting the License. 14 + 15 + "Legal Entity" shall mean the union of the acting entity and all 16 + other entities that control, are controlled by, or are under common 17 + control with that entity. For the purposes of this definition, 18 + "control" means (i) the power, direct or indirect, to cause the 19 + direction or management of such entity, whether by contract or 20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 + outstanding shares, or (iii) beneficial ownership of such entity. 22 + 23 + "You" (or "Your") shall mean an individual or Legal Entity 24 + exercising permissions granted by this License. 25 + 26 + "Source" form shall mean the preferred form for making modifications, 27 + including but not limited to software source code, documentation 28 + source, and configuration files. 29 + 30 + "Object" form shall mean any form resulting from mechanical 31 + transformation or translation of a Source form, including but 32 + not limited to compiled object code, generated documentation, 33 + and conversions to other media types. 34 + 35 + "Work" shall mean the work of authorship, whether in Source or 36 + Object form, made available under the License, as indicated by a 37 + copyright notice that is included in or attached to the work 38 + (an example is provided in the Appendix below). 39 + 40 + "Derivative Works" shall mean any work, whether in Source or Object 41 + form, that is based on (or derived from) the Work and for which the 42 + editorial revisions, annotations, elaborations, or other modifications 43 + represent, as a whole, an original work of authorship. For the purposes 44 + of this License, Derivative Works shall not include works that remain 45 + separable from, or merely link (or bind by name) to the interfaces of, 46 + the Work and Derivative Works thereof. 47 + 48 + "Contribution" shall mean any work of authorship, including 49 + the original version of the Work and any modifications or additions 50 + to that Work or Derivative Works thereof, that is intentionally 51 + submitted to Licensor for inclusion in the Work by the copyright owner 52 + or by an individual or Legal Entity authorized to submit on behalf of 53 + the copyright owner. For the purposes of this definition, "submitted" 54 + means any form of electronic, verbal, or written communication sent 55 + to the Licensor or its representatives, including but not limited to 56 + communication on electronic mailing lists, source code control systems, 57 + and issue tracking systems that are managed by, or on behalf of, the 58 + Licensor for the purpose of discussing and improving the Work, but 59 + excluding communication that is conspicuously marked or otherwise 60 + designated in writing by the copyright owner as "Not a Contribution." 61 + 62 + "Contributor" shall mean Licensor and any individual or Legal Entity 63 + on behalf of whom a Contribution has been received by Licensor and 64 + subsequently incorporated within the Work. 65 + 66 + 2. Grant of Copyright License. Subject to the terms and conditions of 67 + this License, each Contributor hereby grants to You a perpetual, 68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 + copyright license to reproduce, prepare Derivative Works of, 70 + publicly display, publicly perform, sublicense, and distribute the 71 + Work and such Derivative Works in Source or Object form. 72 + 73 + 3. Grant of Patent License. Subject to the terms and conditions of 74 + this License, each Contributor hereby grants to You a perpetual, 75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 + (except as stated in this section) patent license to make, have made, 77 + use, offer to sell, sell, import, and otherwise transfer the Work, 78 + where such license applies only to those patent claims licensable 79 + by such Contributor that are necessarily infringed by their 80 + Contribution(s) alone or by combination of their Contribution(s) 81 + with the Work to which such Contribution(s) was submitted. If You 82 + institute patent litigation against any entity (including a 83 + cross-claim or counterclaim in a lawsuit) alleging that the Work 84 + or a Contribution incorporated within the Work constitutes direct 85 + or contributory patent infringement, then any patent licenses 86 + granted to You under this License for that Work shall terminate 87 + as of the date such litigation is filed. 88 + 89 + 4. Redistribution. You may reproduce and distribute copies of the 90 + Work or Derivative Works thereof in any medium, with or without 91 + modifications, and in Source or Object form, provided that You 92 + meet the following conditions: 93 + 94 + (a) You must give any other recipients of the Work or 95 + Derivative Works a copy of this License; and 96 + 97 + (b) You must cause any modified files to carry prominent notices 98 + stating that You changed the files; and 99 + 100 + (c) You must retain, in the Source form of any Derivative Works 101 + that You distribute, all copyright, patent, trademark, and 102 + attribution notices from the Source form of the Work, 103 + excluding those notices that do not pertain to any part of 104 + the Derivative Works; and 105 + 106 + (d) If the Work includes a "NOTICE" text file as part of its 107 + distribution, then any Derivative Works that You distribute must 108 + include a readable copy of the attribution notices contained 109 + within such NOTICE file, excluding those notices that do not 110 + pertain to any part of the Derivative Works, in at least one 111 + of the following places: within a NOTICE text file distributed 112 + as part of the Derivative Works; within the Source form or 113 + documentation, if provided along with the Derivative Works; or, 114 + within a display generated by the Derivative Works, if and 115 + wherever such third-party notices normally appear. The contents 116 + of the NOTICE file are for informational purposes only and 117 + do not modify the License. You may add Your own attribution 118 + notices within Derivative Works that You distribute, alongside 119 + or as an addendum to the NOTICE text from the Work, provided 120 + that such additional attribution notices cannot be construed 121 + as modifying the License. 122 + 123 + You may add Your own copyright statement to Your modifications and 124 + may provide additional or different license terms and conditions 125 + for use, reproduction, or distribution of Your modifications, or 126 + for any such Derivative Works as a whole, provided Your use, 127 + reproduction, and distribution of the Work otherwise complies with 128 + the conditions stated in this License. 129 + 130 + 5. Submission of Contributions. Unless You explicitly state otherwise, 131 + any Contribution intentionally submitted for inclusion in the Work 132 + by You to the Licensor shall be under the terms and conditions of 133 + this License, without any additional terms or conditions. 134 + Notwithstanding the above, nothing herein shall supersede or modify 135 + the terms of any separate license agreement you may have executed 136 + with Licensor regarding such Contributions. 137 + 138 + 6. Trademarks. This License does not grant permission to use the trade 139 + names, trademarks, service marks, or product names of the Licensor, 140 + except as required for reasonable and customary use in describing the 141 + origin of the Work and reproducing the content of the NOTICE file. 142 + 143 + 7. Disclaimer of Warranty. Unless required by applicable law or 144 + agreed to in writing, Licensor provides the Work (and each 145 + Contributor provides its Contributions) on an "AS IS" BASIS, 146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 + implied, including, without limitation, any warranties or conditions 148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 + PARTICULAR PURPOSE. You are solely responsible for determining the 150 + appropriateness of using or redistributing the Work and assume any 151 + risks associated with Your exercise of permissions under this License. 152 + 153 + 8. Limitation of Liability. In no event and under no legal theory, 154 + whether in tort (including negligence), contract, or otherwise, 155 + unless required by applicable law (such as deliberate and grossly 156 + negligent acts) or agreed to in writing, shall any Contributor be 157 + liable to You for damages, including any direct, indirect, special, 158 + incidental, or consequential damages of any character arising as a 159 + result of this License or out of the use or inability to use the 160 + Work (including but not limited to damages for loss of goodwill, 161 + work stoppage, computer failure or malfunction, or any and all 162 + other commercial damages or losses), even if such Contributor 163 + has been advised of the possibility of such damages. 164 + 165 + 9. Accepting Warranty or Additional Liability. While redistributing 166 + the Work or Derivative Works thereof, You may choose to offer, 167 + and charge a fee for, acceptance of support, warranty, indemnity, 168 + or other liability obligations and/or rights consistent with this 169 + License. However, in accepting such obligations, You may act only 170 + on Your own behalf and on Your sole responsibility, not on behalf 171 + of any other Contributor, and only if You agree to indemnify, 172 + defend, and hold each Contributor harmless for any liability 173 + incurred by, or claims asserted against, such Contributor by reason 174 + of your accepting any such warranty or additional liability. 175 + 176 + END OF TERMS AND CONDITIONS 177 + 178 + APPENDIX: How to apply the Apache License to your work. 179 + 180 + To apply the Apache License to your work, attach the following 181 + boilerplate notice, with the fields enclosed by brackets "[]" 182 + replaced with your own identifying information. (Don't include 183 + the brackets!) The text should be enclosed in the appropriate 184 + comment syntax for the file format. We also recommend that a 185 + file or class name and description of purpose be included on the 186 + same "printed page" as the copyright notice for easier 187 + identification within third-party archives. 188 + 189 + Copyright [yyyy] [name of copyright owner] 190 + 191 + Licensed under the Apache License, Version 2.0 (the "License"); 192 + you may not use this file except in compliance with the License. 193 + You may obtain a copy of the License at 194 + 195 + http://www.apache.org/licenses/LICENSE-2.0 196 + 197 + Unless required by applicable law or agreed to in writing, software 198 + distributed under the License is distributed on an "AS IS" BASIS, 199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 + See the License for the specific language governing permissions and 201 + limitations under the License.
+342
config/lua/ivy/treesitter-indentexpr.lua
··· 1 + -- copied from @nvim-treesitter https://github.com/nvim-treesitter/nvim-treesitter/blob/6620ae1c44dfa8623b22d0cbf873a9e8d073b849/lua/nvim-treesitter/indent.lua 2 + -- license: APACHE-2.0 3 + 4 + local ts = vim.treesitter 5 + 6 + local M = {} 7 + 8 + M.comment_parsers = { 9 + comment = true, 10 + luadoc = true, 11 + javadoc = true, 12 + jsdoc = true, 13 + phpdoc = true, 14 + } 15 + 16 + local function getline(lnum) 17 + return vim.api.nvim_buf_get_lines(0, lnum - 1, lnum, false)[1] or "" 18 + end 19 + 20 + ---@param lnum integer 21 + ---@return integer 22 + local function get_indentcols_at_line(lnum) 23 + local _, indentcols = getline(lnum):find("^%s*") 24 + return indentcols or 0 25 + end 26 + 27 + ---@param root TSNode 28 + ---@param lnum integer 29 + ---@param col? integer 30 + ---@return TSNode? 31 + local function get_first_node_at_line(root, lnum, col) 32 + col = col or get_indentcols_at_line(lnum) 33 + return root:descendant_for_range(lnum - 1, col, lnum - 1, col + 1) 34 + end 35 + 36 + ---@param root TSNode 37 + ---@param lnum integer 38 + ---@param col? integer 39 + ---@return TSNode? 40 + local function get_last_node_at_line(root, lnum, col) 41 + col = col or (#getline(lnum) - 1) 42 + return root:descendant_for_range(lnum - 1, col, lnum - 1, col + 1) 43 + end 44 + 45 + ---@param bufnr integer 46 + ---@param node TSNode 47 + ---@param delimiter string 48 + ---@return TSNode? child 49 + ---@return boolean? is_end 50 + local function find_delimiter(bufnr, node, delimiter) 51 + for child, _ in node:iter_children() do 52 + if child:type() == delimiter then 53 + local linenr = child:start() 54 + local line = vim.api.nvim_buf_get_lines(bufnr, linenr, linenr + 1, false)[1] 55 + local end_char = { child:end_() } 56 + local trimmed_after_delim 57 + local escaped_delimiter = delimiter:gsub("[%-%.%+%[%]%(%)%$%^%%%?%*]", "%%%1") 58 + trimmed_after_delim = assert(line):sub(end_char[2] + 1):gsub("[%s" .. escaped_delimiter .. "]*", "") 59 + return child, #trimmed_after_delim == 0 60 + end 61 + end 62 + end 63 + 64 + ---Memoize a function using hash_fn to hash the arguments. 65 + ---@generic F: function 66 + ---@param fn F 67 + ---@param hash_fn fun(...): any 68 + ---@return F 69 + local function memoize(fn, hash_fn) 70 + local cache = setmetatable({}, { __mode = "kv" }) ---@type table<any,any> 71 + 72 + return function(...) 73 + local key = hash_fn(...) 74 + if cache[key] == nil then 75 + local v = fn(...) ---@type any 76 + cache[key] = v ~= nil and v or vim.NIL 77 + end 78 + 79 + local v = cache[key] 80 + return v ~= vim.NIL and v or nil 81 + end 82 + end 83 + 84 + local get_indents = memoize(function(bufnr, root, lang) 85 + ---@type table<string,table<string,table>> 86 + local map = { 87 + ["indent.auto"] = {}, 88 + ["indent.begin"] = {}, 89 + ["indent.end"] = {}, 90 + ["indent.dedent"] = {}, 91 + ["indent.branch"] = {}, 92 + ["indent.ignore"] = {}, 93 + ["indent.align"] = {}, 94 + ["indent.zero"] = {}, 95 + } 96 + 97 + local query = ts.query.get(lang, "indents") 98 + if not query then 99 + return map 100 + end 101 + for id, node, metadata in query:iter_captures(root, bufnr) do 102 + if query.captures[id]:sub(1, 1) ~= "_" then 103 + map[query.captures[id]][node:id()] = metadata or {} 104 + end 105 + end 106 + 107 + return map 108 + end, function(bufnr, root, lang) 109 + return tostring(bufnr) .. root:id() .. "_" .. lang 110 + end) 111 + 112 + ---@param lnum integer (1-indexed) 113 + ---@return integer 114 + function M.get_indent(lnum) 115 + local bufnr = vim.api.nvim_get_current_buf() 116 + local parser = ts.get_parser(bufnr) 117 + if not parser or not lnum then 118 + return -1 119 + end 120 + 121 + parser:parse({ vim.fn.line("w0") - 1, vim.fn.line("w$") }) 122 + 123 + -- Get language tree with smallest range around node that's not a comment parser 124 + local root, lang_tree ---@type TSNode, vim.treesitter.LanguageTree 125 + parser:for_each_tree(function(tstree, tree) 126 + if not tstree or M.comment_parsers[tree:lang()] then 127 + return 128 + end 129 + local local_root = tstree:root() 130 + if ts.is_in_node_range(local_root, lnum - 1, 0) then 131 + if not root or root:byte_length() >= local_root:byte_length() then 132 + root = local_root 133 + lang_tree = tree 134 + end 135 + end 136 + end) 137 + 138 + -- Not likely, but just in case... 139 + if not root then 140 + return 0 141 + end 142 + 143 + local q = get_indents(vim.api.nvim_get_current_buf(), root, lang_tree:lang()) 144 + local node ---@type TSNode? 145 + if getline(lnum):find("^%s*$") then 146 + local prevlnum = vim.fn.prevnonblank(lnum) 147 + local indentcols = get_indentcols_at_line(prevlnum) 148 + local prevline = vim.trim(getline(prevlnum)) 149 + -- The final position can be trailing spaces, which should not affect indentation 150 + node = get_last_node_at_line(root, prevlnum, indentcols + #prevline - 1) 151 + if node and node:type():match("comment") then 152 + -- The final node we capture of the previous line can be a comment node, which should also be ignored 153 + -- Unless the last line is an entire line of comment, ignore the comment range and find the last node again 154 + local first_node = get_first_node_at_line(root, prevlnum, indentcols) 155 + local _, scol, _, _ = node:range() 156 + if first_node and first_node:id() ~= node:id() then 157 + -- In case the last captured node is a trailing comment node, re-trim the string 158 + prevline = vim.trim(prevline:sub(1, scol - indentcols)) 159 + -- Add back indent as indent of prevline was trimmed away 160 + local col = indentcols + #prevline - 1 161 + node = get_last_node_at_line(root, prevlnum, col) 162 + end 163 + end 164 + if node and q["indent.end"][node:id()] then 165 + node = get_first_node_at_line(root, lnum) 166 + end 167 + else 168 + node = get_first_node_at_line(root, lnum) 169 + end 170 + 171 + local indent_size = vim.fn.shiftwidth() 172 + local indent = 0 173 + local _, _, root_start = root:start() 174 + if root_start ~= 0 then 175 + -- injected tree 176 + indent = vim.fn.indent(root:start() + 1) 177 + end 178 + 179 + -- tracks to ensure multiple indent levels are not applied for same line 180 + local is_processed_by_row = {} --- @type table<integer,boolean> 181 + 182 + if node and q["indent.zero"][node:id()] then 183 + return 0 184 + end 185 + 186 + while node do 187 + -- do 'autoindent' if not marked as @indent 188 + if 189 + not q["indent.begin"][node:id()] 190 + and not q["indent.align"][node:id()] 191 + and q["indent.auto"][node:id()] 192 + and node:start() < lnum - 1 193 + and lnum - 1 <= node:end_() 194 + then 195 + return -1 196 + end 197 + 198 + -- Do not indent if we are inside an @ignore block. 199 + -- If a node spans from L1,C1 to L2,C2, we know that lines where L1 < line <= L2 would 200 + -- have their indentations contained by the node. 201 + if 202 + not q["indent.begin"][node:id()] 203 + and q["indent.ignore"][node:id()] 204 + and node:start() < lnum - 1 205 + and lnum - 1 <= node:end_() 206 + then 207 + return 0 208 + end 209 + 210 + local srow, _, erow = node:range() 211 + 212 + local is_processed = false 213 + 214 + if 215 + not is_processed_by_row[srow] 216 + and ((q["indent.branch"][node:id()] and srow == lnum - 1) or (q["indent.dedent"][node:id()] and srow ~= lnum - 1)) 217 + then 218 + indent = indent - indent_size 219 + is_processed = true 220 + end 221 + 222 + -- do not indent for nodes that starts-and-ends on same line and starts on target line (lnum) 223 + local should_process = not is_processed_by_row[srow] 224 + local is_in_err = false 225 + if should_process then 226 + local parent = node:parent() 227 + is_in_err = parent and parent:has_error() or false 228 + end 229 + if 230 + should_process 231 + and ( 232 + q["indent.begin"][node:id()] 233 + and (srow ~= erow or is_in_err or q["indent.begin"][node:id()]["indent.immediate"]) 234 + and (srow ~= lnum - 1 or q["indent.begin"][node:id()]["indent.start_at_same_line"]) 235 + ) 236 + then 237 + indent = indent + indent_size 238 + is_processed = true 239 + end 240 + 241 + if is_in_err and not q["indent.align"][node:id()] then 242 + -- only when the node is in error, promote the 243 + -- first child's aligned indent to the error node 244 + -- to work around ((ERROR "X" . (_)) @aligned_indent (#set! "delimiter" "AB")) 245 + -- matching for all X, instead set do 246 + -- (ERROR "X" @aligned_indent (#set! "delimiter" "AB") . (_)) 247 + -- and we will fish it out here. 248 + for c in node:iter_children() do 249 + if q["indent.align"][c:id()] then 250 + q["indent.align"][node:id()] = q["indent.align"][c:id()] 251 + break 252 + end 253 + end 254 + end 255 + -- do not indent for nodes that starts-and-ends on same line and starts on target line (lnum) 256 + if should_process and q["indent.align"][node:id()] and (srow ~= erow or is_in_err) and (srow ~= lnum - 1) then 257 + local metadata = q["indent.align"][node:id()] 258 + local o_delim_node, o_is_last_in_line ---@type TSNode?, boolean? 259 + local c_delim_node, c_is_last_in_line ---@type TSNode?, boolean?, boolean? 260 + local indent_is_absolute = false 261 + if metadata["indent.open_delimiter"] then 262 + o_delim_node, o_is_last_in_line = find_delimiter(bufnr, node, metadata["indent.open_delimiter"]) 263 + else 264 + o_delim_node = node 265 + end 266 + if metadata["indent.close_delimiter"] then 267 + c_delim_node, c_is_last_in_line = find_delimiter(bufnr, node, metadata["indent.close_delimiter"]) 268 + else 269 + c_delim_node = node 270 + end 271 + 272 + if o_delim_node then 273 + local o_srow, o_scol = o_delim_node:start() 274 + local c_srow = nil --- @type integer? 275 + if c_delim_node then 276 + c_srow = c_delim_node:start() 277 + end 278 + if o_is_last_in_line then 279 + -- hanging indent (previous line ended with starting delimiter) 280 + -- should be processed like indent 281 + if should_process then 282 + indent = indent + indent_size * 1 283 + if c_is_last_in_line then 284 + -- If current line is outside the range of a node marked with `@aligned_indent` 285 + -- Then its indent level shouldn't be affected by `@aligned_indent` node 286 + if c_srow and c_srow < lnum - 1 then 287 + indent = math.max(indent - indent_size, 0) 288 + end 289 + end 290 + end 291 + else 292 + -- aligned indent 293 + if c_is_last_in_line and c_srow and o_srow ~= c_srow and c_srow < lnum - 1 then 294 + -- If current line is outside the range of a node marked with `@aligned_indent` 295 + -- Then its indent level shouldn't be affected by `@aligned_indent` node 296 + indent = math.max(indent - indent_size, 0) 297 + else 298 + indent = o_scol + (metadata["indent.increment"] or 1) 299 + indent_is_absolute = true 300 + end 301 + end 302 + -- deal with the final line 303 + local avoid_last_matching_next = false 304 + if c_srow and c_srow ~= o_srow and c_srow == lnum - 1 then 305 + -- delims end on current line, and are not open and closed same line. 306 + -- then this last line may need additional indent to avoid clashes 307 + -- with the next. `indent.avoid_last_matching_next` controls this behavior, 308 + -- for example this is needed for function parameters. 309 + avoid_last_matching_next = metadata["indent.avoid_last_matching_next"] or false 310 + end 311 + if avoid_last_matching_next then 312 + -- last line must be indented more in cases where 313 + -- it would be same indent as next line (we determine this as one 314 + -- width more than the open indent to avoid confusing with any 315 + -- hanging indents) 316 + if indent <= vim.fn.indent(o_srow + 1) + indent_size then 317 + indent = indent + indent_size * 1 318 + else 319 + indent = indent 320 + end 321 + end 322 + is_processed = true 323 + if indent_is_absolute then 324 + -- don't allow further indenting by parent nodes, this is an absolute position 325 + return indent 326 + end 327 + end 328 + end 329 + 330 + is_processed_by_row[srow] = is_processed_by_row[srow] or is_processed 331 + 332 + node = node:parent() 333 + end 334 + 335 + return indent 336 + end 337 + 338 + function M.indent() 339 + return M.get_indent(vim.v.lnum) 340 + end 341 + 342 + return M
+3 -2
config/plugin/treesitter.lua
··· 37 37 if not ok then 38 38 return 39 39 end 40 - vim.o.foldmethod = "expr" 41 - vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" 40 + vim.wo.foldmethod = "expr" 41 + vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()" 42 + vim.bo.indentexpr = "v:lua.require('ivy.treesitter-indentexpr').indent()" 42 43 end)