diff options
| author | Thomas Vigouroux <39092278+vigoux@users.noreply.github.com> | 2020-04-19 20:38:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-19 20:38:51 +0200 |
| commit | 05be31024adc868af782c51dd63c6ccdfbfeb2a9 (patch) | |
| tree | 45970745e65c16d52bcb93db4a4a466c6f9f105c | |
| parent | Merge pull request #2 from kyazdani42/install-parser (diff) | |
| parent | perf: don't compute locals on buffer updates (diff) | |
| download | nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar.gz nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar.bz2 nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar.lz nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar.xz nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.tar.zst nvim-treesitter-05be31024adc868af782c51dd63c6ccdfbfeb2a9.zip | |
Merge pull request #3 from vigoux/feature/locals
Add locals handling
| -rw-r--r-- | lua/nvim-treesitter.lua | 1 | ||||
| -rw-r--r-- | lua/nvim-treesitter/locals.lua | 91 | ||||
| -rw-r--r-- | lua/nvim-treesitter/parsers.lua | 10 | ||||
| -rw-r--r-- | lua/nvim-treesitter/query.lua | 2 | ||||
| -rw-r--r-- | plugin/nvim-treesitter.vim | 10 | ||||
| -rw-r--r-- | queries/lua/locals.scm | 16 |
6 files changed, 118 insertions, 12 deletions
diff --git a/lua/nvim-treesitter.lua b/lua/nvim-treesitter.lua index abb3b6d91..8dae7c33b 100644 --- a/lua/nvim-treesitter.lua +++ b/lua/nvim-treesitter.lua @@ -1,6 +1,7 @@ local api = vim.api local parsers = require'nvim-treesitter.parsers' local install = require'nvim-treesitter.install' +local locals = require'nvim-treesitter.locals' local M = {} diff --git a/lua/nvim-treesitter/locals.lua b/lua/nvim-treesitter/locals.lua new file mode 100644 index 000000000..808b0f3ff --- /dev/null +++ b/lua/nvim-treesitter/locals.lua @@ -0,0 +1,91 @@ +-- Functions to handle locals +-- Locals are a generalization of definition and scopes +-- its the way nvim-treesitter uses to "understand" the code +local api = vim.api +local ts = vim.treesitter +local queries = require'nvim-treesitter.query' +local parsers = require'nvim-treesitter.parsers' + +local M = { + locals={} +} + +function M.collect_locals(bufnr) + local ft = api.nvim_buf_get_option(bufnr, "ft") + if not ft then return end + + local query = queries.get_query(ft, 'locals') + if not query then return end + + local parser = parsers.get_parser(bufnr, ft) + if not parser then return end + + local root = parser:parse():root() + local start_row, _, end_row, _ = root:range() + + local locals = {} + + for prepared_match in queries.iter_prepared_matches(query, root, bufnr, start_row, end_row) do + table.insert(locals, prepared_match) + end + + return locals +end + +local function update_cached_locals(bufnr, changed_tick) + M.locals[bufnr] = {tick=changed_tick, cache=( M.collect_locals(bufnr) or {} )} +end + +function M.get_locals(bufnr) + local bufnr = bufnr or api.nvim_get_current_buf() + local cached_local = M.locals[bufnr] + if not cached_local or api.nvim_buf_get_changedtick(bufnr) < cached_local.tick then + update_cached_locals(bufnr,api.nvim_buf_get_changedtick(bufnr)) + end + + return M.locals[bufnr].cache +end + +function M.get_definitions(bufnr) + local locals = M.get_locals(bufnr) + + local defs = {} + + for _, loc in ipairs(locals) do + if loc.definition then + table.insert(defs, {definition=loc.definition, kind=loc.kind}) + end + end + + return defs +end + +function M.get_scopes(bufnr) + local locals = M.get_locals(bufnr) + + local scopes = {} + + for _, loc in ipairs(locals) do + if loc.scope then + table.insert(scopes, loc.scope) + end + end + + return scopes +end + +function M.get_references(bufnr) + local locals = M.get_locals(bufnr) + + local refs = {} + + for _, loc in ipairs(locals) do + if loc.reference then + table.insert(refs, loc.reference) + end + end + + return refs +end + +return M diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index c85177733..e046ca45c 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -8,13 +8,17 @@ function M.has_parser(lang) return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0 end -function M.get_parser(bufnr) +function M.get_parser(bufnr, lang) if M.has_parser() then local buf = bufnr or api.nvim_get_current_buf() + local lang = lang or api.nvim_buf_get_option(buf, 'ft') if not M[buf] then - M[buf] = ts.get_parser(buf) + M[buf] = {} end - return M[buf] + if not M[buf][lang] then + M[buf][lang] = ts.get_parser(buf, lang) + end + return M[buf][lang] end end diff --git a/lua/nvim-treesitter/query.lua b/lua/nvim-treesitter/query.lua index be650c795..e9f671f93 100644 --- a/lua/nvim-treesitter/query.lua +++ b/lua/nvim-treesitter/query.lua @@ -54,7 +54,7 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row) local name = query.captures[id] -- name of the capture in the query if name ~= nil then local path = split(name) - insert_to_path(prepared_match, path, node) + insert_to_path(prepared_match, path, { node=node }) end end diff --git a/plugin/nvim-treesitter.vim b/plugin/nvim-treesitter.vim new file mode 100644 index 000000000..03b738763 --- /dev/null +++ b/plugin/nvim-treesitter.vim @@ -0,0 +1,10 @@ +" Last Change: 2020 avril 19 + +if exists('g:loaded_nvim_treesitter') + finish +endif + +let g:loaded_nvim_treesitter = 1 + +augroup NvimTreesitter +augroup END diff --git a/queries/lua/locals.scm b/queries/lua/locals.scm index a7b15d1e5..4764c021c 100644 --- a/queries/lua/locals.scm +++ b/queries/lua/locals.scm @@ -3,19 +3,19 @@ ;; Variable and field declarations ((variable_declarator (identifier) @definition) - (set! kind "v")) + (set! definition.kind "v")) ((variable_declarator (field_expression object:(*) @definition.associated (property_identifier) @definition)) - (set! kind "v")) + (set! difinition.kind "v")) ;; Parameters ((local_function (parameters (identifier) @definition)) - (set! kind "v")) + (set! definition.kind "v")) ((function (parameters (identifier) @definition)) - (set! kind "v")) + (set! definition.kind "v")) ;; Function definitions ;; Functions definitions creates both a definition and a new scope @@ -23,15 +23,15 @@ (function_name_field object: (identifier) @definition.associated (property_identifier) @definition)) @scope - (set! kind "m")) + (set! definition.kind "m")) ((function (function_name (identifier) @definition)) @scope - (set! kind "f")) + (set! definition.kind "f")) ((local_function (identifier) @definition) @scope - (set! kind "f")) + (set! definition.kind "f")) ((if_statement) @scope) ((for_in_statement) @scope) @@ -39,7 +39,7 @@ ;; Loops ((loop_expression (identifier) @definition) - (set! kind "v")) + (set! definition.kind "v")) ;;; REFERENCES ((identifier) @reference) |
