From 6e9742a006ae69c015e6dc1ed9b477033193778b Mon Sep 17 00:00:00 2001 From: Price Hiller Date: Sun, 19 May 2024 07:02:34 -0500 Subject: [PATCH] feat!: remove hard dependency on `nvim-treesitter` This has deprecated `nvim-treesitter` setup. It has *not* been removed yet. I intend to tag the previous commit to this as `0.1.0` and then fully remove `nvim-treesitter` setup support in `1.0.0` -- a breaking change. TODO: We *must* have a way of detaching the plugin for a given buffer or even globally. Currently the plugin does not have it's own capabilities to do so. --- README.md | 41 +++++++++-------------------- lua/nvim-ts-autotag.lua | 34 +++++++++++++++++------- lua/nvim-ts-autotag/internal.lua | 27 +++++++++++-------- lua/nvim-ts-autotag/utils.lua | 45 ++++++++++++++++++++++++++++++-- 4 files changed, 96 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 6a61a27..c1858f2 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ It works with: ## Usage -``` text +```text Before Input After ------------------------------------
@@ -30,26 +30,18 @@ Before Input After ------------------------------------ ``` - ## Setup -Neovim 0.7 and nvim-treesitter to work -User treesitter setup -```lua -require'nvim-treesitter.configs'.setup { - autotag = { - enable = true, - } -} +Requires `Nvim 0.9.0` and up. -``` -or you can use a set up function - -``` lua +```lua require('nvim-ts-autotag').setup() - ``` +> [!CAUTION] +> If you are setting up via `nvim-treesitter.configs` it has been deprecated! Please migrate to the +> new way. It will be removed in `1.0.0`. + ### Enable update on insert If you have that issue @@ -68,9 +60,10 @@ vim.lsp.handlers['textDocument/publishDiagnostics'] = vim.lsp.with( } ) ``` + ## Default values -``` lua +```lua local filetypes = { 'html', 'javascript', 'typescript', 'javascriptreact', 'typescriptreact', 'svelte', 'vue', 'tsx', 'jsx', 'rescript', 'xml', @@ -87,25 +80,15 @@ local skip_tag = { ### Override default values -``` lua -require'nvim-treesitter.configs'.setup { - autotag = { - enable = true, - enable_rename = true, - enable_close = true, - enable_close_on_slash = true, - filetypes = { "html" , "xml" }, - } -} --- OR +```lua require('nvim-ts-autotag').setup({ filetypes = { "html" , "xml" }, }) - ``` ## Fork Status + This is forked from https://github.com/windwp/nvim-ts-autotag due to the primary maintainer's disappearance. Any -PRs/work given to this fork *may* end up back in the original repository if the primary maintainer comes back. +PRs/work given to this fork _may_ end up back in the original repository if the primary maintainer comes back. Full credit to [@windwp](https://github.com/windwp) for the creation of this plugin. Here's to hoping they're ok and will be back sometime down the line. diff --git a/lua/nvim-ts-autotag.lua b/lua/nvim-ts-autotag.lua index 51cf99f..c155b0f 100644 --- a/lua/nvim-ts-autotag.lua +++ b/lua/nvim-ts-autotag.lua @@ -2,16 +2,32 @@ local internal = require("nvim-ts-autotag.internal") local M = {} +---@deprecated +---Will be removed in 1.0.0 function M.init() - local ts = require('nvim-treesitter') - if ts and ts.define_modules then - require('nvim-treesitter').define_modules({ - autotag = { - module_path = 'nvim-ts-autotag.internal', - is_supported = function(lang) - return internal.is_supported(lang) - end, - }, + local _, nvim_ts = pcall(require, "nvim-treesitter") + if not nvim_ts then + return + end + nvim_ts.define_modules({ + autotag = { + attach = function(bufnr, lang) + vim.deprecate( + "Nvim Treesitter Setup", + "`require('nvim-ts-autotag').setup()`", + "1.0.0", + "nvim-ts-autotag", + true + ) + internal.attach(bufnr, lang) + end, + detach = function(bufnr) + internal.detach(bufnr) + end, + is_supported = function(lang) + return internal.is_supported(lang) + end, + }, }) end end diff --git a/lua/nvim-ts-autotag/internal.lua b/lua/nvim-ts-autotag/internal.lua index 23bb0b6..6cf229a 100644 --- a/lua/nvim-ts-autotag/internal.lua +++ b/lua/nvim-ts-autotag/internal.lua @@ -146,6 +146,8 @@ M.enable_rename = true M.enable_close = true M.enable_close_on_slash = false +local did_setup = false + M.setup = function(opts) opts = opts or {} M.tbl_filetypes = opts.filetypes or M.tbl_filetypes @@ -159,6 +161,7 @@ M.setup = function(opts) if opts.enable_close_on_slash ~= nil then M.enable_close_on_slash = opts.enable_close_on_slash end + did_setup = true end local function is_in_table(tbl, val) @@ -191,7 +194,7 @@ local setup_ts_tag = function() end local function is_in_template_tag() - local cursor_node = vim.treesitter.get_node() + local cursor_node = utils.get_node_at_cursor() if not cursor_node then return false end @@ -279,7 +282,7 @@ local function get_tag_name(node) end local function find_tag_node(opt) - local target = opt.target or vim.treesitter.get_node() + local target = opt.target or utils.get_node_at_cursor() local tag_pattern = opt.tag_pattern local name_tag_pattern = opt.name_tag_pattern local skip_tag_pattern = opt.skip_tag_pattern @@ -355,7 +358,7 @@ local function check_close_tag(close_slash_tag) if close_slash_tag then -- Find start node from non closed tag - local current = vim.treesitter.get_node() + local current = utils.get_node_at_cursor() -- log.debug(current) target = find_start_tag(current) -- log.debug(target) @@ -584,8 +587,12 @@ local is_before_word = is_before("%w", 1) local is_before_arrow = is_before("<", 0) M.rename_tag = function() - if is_before_word() and parsers.has_parser() then - parsers.get_parser():parse(true) + if is_before_word() then + local parser = vim.treesitter.get_parser() + if not parser then + return + end + parser:parse(true) rename_start_tag() rename_end_tag() end @@ -593,12 +600,10 @@ end M.attach = function(bufnr, lang) M.lang = lang - local ok, configs = pcall(require, "nvim-treesitter.configs") - if ok then - local config = configs.get_module("autotag") + + if not did_setup then + local config = require("nvim-treesitter.configs").get_module("autotag") M.setup(config) - else - M.setup() end if is_in_table(M.tbl_filetypes, vim.bo.filetype) then @@ -644,7 +649,7 @@ M.attach = function(bufnr, lang) end M.detach = function(bufnr) - local bufnr = tonumber(bufnr) or vim.api.nvim_get_current_buf() + bufnr = tonumber(bufnr) or vim.api.nvim_get_current_buf() buffer_tag[bufnr] = nil end diff --git a/lua/nvim-ts-autotag/utils.lua b/lua/nvim-ts-autotag/utils.lua index bf9899e..9b93ac6 100644 --- a/lua/nvim-ts-autotag/utils.lua +++ b/lua/nvim-ts-autotag/utils.lua @@ -1,5 +1,5 @@ -local log = require('nvim-ts-autotag._log') -local get_node_text = vim.treesitter.get_node_text or vim.treesitter.query.get_node_text +local log = require("nvim-ts-autotag._log") +local get_node_text = vim.treesitter.get_node_text local M = {} M.get_node_text = function(node) @@ -18,6 +18,47 @@ M.get_cursor = function(bufnr) local row, col = unpack(vim.api.nvim_win_get_cursor(bufnr or 0)) return row - 1, col end + +-- Credit to `nvim-treesitter`, where this was adapted from +--- Get the root of the given tree for a given row & column position +---@param row integer 0-indexed row position +---@param col integer 0-indexec column position +---@param root_lang_tree vim.treesitter.LanguageTree +M.get_root_for_position = function(row, col, root_lang_tree) + local lang_tree = root_lang_tree:language_for_range({ row, col, row, col }) + + for _, tree in pairs(lang_tree:trees()) do + local root = tree:root() + if root and vim.treesitter.is_in_node_range(root, row, col) then + return root, tree, lang_tree + end + end + + return nil, nil, lang_tree +end + +-- Credit to `nvim-treesitter`, where this was adapted from +--- Get the current TSNode at the cursor +---@param winnr integer? +---@return TSNode? +M.get_node_at_cursor = function(winnr) + winnr = winnr or 0 + local row, col = unpack(vim.api.nvim_win_get_cursor(winnr)) + row = row - 1 + local buf = vim.api.nvim_win_get_buf(winnr) + local root_lang_tree = vim.treesitter.get_parser(buf) + if not root_lang_tree then + return + end + + local root = M.get_root_for_position(row, col, root_lang_tree) + if not root then + return + end + + return root:named_descendant_for_range(row, col, row, col) +end + M.dump_node = function(node) local text = M.get_node_text(node) for _, txt in pairs(text) do