├── .editorconfig ├── .github └── FUNDING.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── lua └── nvim-gps │ ├── init.lua │ ├── internal.lua │ └── utils.lua ├── plugin └── nvim-gps.vim └── queries ├── bash └── nvimGPS.scm ├── c └── nvimGPS.scm ├── c_sharp └── nvimGPS.scm ├── cpp └── nvimGPS.scm ├── fennel └── nvimGPS.scm ├── go └── nvimGPS.scm ├── haskell └── nvimGPS.scm ├── html └── nvimGPS.scm ├── java └── nvimGPS.scm ├── javascript └── nvimGPS.scm ├── json └── nvimGPS.scm ├── jsx └── nvimGPS.scm ├── latex └── nvimGPS.scm ├── lua └── nvimGPS.scm ├── nix └── nvimGPS.scm ├── norg └── nvimGPS.scm ├── ocaml └── nvimGPS.scm ├── php └── nvimGPS.scm ├── python └── nvimGPS.scm ├── ruby └── nvimGPS.scm ├── rust └── nvimGPS.scm ├── scss └── nvimGPS.scm ├── toml └── nvimGPS.scm ├── tsx └── nvimGPS.scm ├── typescript └── nvimGPS.scm ├── verilog └── nvimGPS.scm ├── yaml └── nvimGPS.scm ├── yang └── nvimGPS.scm └── zig └── nvimGPS.scm /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = tab 3 | indent_size = 4 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: SmiteshP 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## How does the nvim-gps work? 2 | 3 | From the current node under our cursor, it travels up the tree towards its root. On the way up, it looks for a hint whether the current node has a "name" to be captured. That hint is provided by the scope-root capture. 4 | When it sees that the current node is captured as a scope-root, it looks at the next capture (class-name, function-name or method-name) and then outputs the text of that next captured node. 5 | 6 | To better understand this, lets look at the following example query for C++. 7 | 8 | ```scm 9 | ((class_specifier 10 | name: (type_identifier) @class-name 11 | body: (field_declaration_list)) @scope-root) 12 | ``` 13 | Here, the top level node ("class_specifier") is captured as a "scope-root". This indicates that, we have to look for some name under this node. So the next node captured is the "type_identifier" which actually has the text of class name. It gets captured as class-name, and thus accordingly the suitable icon is appended to the name of the node before outputting it. 14 | 15 | You can learn more about how to write a tree-sitter query over [here](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax). 16 | Also, you may find using [playground](https://github.com/nvim-treesitter/playground) very helpful. 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 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. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ Deprecated! Use [nvim-navic](https://github.com/SmiteshP/nvim-navic) instead of this plugin 2 | 3 | nvim-navic is an improved version of nvim-gps (a version 2.0!). It accompishes the same task as this plugin, but uses LSP instead of Treesitter. It also adds ability to have coloured icons! 4 | 5 | # 🛰️ nvim-gps 6 | 7 | Take this handy dandy gps with you on your coding adventures and always know where you are! 8 | 9 | ## 🤔 What is nvim-gps? 10 | 11 | nvim-gps is a simple status line component that shows context of the current cursor position in file. It is similar to the statusline function provided by [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter/blob/af96150a2d34a05b7265ee3c42425315bcd62e39/doc/nvim-treesitter.txt#L414), but smarter. Using custom treesitter queries for each language, nvim-gps is able to show exact name of containing class, struct, function, method, etc. along with some fancy symbols! 12 | 13 | ![example](https://user-images.githubusercontent.com/43147494/130349444-fa7176a3-d068-4309-87ec-bcf6f0204261.png) 14 | 15 | Here is a barebones example how it looks in a statusline 16 | 17 | ![nvim-gps-barebone-demo](https://user-images.githubusercontent.com/43147494/130415000-6ae9c965-d631-41b2-b1f0-40ad4840a192.gif) 18 | 19 | Here is a example of how it can look in a fully configured statusline 20 | 21 | ![nvim-gps-demo](https://user-images.githubusercontent.com/43147494/130349453-d3e1fd61-348e-439c-b013-3433fd284323.gif) 22 | 23 | ## ✅ Supported Languages 24 | 25 | * Bash (and Zsh) 26 | * C 27 | * C++ 28 | * C# 29 | * Fennel 30 | * Go 31 | * Haskell 32 | * Html 33 | * Java 34 | * Javascript (and jsx) 35 | * JSON 36 | * LaTeX 37 | * Lua 38 | * Norg 39 | * Nix 40 | * Ocaml 41 | * Php 42 | * Python 43 | * Ruby 44 | * Rust 45 | * TOML 46 | * Typescript (and tsx) 47 | * Verilog 48 | * YAML 49 | * YANG 50 | * Zig 51 | 52 | ## ⚡️ Requirements 53 | 54 | * Neovim >= 0.5.0 55 | * [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) 56 | 57 | ## 📦 Installation 58 | 59 | Install the plugin with your preferred package manager: 60 | 61 | ### [packer](https://github.com/wbthomason/packer.nvim) 62 | 63 | ```lua 64 | -- Lua 65 | use { 66 | "SmiteshP/nvim-gps", 67 | requires = "nvim-treesitter/nvim-treesitter" 68 | } 69 | ``` 70 | 71 | ### [vim-plug](https://github.com/junegunn/vim-plug) 72 | 73 | ```vim 74 | " Vimscript 75 | Plug "nvim-treesitter/nvim-treesitter" 76 | Plug "SmiteshP/nvim-gps" 77 | ``` 78 | 79 | ## ⚙️ Configuration 80 | 81 | nvim-gps provides a `setup` function that takes in a table with configuration options. 82 | The default configuration assumes that you are using a nerd font. 83 | 84 | > Note: `setup` function needs to be called once for nvim-gps to work. 85 | 86 | ```lua 87 | -- Lua 88 | 89 | -- Default config 90 | require("nvim-gps").setup() 91 | ``` 92 | 93 | ```lua 94 | -- Lua 95 | 96 | -- Customized config 97 | require("nvim-gps").setup({ 98 | 99 | disable_icons = false, -- Setting it to true will disable all icons 100 | 101 | icons = { 102 | ["class-name"] = ' ', -- Classes and class-like objects 103 | ["function-name"] = ' ', -- Functions 104 | ["method-name"] = ' ', -- Methods (functions inside class-like objects) 105 | ["container-name"] = '⛶ ', -- Containers (example: lua tables) 106 | ["tag-name"] = '炙' -- Tags (example: html tags) 107 | }, 108 | 109 | -- Add custom configuration per language or 110 | -- Disable the plugin for a language 111 | -- Any language not disabled here is enabled by default 112 | languages = { 113 | -- Some languages have custom icons 114 | ["json"] = { 115 | icons = { 116 | ["array-name"] = ' ', 117 | ["object-name"] = ' ', 118 | ["null-name"] = '[] ', 119 | ["boolean-name"] = 'ﰰﰴ ', 120 | ["number-name"] = '# ', 121 | ["string-name"] = ' ' 122 | } 123 | }, 124 | ["latex"] = { 125 | icons = { 126 | ["title-name"] = "# ", 127 | ["label-name"] = " ", 128 | }, 129 | }, 130 | ["norg"] = { 131 | icons = { 132 | ["title-name"] = " ", 133 | }, 134 | }, 135 | ["toml"] = { 136 | icons = { 137 | ["table-name"] = ' ', 138 | ["array-name"] = ' ', 139 | ["boolean-name"] = 'ﰰﰴ ', 140 | ["date-name"] = ' ', 141 | ["date-time-name"] = ' ', 142 | ["float-name"] = ' ', 143 | ["inline-table-name"] = ' ', 144 | ["integer-name"] = '# ', 145 | ["string-name"] = ' ', 146 | ["time-name"] = ' ' 147 | } 148 | }, 149 | ["verilog"] = { 150 | icons = { 151 | ["module-name"] = ' ' 152 | } 153 | }, 154 | ["yaml"] = { 155 | icons = { 156 | ["mapping-name"] = ' ', 157 | ["sequence-name"] = ' ', 158 | ["null-name"] = '[] ', 159 | ["boolean-name"] = 'ﰰﰴ ', 160 | ["integer-name"] = '# ', 161 | ["float-name"] = ' ', 162 | ["string-name"] = ' ' 163 | } 164 | }, 165 | ["yang"] = { 166 | icons = { 167 | ["module-name"] = " ", 168 | ["augment-path"] = " ", 169 | ["container-name"] = " ", 170 | ["grouping-name"] = " ", 171 | ["typedef-name"] = " ", 172 | ["identity-name"] = " ", 173 | ["list-name"] = "﬘ ", 174 | ["leaf-list-name"] = " ", 175 | ["leaf-name"] = " ", 176 | ["action-name"] = " ", 177 | } 178 | }, 179 | 180 | -- Disable for particular languages 181 | -- ["bash"] = false, -- disables nvim-gps for bash 182 | -- ["go"] = false, -- disables nvim-gps for golang 183 | 184 | -- Override default setting for particular languages 185 | -- ["ruby"] = { 186 | -- separator = '|', -- Overrides default separator with '|' 187 | -- icons = { 188 | -- -- Default icons not specified in the lang config 189 | -- -- will fallback to the default value 190 | -- -- "container-name" will fallback to default because it's not set 191 | -- ["function-name"] = '', -- to ensure empty values, set an empty string 192 | -- ["tag-name"] = '' 193 | -- ["class-name"] = '::', 194 | -- ["method-name"] = '#', 195 | -- } 196 | --} 197 | }, 198 | 199 | separator = ' > ', 200 | 201 | -- limit for amount of context shown 202 | -- 0 means no limit 203 | depth = 0, 204 | 205 | -- indicator used when context hits depth limit 206 | depth_limit_indicator = ".." 207 | }) 208 | ``` 209 | 210 | ## 🚀 Usage 211 | 212 | nvim-gps doesn't modify your statusline by itself, instead you are provided with two functions and it is left up to you to incorporate them into your statusline. 213 | 214 | ```lua 215 | -- Lua 216 | local gps = require("nvim-gps") 217 | 218 | gps.is_available() -- Returns boolean value indicating whether a output can be provided 219 | gps.get_location() -- Returns a string with context information (or nil if not available) 220 | 221 | -- example output: "mystruct > sum" 222 | ``` 223 | 224 | 225 |
226 | You can also pass optional arguments to get_location function to override options given in setup function: 227 | 228 | ```lua 229 | opts = { 230 | disable_icons = false, 231 | separator = ' > ', 232 | depth = 0, 233 | depth_limit_indicator = ".." 234 | } 235 | 236 | gps.get_location(opts) 237 | ``` 238 | 239 |
240 | 241 | These two functions should satisfy the needs of most users, however if you want the raw intermediate data for custom usage you can use the following function: 242 | 243 | ```lua 244 | gps.get_data() -- Returns a table of intermediate representation of data (which is used by get_location) 245 | -- Table of tables that contain 'text', 'type' and 'icon' for each context 246 | ``` 247 | 248 |
249 | An example output of get_data function: 250 | 251 | ```lua 252 | { 253 | { 254 | text = "mystruct", 255 | type = "class-name", 256 | icon = " " 257 | }, 258 | { 259 | text = "sum", 260 | type = "method-name", 261 | icon = " " 262 | } 263 | } 264 | ``` 265 | 266 |
267 | 268 | 269 | 270 | ## Examples of Integrating with Other Plugins 271 | 272 | ### [feline](https://github.com/famiu/feline.nvim) 273 | 274 |
275 | An example feline setup 276 | 277 | ```lua 278 | -- Lua 279 | local gps = require("nvim-gps") 280 | 281 | table.insert(components.active[1], { 282 | provider = function() 283 | return gps.get_location() 284 | end, 285 | enabled = function() 286 | return gps.is_available() 287 | end 288 | }) 289 | ``` 290 | 291 |
292 | 293 | ### [galaxyline](https://github.com/glepnir/galaxyline.nvim) 294 | 295 |
296 | An example galaxyline setup 297 | 298 | ```lua 299 | -- Lua 300 | local gps = require("nvim-gps") 301 | 302 | require('galaxyline').section.left[1]= { 303 | nvimGPS = { 304 | provider = function() 305 | return gps.get_location() 306 | end, 307 | condition = function() 308 | return gps.is_available() 309 | end 310 | } 311 | } 312 | ``` 313 | 314 |
315 | 316 | ### [lualine](https://github.com/hoob3rt/lualine.nvim) 317 | 318 |
319 | An example lualine setup 320 | 321 | ```lua 322 | -- Lua 323 | local gps = require("nvim-gps") 324 | 325 | require("lualine").setup({ 326 | sections = { 327 | lualine_c = { 328 | { gps.get_location, cond = gps.is_available }, 329 | } 330 | } 331 | }) 332 | ``` 333 | 334 |
335 | 336 | ### vimscript 337 | 338 |
339 | example setup using native vim way 340 | 341 | ```vim 342 | " vimscript 343 | func! NvimGps() abort 344 | return luaeval("require'nvim-gps'.is_available()") ? 345 | \ luaeval("require'nvim-gps'.get_location()") : '' 346 | endf 347 | 348 | set statusline+=%{NvimGps()} 349 | ``` 350 | 351 |
352 | 353 | ### [windline](https://github.com/windwp/windline.nvim) 354 | 355 |
356 | example windline setup 357 | 358 | ```lua 359 | -- Lua 360 | local gps = require("nvim-gps") 361 | 362 | comps.gps = { 363 | function() 364 | if gps.is_available() then 365 | return gps.get_location() 366 | end 367 | return '' 368 | end, 369 | {"white", "black"} 370 | } 371 | ``` 372 | 373 |
374 | 375 | ## 🔥 Contributions 376 | 377 | Is your favorite language not supported? Or did you find something not being captured by the nvim-gps? Please consider opening a issue, or even better make a PR and solve the issue!! 😄 378 | 379 | Please read the CONTRIBUTING.md to understand how the treesitter queries work and how you can add/enhance the queries for your favorite programming languages! 380 | -------------------------------------------------------------------------------- /lua/nvim-gps/init.lua: -------------------------------------------------------------------------------- 1 | local ts_utils = require("nvim-treesitter.ts_utils") 2 | local ts_parsers = require("nvim-treesitter.parsers") 3 | local ts_queries = require("nvim-treesitter.query") 4 | local utils = require("nvim-gps.utils") 5 | 6 | local M = {} 7 | 8 | -- Default configuration that can be overridden by users 9 | local default_config = { 10 | enabled = true, 11 | disable_icons = false, 12 | icons = { 13 | ["class-name"] = ' ', 14 | ["function-name"] = ' ', 15 | ["method-name"] = ' ', 16 | ["container-name"] = 'ﮅ ', 17 | ["tag-name"] = '炙', 18 | }, 19 | separator = ' > ', 20 | depth = 0, 21 | depth_limit_indicator = ".." 22 | } 23 | 24 | -- Languages specific default configuration must be added to configs 25 | -- using the `with_default_config` helper. 26 | -- In setup_language_configs function 27 | -- 28 | -- Example 29 | -- 30 | -- configs = { 31 | -- ["cpp"] = with_default_config({ 32 | -- icons = { 33 | -- ["function-name"] = " " 34 | -- } 35 | -- }) 36 | -- } 37 | local with_default_config = function(config) 38 | return vim.tbl_deep_extend("force", default_config, config) 39 | end 40 | 41 | -- Placeholder where the configuration will be saved in setup() 42 | local configs = {} 43 | 44 | local function setup_language_configs() 45 | configs = { 46 | ["javascript"] = with_default_config({ 47 | icons = { 48 | ["array-name"] = ' ', 49 | ["object-name"] = ' ', 50 | } 51 | }), 52 | ["json"] = with_default_config({ 53 | icons = { 54 | ["array-name"] = ' ', 55 | ["object-name"] = ' ', 56 | ["null-name"] = '[] ', 57 | ["boolean-name"] = 'ﰰﰴ ', 58 | ["number-name"] = '# ', 59 | ["string-name"] = ' ' 60 | } 61 | }), 62 | ["latex"] = with_default_config({ 63 | icons = { 64 | ["title-name"] = "# ", 65 | ["label-name"] = " ", 66 | }, 67 | }), 68 | ["norg"] = with_default_config({ 69 | icons = { 70 | ["title-name"] = " ", 71 | }, 72 | }), 73 | ["toml"] = with_default_config({ 74 | icons = { 75 | ["table-name"] = ' ', 76 | ["array-name"] = ' ', 77 | ["boolean-name"] = 'ﰰﰴ ', 78 | ["date-name"] = ' ', 79 | ["date-time-name"] = ' ', 80 | ["float-name"] = ' ', 81 | ["inline-table-name"] = ' ', 82 | ["integer-name"] = '# ', 83 | ["string-name"] = ' ', 84 | ["time-name"] = ' ' 85 | } 86 | }), 87 | ["verilog"] = with_default_config({ 88 | icons = { 89 | ["module-name"] = ' ' 90 | } 91 | }), 92 | ["yaml"] = with_default_config({ 93 | icons = { 94 | ["mapping-name"] = ' ', 95 | ["sequence-name"] = ' ', 96 | ["null-name"] = '[] ', 97 | ["boolean-name"] = 'ﰰﰴ ', 98 | ["integer-name"] = '# ', 99 | ["float-name"] = ' ', 100 | ["string-name"] = ' ' 101 | } 102 | }), 103 | ["yang"] = with_default_config({ 104 | icons = { 105 | ["module-name"] = " ", 106 | ["augment-path"] = " ", 107 | ["container-name"] = " ", 108 | ["grouping-name"] = " ", 109 | ["typedef-name"] = " ", 110 | ["identity-name"] = " ", 111 | ["list-name"] = "﬘ ", 112 | ["leaf-list-name"] = " ", 113 | ["leaf-name"] = " ", 114 | ["action-name"] = " ", 115 | } 116 | }), 117 | ["scss"] = with_default_config({ 118 | icons = { 119 | ["scss-name"] = "", 120 | ["scss-mixin-name"] = "@mixin ", 121 | ["scss-include-name"] = "@include ", 122 | ["scss-keyframes-name"] = "@keyframes ", 123 | } 124 | }), 125 | ["tsx"] = with_default_config({ 126 | icons = { 127 | ["hook-name"] = "ﯠ ", 128 | } 129 | }), 130 | } 131 | end 132 | 133 | local data_cache_value = nil -- table 134 | local location_cache_value = "" -- string 135 | local data_prev_loc = {0, 0} 136 | local location_prev_loc = {0, 0} 137 | local setup_complete = false 138 | 139 | local function default_transform(config, capture_name, capture_text) 140 | return { 141 | text = capture_text, 142 | type = capture_name, 143 | icon = config.icons[capture_name] 144 | } 145 | end 146 | 147 | local transform_lang = { 148 | ["cpp"] = function(config, capture_name, capture_text) 149 | if capture_name == "multi-class-method" then 150 | local temp = vim.split(capture_text, "%:%:") 151 | local ret = {} 152 | for i = 1, #temp-1 do 153 | local text = string.match(temp[i], "%s*([%w_]*)%s*?%s*") 154 | table.insert(ret, default_transform(config, "class-name", text)) 155 | end 156 | table.insert(ret, default_transform(config, "method-name", string.match(temp[#temp], "%s*(~?%s*[%w_]*)%s*"))) 157 | return ret 158 | elseif capture_name == "multi-class-class" then 159 | local temp = vim.split(capture_text, "%:%:") 160 | local ret = {} 161 | for i = 1, #temp-1 do 162 | local text = string.match(temp[i], "%s*([%w_]*)%s*?%s*") 163 | table.insert(ret, default_transform(config, "class-name", text)) 164 | end 165 | table.insert(ret, default_transform(config, "class-name", string.match(temp[#temp], "%s*([%w_]*)%s*?%s*"))) 166 | return ret 167 | else 168 | return default_transform(config, capture_name, capture_text) 169 | end 170 | end, 171 | ["html"] = function(config, capture_name, capture_text) 172 | if capture_name == "tag-name" then 173 | local text = string.match(capture_text, "<(.*)>") 174 | local tag_name, attributes = string.match(text, "([%w-]+)(.*)") 175 | local ret = tag_name 176 | local id_name = string.match(attributes, "id%s*=%s*%\"([^%s]+)%\"") 177 | if id_name ~= nil then 178 | ret = ret..'#'..id_name 179 | else 180 | local class_name = string.match(attributes, "class%s*=%s*%\"([%w-_%s]+)%\"") 181 | if class_name ~= nil then 182 | ret = ret..'.'..string.match(class_name, "(%w+)") 183 | end 184 | end 185 | return default_transform(config, "tag-name", ret) 186 | end 187 | end, 188 | ["haskell"] = function(config, capture_name, capture_text) 189 | if capture_name == "operator-name" then 190 | return default_transform(config, "function-name", ("(" .. capture_text .. ")" )) 191 | else 192 | return default_transform(config, capture_name, capture_text) 193 | end 194 | end, 195 | 196 | ["lua"] = function(config, capture_name, capture_text) 197 | if capture_name == "string-method" then 198 | return default_transform(config, "method-name", string.match(capture_text, "[\"\'](.*)[\"\']")) 199 | elseif capture_name == "multi-container" then 200 | local temp = vim.split(capture_text, "%.") 201 | local ret = {} 202 | for i = 1, #temp do 203 | table.insert(ret, default_transform(config, "container-name", temp[i])) 204 | end 205 | return ret 206 | elseif capture_name == "table-function" then 207 | local temp = vim.split(capture_text, "%.") 208 | local ret = {} 209 | for i = 1, #temp-1 do 210 | table.insert(ret, default_transform(config, "container-name", temp[i])) 211 | end 212 | table.insert(ret, default_transform(config, "function-name", temp[#temp])) 213 | return ret 214 | else 215 | return default_transform(config, capture_name, capture_text) 216 | end 217 | end, 218 | ["python"] = function(config, capture_name, capture_text) 219 | if capture_name == "main-function" then 220 | return default_transform(config, "function-name", "main") 221 | else 222 | return default_transform(config, capture_name, capture_text) 223 | end 224 | end, 225 | ["yang"] = function(config, capture_name, capture_text) 226 | if capture_name == "keyword" then 227 | return nil 228 | else 229 | return default_transform(config, capture_name, capture_text) 230 | end 231 | end 232 | } 233 | 234 | -- If a language doesn't have a transformation 235 | -- fallback to the default_transform 236 | setmetatable(transform_lang, { 237 | __index = function() 238 | return default_transform 239 | end 240 | }) 241 | 242 | -- Checks the availability of the plugin for the current buffer 243 | -- The availability is cached in a buffer variable (b:nvim_gps_available) 244 | function M.is_available() 245 | if setup_complete and vim.b.nvim_gps_available == nil then 246 | local filelang = ts_parsers.ft_to_lang(vim.bo.filetype) 247 | local config = configs[filelang] 248 | 249 | if config.enabled then 250 | local has_parser = ts_parsers.has_parser(filelang) 251 | local has_query = ts_queries.has_query_files(filelang, "nvimGPS") 252 | 253 | vim.b.nvim_gps_available = has_parser and has_query 254 | else 255 | vim.b.nvim_gps_available = false 256 | end 257 | end 258 | 259 | return vim.b.nvim_gps_available 260 | end 261 | 262 | -- Enables the treesitter nvimGPS module and loads the user configuration, or fallback to the 263 | -- default_config. 264 | function M.setup(user_config) 265 | -- Override default configurations with user definitions 266 | user_config = user_config or {} 267 | default_config.separator = user_config.separator or default_config.separator 268 | default_config.disable_icons = user_config.disable_icons or default_config.disable_icons 269 | default_config.icons = vim.tbl_extend("force", default_config.icons, user_config["icons"] or {}) 270 | setup_language_configs() 271 | default_config.depth = user_config.depth or default_config.depth 272 | default_config.depth_limit_indicator = user_config.depth_limit_indicator or default_config.depth_limit_indicator 273 | 274 | -- Override languages specific configurations with user definitions 275 | for lang, values in pairs(user_config.languages or {}) do 276 | if type(values) == "table" then 277 | configs[lang] = with_default_config(values) 278 | else 279 | configs[lang] = with_default_config({ enabled = values }) 280 | end 281 | end 282 | 283 | -- If a language doesn't have a configuration, fallback to the default_config 284 | setmetatable(configs, { 285 | __index = function() 286 | return default_config 287 | end 288 | }) 289 | 290 | require("nvim-treesitter.configs").setup({ 291 | nvimGPS = { 292 | enable = true 293 | } 294 | }) 295 | 296 | setup_complete = true 297 | end 298 | 299 | -- Request treesitter parser to update the syntax tree, 300 | -- when the buffer content has changed. 301 | local update_tree = ts_utils.memoize_by_buf_tick(function(bufnr) 302 | local filelang = ts_parsers.ft_to_lang(vim.api.nvim_buf_get_option(bufnr, "filetype")) 303 | local parser = ts_parsers.get_parser(bufnr, filelang) 304 | return parser:parse() 305 | end) 306 | 307 | ---@return table|nil the data in table format, or nil if gps is not available 308 | function M.get_data() 309 | -- Inserting text cause error nodes 310 | if vim.api.nvim_get_mode().mode == 'i' then 311 | return data_cache_value 312 | end 313 | 314 | -- Avoid repeated calls on same cursor position 315 | local curr_loc = vim.api.nvim_win_get_cursor(0) 316 | if data_prev_loc[1] == curr_loc[1] and data_prev_loc[2] == curr_loc[2] then 317 | return data_cache_value 318 | end 319 | 320 | data_prev_loc = vim.api.nvim_win_get_cursor(0) 321 | 322 | local filelang = ts_parsers.ft_to_lang(vim.bo.filetype) 323 | local gps_query = ts_queries.get_query(filelang, "nvimGPS") 324 | local transform = transform_lang[filelang] 325 | local config = configs[filelang] 326 | 327 | if not gps_query then 328 | return nil 329 | end 330 | 331 | -- Request treesitter parser to update the syntax tree for the current buffer. 332 | update_tree(vim.api.nvim_get_current_buf()) 333 | 334 | local current_node = ts_utils.get_node_at_cursor() 335 | 336 | local node_data = {} 337 | local node = current_node 338 | 339 | local function add_node_data(pos, capture_name, capture_node) 340 | local text = "" 341 | 342 | if vim.fn.has("nvim-0.7") > 0 then 343 | text = vim.treesitter.query.get_node_text(capture_node, 0) 344 | if text == nil then 345 | return data_cache_value 346 | end 347 | text = string.gsub(text, "%s+", ' ') 348 | else 349 | text = utils.get_node_text() 350 | text = table.concat(text, ' ') 351 | end 352 | 353 | local node_text = transform( 354 | config, 355 | capture_name, 356 | text 357 | ) 358 | 359 | if node_text ~= nil then 360 | table.insert(node_data, pos, node_text) 361 | end 362 | end 363 | 364 | while node do 365 | local iter = gps_query:iter_captures(node, 0) 366 | local capture_ID, capture_node = iter() 367 | 368 | if capture_node == node then 369 | if gps_query.captures[capture_ID] == "scope-root" then 370 | 371 | while capture_node == node do 372 | capture_ID, capture_node = iter() 373 | end 374 | local capture_name = gps_query.captures[capture_ID] 375 | add_node_data(1, capture_name, capture_node) 376 | 377 | elseif gps_query.captures[capture_ID] == "scope-root-2" then 378 | 379 | capture_ID, capture_node = iter() 380 | local capture_name = gps_query.captures[capture_ID] 381 | add_node_data(1, capture_name, capture_node) 382 | 383 | capture_ID, capture_node = iter() 384 | capture_name = gps_query.captures[capture_ID] 385 | add_node_data(2, capture_name, capture_node) 386 | 387 | end 388 | end 389 | 390 | node = node:parent() 391 | end 392 | 393 | local data = {} 394 | for _, v in pairs(node_data) do 395 | if not vim.tbl_islist(v) then 396 | table.insert(data, v) 397 | else 398 | vim.list_extend(data, v) 399 | end 400 | end 401 | 402 | data_cache_value = data 403 | return data_cache_value 404 | end 405 | 406 | ---@return string|nil the pretty statusline component, or nil if not available 407 | function M.get_location(opts) 408 | if vim.api.nvim_get_mode().mode == 'i' then 409 | return location_cache_value 410 | end 411 | 412 | local curr_loc = vim.api.nvim_win_get_cursor(0) 413 | if location_prev_loc[1] == curr_loc[1] and location_prev_loc[2] == curr_loc[2] then 414 | return location_cache_value 415 | end 416 | 417 | location_prev_loc = vim.api.nvim_win_get_cursor(0) 418 | 419 | local filelang = ts_parsers.ft_to_lang(vim.bo.filetype) 420 | local config = configs[filelang] 421 | local data = M.get_data() 422 | 423 | if not data then 424 | return nil 425 | end 426 | 427 | local depth = config.depth 428 | local separator = config.separator 429 | local disable_icons = config.disable_icons 430 | local depth_limit_indicator = config.depth_limit_indicator 431 | 432 | if opts ~= nil then 433 | depth = opts.depth or config.depth 434 | separator = opts.separator or config.separator 435 | disable_icons = opts.disable_icons or config.disable_icons 436 | depth_limit_indicator = opts.depth_limit_indicator or config.depth_limit_indicator 437 | end 438 | 439 | local context = {} 440 | for _, v in pairs(data) do 441 | if not disable_icons then 442 | table.insert(context, v.icon..v.text) 443 | else 444 | table.insert(context, v.text) 445 | end 446 | end 447 | 448 | if depth ~= 0 and #context > depth then 449 | context = vim.list_slice(context, #context-depth+1, #context) 450 | table.insert(context, 1, depth_limit_indicator) 451 | end 452 | 453 | context = table.concat(context, separator) 454 | 455 | location_cache_value = context 456 | return location_cache_value 457 | end 458 | 459 | return M 460 | -------------------------------------------------------------------------------- /lua/nvim-gps/internal.lua: -------------------------------------------------------------------------------- 1 | local ts_queries = require("nvim-treesitter.query") 2 | 3 | local M = {} 4 | 5 | -- TreeSitter module setup 6 | function M.init() 7 | require("nvim-treesitter").define_modules { 8 | nvimGPS = { 9 | module_path = "nvim-gps.internal", 10 | is_supported = function(lang) 11 | return ts_queries.get_query(lang, "nvimGPS") ~= nil 12 | end 13 | } 14 | } 15 | end 16 | 17 | function M.attach(bufnr, lang) 18 | -- Nothing 19 | end 20 | 21 | function M.detach(bufnr) 22 | -- Nothing 23 | end 24 | 25 | return M 26 | -------------------------------------------------------------------------------- /lua/nvim-gps/utils.lua: -------------------------------------------------------------------------------- 1 | local ts_utils = require("nvim-treesitter.ts_utils") 2 | 3 | local M = {} 4 | 5 | function M.get_node_text(node) 6 | local bufnr = vim.api.nvim_get_current_buf() 7 | 8 | -- We have to remember that end_col is end-exclusive 9 | local start_row, start_col, end_row, end_col = ts_utils.get_node_range(node) 10 | 11 | if start_row ~= end_row then 12 | local lines = vim.api.nvim_buf_get_lines(bufnr, start_row, end_row + 1, false) 13 | lines[1] = string.sub(lines[1], start_col + 1) 14 | -- end_row might be just after the last line. In this case the last line is not truncated. 15 | if #lines == end_row - start_row + 1 then 16 | lines[#lines] = string.sub(lines[#lines], 1, end_col) 17 | end 18 | return lines 19 | else 20 | local line = vim.api.nvim_buf_get_lines(bufnr, start_row, start_row + 1, false)[1] 21 | -- If line is nil then the line is empty 22 | return line and { string.sub(line, start_col + 1, end_col) } or {} 23 | end 24 | end 25 | 26 | return M 27 | -------------------------------------------------------------------------------- /plugin/nvim-gps.vim: -------------------------------------------------------------------------------- 1 | lua require("nvim-gps.internal").init() 2 | -------------------------------------------------------------------------------- /queries/bash/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Function 3 | ((function_definition 4 | name: (word) @function-name 5 | body: (compound_statement)) @scope-root) 6 | -------------------------------------------------------------------------------- /queries/c/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Struct 3 | ((struct_specifier 4 | name: (type_identifier) @class-name 5 | body: (field_declaration_list)) @scope-root) 6 | 7 | ; Function 8 | ((function_definition 9 | declarator: (function_declarator 10 | declarator: (identifier) @function-name )) @scope-root) 11 | 12 | ; Function with pointer as return type 13 | ((function_definition 14 | declarator: (pointer_declarator 15 | declarator: (function_declarator 16 | (identifier) @function-name))) @scope-root) 17 | -------------------------------------------------------------------------------- /queries/c_sharp/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Class 2 | ((class_declaration 3 | name: (identifier) @class-name 4 | body: (declaration_list)) @scope-root) 5 | 6 | ; Struct 7 | ((struct_declaration 8 | name: (identifier) @class-name 9 | body: (declaration_list)) @scope-root) 10 | 11 | ; Interface 12 | ((interface_declaration 13 | name: (identifier) @method-name 14 | body: (declaration_list)) @scope-root) 15 | 16 | ; Record 17 | ((record_declaration 18 | name: (identifier) @method-name 19 | body: (declaration_list)) @scope-root) 20 | 21 | ; Namespace 22 | ((namespace_declaration 23 | name: (identifier) @class-name 24 | body: (declaration_list)) @scope-root) 25 | 26 | ; Method 27 | ((method_declaration 28 | name: (identifier) @method-name 29 | body: (block)) @scope-root) 30 | ((method_declaration 31 | name: (identifier) @method-name 32 | body: (arrow_expression_clause)) @scope-root) 33 | 34 | ; Property 35 | ((property_declaration 36 | name: (identifier) @method-name 37 | accessors: (accessor_list)) @scope-root) 38 | ((property_declaration 39 | name: (identifier) @method-name 40 | value: (arrow_expression_clause)) @scope-root) 41 | 42 | ; Lambda function 43 | ((variable_declaration 44 | (variable_declarator 45 | (identifier) @function-name 46 | (equals_value_clause 47 | (lambda_expression)))) @scope-root) 48 | 49 | -------------------------------------------------------------------------------- /queries/cpp/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Class 3 | ((class_specifier 4 | name: [(type_identifier) @class-name (qualified_identifier) @multi-class-class] 5 | body: (field_declaration_list)) @scope-root) 6 | 7 | ; Struct 8 | ((struct_specifier 9 | name: [(type_identifier) @class-name (qualified_identifier) @multi-class-class] 10 | body: (field_declaration_list)) @scope-root) 11 | 12 | ; Namespace 13 | ((namespace_definition 14 | name: (identifier) @class-name 15 | body: (declaration_list)) @scope-root) 16 | 17 | ; Function 18 | ((function_definition 19 | declarator: (function_declarator 20 | declarator: (identifier) @function-name)) @scope-root) 21 | 22 | ; Function with pointer as return type 23 | ((function_definition 24 | declarator: (pointer_declarator 25 | declarator: (function_declarator 26 | declarator: (identifier) @function-name))) @scope-root) 27 | 28 | ; Function with reference as return type 29 | ((function_definition 30 | declarator: (reference_declarator 31 | (function_declarator 32 | declarator: [(identifier) @function-name (qualified_identifier) @multi-class-method (field_identifier) @method-name]))) @scope-root) 33 | 34 | ; Lambda function 35 | ((declaration 36 | declarator: (init_declarator 37 | declarator: (identifier) @function-name 38 | value: (lambda_expression))) @scope-root) 39 | 40 | ; Methods 41 | ((function_definition 42 | declarator: (function_declarator 43 | declarator: [(field_identifier) @method-name (qualified_identifier) @multi-class-method])) @scope-root) 44 | 45 | ; Methods with pointer as return type 46 | ((function_definition 47 | declarator: (pointer_declarator 48 | declarator: (function_declarator 49 | declarator: [(field_identifier) @method-name (qualified_identifier) @multi-class-method]))) @scope-root) 50 | 51 | ; Methods with reference as return type 52 | ((function_definition 53 | declarator: (reference_declarator 54 | (function_declarator 55 | declarator: [(field_identifier) @method-name (qualified_identifier) @multi-class-method]))) @scope-root) 56 | -------------------------------------------------------------------------------- /queries/fennel/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Functions 3 | ((fn 4 | name: (symbol) @function-name) @scope-root) 5 | 6 | ; Lambda 7 | ((lambda 8 | name: (symbol) @function-name) @scope-root) 9 | 10 | ; Methods 11 | ((fn 12 | name: (multi_symbol) @method-name) @scope-root) 13 | 14 | ; Lambda Methods 15 | ((lambda 16 | name: (multi_symbol) @method-name) @scope-root) 17 | -------------------------------------------------------------------------------- /queries/go/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Struct and Interface 3 | ((type_spec 4 | name: (type_identifier) @class-name) @scope-root) 5 | 6 | ; Function 7 | ((function_declaration 8 | name: (identifier) @function-name) @scope-root) 9 | 10 | ; Method 11 | ((method_declaration 12 | receiver: (parameter_list 13 | (parameter_declaration 14 | type: (type_identifier) @class-name)) 15 | name: (field_identifier) @method-name) @scope-root-2) 16 | 17 | ; Method with pointer 18 | ((method_declaration 19 | receiver: (parameter_list 20 | (parameter_declaration 21 | type: (pointer_type 22 | (type_identifier) @class-name))) 23 | name: (field_identifier) @method-name) @scope-root-2) 24 | -------------------------------------------------------------------------------- /queries/haskell/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Function Definition 2 | ((signature 3 | name: (variable) @function-name) @scope-root) 4 | 5 | ; Function 6 | ((function 7 | name: (variable) @function-name) @scope-root) 8 | 9 | ; Operator Definition 10 | ((signature 11 | name: (operator) @operator-name) @scope-root) 12 | 13 | ; Operator 14 | ((function 15 | infix: (infix op: (varop) @operator-name)) @scope-root) 16 | 17 | ; Operator in Where Clause 18 | ((function 19 | name: (operator) @operator-name) @scope-root) 20 | 21 | ; Data 22 | ((adt 23 | name: (type) @class-name) @scope-root) 24 | 25 | ; Constructors 26 | ((data_constructor 27 | (constructor) @method-name) @scope-root) 28 | 29 | ; Record Field 30 | ((field 31 | (variable) @method-name) @scope-root) 32 | 33 | ; Newtype 34 | ((newtype 35 | name: (type) @class-name) @scope-root) 36 | 37 | ; Instance 38 | ((instance 39 | (instance_head) @class-name) @scope-root) 40 | 41 | ; TypeClass 42 | ((class 43 | (class_head 44 | class: (class_name) @class-name)) @scope-root) 45 | 46 | 47 | -------------------------------------------------------------------------------- /queries/html/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ((element 3 | (start_tag) @tag-name 4 | (end_tag)) @scope-root) 5 | -------------------------------------------------------------------------------- /queries/java/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Class 3 | ((class_declaration 4 | name: (identifier) @class-name 5 | body: (class_body)) @scope-root) 6 | 7 | ; Interface 8 | ((interface_declaration 9 | name: (identifier) @class-name 10 | body: (interface_body)) @scope-root) 11 | 12 | ; Enum 13 | ((enum_declaration 14 | name: (identifier) @class-name 15 | body: (enum_body)) @scope-root) 16 | 17 | ; Method 18 | ((method_declaration 19 | name: (identifier) @method-name 20 | body: (block)) @scope-root) 21 | -------------------------------------------------------------------------------- /queries/javascript/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Class 3 | ((class_declaration 4 | name: (identifier) @class-name 5 | body: (class_body)) @scope-root) 6 | 7 | ; Function 8 | ((function_declaration 9 | name: (identifier) @function-name 10 | body: (statement_block)) @scope-root) 11 | 12 | ; Method 13 | ((method_definition 14 | name: (property_identifier) @method-name 15 | body: (statement_block)) @scope-root) 16 | 17 | ; Arrow Function 18 | ((variable_declarator 19 | name: (identifier) @function-name 20 | value: (arrow_function)) @scope-root) 21 | 22 | ; Function Expression 23 | ((variable_declarator 24 | name: (identifier) @function-name 25 | value: (function)) @scope-root) 26 | 27 | ; Tests 28 | ((expression_statement 29 | (call_expression 30 | function: (identifier) 31 | arguments: (arguments 32 | (string) @method-name 33 | (arrow_function)))) @scope-root) 34 | 35 | ; Arrow function methods 36 | ((field_definition 37 | property: (property_identifier) @method-name 38 | value: (arrow_function)) @scope-root) 39 | 40 | ; object literal 41 | ((variable_declarator 42 | name: (identifier) @object-name 43 | value: (object)) @scope-root) 44 | 45 | ; object literal modification 46 | ((assignment_expression 47 | left: (identifier) @object-name 48 | right: (object)) @scope-root) 49 | 50 | ; nested objects 51 | ((pair 52 | key: (property_identifier) @object-name 53 | value: (_)) @scope-root) 54 | 55 | ; nested objects with computed_property_name e.g. { [bar] : true } 56 | ((pair 57 | key: (computed_property_name) @object-name 58 | value: (_)) @scope-root) 59 | 60 | ; object property modification 61 | ((assignment_expression 62 | left: (member_expression) @object-name 63 | right: (object)) @scope-root) 64 | 65 | ; array 66 | ((variable_declarator 67 | name: (identifier) @array-name 68 | value: (array)) @scope-root) 69 | 70 | ; array modification 71 | ((assignment_expression 72 | left: (identifier) @array-name 73 | right: (array)) @scope-root) 74 | 75 | -------------------------------------------------------------------------------- /queries/json/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Array 2 | ((pair 3 | key: (string (string_content) @array-name) 4 | value: (array)) @scope-root) 5 | 6 | ; Object 7 | ((pair 8 | key: (string (string_content) @object-name) 9 | value: (object)) @scope-root) 10 | 11 | ; Null 12 | ((pair 13 | key: (string (string_content) @null-name) 14 | value: (null)) @scope-root) 15 | 16 | ; Boolean (false) 17 | ((pair 18 | key: (string (string_content) @boolean-name) 19 | value: (false)) @scope-root) 20 | 21 | ; Boolean (true) 22 | ((pair 23 | key: (string (string_content) @boolean-name) 24 | value: (true)) @scope-root) 25 | 26 | ; Number 27 | ((pair 28 | key: (string (string_content) @number-name) 29 | value: (number)) @scope-root) 30 | 31 | ; String 32 | ((pair 33 | key: (string (string_content) @string-name) 34 | value: (string)) @scope-root) 35 | -------------------------------------------------------------------------------- /queries/jsx/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; inherits: javascript 2 | -------------------------------------------------------------------------------- /queries/latex/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ;; Sectioning 2 | ((chapter 3 | command: _ 4 | text: (curly_group 5 | (_) @title-name)) @scope-root) 6 | 7 | ((part 8 | command: _ 9 | text: (curly_group 10 | (_) @title-name)) @scope-root) 11 | 12 | ((section 13 | command: _ 14 | text: (curly_group 15 | (_) @title-name)) @scope-root) 16 | 17 | ((subsection 18 | command: _ 19 | text: (curly_group 20 | (_) @title-name)) @scope-root) 21 | 22 | ((subsubsection 23 | command: _ 24 | text: (curly_group 25 | (_) @title-name)) @scope-root) 26 | 27 | ((paragraph 28 | command: _ 29 | text: (curly_group 30 | (_) @title-name)) @scope-root) 31 | 32 | ((subparagraph 33 | command: _ 34 | text: (curly_group 35 | (_) @title-name)) @scope-root) 36 | 37 | ;; Labeled environments 38 | ((generic_environment 39 | (label_definition 40 | name: (curly_group_text 41 | (_) @label-name))) @scope-root) 42 | -------------------------------------------------------------------------------- /queries/lua/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Functions 3 | ((function_declaration 4 | name: (identifier) @function-name) @scope-root) 5 | 6 | ((function_declaration 7 | name: (dot_index_expression) @table-function) @scope-root) 8 | 9 | ; Function assined to variables 10 | ((assignment_statement 11 | (variable_list 12 | name: (identifier) @function-name) 13 | (expression_list 14 | value: (function_definition))) @scope-root) 15 | 16 | ((assignment_statement 17 | (variable_list 18 | name: (dot_index_expression) @table-function) 19 | (expression_list 20 | value: (function_definition))) @scope-root) 21 | 22 | ; Methods 23 | ((field 24 | name: (identifier) @method-name 25 | value: (function_definition)) @scope-root) 26 | 27 | ((field 28 | name: (string) @string-method 29 | value: (function_definition)) @scope-root) 30 | 31 | ; Tables 32 | ((assignment_statement 33 | (variable_list 34 | name: (_) @multi-container) 35 | (expression_list 36 | value: (table_constructor))) @scope-root) 37 | 38 | ; Table inside table 39 | ((field 40 | name: (identifier) @container-name 41 | value: (table_constructor)) @scope-root) 42 | 43 | -------------------------------------------------------------------------------- /queries/nix/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Functions 2 | ((binding 3 | attrpath: (attrpath) @function-name 4 | expression: (function_expression))) @scope-root 5 | 6 | ((binding 7 | attrpath: (attrpath) @function-name 8 | expression: (parenthesized_expression expression: (function_expression))) @scope-root) 9 | 10 | ; Bindings 11 | ((binding 12 | attrpath: (attrpath) @container-name) @scope-root) 13 | 14 | -------------------------------------------------------------------------------- /queries/norg/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ;; Headings 2 | ((heading1 3 | (heading1_prefix) 4 | title: (paragraph_segment) @title-name) @scope-root) 5 | 6 | ((heading2 7 | (heading2_prefix) 8 | title: (paragraph_segment) @title-name) @scope-root) 9 | 10 | ((heading3 11 | (heading3_prefix) 12 | title: (paragraph_segment) @title-name) @scope-root) 13 | 14 | ((heading4 15 | (heading4_prefix) 16 | title: (paragraph_segment) @title-name) @scope-root) 17 | 18 | ((heading5 19 | (heading5_prefix) 20 | title: (paragraph_segment) @title-name) @scope-root) 21 | 22 | ((heading6 23 | (heading6_prefix) 24 | title: (paragraph_segment) @title-name) @scope-root) 25 | -------------------------------------------------------------------------------- /queries/ocaml/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ;; module 2 | ((module_definition 3 | (module_binding 4 | name: (module_name) @class-name)) @scope-root) 5 | 6 | ;; function/value 7 | ((value_definition 8 | (let_binding 9 | pattern: (value_name) @function-name)) @scope-root) 10 | 11 | -------------------------------------------------------------------------------- /queries/php/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Class 2 | ((class_declaration 3 | name: (name) @class-name 4 | body: (declaration_list)) @scope-root) 5 | 6 | ; Interface 7 | ((interface_declaration 8 | name: (name) @class-name 9 | body: (declaration_list)) @scope-root) 10 | 11 | ; Method 12 | ((method_declaration 13 | name: (name) @method-name 14 | body: (compound_statement)) @scope-root) 15 | 16 | ((function_definition 17 | name: (name) @function-name 18 | body: (compound_statement)) @scope-root) 19 | -------------------------------------------------------------------------------- /queries/python/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Class 3 | ((class_definition 4 | name: (identifier) @class-name) @scope-root) 5 | 6 | ; Method 7 | ((function_definition 8 | name: (identifier) @method-name 9 | parameters: (parameters 10 | (identifier) @self-capture (#eq? @self-capture "self"))) @scope-root) 11 | 12 | ; Function 13 | ((function_definition 14 | name: (identifier) @function-name) @scope-root) 15 | 16 | ; Main 17 | ((if_statement 18 | condition: (comparison_operator 19 | (string) @main-function (#match? @main-function "[\"\']__main__[\"\']"))) @scope-root) 20 | -------------------------------------------------------------------------------- /queries/ruby/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | (module [ 2 | (scope_resolution) 3 | (constant) 4 | ] @container-name) @scope-root 5 | 6 | (class 7 | (constant) @class-name) @scope-root 8 | 9 | (class 10 | (scope_resolution (constant)) @class-name) @scope-root 11 | 12 | (singleton_method 13 | (identifier) @function-name) @scope-root 14 | 15 | (method 16 | (identifier) @method-name) @scope-root 17 | -------------------------------------------------------------------------------- /queries/rust/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Struct 3 | ((struct_item 4 | name: (type_identifier) @class-name) @scope-root) 5 | 6 | ; Impl 7 | ((impl_item 8 | type: (type_identifier) @class-name) @scope-root) 9 | 10 | ; Impl with generic 11 | ((impl_item 12 | type: (generic_type 13 | type: (type_identifier) @class-name)) @scope-root) 14 | 15 | ; Mod 16 | ((mod_item 17 | name: (identifier) @class-name) @scope-root) 18 | 19 | ; Enum 20 | ((enum_item 21 | name: (type_identifier) @class-name) @scope-root) 22 | 23 | ; Function 24 | ((function_item 25 | name: (identifier) @function-name 26 | body: (block)) @scope-root) 27 | -------------------------------------------------------------------------------- /queries/scss/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ((rule_set 2 | (selectors) @scss-name 3 | ) @scope-root) 4 | 5 | ((mixin_statement 6 | (name) @scss-mixin-name 7 | ) @scope-root) 8 | 9 | ((include_statement 10 | (identifier) @scss-include-name 11 | ) @scope-root) 12 | 13 | ((keyframes_statement 14 | (keyframes_name) @scss-keyframes-name 15 | ) @scope-root) 16 | -------------------------------------------------------------------------------- /queries/toml/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Table 2 | ((table 3 | (_) @table-name) @scope-root) 4 | 5 | ; Array 6 | ((pair 7 | (_) @array-name 8 | (array)) @scope-root) 9 | 10 | ; Boolean 11 | ((pair 12 | (_) @boolean-name 13 | (boolean)) @scope-root) 14 | 15 | ; Date 16 | ((pair 17 | (_) @date-name 18 | (local_date)) @scope-root) 19 | 20 | ; Date Time 21 | ((pair 22 | (_) @date-time-name 23 | (offset_date_time)) @scope-root) 24 | 25 | ((pair 26 | (_) @date-time-name 27 | (local_date_time)) @scope-root) 28 | 29 | ; Float 30 | ((pair 31 | (_) @float-name 32 | (float)) @scope-root) 33 | 34 | ; Inline Table 35 | ((pair 36 | (_) @inline-table-name 37 | (inline_table)) @scope-root) 38 | 39 | ; Integer 40 | ((pair 41 | (_) @integer-name 42 | (integer)) @scope-root) 43 | 44 | ; String 45 | ((pair 46 | (_) @string-name 47 | (string)) @scope-root) 48 | 49 | ; Time 50 | ((pair 51 | (_) @time-name 52 | (local_time)) @scope-root) 53 | 54 | -------------------------------------------------------------------------------- /queries/tsx/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; inherits: typescript 2 | 3 | ; React hook name 4 | ((call_expression 5 | function: (identifier) @hook-name (#match? @hook-name "^use") 6 | ) @scope-root) 7 | 8 | ; React hook function name 9 | ((variable_declarator 10 | name: (identifier) @function-name 11 | value: (call_expression 12 | function: (identifier) @hook-identifier (#match? @hook-identifier "^use") 13 | )) @scope-root) 14 | -------------------------------------------------------------------------------- /queries/typescript/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | 2 | ; Class 3 | ((class_declaration 4 | name: (type_identifier) @class-name 5 | body: (class_body)) @scope-root) 6 | 7 | ; Interface 8 | ((interface_declaration 9 | name: (type_identifier) @class-name 10 | body: (object_type)) @scope-root) 11 | 12 | ; Function 13 | ((function_declaration 14 | name: (identifier) @function-name 15 | body: (statement_block)) @scope-root) 16 | 17 | ; Anonymous function 18 | ((variable_declarator 19 | name: (identifier) @function-name 20 | value: (function 21 | body: (statement_block))) @scope-root) 22 | 23 | ; Method 24 | ((method_definition 25 | name: (property_identifier) @method-name 26 | body: (statement_block)) @scope-root) 27 | 28 | ; Arrow function 29 | ((variable_declarator 30 | name: (identifier) @function-name 31 | value: (arrow_function)) @scope-root) 32 | 33 | ; Describe blocks 34 | ((expression_statement 35 | (call_expression 36 | function: (identifier) 37 | arguments: (arguments 38 | (string) @method-name 39 | (arrow_function)))) @scope-root) 40 | 41 | ; Arrow function methods 42 | ((public_field_definition 43 | name: (property_identifier) @method-name 44 | value: (arrow_function)) @scope-root) 45 | -------------------------------------------------------------------------------- /queries/verilog/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Module 2 | ((module_declaration 3 | (module_header 4 | (simple_identifier) @module-name)) @scope-root) 5 | 6 | ; Function 7 | ((function_declaration 8 | (function_body_declaration 9 | (function_identifier) @function-name)) @scope-root) 10 | -------------------------------------------------------------------------------- /queries/yaml/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Mapping 2 | ((block_mapping_pair 3 | key: (flow_node) @mapping-name 4 | value: (block_node (block_mapping))) @scope-root) 5 | 6 | ; Sequence 7 | ((block_mapping_pair 8 | key: (flow_node) @sequence-name 9 | value: (block_node (block_sequence))) @scope-root) 10 | 11 | ; Null 12 | ((block_mapping_pair 13 | key: (flow_node) @null-name 14 | value: (flow_node (plain_scalar (null_scalar)))) @scope-root) 15 | 16 | ; Boolean 17 | ((block_mapping_pair 18 | key: (flow_node) @boolean-name 19 | value: (flow_node (plain_scalar (boolean_scalar)))) @scope-root) 20 | 21 | ; Integer 22 | ((block_mapping_pair 23 | key: (flow_node) @integer-name 24 | value: (flow_node (plain_scalar (integer_scalar)))) @scope-root) 25 | 26 | ; Float 27 | ((block_mapping_pair 28 | key: (flow_node) @float-name 29 | value: (flow_node (plain_scalar (float_scalar)))) @scope-root) 30 | 31 | ; String 32 | ((block_mapping_pair 33 | key: (flow_node) @string-name 34 | value: (flow_node (double_quote_scalar))) @scope-root) 35 | 36 | ((block_mapping_pair 37 | key: (flow_node) @string-name 38 | value: (flow_node (single_quote_scalar))) @scope-root) 39 | 40 | ((block_mapping_pair 41 | key: (flow_node) @string-name 42 | value: (flow_node (plain_scalar (string_scalar)))) @scope-root) 43 | -------------------------------------------------------------------------------- /queries/yang/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ((module module_name: (identifier) @module-name) @scope-root) 2 | 3 | ((statement 4 | (statement_keyword "augment") 5 | (argument) @augment-path) @scope-root) 6 | 7 | ((statement 8 | (statement_keyword "container") 9 | (argument) @container-name) @scope-root) 10 | 11 | ((statement 12 | (statement_keyword "grouping") 13 | (argument) @grouping-name) @scope-root) 14 | 15 | ((statement 16 | (statement_keyword "typedef") 17 | (argument) @typedef-name) @scope-root) 18 | 19 | ((statement 20 | (statement_keyword "identity") 21 | (argument) @identity-name) @scope-root) 22 | 23 | ((statement 24 | (statement_keyword "list") 25 | (argument) @list-name) @scope-root) 26 | 27 | ((statement 28 | (statement_keyword "leaf-list") 29 | (argument) @leaf-list-name) @scope-root) 30 | 31 | ((statement 32 | (statement_keyword "leaf") 33 | (argument) @leaf-name) @scope-root) 34 | 35 | ((extension_statement 36 | (extension_keyword) @keyword (#eq? @keyword "tailf:action") 37 | (argument) @action-name) @scope-root-2) 38 | -------------------------------------------------------------------------------- /queries/zig/nvimGPS.scm: -------------------------------------------------------------------------------- 1 | ; Struct 2 | ((TopLevelDecl 3 | (VarDecl 4 | variable_type_function: (IDENTIFIER) @class-name)) @scope-root) 5 | 6 | ; Function 7 | ((TopLevelDecl 8 | (FnProto 9 | function: (IDENTIFIER) @function-name)) @scope-root) 10 | 11 | ; Test 12 | ((TestDecl 13 | ((STRINGLITERALSINGLE) @function-name)) @scope-root) --------------------------------------------------------------------------------