├── .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 | 
14 |
15 | Here is a barebones example how it looks in a statusline
16 |
17 | 
18 |
19 | Here is a example of how it can look in a fully configured statusline
20 |
21 | 
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)
--------------------------------------------------------------------------------