diff --git a/README.md b/README.md index 995488f..f46170e 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ https://github.com/Wansmer/treesj/assets/46977173/4277455b-81fd-4e99-9af7-43c77d ## Requirements -- [Neovim 0.8+](https://github.com/neovim/neovim/releases) +- [Neovim 0.9+](https://github.com/neovim/neovim/releases) - [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) ## Installation diff --git a/lua/treesj/format.lua b/lua/treesj/format.lua index c19f5fe..2967a5f 100644 --- a/lua/treesj/format.lua +++ b/lua/treesj/format.lua @@ -6,17 +6,45 @@ local tu = require('treesj.treesj.utils') local settings = require('treesj.settings').settings local msg = notify.msg -local ok_ts_utils, ts_utils = pcall(require, 'nvim-treesitter.ts_utils') -if not ok_ts_utils then - notify.warn(msg.ts_not_found) -end - local SPLIT = 'split' local JOIN = 'join' local MAX_LENGTH = settings.max_join_length local M = {} +---@param root_lang_tree LanguageTree +---@return TSNode? +function M.get_node_at_cursor(root_lang_tree) + local cursor = vim.api.nvim_win_get_cursor(0) + local cursor_range = { cursor[1] - 1, cursor[2] } + + ---@type TSNode? + local root + local line = cursor_range[1] + local col = cursor_range[2] + + local lang_tree = root_lang_tree:language_for_range({ line, col, line, col }) + + for _, tree in pairs(lang_tree:trees()) do + root = tree:root() + + if root and vim.treesitter.is_in_node_range(root, line, col) then + break + end + end + + if not root then + return + end + + return root:named_descendant_for_range( + cursor_range[1], + cursor_range[2], + cursor_range[1], + cursor_range[2] + ) +end + function M._format(mode, override) -- Tree reparsing is required, otherwise the tree may not be updated -- and each node will be processed only once (until @@ -28,7 +56,7 @@ function M._format(mode, override) end parser:parse() - local start_node = ts_utils.get_node_at_cursor(0) + local start_node = M.get_node_at_cursor(parser) if not start_node then notify.info(msg.no_detect_node) return diff --git a/lua/treesj/notify.lua b/lua/treesj/notify.lua index 29ff3c9..7940e29 100644 --- a/lua/treesj/notify.lua +++ b/lua/treesj/notify.lua @@ -11,7 +11,6 @@ M.msg = { contains_error = 'The node "%s" or its descendants contain a syntax error and cannot be %s', no_configured_node = 'Node "%s" for lang "%s" is not configured', no_contains_target_node = 'Node "%s" has no contains descendants for split/join', - ts_not_found = 'Nvim-treesitter not found. TreeSJ required treesitter for work.', no_format_with = 'Cannot %s "%s" containing node from one of this: %s', extra_longer = 'Cannot "join" node longer than %s symbols. Check your settings to change it.', version_not_support = 'Current version of neovim is "0.%s". TreeSJ requires version "0.8" or higher', diff --git a/lua/treesj/search.lua b/lua/treesj/search.lua index cc83c4e..af64910 100644 --- a/lua/treesj/search.lua +++ b/lua/treesj/search.lua @@ -3,21 +3,23 @@ local langs = require('treesj.settings').settings.langs local u = require('treesj.utils') local msg = notify.msg -local ts_ok, parsers = pcall(require, 'nvim-treesitter.parsers') -if not ts_ok then - notify.error(msg.ts_not_found) - return -end - local M = {} ----Get lunguage for node +---Get language for node ---@param node TSNode TSNode instance ---@return string local function get_node_lang(node) local range = { node:range() } - local lang_tree = parsers.get_parser() - local current_tree = lang_tree:language_for_range(range) + local buf = vim.api.nvim_get_current_buf() + local ok, parser = pcall( + vim.treesitter.get_parser, + buf, + vim.treesitter.language.get_lang(vim.bo[buf].ft) + ) + if not ok then + return '' + end + local current_tree = parser:language_for_range(range) return current_tree:lang() end