From 2532be80b319d1e591d5b479dee7373714b0a4b0 Mon Sep 17 00:00:00 2001 From: brianhuster Date: Wed, 22 Jan 2025 02:11:26 +0700 Subject: [PATCH] Less dependent on nvim-treesitter Remove nvim-treesitter module support (inspired by https://github.com/RRethy/nvim-treesitter-endwise/pull/39) Replace built-in nvim-treesitter functions with vim.treesitter as much as possible Add pkg.json and .gitattributes --- .gitattributes | 1 + README.md | 13 ++---- lua/nvim-treesitter-endwise.lua | 44 ------------------ lua/nvim-treesitter/endwise.lua | 75 ++++++++++++++++++++++++++---- lua/treesitter-endwise.lua | 1 + pkg.json | 10 ++++ plugin/nvim-treesitter-endwise.lua | 9 +++- 7 files changed, 89 insertions(+), 64 deletions(-) create mode 100644 .gitattributes delete mode 100644 lua/nvim-treesitter-endwise.lua create mode 100644 lua/treesitter-endwise.lua create mode 100644 pkg.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9d85ab5 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.rb linguist-documentation diff --git a/README.md b/README.md index 4491cb9..985b8bf 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,14 @@ https://user-images.githubusercontent.com/21000943/150613732-442589e2-6b08-4b14-b0a3-47effef0eb28.mov -# Quick Start - -```lua --- Requires nvim-treesitter installed -require('nvim-treesitter.configs').setup { - endwise = { - enable = true, - }, -} -``` +# Introduction This is a simple plugin that helps to end certain structures automatically. In Ruby, this means adding end after if, do, def, etc. This even works for languages nested inside other, such as Markdown with a Lua code block! **Supported Languages**: *Ruby*, *Lua*, *Vimscript*, *Bash*, *Elixir*, *Fish*, *Julia* +This plugin requires [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) to work. You don't need to worry about this if you're using a plugin manager that supports [pkg.json](https://github.com/neovim/packspec) such as [lazy.nvim](https://github.com/folke/lazy.nvim) + # Additional Language Support Please open an issue for new languages, right now I'm open PRs but I won't be implementing other languages myself (except for maybe shell script). See https://github.com/RRethy/nvim-treesitter-endwise/issues/2#issuecomment-1019574925 for more information on adding support for a new language. diff --git a/lua/nvim-treesitter-endwise.lua b/lua/nvim-treesitter-endwise.lua deleted file mode 100644 index 79c620f..0000000 --- a/lua/nvim-treesitter-endwise.lua +++ /dev/null @@ -1,44 +0,0 @@ -local queries = require("nvim-treesitter.query") -local parsers = require('nvim-treesitter.parsers') - -local M = {} - -function M.init() - require('nvim-treesitter').define_modules { - endwise = { - module_path = 'nvim-treesitter.endwise', - enable = false, - disable = {}, - is_supported = function(lang) - local seen = {} - local function has_nested_endwise_language(nested_lang) - if not parsers.has_parser(nested_lang) then - return false - end - if queries.has_query_files(nested_lang, 'endwise') then - return true - end - if seen[nested_lang] then - return false - end - seen[nested_lang] = true - - if queries.has_query_files(nested_lang, 'injections') then - local query = queries.get_query(nested_lang, 'injections') - for _, capture in ipairs(query.info.captures) do - if capture == 'language' or has_nested_endwise_language(capture) then - return true - end - end - end - - return false - end - - return has_nested_endwise_language(lang) - end, - } - } -end - -return M diff --git a/lua/nvim-treesitter/endwise.lua b/lua/nvim-treesitter/endwise.lua index 938d5e9..b856312 100644 --- a/lua/nvim-treesitter/endwise.lua +++ b/lua/nvim-treesitter/endwise.lua @@ -1,6 +1,5 @@ local parsers = require('nvim-treesitter.parsers') -local queries = require('nvim-treesitter.query') -local ts_utils = require('nvim-treesitter.ts_utils') +local ts = vim.treesitter local M = {} local indent_regex = vim.regex('\\v^\\s*\\zs\\S') @@ -8,6 +7,53 @@ local tracking = {} local query_opts = vim.fn.has "nvim-0.10" == 1 and { force = true, all = false } or true +---@param lang string +---@param query_name string +---@return boolean +local function has_query_files(lang, query_name) + return #ts.query.get_files(lang, query_name) > 0 +end + +local function get_buf_lang(bufnr) + local ft = vim.bo[bufnr].filetype + if not ft or ft == '' then + return nil + end + return ts.language.get_lang(ft) +end + +---@param lang string +---@return boolean +local function is_supported(lang) + local seen = {} + local function has_nested_endwise_language(nested_lang) + if not parsers.has_parser(nested_lang) then + return false + end + -- Has query file /endwise.scm + if has_query_files(nested_lang, "endwise") then + return true + end + if seen[nested_lang] then + return false + end + seen[nested_lang] = true + + if has_query_files(nested_lang, "injections") then + local query = ts.query.get(nested_lang, "injections") + for _, capture in ipairs(query.info.captures) do + if capture == "language" or has_nested_endwise_language(capture) then + return true + end + end + end + + return false + end + + return has_nested_endwise_language(lang) +end + local function tabstr() if vim.bo.expandtab then return string.rep(" ", vim.fn.shiftwidth()) @@ -103,7 +149,7 @@ local function add_end_node(indent_node_range, endable_node_range, end_text, shi end local function endwise(bufnr) - local lang = parsers.get_buf_lang(bufnr) + local lang = get_buf_lang(bufnr) if not lang then return end @@ -117,18 +163,26 @@ local function endwise(bufnr) row = row - 1 col = col - 1 - local lang_tree = parsers.get_parser(bufnr):language_for_range({ row, col, row, col }) + ---@type vim.treesitter.LanguageTree + local lang_tree = ts.get_parser(bufnr):language_for_range({ row, col, row, col }) lang = lang_tree:lang() if not lang then return end - local root = ts_utils.get_root_for_position(row, col, lang_tree) + -- local root = ts_utils.get_root_for_position(row, col, lang_tree) + -- if not root then + -- return + -- end + + ---@type TSNode + local node = ts.get_node { bufnr = bufnr, pos = { row, col }, lang = lang } + local root = node and node:root() if not root then return end - local query = queries.get_query(lang, 'endwise') + local query = ts.query.get(lang, 'endwise') if not query then return end @@ -197,14 +251,17 @@ vim.on_key(function(key) vim.schedule_wrap(function() local bufnr = vim.fn.bufnr() if not tracking[bufnr] then return end - vim.cmd('doautocmd User PreNvimTreesitterEndwiseCR') -- Not currently used + vim.cmd('doautocmd User PreNvimTreesitterEndwiseCR') -- Not currently used endwise(bufnr) vim.cmd('doautocmd User PostNvimTreesitterEndwiseCR') -- Used in tests to know when to exit Neovim end)() end, nil) -function M.attach(bufnr) - tracking[bufnr] = true +function M.attach(bufnr, lang) + lang = lang or get_buf_lang(bufnr) + if is_supported(lang) then + tracking[bufnr] = true + end end function M.detach(bufnr) diff --git a/lua/treesitter-endwise.lua b/lua/treesitter-endwise.lua new file mode 100644 index 0000000..831fab1 --- /dev/null +++ b/lua/treesitter-endwise.lua @@ -0,0 +1 @@ +return require 'nvim-treesitter'.endwise diff --git a/pkg.json b/pkg.json new file mode 100644 index 0000000..6892544 --- /dev/null +++ b/pkg.json @@ -0,0 +1,10 @@ +{ + "name": "nvim-treesitter-endwise", + "description": "A treesitter-based and `tpope/vim-endwise`-inspired plugin for Neovim", + "engines": { + "nvim": "^0.9.0" + }, + "dependencies": { + "https://github.com/nvim-treesitter/nvim-treesitter": "master" + } +} diff --git a/plugin/nvim-treesitter-endwise.lua b/plugin/nvim-treesitter-endwise.lua index 5f6ef2c..03afd55 100644 --- a/plugin/nvim-treesitter-endwise.lua +++ b/plugin/nvim-treesitter-endwise.lua @@ -1 +1,8 @@ -require('nvim-treesitter-endwise').init() +vim.api.nvim_create_autocmd("FileType", { + group = vim.api.nvim_create_augroup("TreesitterEndwise", {}), + callback = function(args) + require("treesitter-endwise").detach(args.buf) + require("treesitter-endwise").attach(args.buf) + end, + desc = "Reattach module", +})