mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-19 03:40:04 -04:00
refacto: remove buf_state
- remove buf_state and related code - add get_node_at_cursor() - better incremental selection (code is localized)
This commit is contained in:
parent
772aa4c169
commit
38af29a912
9 changed files with 100 additions and 233 deletions
|
|
@ -2,10 +2,9 @@ local api = vim.api
|
||||||
|
|
||||||
local install = require'nvim-treesitter.install'
|
local install = require'nvim-treesitter.install'
|
||||||
local utils = require'nvim-treesitter.utils'
|
local utils = require'nvim-treesitter.utils'
|
||||||
|
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||||
local info = require'nvim-treesitter.info'
|
local info = require'nvim-treesitter.info'
|
||||||
local configs = require'nvim-treesitter.configs'
|
local configs = require'nvim-treesitter.configs'
|
||||||
local state = require'nvim-treesitter.state'
|
|
||||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
|
@ -21,20 +20,13 @@ function M.setup()
|
||||||
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
|
api.nvim_command(string.format("autocmd NvimTreesitter FileType %s %s", ft, cmd))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local cmd = string.format("lua require'nvim-treesitter.state'.attach_to_buffer(%s)", ft)
|
|
||||||
api.nvim_command(string.format('autocmd NvimTreesitter FileType %s %s', ft, cmd))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
state.run_update()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.statusline(indicator_size)
|
function M.statusline(indicator_size)
|
||||||
local indicator_size = indicator_size or 100
|
local indicator_size = indicator_size or 100
|
||||||
local bufnr = api.nvim_get_current_buf()
|
|
||||||
local buf_state = state.get_buf_state(bufnr)
|
|
||||||
if not buf_state then return "" end
|
|
||||||
|
|
||||||
local current_node = buf_state.current_node
|
local current_node = ts_utils.get_node_at_cursor()
|
||||||
if not current_node then return "" end
|
if not current_node then return "" end
|
||||||
|
|
||||||
local expr = current_node:parent()
|
local expr = current_node:parent()
|
||||||
|
|
@ -56,13 +48,4 @@ function M.statusline(indicator_size)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_buf_state()
|
|
||||||
local bufnr = api.nvim_get_current_buf()
|
|
||||||
return state.exposed_state(bufnr)
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.get_node_api()
|
|
||||||
return ts_utils
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -1,137 +1,137 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
|
|
||||||
local queries = require'nvim-treesitter.query'
|
local queries = require'nvim-treesitter.query'
|
||||||
local utils = require'nvim-treesitter.utils'
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
|
||||||
local parsers = {}
|
local parserlist = {}
|
||||||
|
|
||||||
parsers.javascript = {
|
parserlist.javascript = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
url = "https://github.com/tree-sitter/tree-sitter-javascript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.c = {
|
parserlist.c = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-c",
|
url = "https://github.com/tree-sitter/tree-sitter-c",
|
||||||
files = { "src/parser.c" }
|
files = { "src/parser.c" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.cpp = {
|
parserlist.cpp = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
url = "https://github.com/tree-sitter/tree-sitter-cpp",
|
||||||
files = { "src/parser.c", "src/scanner.cc" }
|
files = { "src/parser.c", "src/scanner.cc" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.rust = {
|
parserlist.rust = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
url = "https://github.com/tree-sitter/tree-sitter-rust",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.lua = {
|
parserlist.lua = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
url = "https://github.com/nvim-treesitter/tree-sitter-lua",
|
||||||
files = { "src/parser.c", "src/scanner.cc" }
|
files = { "src/parser.c", "src/scanner.cc" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.python = {
|
parserlist.python = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-python",
|
url = "https://github.com/tree-sitter/tree-sitter-python",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.go = {
|
parserlist.go = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-go",
|
url = "https://github.com/tree-sitter/tree-sitter-go",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.ruby = {
|
parserlist.ruby = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
url = "https://github.com/tree-sitter/tree-sitter-ruby",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.bash = {
|
parserlist.bash = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
url = "https://github.com/tree-sitter/tree-sitter-bash",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.php = {
|
parserlist.php = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-php",
|
url = "https://github.com/tree-sitter/tree-sitter-php",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.java = {
|
parserlist.java = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-java",
|
url = "https://github.com/tree-sitter/tree-sitter-java",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.html = {
|
parserlist.html = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-html",
|
url = "https://github.com/tree-sitter/tree-sitter-html",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.julia = {
|
parserlist.julia = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
url = "https://github.com/tree-sitter/tree-sitter-julia",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.json = {
|
parserlist.json = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-json",
|
url = "https://github.com/tree-sitter/tree-sitter-json",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.css = {
|
parserlist.css = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-css",
|
url = "https://github.com/tree-sitter/tree-sitter-css",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.ocaml = {
|
parserlist.ocaml = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
url = "https://github.com/tree-sitter/tree-sitter-ocaml",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.swift = {
|
parserlist.swift = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
url = "https://github.com/tree-sitter/tree-sitter-swift",
|
||||||
files = { "src/parser.c" },
|
files = { "src/parser.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.csharp = {
|
parserlist.csharp = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
url = "https://github.com/tree-sitter/tree-sitter-c-sharp",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.typescript = {
|
parserlist.typescript = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
|
|
@ -139,7 +139,7 @@ parsers.typescript = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.tsx = {
|
parserlist.tsx = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
url = "https://github.com/tree-sitter/tree-sitter-typescript",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
|
|
@ -147,63 +147,63 @@ parsers.tsx = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.scala = {
|
parserlist.scala = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
url = "https://github.com/tree-sitter/tree-sitter-scala",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.haskell = {
|
parserlist.haskell = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
url = "https://github.com/tree-sitter/tree-sitter-haskell",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.markdown = {
|
parserlist.markdown = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/ikatyang/tree-sitter-markdown",
|
url = "https://github.com/ikatyang/tree-sitter-markdown",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.toml = {
|
parserlist.toml = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/ikatyang/tree-sitter-toml",
|
url = "https://github.com/ikatyang/tree-sitter-toml",
|
||||||
files = { "src/parser.c", "src/scanner.c" },
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.vue = {
|
parserlist.vue = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/ikatyang/tree-sitter-vue",
|
url = "https://github.com/ikatyang/tree-sitter-vue",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.elm = {
|
parserlist.elm = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com//razzeee/tree-sitter-elm",
|
url = "https://github.com//razzeee/tree-sitter-elm",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.yaml = {
|
parserlist.yaml = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
url = "https://github.com/ikatyang/tree-sitter-yaml",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.nix = {
|
parserlist.nix = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/cstrahan/tree-sitter-nix",
|
url = "https://github.com/cstrahan/tree-sitter-nix",
|
||||||
files = { "src/parser.c", "src/scanner.cc" },
|
files = { "src/parser.c", "src/scanner.cc" },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsers.regex = {
|
parserlist.regex = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/tree-sitter/tree-sitter-regex",
|
url = "https://github.com/tree-sitter/tree-sitter-regex",
|
||||||
files = { "src/parser.c" }
|
files = { "src/parser.c" }
|
||||||
|
|
@ -245,7 +245,7 @@ local M = {}
|
||||||
local function enable_module(mod, bufnr, ft)
|
local function enable_module(mod, bufnr, ft)
|
||||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
||||||
if not parsers[ft] or not config.modules[mod] then
|
if not parserlist[ft] or not config.modules[mod] then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -275,12 +275,12 @@ local function enable_all(mod, ft)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if ft then
|
if ft then
|
||||||
if utils.has_parser(ft) then
|
if parsers.has_parser(ft) then
|
||||||
enable_mod_conf_autocmd(mod, ft)
|
enable_mod_conf_autocmd(mod, ft)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for _, ft in pairs(M.available_parsers()) do
|
for _, ft in pairs(M.available_parsers()) do
|
||||||
if utils.has_parser(ft) then
|
if parsers.has_parser(ft) then
|
||||||
enable_mod_conf_autocmd(mod, ft)
|
enable_mod_conf_autocmd(mod, ft)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -291,7 +291,7 @@ end
|
||||||
local function disable_module(mod, bufnr, ft)
|
local function disable_module(mod, bufnr, ft)
|
||||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
||||||
if not parsers[ft] or not config.modules[mod] then
|
if not parserlist[ft] or not config.modules[mod] then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -360,7 +360,7 @@ M.commands = {
|
||||||
-- @param mod: module (string)
|
-- @param mod: module (string)
|
||||||
-- @param ft: filetype (string)
|
-- @param ft: filetype (string)
|
||||||
function M.is_enabled(mod, ft)
|
function M.is_enabled(mod, ft)
|
||||||
if not M.get_parser_configs()[ft] or not utils.has_parser(ft) then
|
if not M.get_parser_configs()[ft] or not parsers.has_parser(ft) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -404,11 +404,11 @@ function M.setup(user_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_parser_configs()
|
function M.get_parser_configs()
|
||||||
return parsers
|
return parserlist
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.available_parsers()
|
function M.available_parsers()
|
||||||
return vim.tbl_keys(parsers)
|
return vim.tbl_keys(parserlist)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.available_modules()
|
function M.available_modules()
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
|
|
||||||
local state = require'nvim-treesitter.state'
|
|
||||||
local configs = require'nvim-treesitter.configs'
|
local configs = require'nvim-treesitter.configs'
|
||||||
local ts_utils = require'nvim-treesitter.ts_utils'
|
local ts_utils = require'nvim-treesitter.ts_utils'
|
||||||
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
local selections = {}
|
||||||
|
|
||||||
local function update_selection(buf, node)
|
local function update_selection(buf, node)
|
||||||
local start_row, start_col, end_row, end_col = node:range()
|
local start_row, start_col, end_row, end_col = node:range()
|
||||||
|
|
||||||
|
|
@ -18,32 +20,49 @@ local function update_selection(buf, node)
|
||||||
vim.fn.setpos(".", { buf, end_row+1, end_col+1, 0 })
|
vim.fn.setpos(".", { buf, end_row+1, end_col+1, 0 })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.init_selection()
|
||||||
|
local buf = api.nvim_get_current_buf()
|
||||||
|
local node = ts_utils.get_node_at_cursor()
|
||||||
|
selections[buf] = { [1] = node }
|
||||||
|
update_selection(buf, node)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function visual_selection_range()
|
||||||
|
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
|
||||||
|
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
|
||||||
|
if csrow < cerow then
|
||||||
|
return csrow-1, cscol-1, cerow-1, cecol-1
|
||||||
|
else
|
||||||
|
return cerow-1, cecol-1, csrow-1, cscol-1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function range_matches(node)
|
||||||
|
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||||
|
local srow, scol, erow, ecol = node:range()
|
||||||
|
return srow == csrow and scol == cscol and erow == cerow and ecol == cecol
|
||||||
|
end
|
||||||
|
|
||||||
local function select_incremental(get_parent)
|
local function select_incremental(get_parent)
|
||||||
return function()
|
return function()
|
||||||
local buf = api.nvim_get_current_buf()
|
local buf = api.nvim_get_current_buf()
|
||||||
local buf_state = state.get_buf_state(buf)
|
local nodes = selections[buf]
|
||||||
|
|
||||||
local node
|
-- initialize incremental selection with current selection
|
||||||
-- initialize incremental selection with current range
|
if not nodes or #nodes == 0 or not range_matches(nodes[#nodes]) then
|
||||||
if #buf_state.selection.nodes == 0 then
|
local csrow, cscol, cerow, cecol = visual_selection_range()
|
||||||
local cur_range = buf_state.selection.range
|
local root = parsers.get_parser().tree:root()
|
||||||
if not cur_range then
|
local node = root:named_descendant_for_range(csrow, cscol, cerow, cecol)
|
||||||
local _, cursor_row, cursor_col, _ = unpack(vim.fn.getpos("."))
|
update_selection(buf, node)
|
||||||
cur_range = { cursor_row, cursor_col, cursor_row, cursor_col + 1 }
|
selections[buf] = { [1] = node }
|
||||||
end
|
return
|
||||||
|
|
||||||
local root = buf_state.parser.tree:root()
|
|
||||||
if not root then return end
|
|
||||||
|
|
||||||
node = root:named_descendant_for_range(cur_range[1]-1, cur_range[2]-1, cur_range[3]-1, cur_range[4]-1)
|
|
||||||
else
|
|
||||||
node = get_parent(buf_state.selection.nodes[#buf_state.selection.nodes])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
node = get_parent(nodes[#nodes])
|
||||||
if not node then return end
|
if not node then return end
|
||||||
|
|
||||||
if node ~= buf_state.selection.nodes[#buf_state.selection.nodes] then
|
if node ~= nodes[#nodes] then
|
||||||
state.insert_selection_node(buf, node)
|
table.insert(nodes, node)
|
||||||
end
|
end
|
||||||
|
|
||||||
update_selection(buf, node)
|
update_selection(buf, node)
|
||||||
|
|
@ -60,13 +79,10 @@ end)
|
||||||
|
|
||||||
function M.node_decremental()
|
function M.node_decremental()
|
||||||
local buf = api.nvim_get_current_buf()
|
local buf = api.nvim_get_current_buf()
|
||||||
local buf_state = state.get_buf_state(buf)
|
local nodes = selections[buf]
|
||||||
|
if not nodes or #nodes < 2 then return end
|
||||||
local nodes = buf_state.selection.nodes
|
|
||||||
if #nodes < 2 then return end
|
|
||||||
|
|
||||||
state.pop_selection_node(buf)
|
|
||||||
|
|
||||||
|
table.remove(selections[buf])
|
||||||
local node = nodes[#nodes]
|
local node = nodes[#nodes]
|
||||||
update_selection(buf, node)
|
update_selection(buf, node)
|
||||||
end
|
end
|
||||||
|
|
@ -76,14 +92,14 @@ function M.attach(bufnr)
|
||||||
|
|
||||||
local config = configs.get_module('incremental_selection')
|
local config = configs.get_module('incremental_selection')
|
||||||
for funcname, mapping in pairs(config.keymaps) do
|
for funcname, mapping in pairs(config.keymaps) do
|
||||||
|
local mode
|
||||||
if funcname == "init_selection" then
|
if funcname == "init_selection" then
|
||||||
local cmd = ":lua require'nvim-treesitter.incremental_selection'.node_incremental()<CR>"
|
mode = 'n'
|
||||||
api.nvim_buf_set_keymap(buf, 'n', mapping, cmd, { silent = true })
|
|
||||||
else
|
else
|
||||||
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
mode = 'v'
|
||||||
api.nvim_buf_set_keymap(buf, 'v', mapping, cmd, { silent = true })
|
|
||||||
end
|
end
|
||||||
|
local cmd = string.format(":lua require'nvim-treesitter.incremental_selection'.%s()<CR>", funcname)
|
||||||
|
api.nvim_buf_set_keymap(buf, mode, mapping, cmd, { silent = true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ local luv = vim.loop
|
||||||
|
|
||||||
local configs = require'nvim-treesitter.configs'
|
local configs = require'nvim-treesitter.configs'
|
||||||
local utils = require'nvim-treesitter.utils'
|
local utils = require'nvim-treesitter.utils'
|
||||||
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
|
@ -128,7 +129,7 @@ M.ensure_installed = function(languages)
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, ft in ipairs(languages) do
|
for _, ft in ipairs(languages) do
|
||||||
if not utils.has_parser(ft) then
|
if not parsers.has_parser(ft) then
|
||||||
install(ft)
|
install(ft)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ local api = vim.api
|
||||||
local ts = vim.treesitter
|
local ts = vim.treesitter
|
||||||
|
|
||||||
local queries = require'nvim-treesitter.query'
|
local queries = require'nvim-treesitter.query'
|
||||||
local utils = require'nvim-treesitter.utils'
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
|
||||||
local M = {
|
local M = {
|
||||||
locals = {}
|
locals = {}
|
||||||
|
|
@ -18,7 +18,7 @@ function M.collect_locals(bufnr)
|
||||||
local query = queries.get_query(ft, 'locals')
|
local query = queries.get_query(ft, 'locals')
|
||||||
if not query then return end
|
if not query then return end
|
||||||
|
|
||||||
local parser = utils.get_parser(bufnr, ft)
|
local parser = parsers.get_parser(bufnr, ft)
|
||||||
if not parser then return end
|
if not parser then return end
|
||||||
|
|
||||||
local root = parser:parse():root()
|
local root = parser:parse():root()
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,10 @@ function M.has_parser(lang)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.get_parser(bufnr, lang)
|
function M.get_parser(bufnr, lang)
|
||||||
|
local buf = bufnr or api.nvim_get_current_buf()
|
||||||
|
local lang = lang or api.nvim_buf_get_option(buf, 'ft')
|
||||||
|
|
||||||
if M.has_parser(lang) then
|
if M.has_parser(lang) 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
|
if not M[buf] then
|
||||||
M[buf] = {}
|
M[buf] = {}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
local api = vim.api
|
|
||||||
|
|
||||||
local utils = require'nvim-treesitter.utils'
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
|
|
||||||
local buffers = {}
|
|
||||||
|
|
||||||
local g_mode = api.nvim_get_mode().mode
|
|
||||||
|
|
||||||
local function get_selection_range()
|
|
||||||
local _, vstart_row, vstart_col, _ = unpack(vim.fn.getpos("v"))
|
|
||||||
local _, cursor_row, cursor_col, _ = unpack(vim.fn.getpos("."))
|
|
||||||
if vstart_row < cursor_row then
|
|
||||||
return vstart_row, vstart_col, cursor_row, cursor_col
|
|
||||||
else
|
|
||||||
return cursor_row, cursor_col, vstart_row, vstart_col
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.update()
|
|
||||||
local bufnr = api.nvim_get_current_buf()
|
|
||||||
local buf_config = buffers[bufnr]
|
|
||||||
if not buf_config then return end
|
|
||||||
|
|
||||||
local mode = api.nvim_get_mode().mode
|
|
||||||
local cursor = api.nvim_win_get_cursor(0)
|
|
||||||
local row = cursor[1]
|
|
||||||
local col = cursor[2]
|
|
||||||
if row == buf_config.cursor_pos.row
|
|
||||||
and col == buf_config.cursor_pos.col
|
|
||||||
and mode == g_mode
|
|
||||||
then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local root = buf_config.parser.tree:root()
|
|
||||||
if not root then return end
|
|
||||||
|
|
||||||
local new_node = root:named_descendant_for_range(row - 1, col, row - 1, col)
|
|
||||||
|
|
||||||
if new_node ~= buf_config.current_node then
|
|
||||||
buf_config.current_node = new_node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- We only want to update the range when the incremental selection has not started yet
|
|
||||||
if mode == "v" and #buf_config.selection.nodes == 0 then
|
|
||||||
local row_start, col_start, row_end, col_end = get_selection_range()
|
|
||||||
buf_config.selection.range = { row_start, col_start, row_end, col_end }
|
|
||||||
elseif mode ~= "v" then
|
|
||||||
buf_config.selection.nodes = {}
|
|
||||||
buf_config.selection.range = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
g_mode = mode
|
|
||||||
buf_config.cursor_pos.row = row
|
|
||||||
buf_config.cursor_pos.col = col
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.insert_selection_node(bufnr, range)
|
|
||||||
local buf_config = buffers[bufnr]
|
|
||||||
if not buf_config then return end
|
|
||||||
|
|
||||||
table.insert(buffers[bufnr].selection.nodes, range)
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.pop_selection_node(bufnr)
|
|
||||||
local buf_config = buffers[bufnr]
|
|
||||||
if not buf_config then return end
|
|
||||||
|
|
||||||
table.remove(
|
|
||||||
buffers[bufnr].selection.nodes,
|
|
||||||
#buffers[bufnr].selection.nodes
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.run_update()
|
|
||||||
local cmd = "lua require'nvim-treesitter.state'.update()"
|
|
||||||
api.nvim_command('autocmd NvimTreesitter CursorMoved * '..cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.attach_to_buffer(ft)
|
|
||||||
local bufnr = api.nvim_get_current_buf()
|
|
||||||
local ft = ft or api.nvim_buf_get_option(bufnr, 'ft')
|
|
||||||
|
|
||||||
if buffers[bufnr] then return end
|
|
||||||
|
|
||||||
local parser = utils.get_parser(bufnr, ft)
|
|
||||||
if not parser then return end
|
|
||||||
|
|
||||||
buffers[bufnr] = {
|
|
||||||
cursor_pos = {},
|
|
||||||
current_node = nil,
|
|
||||||
selection = {
|
|
||||||
range = nil,
|
|
||||||
nodes = {}
|
|
||||||
},
|
|
||||||
parser = parser,
|
|
||||||
}
|
|
||||||
|
|
||||||
M.update()
|
|
||||||
api.nvim_buf_attach(bufnr, false, {
|
|
||||||
-- TODO(kyazdani): on lines should only parse the changed content
|
|
||||||
-- TODO(kyazdani): add a timer to avoid too frequent updates
|
|
||||||
on_lines = function(_, buf) buffers[buf].parser:parse() end,
|
|
||||||
on_detach = function(bufnr) buffers[bufnr] = nil end,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.get_buf_state(bufnr)
|
|
||||||
return buffers[bufnr]
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.exposed_state(bufnr)
|
|
||||||
local buf_state = buffers[bufnr]
|
|
||||||
return {
|
|
||||||
cursor_pos = buf_state.cursor_pos,
|
|
||||||
current_node = buf_state.current_node
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
|
|
||||||
local locals = require'nvim-treesitter.locals'
|
local locals = require'nvim-treesitter.locals'
|
||||||
|
local parsers = require'nvim-treesitter.parsers'
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
|
@ -205,4 +206,10 @@ function M.previous_scope(node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.get_node_at_cursor()
|
||||||
|
local cursor = api.nvim_win_get_cursor(0)
|
||||||
|
local root = parsers.get_parser().tree:root()
|
||||||
|
return root:named_descendant_for_range(cursor[1]-1,cursor[2],cursor[1]-1,cursor[2])
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -45,23 +45,4 @@ function M.get_cache_dir()
|
||||||
return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write'
|
return nil, 'Invalid cache rights, $XDG_CACHE_HOME or /tmp should be read/write'
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.has_parser(lang)
|
|
||||||
local lang = lang or api.nvim_buf_get_option(0, 'filetype')
|
|
||||||
return #api.nvim_get_runtime_file('parser/' .. lang .. '.so', false) > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
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] = {}
|
|
||||||
end
|
|
||||||
if not M[buf][lang] then
|
|
||||||
M[buf][lang] = ts.get_parser(buf, lang)
|
|
||||||
end
|
|
||||||
return M[buf][lang]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue