From 2bb1fdcbe21c0395a48bdeda67fb3000333ca43e Mon Sep 17 00:00:00 2001 From: TravonteD Date: Thu, 23 Apr 2020 12:51:00 -0400 Subject: Fix spelling inconsistencies --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7a677f2bc..5b64cdd33 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Treesitter configurations and abstraction layer for Neovim. ## Installation -You can install `nvim-treesitter` with your favorite package manager, or using the default `pack` feature of neovim ! +You can install `nvim-treesitter` with your favorite package manager, or using the default `pack` feature of Neovim! ### Using a package manager @@ -79,19 +79,19 @@ bash [✗] not installed tsx [✗] not installed ``` -And now you should be able to use every functionnality `nvim-treesitter` provides ! +And now you should be able to use every functionality `nvim-treesitter` provides! ## Features and Roadmap -The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for treesitter in neovim, -but also to add some functionnalities to it: +The goal of `nvim-treesitter` is both to provide a simple and easy way to use the interface for Treesitter in Neovim, +but also to add some functionalities to it: Some of these features are : - [ ] Incremental selection - [ ] Syntax based code folding - [ ] Consistent syntax highlighting You can find the roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1). -The roadmap and all features of this plugin are open to change, and any suggestion will be highly apreciated ! +The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated! ## Troubleshooting Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from. -- cgit v1.2.3-70-g09d2 From 79ab9fc6fbbccd9cf3ea7877bd47c187360086a5 Mon Sep 17 00:00:00 2001 From: TravonteD Date: Fri, 24 Apr 2020 08:48:18 -0400 Subject: Squashed commit of the following: commit 1b3700b0cd68cb507c64b7243a5bea050379f09c Author: TravonteD Date: Fri Apr 24 08:44:34 2020 -0400 remove local from the capture groups commit 62f1a613c7c6f26e3a85f06f322ead28280dc7ca Author: TravonteD Date: Thu Apr 23 18:43:09 2020 -0400 update captures for identifiers commit 9966d5a9cd780b2de80e620cee6833fd341028d0 Author: TravonteD Date: Thu Apr 23 18:42:42 2020 -0400 add capture for constants that are recievers of a method call commit 10f03606710a3a54c8c722e4883b9475c6f9f776 Author: TravonteD Date: Thu Apr 23 17:54:25 2020 -0400 update captures for function definitions and calls commit 4b350274cb02e1b69ae013fa157bae5c6be9e577 Author: TravonteD Date: Thu Apr 23 17:21:10 2020 -0400 update captures for operators commit c66d42cd0d56d0a1bbfb1f88ffa7ff6ae8b6c2df Author: TravonteD Date: Thu Apr 23 17:10:13 2020 -0400 update captures for literals commit a9c097fe03f7294fdaede760f2c016cf6c960a45 Author: TravonteD Date: Thu Apr 23 15:54:47 2020 -0400 add highlights and locals from treesitter-ruby --- queries/ruby/highlights.scm | 140 ++++++++++++++++++++++++++++++++++++++++++++ queries/ruby/locals.scm | 45 ++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 queries/ruby/highlights.scm create mode 100644 queries/ruby/locals.scm diff --git a/queries/ruby/highlights.scm b/queries/ruby/highlights.scm new file mode 100644 index 000000000..22e2267ed --- /dev/null +++ b/queries/ruby/highlights.scm @@ -0,0 +1,140 @@ +; Keywords + +"alias" @keyword +"and" @keyword +"begin" @keyword +"break" @keyword +"case" @keyword +"class" @keyword +"def" @keyword +"do" @keyword +"else" @keyword +"elsif" @keyword +"end" @keyword +"ensure" @keyword +"for" @keyword +"if" @keyword +"in" @keyword +"module" @keyword +"next" @keyword +"or" @keyword +"rescue" @keyword +"retry" @keyword +"return" @keyword +"then" @keyword +"unless" @keyword +"until" @keyword +"when" @keyword +"while" @keyword +"yield" @keyword + +((identifier) @keyword + (match? @keyword "^(private|protected|public)$")) + +; Function calls + +((identifier) @function + (eq? @function "require")) + +"defined?" @function + +(call + receiver: (constant) @constant) +(method_call + receiver: (constant) @constant) +(call + method: (identifier) @function) +(method_call + method: (identifier) @function) +(call + method: (constant) @function) +(method_call + method: (constant) @function) + +; Function definitions + +(alias (identifier) @function) +(setter (identifier) @function) +(method name: (identifier) @function) +(method name: (constant) @constant) +(class name: (constant) @constant) +(singleton_method name: (identifier) @function) +(singleton_method name: (constant) @constant) + +; Identifiers + +(class_variable) @Identifier +(instance_variable) @Identifier + +((identifier) @constant + (match? @constant "^__(FILE|LINE|ENCODING)__$")) + +((constant) @constant + (match? @constant "^[A-Z\\d_]+$")) + +(constant) @constant + +(self) @constant +(super) @Identifier + +(method_parameters (identifier) @Type) +(lambda_parameters (identifier) @Type) +(block_parameters (identifier) @Type) +(splat_parameter (identifier) @Type) +(hash_splat_parameter (identifier) @Type) +(optional_parameter (identifier) @Type) +(destructured_parameter (identifier) @Type) +(block_parameter (identifier) @Type) +(keyword_parameter (identifier) @Type) + +((identifier) @function + (is-not? local)) + +; Literals + +(string) @string +(bare_string) @string +(bare_symbol) @constant +(subshell) @string +(heredoc_beginning) @Delimiter +(heredoc_body) @string +(heredoc_end) @Delimiter +(symbol) @constant +(regex) @string +(escape_sequence) @Special +(integer) @number +(float) @number + +(nil) @Identifier +(true) @Identifier +(false) @Identifier + +(interpolation + "#{" @Delimiter + (identifier) @Identifier + "}" @Delimiter) @embedded + +(comment) @comment + +; Operators + +"=" @operator +"=>" @operator +"->" @operator +"+" @operator +"-" @operator +"*" @operator +"/" @operator + +"," @Normal +";" @Normal +"." @Normal + +"(" @Normal +")" @Normal +"[" @Normal +"]" @Normal +"{" @Normal +"}" @Normal +"%w(" @Normal +"%i(" @Normal diff --git a/queries/ruby/locals.scm b/queries/ruby/locals.scm new file mode 100644 index 000000000..6c1b25238 --- /dev/null +++ b/queries/ruby/locals.scm @@ -0,0 +1,45 @@ +; The MIT License (MIT) +; +; Copyright (c) 2016 Rob Rix +; +; Permission is hereby granted, free of charge, to any person obtaining a copy +; of this software and associated documentation files (the "Software"), to deal +; in the Software without restriction, including without limitation the rights +; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +; copies of the Software, and to permit persons to whom the Software is +; furnished to do so, subject to the following conditions: +; +; The above copyright notice and this permission notice shall be included in all +; copies or substantial portions of the Software. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +; SOFTWARE. + +;;; DESCLARATIONS AND SCOPES +((method) @scope + (set! scope-inherits false)) + +(block) @scope +(do_block) @scope + +(method_parameters (identifier) @definition) +(lambda_parameters (identifier) @definition) +(block_parameters (identifier) @definition) +(splat_parameter name: (identifier) @definition) +(hash_splat_parameter name: (identifier) @definition) +(optional_parameter name: (identifier) @definition) +(destructured_parameter name: (identifier) @definition) +(block_parameter name: (identifier) @definition) +(keyword_parameter name: (identifier) @definition) + +(identifier) @reference + +(assignment left:(identifier) @definition) +(left_assignment_list (identifier) @definition) +(rest_assignment (identifier) @definition) +(destructured_left_assignment (identifier) @definition) -- cgit v1.2.3-70-g09d2 From 62786ec7c60ea29cbbd48ae658cde7042dba4bb3 Mon Sep 17 00:00:00 2001 From: kiyan42 Date: Wed, 22 Apr 2020 11:13:05 +0200 Subject: feat/refacto: improve configurations - You should now get the configs through functions - Configs for languages are now inside a local object called parsers - You can get the parser installation configurations with `get_parser_configs` - A new object has been initialized inside configs to specify module config (called config). - Provide functions to enable/disable a module on one buffer - Provide functions to enable/disable a module on all buffers, and if filetype is specified, for specific filetype - Provide function to determine if module is activated for a specified filetype --- lua/nvim-treesitter.lua | 30 ++-- lua/nvim-treesitter/configs.lua | 337 +++++++++++++++++++++++++++++++++----- lua/nvim-treesitter/health.lua | 6 +- lua/nvim-treesitter/highlight.lua | 15 +- lua/nvim-treesitter/info.lua | 96 +++++++++++ lua/nvim-treesitter/install.lua | 49 +----- lua/nvim-treesitter/utils.lua | 13 ++ plugin/nvim-treesitter.vim | 17 +- 8 files changed, 452 insertions(+), 111 deletions(-) create mode 100644 lua/nvim-treesitter/info.lua diff --git a/lua/nvim-treesitter.lua b/lua/nvim-treesitter.lua index b053f39b0..731f55e5d 100644 --- a/lua/nvim-treesitter.lua +++ b/lua/nvim-treesitter.lua @@ -1,30 +1,28 @@ local api = vim.api local parsers = require'nvim-treesitter.parsers' -local configs = require 'nvim-treesitter.configs' local install = require'nvim-treesitter.install' local locals = require'nvim-treesitter.locals' -local highlight = require'nvim-treesitter.highlight' +local utils = require'nvim-treesitter.utils' +local info = require'nvim-treesitter.info' +local configs = require'nvim-treesitter.configs' local M = {} -function M.available_parsers() - return vim.tbl_keys(configs.repositories) -end - -- This function sets up everythin needed for a given language -- this is the main interface through the plugin function M.setup(lang) - if parsers.has_parser(lang) then - local autocmd = "autocmd NvimTreesitter FileType %s lua require'nvim-treesitter.highlight'.setup()" - api.nvim_command(string.format(autocmd, lang)) - end -end + utils.setup_commands('install', install.commands) + utils.setup_commands('info', info.commands) + utils.setup_commands('configs', configs.commands) --- This function initialize the plugin --- it is run at startup -M._root = {} -function M._root.setup() - install.setup() + for _, ft in pairs(configs.available_parsers()) do + for _, mod in pairs(configs.available_modules()) do + if parsers.has_parser(ft) and configs.is_enabled(mod, ft) then + local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) + api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd)) + end + end + end end return M diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index fd3b41d29..c9450ed61 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -1,88 +1,343 @@ -local M = {} +local api = vim.api +local queries = require'nvim-treesitter.query' +local parser_utils = require'nvim-treesitter.parsers' +local parsers = {} -M.repositories = { - javascript = { +parsers.javascript = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-javascript", files = { "src/parser.c", "src/scanner.c" }, - }, - c = { + } +} + +parsers.c = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-c", files = { "src/parser.c" } - }, - cpp = { + } +} + +parsers.cpp = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-cpp", files = { "src/parser.c", "src/scanner.cc" } - }, - rust = { + } +} + +parsers.rust = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-rust", files = { "src/parser.c", "src/scanner.c" }, - }, - lua = { + } +} + +parsers.lua = { + install_info = { url = "https://github.com/nvim-treesitter/tree-sitter-lua", files = { "src/parser.c", "src/scanner.cc" } - }, - python = { + } +} + +parsers.python = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-python", files = { "src/parser.c", "src/scanner.cc" }, - }, - go = { + } +} + +parsers.go = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-go", files = { "src/parser.c" }, - }, - ruby = { + } +} + +parsers.ruby = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-ruby", files = { "src/parser.c", "src/scanner.cc" }, - }, - bash = { + } +} + +parsers.bash = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-bash", files = { "src/parser.c", "src/scanner.cc" }, - }, - php = { + } +} + +parsers.php = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-php", files = { "src/parser.c", "src/scanner.cc" }, - }, - java = { + } +} + +parsers.java = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-java", files = { "src/parser.c" }, - }, - html = { + } +} + +parsers.html = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-html", files = { "src/parser.c", "src/scanner.cc" }, - }, - julia = { + } +} + +parsers.julia = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-julia", files = { "src/parser.c", "src/scanner.c" }, - }, - json = { + } +} + +parsers.json = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-json", files = { "src/parser.c" }, - }, - css = { + } +} + +parsers.css = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-css", files = { "src/parser.c", "src/scanner.c" }, - }, - ocaml = { + } +} + +parsers.ocaml = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-ocaml", files = { "src/parser.c", "src/scanner.cc" }, - }, - swift = { + } +} + +parsers.swift = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-swift", files = { "src/parser.c" }, - }, - csharp = { + } +} + +parsers.csharp = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-c-sharp", files = { "src/parser.c", "src/scanner.c" }, - }, - typescript = { + } +} + +parsers.typescript = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-typescript", files = { "src/parser.c", "src/scanner.c" }, location = "tree-sitter-typescript/typescript" - }, - tsx = { + } +} + +parsers.tsx = { + install_info = { url = "https://github.com/tree-sitter/tree-sitter-typescript", files = { "src/parser.c", "src/scanner.c" }, location = "tree-sitter-tsx/tsx" } } +-- @enable can be true or false +-- @disable is a list of languages, only relevant if enable is true +-- @keymaps list of user mappings for a given module if relevant +-- @is_supported function which, given a ft, will return true if the ft works on the module +local config = { + highlight = { + enable = false, + disable = {}, + is_supported = function(ft) + return queries.get_query(ft, 'highlights') ~= nil + end + }, + -- selection = { + -- enable = false, + -- disable = {}, + -- keymaps = {}, + -- is_supported = function() return false end + -- }, + -- folding = { + -- enable = false, + -- disable = {}, + -- keymaps = {}, + -- is_supported = function() return false end + -- } +} + +local M = {} + +local function enable_module(mod, bufnr, ft) + local bufnr = bufnr or api.nvim_get_current_buf() + local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') + if not parsers[ft] or not config[mod] then + return + end + + local loaded_mod = require(string.format("nvim-treesitter.%s", mod)) + loaded_mod.attach(bufnr, ft) +end + +local function enable_mod_conf_autocmd(mod, ft) + if not config[mod] or M.is_enabled(mod, ft) then return end + + local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) + api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd)) + for i, parser in pairs(config[mod].disable) do + if parser == ft then + table.remove(config[mod].disable, i) + break + end + end +end + +local function enable_all(mod, ft) + if not config[mod] then return end + + for _, bufnr in pairs(api.nvim_list_bufs()) do + if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then + enable_module(mod, bufnr, ft) + end + end + if ft then + enable_mod_conf_autocmd(mod, ft) + else + for _, ft in pairs(M.available_parsers()) do + if parser_utils.has_parser(ft) then + enable_mod_conf_autocmd(mod, ft) + end + end + end + config[mod].enable = true +end + +local function disable_module(mod, bufnr, ft) + local bufnr = bufnr or api.nvim_get_current_buf() + local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') + if not parsers[ft] or not config[mod] then + return + end + + local loaded_mod = require(string.format("nvim-treesitter.%s", mod)) + loaded_mod.detach(bufnr, ft) +end + +local function disable_mod_conf_autocmd(mod, ft) + if not config[mod] or not M.is_enabled(mod, ft) then return end + + api.nvim_command(string.format("autocmd! FileType %s", ft)) + table.insert(config[mod].disable, ft) +end + +local function disable_all(mod, ft) + for _, bufnr in pairs(api.nvim_list_bufs()) do + if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then + disable_module(mod, bufnr, ft) + end + end + if ft then + disable_mod_conf_autocmd(mod, ft) + else + for _, ft in pairs(M.available_parsers()) do + if parser_utils.has_parser(ft) then + disable_mod_conf_autocmd(mod, ft) + end + end + config[mod].enable = false + end +end + +M.commands = { + TSBufEnable = { + run = enable_module, + args = { + "-nargs=1", + "-complete=custom,v:lua.ts_available_modules" + }, + description = '`:TSBufEnable module_name` enable a specified module on the current buffer' + }, + TSBufDisable = { + run = disable_module, + args = { + "-nargs=1", + "-complete=custom,v:lua.ts_available_modules" + }, + description = '`:TSBufDisable module_name` disable a specified module on the current buffer' + }, + TSEnableAll = { + run = enable_all, + args = { + "-nargs=+", + "-complete=custom,v:lua.ts_available_modules" + }, + description = '`:TSEnableAll module_name (filetype)` enables a specified module on all buffers. If filetype is specified, enable only for specified filetype' + }, + TSDisableAll = { + run = disable_all, + args = { + "-nargs=+", + "-complete=custom,v:lua.ts_available_modules" + }, + description = '`:TSDisableAll module_name (filetype)` disables a specified module on all buffers. If filetype is specified, disable only for specified filetype' + }, +} + +-- @param mod: module (string) +-- @param ft: filetype (string) +function M.is_enabled(mod, ft) + if not M.get_parser_configs()[ft] then return false end + + local module_config = M.get_config()[mod] + if not module_config then return false end + + if not module_config.enable or not module_config.is_supported(ft) then + return false + end + + for _, parser in pairs(module_config.disable) do + if ft == parser then return false end + end + return true +end + +function M.setup(user_data) + if not user_data then return end + + for mod, data in pairs(user_data) do + if config[mod] then + if type(data.enable) == 'boolean' then + config[mod].enable = data.enable + end + if type(data.disable) == 'table' then + config[mod].disable = data.disable + end + if config[mod].keymaps and type(data.keymaps) == 'table' then + config[mod].keymaps = data.keymaps + end + end + end +end + +function M.get_config() + return config +end + +function M.get_parser_configs() + return parsers +end + +function M.available_parsers() + return vim.tbl_keys(parsers) +end + +function M.available_modules() + return vim.tbl_keys(config) +end + return M diff --git a/lua/nvim-treesitter/health.lua b/lua/nvim-treesitter/health.lua index 25da7fe35..563e46a90 100644 --- a/lua/nvim-treesitter/health.lua +++ b/lua/nvim-treesitter/health.lua @@ -13,7 +13,7 @@ local health_error = vim.fn['health#report_error'] local M = {} -local function configs_health() +local function install_health() if fn.executable('git') == 0 then health_error('`git` executable not found.', { 'Install it with your package manager.', @@ -38,11 +38,11 @@ end function M.checkhealth() -- Installation dependency checks health_start('Installation') - configs_health() + install_health() local missing_parsers = {} -- Parser installation checks - for parser_name in pairs(configs.repositories) do + for _, parser_name in pairs(configs.available_parsers()) do local installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false) -- Only print informations about installed parsers diff --git a/lua/nvim-treesitter/highlight.lua b/lua/nvim-treesitter/highlight.lua index 110954a6a..65ab48dcb 100644 --- a/lua/nvim-treesitter/highlight.lua +++ b/lua/nvim-treesitter/highlight.lua @@ -1,12 +1,12 @@ local api = vim.api -local queries = require'nvim-treesitter.query' local ts = vim.treesitter +local queries = require'nvim-treesitter.query' local M = { - highlighters={} + highlighters = {} } -function M.setup(bufnr, ft) +function M.attach(bufnr, ft) local buf = bufnr or api.nvim_get_current_buf() local ft = ft or api.nvim_buf_get_option(buf, 'ft') @@ -16,4 +16,13 @@ function M.setup(bufnr, ft) M.highlighters[buf] = ts.TSHighlighter.new(query, buf, ft) end +function M.detach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + if M.highlighters[buf] then + M.highlighters[buf]:set_query("") + M.highlighters[buf] = nil + end + api.nvim_buf_set_option(buf, 'syntax', 'on') +end + return M diff --git a/lua/nvim-treesitter/info.lua b/lua/nvim-treesitter/info.lua new file mode 100644 index 000000000..18b1b611f --- /dev/null +++ b/lua/nvim-treesitter/info.lua @@ -0,0 +1,96 @@ +local api = vim.api +local configs = require'nvim-treesitter.configs' + +local M = {} + +local function install_info() + local max_len = 0 + for _, ft in pairs(configs.available_parsers()) do + if #ft > max_len then max_len = #ft end + end + + for _, ft in pairs(configs.available_parsers()) do + local is_installed = #api.nvim_get_runtime_file('parser/'..ft..'.so', false) > 0 + api.nvim_out_write(ft..string.rep(' ', max_len - #ft + 1)) + if is_installed then + api.nvim_out_write("[✓] installed\n") + else + api.nvim_out_write("[✗] not installed\n") + end + end +end + +local function print_info_module(sorted_filetypes, mod) + local max_str_len = #sorted_filetypes[1] + local header = string.format('%s%s', string.rep(' ', max_str_len + 2), mod) + api.nvim_out_write(header..'\n') + for _, ft in pairs(sorted_filetypes) do + local padding = string.rep(' ', max_str_len - #ft + #mod / 2 + 1) + api.nvim_out_write(ft..":"..padding) + if configs.is_enabled(mod, ft) then + api.nvim_out_write('✓') + else + api.nvim_out_write('✗') + end + api.nvim_out_write('\n') + end +end + +local function print_info_modules(sorted_filetypes) + local max_str_len = #sorted_filetypes[1] + local header = string.rep(' ', max_str_len + 2) + for _, mod in pairs(configs.available_modules()) do + header = string.format('%s%s ', header, mod) + end + api.nvim_out_write(header..'\n') + + for _, ft in pairs(sorted_filetypes) do + local padding = string.rep(' ', max_str_len - #ft) + api.nvim_out_write(ft..":"..padding) + + for _, mod in pairs(configs.available_modules()) do + local pad_len = #mod / 2 + 1 + api.nvim_out_write(string.rep(' ', pad_len)) + + if configs.is_enabled(mod, ft) then + api.nvim_out_write('✓') + else + api.nvim_out_write('✗') + end + api.nvim_out_write(string.rep(' ', pad_len - 1)) + end + api.nvim_out_write('\n') + end +end + +local function module_info(mod) + if mod and not configs.get_config()[mod] then return end + + local ft_by_len = configs.available_parsers() + table.sort(ft_by_len, function(a, b) return #a > #b end) + if mod then + print_info_module(ft_by_len, mod) + else + print_info_modules(ft_by_len) + end +end + +M.commands = { + TSInstallInfo = { + run = install_info, + args = { + "-nargs=0", + }, + description = '`:TSInstallInfo` print installation state for every filetype' + }, + TSModuleInfo = { + run = module_info, + args = { + "-nargs=?", + "-complete=custom,v:lua.ts_available_modules" + }, + description = '`:TSModuleInfo` print module state for every filetype, if module is specified, only for current module' + } +} + +return M diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index b00d3d773..be09a3bc1 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -1,7 +1,8 @@ local api = vim.api local fn = vim.fn local luv = vim.loop -local repositories = require'nvim-treesitter/configs'.repositories +local configs = require'nvim-treesitter/configs' +local parsers = configs.get_parser_configs() local M = {} @@ -118,14 +119,15 @@ local function install(ft) if not string.match(yesno, '^y.*') then return end end - local repository = repositories[ft] - if not repository then + local parser_config = parsers[ft] + if not parser_config then return api.nvim_err_writeln('Parser not available for language '..ft) end + local install_info = parser_config.install_info vim.validate { - url={ repository.url, 'string' }, - files={ repository.files, 'table' } + url={ install_info.url, 'string' }, + files={ install_info.files, 'table' } } if fn.executable('git') == 0 then @@ -138,24 +140,7 @@ local function install(ft) local cache_folder, err = get_cache_dir() if err then return api.nvim_err_writeln(err) end - run_install(cache_folder, package_path, ft, repository) -end - -local function install_info() - local max_len = 0 - for parser_name, _ in pairs(repositories) do - if #parser_name > max_len then max_len = #parser_name end - end - - for parser_name, _ in pairs(repositories) do - local is_installed = #api.nvim_get_runtime_file('parser/'..parser_name..'.so', false) > 0 - api.nvim_out_write(parser_name..string.rep(' ', max_len - #parser_name + 1)) - if is_installed then - api.nvim_out_write("[✓] installed\n") - else - api.nvim_out_write("[✗] not installed\n") - end - end + run_install(cache_folder, package_path, ft, install_info) end M.commands = { @@ -166,25 +151,7 @@ M.commands = { "-complete=custom,v:lua.ts_installable_parsers" }, description = '`:TSInstall {ft}` installs a parser under nvim-treesitter/parser/{name}.so' - }, - TSInstallInfo = { - run = install_info, - args = { "-nargs=0" }, - description = '`:TSInstallInfo` print installation state for every filetype' } } -function M.setup() - for command_name, def in pairs(M.commands) do - local call_fn = string.format("lua require'nvim-treesitter.install'.commands.%s.run()", command_name) - local parts = vim.tbl_flatten({ - "command!", - def.args, - command_name, - call_fn, - }) - api.nvim_command(table.concat(parts, " ")) - end -end - return M diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 8313a46a7..59de5dd57 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -63,4 +63,17 @@ function M.is_parent(dest, source) return false end +function M.setup_commands(mod, commands) + for command_name, def in pairs(commands) do + local call_fn = string.format("lua require'nvim-treesitter.%s'.commands.%s.run()", mod, command_name) + local parts = vim.tbl_flatten({ + "command!", + def.args, + command_name, + call_fn, + }) + api.nvim_command(table.concat(parts, " ")) + end +end + return M diff --git a/plugin/nvim-treesitter.vim b/plugin/nvim-treesitter.vim index 06c760a18..a94f56a96 100644 --- a/plugin/nvim-treesitter.vim +++ b/plugin/nvim-treesitter.vim @@ -4,14 +4,17 @@ if exists('g:loaded_nvim_treesitter') finish endif +augroup NvimTreesitter +augroup END + +let g:loaded_nvim_treesitter = 1 + lua << EOF ts_installable_parsers = function() - return table.concat(require'nvim-treesitter'.available_parsers(), '\n') + return table.concat(require'nvim-treesitter.configs'.available_parsers(), '\n') +end +ts_available_modules = function() + return table.concat(require'nvim-treesitter.configs'.available_modules(), '\n') end -require'nvim-treesitter'._root.setup() +require'nvim-treesitter'.setup() EOF - -let g:loaded_nvim_treesitter = 1 - -augroup NvimTreesitter -augroup END -- cgit v1.2.3-70-g09d2 From f489b4b0a337379973d6801805aa9b7800d2e6e8 Mon Sep 17 00:00:00 2001 From: kiyan42 Date: Sat, 25 Apr 2020 16:11:53 +0200 Subject: fix: config is enabled also checks parser existence --- lua/nvim-treesitter.lua | 3 +-- lua/nvim-treesitter/configs.lua | 12 +++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lua/nvim-treesitter.lua b/lua/nvim-treesitter.lua index 731f55e5d..e1c95ed31 100644 --- a/lua/nvim-treesitter.lua +++ b/lua/nvim-treesitter.lua @@ -1,5 +1,4 @@ local api = vim.api -local parsers = require'nvim-treesitter.parsers' local install = require'nvim-treesitter.install' local locals = require'nvim-treesitter.locals' local utils = require'nvim-treesitter.utils' @@ -17,7 +16,7 @@ function M.setup(lang) for _, ft in pairs(configs.available_parsers()) do for _, mod in pairs(configs.available_modules()) do - if parsers.has_parser(ft) and configs.is_enabled(mod, ft) then + if configs.is_enabled(mod, ft) then local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd)) end diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index c9450ed61..64d4170e2 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -206,7 +206,9 @@ local function enable_all(mod, ft) end end if ft then - enable_mod_conf_autocmd(mod, ft) + if parser_utils.has_parser(ft) then + enable_mod_conf_autocmd(mod, ft) + end else for _, ft in pairs(M.available_parsers()) do if parser_utils.has_parser(ft) then @@ -245,9 +247,7 @@ local function disable_all(mod, ft) disable_mod_conf_autocmd(mod, ft) else for _, ft in pairs(M.available_parsers()) do - if parser_utils.has_parser(ft) then - disable_mod_conf_autocmd(mod, ft) - end + disable_mod_conf_autocmd(mod, ft) end config[mod].enable = false end @@ -291,7 +291,9 @@ M.commands = { -- @param mod: module (string) -- @param ft: filetype (string) function M.is_enabled(mod, ft) - if not M.get_parser_configs()[ft] then return false end + if not M.get_parser_configs()[ft] or not parser_utils.has_parser(ft) then + return false + end local module_config = M.get_config()[mod] if not module_config then return false end -- cgit v1.2.3-70-g09d2 From 78b40f895cb2bf789944f94abd47dd7f7ab3f8dc Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 23 Apr 2020 07:55:00 +0200 Subject: textobj: add incremental node selection --- autoload/nvim_treesitter.vim | 16 ++++++++++++++++ lua/nvim-treesitter/locals.lua | 12 ++++++------ lua/nvim-treesitter/textobj.lua | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 autoload/nvim_treesitter.vim create mode 100644 lua/nvim-treesitter/textobj.lua diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim new file mode 100644 index 000000000..3e5ce40e6 --- /dev/null +++ b/autoload/nvim_treesitter.vim @@ -0,0 +1,16 @@ +function! s:visual_node(node_range) + let [l:cursor_start, l:cursor_end] = a:node_range + if !empty(l:cursor_start) && !empty(l:cursor_end) + call cursor(l:cursor_start[0]+1, l:cursor_start[1]+1) + normal v + call cursor(l:cursor_end[0]+1, l:cursor_end[1]) + endif +endfunction + +function! nvim_treesitter#select_node_incr() + call s:visual_node(luaeval('require"nvim-treesitter.textobj".node_incremental()')) +endfunction + +function! nvim_treesitter#select_context_incr() + call s:visual_node(luaeval('require"nvim-treesitter.textobj".context_incremental()')) +endfunction diff --git a/lua/nvim-treesitter/locals.lua b/lua/nvim-treesitter/locals.lua index 388c7e489..1e19fcd43 100644 --- a/lua/nvim-treesitter/locals.lua +++ b/lua/nvim-treesitter/locals.lua @@ -68,8 +68,8 @@ function M.get_definitions(bufnr) local defs = {} for _, loc in ipairs(locals) do - if loc.definition then - table.insert(defs, {definition=loc.definition, kind=loc.kind}) + if loc.definition and loc.definition.node then + table.insert(defs, {node=loc.definition.node, kind=loc.kind}) end end @@ -82,8 +82,8 @@ function M.get_scopes(bufnr) local scopes = {} for _, loc in ipairs(locals) do - if loc.scope then - table.insert(scopes, loc.scope) + if loc.scope and loc.scope.node then + table.insert(scopes, loc.scope.node) end end @@ -96,8 +96,8 @@ function M.get_references(bufnr) local refs = {} for _, loc in ipairs(locals) do - if loc.reference then - table.insert(refs, loc.reference) + if loc.reference and loc.reference.node then + table.insert(refs, loc.reference.node) end end diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua new file mode 100644 index 000000000..9460e193a --- /dev/null +++ b/lua/nvim-treesitter/textobj.lua @@ -0,0 +1,36 @@ +local api = vim.api +local utils = require'nvim-treesitter.utils' +local parsers = require'nvim-treesitter.parsers' +local M = {} + +local function node_range_to_vim(node) + if node then + local start_row, start_col, end_row, end_col = node:range() + + return {{start_row, start_col}, {end_row, end_col}} + else + return {{}, {}} + end +end + +function M.node_incremental() + local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) + local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + + if parsers.has_parser() then + local root = parsers.get_parser():parse():root() + local node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) + local node_start_row, node_start_col, node_end_row, node_end_col = node:range() + + if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col + and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then + return node_range_to_vim(node:parent() or node) + else + return node_range_to_vim(node) + end + else + return node_range_to_vim() + end +end + +return M -- cgit v1.2.3-70-g09d2 From c62685841e52dacb4659f49d16336765e7e10f10 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 23 Apr 2020 08:43:35 +0200 Subject: textobj: add incremental scope selection --- autoload/nvim_treesitter.vim | 4 ++-- lua/nvim-treesitter/textobj.lua | 22 ++++++++++++++++++++++ lua/nvim-treesitter/utils.lua | 15 +++++++++++++++ plugin/nvim-treesitter.vim | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim index 3e5ce40e6..e050ae5b2 100644 --- a/autoload/nvim_treesitter.vim +++ b/autoload/nvim_treesitter.vim @@ -11,6 +11,6 @@ function! nvim_treesitter#select_node_incr() call s:visual_node(luaeval('require"nvim-treesitter.textobj".node_incremental()')) endfunction -function! nvim_treesitter#select_context_incr() - call s:visual_node(luaeval('require"nvim-treesitter.textobj".context_incremental()')) +function! nvim_treesitter#select_scope_incr() + call s:visual_node(luaeval('require"nvim-treesitter.textobj".scope_incremental()')) endfunction diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua index 9460e193a..a28440e32 100644 --- a/lua/nvim-treesitter/textobj.lua +++ b/lua/nvim-treesitter/textobj.lua @@ -33,4 +33,26 @@ function M.node_incremental() end end +function M.scope_incremental() + local _, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) + local _, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + + if parsers.has_parser() then + local root = parsers.get_parser():parse():root() + local node = utils.smallest_containing_scope( + root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col)) + + local node_start_row, node_start_col, node_end_row, node_end_col = node:range() + + if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col + and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then + return node_range_to_vim(utils.smallest_containing_scope(node:parent() or node)) + else + return node_range_to_vim(node) + end + else + return node_range_to_vim() + end +end + return M diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 59de5dd57..2ef2746aa 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -1,6 +1,7 @@ -- Utils collection for nvim-treesitter local api = vim.api local parsers = require'nvim-treesitter.parsers' +local locals = require'nvim-treesitter.locals' local M = {} @@ -74,6 +75,20 @@ function M.setup_commands(mod, commands) }) api.nvim_command(table.concat(parts, " ")) end +--- Gets the smallest scope which contains @param node +function M.smallest_containing_scope(node, bufnr) + local bufnr = bufnr or api.nvim_get_current_buf() + + local root = parsers.get_parser(bufnr):parse():root() + if not node then return root end + + local scopes = locals.get_scopes(bufnr) + local current = node + while current ~= nil and not vim.tbl_contains(scopes, current) do + current = current:parent() + end + + return current or root end return M diff --git a/plugin/nvim-treesitter.vim b/plugin/nvim-treesitter.vim index a94f56a96..31329c61e 100644 --- a/plugin/nvim-treesitter.vim +++ b/plugin/nvim-treesitter.vim @@ -1,4 +1,4 @@ -" Last Change: 2020 avril 19 +" Last Change: 2020 avril 23 if exists('g:loaded_nvim_treesitter') finish -- cgit v1.2.3-70-g09d2 From 7c7d4e52703ba76a2aa96ddcc30c4e210addc8af Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 23 Apr 2020 12:15:03 +0200 Subject: textobj: little refactor --- lua/nvim-treesitter/textobj.lua | 25 ++++++++++++------------- lua/nvim-treesitter/utils.lua | 2 ++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua index a28440e32..8ba20d793 100644 --- a/lua/nvim-treesitter/textobj.lua +++ b/lua/nvim-treesitter/textobj.lua @@ -17,42 +17,41 @@ function M.node_incremental() local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + local node = nil if parsers.has_parser() then local root = parsers.get_parser():parse():root() - local node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) + node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) local node_start_row, node_start_col, node_end_row, node_end_col = node:range() if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then - return node_range_to_vim(node:parent() or node) - else - return node_range_to_vim(node) + -- TODO(vigoux): actually it is not really the parent here + -- it might be needed to climb more than only one parent, but a strictly growing node + node = node:parent() or node end - else - return node_range_to_vim() end + + return node_range_to_vim(node) end function M.scope_incremental() local _, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) local _, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + local node = nil if parsers.has_parser() then local root = parsers.get_parser():parse():root() - local node = utils.smallest_containing_scope( - root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col)) + node = utils.smallest_containing_scope( + root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col)) local node_start_row, node_start_col, node_end_row, node_end_col = node:range() if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then - return node_range_to_vim(utils.smallest_containing_scope(node:parent() or node)) - else - return node_range_to_vim(node) + node = utils.smallest_containing_scope(node:parent() or node) end - else - return node_range_to_vim() end + return node_range_to_vim(node) end return M diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 2ef2746aa..391863f0d 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -75,6 +75,8 @@ function M.setup_commands(mod, commands) }) api.nvim_command(table.concat(parts, " ")) end +end + --- Gets the smallest scope which contains @param node function M.smallest_containing_scope(node, bufnr) local bufnr = bufnr or api.nvim_get_current_buf() -- cgit v1.2.3-70-g09d2 From cadb3ee1ff0f20a8d26b91502c410e56be90fd46 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sat, 25 Apr 2020 16:35:10 +0200 Subject: refactor(textobj): use configs and don't use VimL --- autoload/nvim_treesitter.vim | 16 ------- lua/nvim-treesitter/configs.lua | 15 +++--- lua/nvim-treesitter/textobj.lua | 103 +++++++++++++++++++++++++--------------- plugin/nvim-treesitter.vim | 2 +- 4 files changed, 76 insertions(+), 60 deletions(-) delete mode 100644 autoload/nvim_treesitter.vim diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim deleted file mode 100644 index e050ae5b2..000000000 --- a/autoload/nvim_treesitter.vim +++ /dev/null @@ -1,16 +0,0 @@ -function! s:visual_node(node_range) - let [l:cursor_start, l:cursor_end] = a:node_range - if !empty(l:cursor_start) && !empty(l:cursor_end) - call cursor(l:cursor_start[0]+1, l:cursor_start[1]+1) - normal v - call cursor(l:cursor_end[0]+1, l:cursor_end[1]) - endif -endfunction - -function! nvim_treesitter#select_node_incr() - call s:visual_node(luaeval('require"nvim-treesitter.textobj".node_incremental()')) -endfunction - -function! nvim_treesitter#select_scope_incr() - call s:visual_node(luaeval('require"nvim-treesitter.textobj".scope_incremental()')) -endfunction diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index 64d4170e2..2761f0be8 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -157,12 +157,15 @@ local config = { return queries.get_query(ft, 'highlights') ~= nil end }, - -- selection = { - -- enable = false, - -- disable = {}, - -- keymaps = {}, - -- is_supported = function() return false end - -- }, + textobj = { + enable = false, + disable = {}, + keymaps = { + node_incremental="grn", + scope_incremental="grc" + }, + is_supported = function() return true end + }, -- folding = { -- enable = false, -- disable = {}, diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua index 8ba20d793..a373e4146 100644 --- a/lua/nvim-treesitter/textobj.lua +++ b/lua/nvim-treesitter/textobj.lua @@ -4,54 +4,83 @@ local parsers = require'nvim-treesitter.parsers' local M = {} local function node_range_to_vim(node) - if node then - local start_row, start_col, end_row, end_col = node:range() + if not node then return end - return {{start_row, start_col}, {end_row, end_col}} - else - return {{}, {}} - end + local start_row, start_col, end_row, end_col = node:range() + + local select_range = [[ + call cursor(%d, %d) + normal v + call cursor(%d, %d) + ]] + local exec_command = string.format(select_range, + start_row+1, start_col+1, + end_row+1, end_col+1) + + api.nvim_exec(exec_command, false) end -function M.node_incremental() - local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) - local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) - - local node = nil - if parsers.has_parser() then - local root = parsers.get_parser():parse():root() - node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) - local node_start_row, node_start_col, node_end_row, node_end_col = node:range() - - if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col - and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then - -- TODO(vigoux): actually it is not really the parent here - -- it might be needed to climb more than only one parent, but a strictly growing node - node = node:parent() or node +local function select_incremental(increment_func) + return function() + local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) + local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + + local node = nil + if parsers.has_parser() then + local root = parsers.get_parser():parse():root() + node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) + local node_start_row, node_start_col, node_end_row, node_end_col = node:range() + + if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col + and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then + node = increment_func(node) + end end - end - return node_range_to_vim(node) + return node_range_to_vim(node) + end end -function M.scope_incremental() - local _, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) - local _, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) +M.node_incremental = select_incremental(function(node) + if node then + return node:parent() or node + end +end) - local node = nil - if parsers.has_parser() then - local root = parsers.get_parser():parse():root() - node = utils.smallest_containing_scope( - root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col)) +M.scope_incremental = select_incremental(function(node) + if node then + return utils.smallest_containing_scope(node:parent() or node) + end +end) - local node_start_row, node_start_col, node_end_row, node_end_col = node:range() +function M.attach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() - if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col - and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then - node = utils.smallest_containing_scope(node:parent() or node) - end + local function textobj_create(mapping, funcname) + api.nvim_buf_set_keymap(buf, 'v', mapping, + string.format(":lua require'nvim-treesitter.textobj'.%s()", funcname), { silent = true }) + api.nvim_buf_set_keymap(buf, 'o', mapping, + string.format(":normal v%s", mapping), { silent = true }) + end + + local config = require'nvim-treesitter.configs'.get_config().textobj + for funcname, mapping in pairs(config.keymaps) do + textobj_create(mapping, funcname) + end +end + +function M.detach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + + local function textobj_delete(mapping) + api.nvim_buf_del_keymap(buf, 'v', default_mapping) + api.nvim_buf_del_keymap(buf, 'o', default_mapping) + end + + local config = require'nvim-treesitter.configs'.get_config().textobj + for _, mapping in pairs(config.keymaps) do + textobj_delete(mapping) end - return node_range_to_vim(node) end return M diff --git a/plugin/nvim-treesitter.vim b/plugin/nvim-treesitter.vim index 31329c61e..30ee3241d 100644 --- a/plugin/nvim-treesitter.vim +++ b/plugin/nvim-treesitter.vim @@ -1,4 +1,4 @@ -" Last Change: 2020 avril 23 +" Last Change: 2020 avril 25 if exists('g:loaded_nvim_treesitter') finish -- cgit v1.2.3-70-g09d2 From bb709aa8d0e241232b31ca1ae9fc042b16413ffd Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sat, 25 Apr 2020 21:49:19 +0200 Subject: refactor(textobj): remove unnecessary functions --- lua/nvim-treesitter/textobj.lua | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua index a373e4146..c2bcc30f0 100644 --- a/lua/nvim-treesitter/textobj.lua +++ b/lua/nvim-treesitter/textobj.lua @@ -56,30 +56,22 @@ end) function M.attach(bufnr) local buf = bufnr or api.nvim_get_current_buf() - local function textobj_create(mapping, funcname) + local config = require'nvim-treesitter.configs'.get_config().textobj + for funcname, mapping in pairs(config.keymaps) do api.nvim_buf_set_keymap(buf, 'v', mapping, string.format(":lua require'nvim-treesitter.textobj'.%s()", funcname), { silent = true }) api.nvim_buf_set_keymap(buf, 'o', mapping, string.format(":normal v%s", mapping), { silent = true }) end - - local config = require'nvim-treesitter.configs'.get_config().textobj - for funcname, mapping in pairs(config.keymaps) do - textobj_create(mapping, funcname) - end end function M.detach(bufnr) local buf = bufnr or api.nvim_get_current_buf() - local function textobj_delete(mapping) - api.nvim_buf_del_keymap(buf, 'v', default_mapping) - api.nvim_buf_del_keymap(buf, 'o', default_mapping) - end - local config = require'nvim-treesitter.configs'.get_config().textobj for _, mapping in pairs(config.keymaps) do - textobj_delete(mapping) + api.nvim_buf_del_keymap(buf, 'v', mapping) + api.nvim_buf_del_keymap(buf, 'o', mapping) end end -- cgit v1.2.3-70-g09d2 From 4d4e7d8a8c03c958e8badf7e3ee34e444ddcb4e0 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 26 Apr 2020 09:29:52 +0200 Subject: health: add highlight to healthchecks --- lua/nvim-treesitter/health.lua | 2 ++ lua/nvim-treesitter/highlight.lua | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lua/nvim-treesitter/health.lua b/lua/nvim-treesitter/health.lua index 563e46a90..862161871 100644 --- a/lua/nvim-treesitter/health.lua +++ b/lua/nvim-treesitter/health.lua @@ -3,6 +3,7 @@ local fn = vim.fn local queries = require'nvim-treesitter.query' local locals = require'nvim-treesitter.locals' +local highlight = require'nvim-treesitter.highlight' local configs = require'nvim-treesitter.configs' local health_start = vim.fn["health#report_start"] @@ -51,6 +52,7 @@ function M.checkhealth() health_ok(parser_name .. " parser found.") locals.checkhealth(parser_name) + highlight.checkhealth(parser_name) elseif installed > 1 then health_warn(string.format("Multiple parsers found for %s, only %s will be used.", parser_name, installed[1])) else diff --git a/lua/nvim-treesitter/highlight.lua b/lua/nvim-treesitter/highlight.lua index 65ab48dcb..04f21eb1e 100644 --- a/lua/nvim-treesitter/highlight.lua +++ b/lua/nvim-treesitter/highlight.lua @@ -25,4 +25,20 @@ function M.detach(bufnr) api.nvim_buf_set_option(buf, 'syntax', 'on') end +function M.checkhealth(lang) + local health_start = vim.fn["health#report_start"] + local health_ok = vim.fn['health#report_ok'] + local health_info = vim.fn['health#report_info'] + local health_warn = vim.fn['health#report_warn'] + local health_error = vim.fn['health#report_error'] + + if not queries.get_query(lang, "highlights") then + health_warn("No `highlights.scm` query found for " .. lang, { + "Open an issue at https://github.com/nvim-treesitter/nvim-treesitter" + }) + else + health_ok("`highlights.scm` found.") + end +end + return M -- cgit v1.2.3-70-g09d2 From ce690e550d0905a9c4f177064e709f5e22d95fe8 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sun, 26 Apr 2020 15:38:32 +0200 Subject: health(refactor): move checks inside health.lua --- lua/nvim-treesitter/health.lua | 25 +++++++++++++++++++++++-- lua/nvim-treesitter/highlight.lua | 16 ---------------- lua/nvim-treesitter/locals.lua | 16 ---------------- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/lua/nvim-treesitter/health.lua b/lua/nvim-treesitter/health.lua index 862161871..7ba1cae65 100644 --- a/lua/nvim-treesitter/health.lua +++ b/lua/nvim-treesitter/health.lua @@ -35,6 +35,27 @@ local function install_health() end end +local function highlight_health(lang) + if not queries.get_query(lang, "highlights") then + health_warn("No `highlights.scm` query found for " .. lang, { + "Open an issue at https://github.com/nvim-treesitter/nvim-treesitter" + }) + else + health_ok("`highlights.scm` found.") + end +end + +function locals_health(lang) + if not queries.get_query(lang, "locals") then + health_warn("No `locals.scm` query found for " .. lang, { + "Open an issue at https://github.com/nvim-treesitter/nvim-treesitter" + }) + else + health_ok("`locals.scm` found.") + end +end + + -- TODO(vigoux): Maybe we should move each check to be perform in its own module function M.checkhealth() -- Installation dependency checks @@ -51,8 +72,8 @@ function M.checkhealth() health_start(parser_name .. " parser healthcheck") health_ok(parser_name .. " parser found.") - locals.checkhealth(parser_name) - highlight.checkhealth(parser_name) + locals_health(parser_name) + highlight_health(parser_name) elseif installed > 1 then health_warn(string.format("Multiple parsers found for %s, only %s will be used.", parser_name, installed[1])) else diff --git a/lua/nvim-treesitter/highlight.lua b/lua/nvim-treesitter/highlight.lua index 04f21eb1e..65ab48dcb 100644 --- a/lua/nvim-treesitter/highlight.lua +++ b/lua/nvim-treesitter/highlight.lua @@ -25,20 +25,4 @@ function M.detach(bufnr) api.nvim_buf_set_option(buf, 'syntax', 'on') end -function M.checkhealth(lang) - local health_start = vim.fn["health#report_start"] - local health_ok = vim.fn['health#report_ok'] - local health_info = vim.fn['health#report_info'] - local health_warn = vim.fn['health#report_warn'] - local health_error = vim.fn['health#report_error'] - - if not queries.get_query(lang, "highlights") then - health_warn("No `highlights.scm` query found for " .. lang, { - "Open an issue at https://github.com/nvim-treesitter/nvim-treesitter" - }) - else - health_ok("`highlights.scm` found.") - end -end - return M diff --git a/lua/nvim-treesitter/locals.lua b/lua/nvim-treesitter/locals.lua index 1e19fcd43..3e5174548 100644 --- a/lua/nvim-treesitter/locals.lua +++ b/lua/nvim-treesitter/locals.lua @@ -10,22 +10,6 @@ local M = { locals={} } -function M.checkhealth(lang) - local health_start = vim.fn["health#report_start"] - local health_ok = vim.fn['health#report_ok'] - local health_info = vim.fn['health#report_info'] - local health_warn = vim.fn['health#report_warn'] - local health_error = vim.fn['health#report_error'] - - if not queries.get_query(lang, "locals") then - health_warn("No `locals.scm` query found for " .. lang, { - "Open an issue at https://github.com/nvim-treesitter/nvim-treesitter" - }) - else - health_ok("`locals.scm` found.") - end -end - function M.collect_locals(bufnr) local ft = api.nvim_buf_get_option(bufnr, "ft") if not ft then return end -- cgit v1.2.3-70-g09d2 From f8029cfc6463c35e76e38ba428688eb259f9e62c Mon Sep 17 00:00:00 2001 From: kiyan42 Date: Mon, 27 Apr 2020 15:27:59 +0200 Subject: fix install by changing cc arguments position --- lua/nvim-treesitter/install.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index be09a3bc1..ca84ac036 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -34,9 +34,9 @@ local function get_cache_dir() end local function iter_cmd(cmd_list, i, ft) - if i == #cmd_list then return print('Treesitter parser for '..ft..' has been installed') end + if i == #cmd_list + 1 then return print('Treesitter parser for '..ft..' has been installed') end - local attr = cmd_list[i + 1] + local attr = cmd_list[i] if attr.info then print(attr.info) end handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) @@ -76,12 +76,12 @@ local function run_install(cache_folder, package_path, ft, repo) args = vim.tbl_flatten({ '-o', 'parser.so', + '-I./src', + repo.files, '-shared', + '-Os', '-lstdc++', '-fPIC', - '-Os', - '-I./src', - repo.files }), cwd = compile_location } @@ -100,7 +100,7 @@ local function run_install(cache_folder, package_path, ft, repo) } } - iter_cmd(command_list, 0, ft) + iter_cmd(command_list, 1, ft) end -- TODO(kyazdani): this should work on windows too -- cgit v1.2.3-70-g09d2 From f83b76b488505720538a37b7b2bffc3c85771adb Mon Sep 17 00:00:00 2001 From: kiyan42 Date: Tue, 28 Apr 2020 12:22:11 +0200 Subject: add documentation --- doc/nvim-treesitter.txt | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 doc/nvim-treesitter.txt diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt new file mode 100644 index 000000000..1fc986c71 --- /dev/null +++ b/doc/nvim-treesitter.txt @@ -0,0 +1,90 @@ +*nvim-treesitter* + +Minimum version of neovim: nightly + +Authors: Yazdani Kiyan , Vigouroux Thomas <@EMAIL?> + +============================================================================== +INTRODUCTION *nvim-treesitter* + +nvim-treesitter wraps the neovim treesitter api to provide functionnalities such +as highlighting and incremental selection, and a command to easily install parsers. + +============================================================================== +QUICK START *nvim-treesitter-quickstart* + +Install the parser for your language +> +:TSInstall {language} +< + +To get a list of supported languages +> +:TSInstallInfo +< + +By default, everything is disabled. To enable support for features, in your `init.vim`: + +> + +lua < Date: Tue, 28 Apr 2020 11:56:00 +0200 Subject: edit: add information to the readme - commands descriptions - list of supported languages --- README.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b64cdd33..bc1f17ef8 100644 --- a/README.md +++ b/README.md @@ -81,18 +81,80 @@ tsx [✗] not installed And now you should be able to use every functionality `nvim-treesitter` provides! +## Setup + +in your `init.vim`: + +```lua +lua < Date: Tue, 28 Apr 2020 12:32:01 +0200 Subject: add vim documentation --- doc/nvim-treesitter.txt | 50 ++++++++++++++++++++++++------------------------- doc/tags | 11 +++++++++++ 2 files changed, 36 insertions(+), 25 deletions(-) create mode 100644 doc/tags diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt index 1fc986c71..798c5bfc1 100644 --- a/doc/nvim-treesitter.txt +++ b/doc/nvim-treesitter.txt @@ -2,10 +2,10 @@ Minimum version of neovim: nightly -Authors: Yazdani Kiyan , Vigouroux Thomas <@EMAIL?> +Authors: Yazdani Kiyan , Vigouroux Thomas ============================================================================== -INTRODUCTION *nvim-treesitter* +INTRODUCTION *nvim-treesitter-intro* nvim-treesitter wraps the neovim treesitter api to provide functionnalities such as highlighting and incremental selection, and a command to easily install parsers. @@ -14,41 +14,41 @@ as highlighting and incremental selection, and a command to easily install parse QUICK START *nvim-treesitter-quickstart* Install the parser for your language + > -:TSInstall {language} + :TSInstall {language} < To get a list of supported languages + > -:TSInstallInfo + :TSInstallInfo < By default, everything is disabled. To enable support for features, in your `init.vim`: > - -lua < Date: Thu, 30 Apr 2020 22:11:44 +0200 Subject: Add function 'nvim-treesitter/install'.ensure_installed --- lua/nvim-treesitter/install.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index ca84ac036..298a0e9f7 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -3,6 +3,7 @@ local fn = vim.fn local luv = vim.loop local configs = require'nvim-treesitter/configs' local parsers = configs.get_parser_configs() +local has_parser = require'nvim-treesitter/parsers'.has_parser local M = {} @@ -143,6 +144,24 @@ local function install(ft) run_install(cache_folder, package_path, ft, install_info) end + +M.ensure_installed = function(languages) + if type(languages) == 'string' then + if languages == 'all' then + languages = configs.available_parsers() + else + languages = {languages} + end + end + + for _, ft in ipairs(languages) do + if not has_parser(ft) then + install(ft) + end + end +end + + M.commands = { TSInstall = { run = install, -- cgit v1.2.3-70-g09d2 From fc88339832e61d7ed0c7604057cb02bb0ceec153 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 1 May 2020 10:20:19 +0200 Subject: Add `ensure_installed` option to config --- lua/nvim-treesitter/configs.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index 2761f0be8..eabe3e3bd 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -325,6 +325,9 @@ function M.setup(user_data) if config[mod].keymaps and type(data.keymaps) == 'table' then config[mod].keymaps = data.keymaps end + if mod == 'ensure_installed' then + require'nvim-treesitter/install'.ensure_installed(data) + end end end end -- cgit v1.2.3-70-g09d2 From 0b4cdba3e49d77d5914af38e29c46229d9cd059a Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 1 May 2020 10:30:25 +0200 Subject: Avoid global handle to enable installing multiple parsers in parallel --- lua/nvim-treesitter/install.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua index 298a0e9f7..77e0fccc4 100644 --- a/lua/nvim-treesitter/install.lua +++ b/lua/nvim-treesitter/install.lua @@ -40,9 +40,11 @@ local function iter_cmd(cmd_list, i, ft) local attr = cmd_list[i] if attr.info then print(attr.info) end + local handle + handle = luv.spawn(attr.cmd, attr.opts, vim.schedule_wrap(function(code) handle:close() - if code ~= 0 then return api.nvim_err_writeln(attr.err) end + if code ~= 0 then return api.nvim_err_writeln(attr.err) end iter_cmd(cmd_list, i + 1, ft) end)) end -- cgit v1.2.3-70-g09d2 From dc06f9ea8147da2b6aed60ce2eb657470e4e99a7 Mon Sep 17 00:00:00 2001 From: kiyan42 Date: Fri, 1 May 2020 12:26:57 +0200 Subject: update docs for ensure installed, move modules config in config.modules --- README.md | 5 ++- doc/nvim-treesitter.txt | 3 +- lua/nvim-treesitter/configs.lua | 87 ++++++++++++++++++++--------------------- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index bc1f17ef8..3903ecb0b 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,11 @@ require'nvim-treesitter.configs'.setup { enable = true, disable = { 'cpp', 'lua' }, keymaps = { -- mappings for incremental selection (visual mappings) - node_incremental = "e", -- "grn" by default, + node_incremental = "e", -- "grn" by default, scope_incremental = "f" -- "grc" by default } - } + }, + ensure_installed = 'all' -- one of 'all', 'language', or a list of languages } EOF ``` diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt index 798c5bfc1..55ada1596 100644 --- a/doc/nvim-treesitter.txt +++ b/doc/nvim-treesitter.txt @@ -41,7 +41,8 @@ By default, everything is disabled. To enable support for features, in your `ini node_incremental = "e", -- "grn" by default, scope_incremental = "f" -- "grc" by default } - } + }, + ensure_installed = 'all' -- can be one of 'all', 'language' or {'language1', 'language2' ... } } < diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index eabe3e3bd..90ab92c4c 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -150,28 +150,31 @@ parsers.tsx = { -- @keymaps list of user mappings for a given module if relevant -- @is_supported function which, given a ft, will return true if the ft works on the module local config = { - highlight = { - enable = false, - disable = {}, - is_supported = function(ft) - return queries.get_query(ft, 'highlights') ~= nil - end - }, - textobj = { - enable = false, - disable = {}, - keymaps = { - node_incremental="grn", - scope_incremental="grc" + modules = { + highlight = { + enable = false, + disable = {}, + is_supported = function(ft) + return queries.get_query(ft, 'highlights') ~= nil + end + }, + textobj = { + enable = false, + disable = {}, + keymaps = { + node_incremental="grn", + scope_incremental="grc" + }, + is_supported = function() return true end }, - is_supported = function() return true end + -- folding = { + -- enable = false, + -- disable = {}, + -- keymaps = {}, + -- is_supported = function() return false end + -- } }, - -- folding = { - -- enable = false, - -- disable = {}, - -- keymaps = {}, - -- is_supported = function() return false end - -- } + ensure_installed = nil } local M = {} @@ -179,7 +182,7 @@ local M = {} local function enable_module(mod, bufnr, ft) local bufnr = bufnr or api.nvim_get_current_buf() local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') - if not parsers[ft] or not config[mod] then + if not parsers[ft] or not config.modules[mod] then return end @@ -188,20 +191,20 @@ local function enable_module(mod, bufnr, ft) end local function enable_mod_conf_autocmd(mod, ft) - if not config[mod] or M.is_enabled(mod, ft) then return end + if not config.modules[mod] or M.is_enabled(mod, ft) then return end local cmd = string.format("lua require'nvim-treesitter.%s'.attach()", mod) api.nvim_command(string.format("autocmd FileType %s %s", ft, cmd)) - for i, parser in pairs(config[mod].disable) do + for i, parser in pairs(config.modules[mod].disable) do if parser == ft then - table.remove(config[mod].disable, i) + table.remove(config.modules[mod].disable, i) break end end end local function enable_all(mod, ft) - if not config[mod] then return end + if not config.modules[mod] then return end for _, bufnr in pairs(api.nvim_list_bufs()) do if not ft or api.nvim_buf_get_option(bufnr, 'ft') == ft then @@ -219,13 +222,13 @@ local function enable_all(mod, ft) end end end - config[mod].enable = true + config.modules[mod].enable = true end local function disable_module(mod, bufnr, ft) local bufnr = bufnr or api.nvim_get_current_buf() local ft = ft or api.nvim_buf_get_option(bufnr, 'ft') - if not parsers[ft] or not config[mod] then + if not parsers[ft] or not config.modules[mod] then return end @@ -234,10 +237,10 @@ local function disable_module(mod, bufnr, ft) end local function disable_mod_conf_autocmd(mod, ft) - if not config[mod] or not M.is_enabled(mod, ft) then return end + if not config.modules[mod] or not M.is_enabled(mod, ft) then return end api.nvim_command(string.format("autocmd! FileType %s", ft)) - table.insert(config[mod].disable, ft) + table.insert(config.modules[mod].disable, ft) end local function disable_all(mod, ft) @@ -252,7 +255,7 @@ local function disable_all(mod, ft) for _, ft in pairs(M.available_parsers()) do disable_mod_conf_autocmd(mod, ft) end - config[mod].enable = false + config.modules[mod].enable = false end end @@ -298,7 +301,7 @@ function M.is_enabled(mod, ft) return false end - local module_config = M.get_config()[mod] + local module_config = config.modules[mod] if not module_config then return false end if not module_config.enable or not module_config.is_supported(ft) then @@ -315,27 +318,23 @@ function M.setup(user_data) if not user_data then return end for mod, data in pairs(user_data) do - if config[mod] then + if config.modules[mod] then if type(data.enable) == 'boolean' then - config[mod].enable = data.enable + config.modules[mod].enable = data.enable end if type(data.disable) == 'table' then - config[mod].disable = data.disable + config.modules[mod].disable = data.disable end - if config[mod].keymaps and type(data.keymaps) == 'table' then - config[mod].keymaps = data.keymaps - end - if mod == 'ensure_installed' then - require'nvim-treesitter/install'.ensure_installed(data) + if config.modules[mod].keymaps and type(data.keymaps) == 'table' then + config.modules[mod].keymaps = data.keymaps end + elseif mod == 'ensure_installed' then + config.ensure_installed = data + require'nvim-treesitter/install'.ensure_installed(data) end end end -function M.get_config() - return config -end - function M.get_parser_configs() return parsers end @@ -345,7 +344,7 @@ function M.available_parsers() end function M.available_modules() - return vim.tbl_keys(config) + return vim.tbl_keys(config.modules) end return M -- cgit v1.2.3-70-g09d2 From 56f4aef198d07940c901b2bce9bab6484e7ab38a Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 1 May 2020 13:31:05 +0200 Subject: Add some more community parsers The haskell one really takes long to compile --- lua/nvim-treesitter/configs.lua | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index eabe3e3bd..fc5a55758 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -145,6 +145,62 @@ parsers.tsx = { } } +parsers.scala = { + install_info = { + url = "https://github.com/tree-sitter/tree-sitter-scala", + files = { "src/parser.c", "src/scanner.c" }, + } +} + +parsers.haskell = { + install_info = { + url = "https://github.com/tree-sitter/tree-sitter-haskell", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + +parsers.markdown = { + install_info = { + url = "https://github.com/ikatyang/tree-sitter-markdown", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + +parsers.toml = { + install_info = { + url = "https://github.com/ikatyang/tree-sitter-toml", + files = { "src/parser.c", "src/scanner.c" }, + } +} + +parsers.vue = { + install_info = { + url = "https://github.com/ikatyang/tree-sitter-vue", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + +parsers.elm = { + install_info = { + url = "https://github.com//razzeee/tree-sitter-elm", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + +parsers.yaml = { + install_info = { + url = "https://github.com/ikatyang/tree-sitter-yaml", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + +parsers.nix = { + install_info = { + url = "https://github.com/cstrahan/tree-sitter-nix", + files = { "src/parser.c", "src/scanner.cc" }, + } +} + -- @enable can be true or false -- @disable is a list of languages, only relevant if enable is true -- @keymaps list of user mappings for a given module if relevant -- cgit v1.2.3-70-g09d2 From 39da51bbd12b8cda64226f905dba6556cc9d9b75 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sat, 2 May 2020 11:33:32 +0200 Subject: modules: move textobj to incremental_selection As suggested in #37, rename the textobj module to incremental_selection. Also adds a utility function to get the config of a module. --- lua/nvim-treesitter/configs.lua | 6 ++- lua/nvim-treesitter/incremental_selection.lua | 78 +++++++++++++++++++++++++++ lua/nvim-treesitter/textobj.lua | 78 --------------------------- 3 files changed, 83 insertions(+), 79 deletions(-) create mode 100644 lua/nvim-treesitter/incremental_selection.lua delete mode 100644 lua/nvim-treesitter/textobj.lua diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index 9363c9e68..10dcc9605 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -214,7 +214,7 @@ local config = { return queries.get_query(ft, 'highlights') ~= nil end }, - textobj = { + incremental_selection = { enable = false, disable = {}, keymaps = { @@ -403,4 +403,8 @@ function M.available_modules() return vim.tbl_keys(config.modules) end +function M.get_module(mod) + return config.modules[mod] +end + return M diff --git a/lua/nvim-treesitter/incremental_selection.lua b/lua/nvim-treesitter/incremental_selection.lua new file mode 100644 index 000000000..70eefe37c --- /dev/null +++ b/lua/nvim-treesitter/incremental_selection.lua @@ -0,0 +1,78 @@ +local api = vim.api +local utils = require'nvim-treesitter.utils' +local parsers = require'nvim-treesitter.parsers' +local M = {} + +local function node_range_to_vim(node) + if not node then return end + + local start_row, start_col, end_row, end_col = node:range() + + local select_range = [[ + call cursor(%d, %d) + normal v + call cursor(%d, %d) + ]] + local exec_command = string.format(select_range, + start_row+1, start_col+1, + end_row+1, end_col+1) + + api.nvim_exec(exec_command, false) +end + +local function select_incremental(increment_func) + return function() + local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) + local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) + + local node = nil + if parsers.has_parser() then + local root = parsers.get_parser():parse():root() + node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) + local node_start_row, node_start_col, node_end_row, node_end_col = node:range() + + if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col + and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then + node = increment_func(node) + end + end + + return node_range_to_vim(node) + end +end + +M.node_incremental = select_incremental(function(node) + if node then + return node:parent() or node + end +end) + +M.scope_incremental = select_incremental(function(node) + if node then + return utils.smallest_containing_scope(node:parent() or node) + end +end) + +function M.attach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + + local config = require'nvim-treesitter.configs'.get_module('incremental_selection') + for funcname, mapping in pairs(config.keymaps) do + api.nvim_buf_set_keymap(buf, 'v', mapping, + string.format(":lua require'nvim-treesitter.incremental_selection'.%s()", funcname), { silent = true }) + api.nvim_buf_set_keymap(buf, 'o', mapping, + string.format(":normal v%s", mapping), { silent = true }) + end +end + +function M.detach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + + local config = require'nvim-treesitter.configs'.get_module('incremental_selection') + for _, mapping in pairs(config.keymaps) do + api.nvim_buf_del_keymap(buf, 'v', mapping) + api.nvim_buf_del_keymap(buf, 'o', mapping) + end +end + +return M diff --git a/lua/nvim-treesitter/textobj.lua b/lua/nvim-treesitter/textobj.lua deleted file mode 100644 index c2bcc30f0..000000000 --- a/lua/nvim-treesitter/textobj.lua +++ /dev/null @@ -1,78 +0,0 @@ -local api = vim.api -local utils = require'nvim-treesitter.utils' -local parsers = require'nvim-treesitter.parsers' -local M = {} - -local function node_range_to_vim(node) - if not node then return end - - local start_row, start_col, end_row, end_col = node:range() - - local select_range = [[ - call cursor(%d, %d) - normal v - call cursor(%d, %d) - ]] - local exec_command = string.format(select_range, - start_row+1, start_col+1, - end_row+1, end_col+1) - - api.nvim_exec(exec_command, false) -end - -local function select_incremental(increment_func) - return function() - local buf, sel_start_line, sel_start_col, _ = unpack(vim.fn.getpos("'<")) - local buf, sel_end_line, sel_end_col, _ = unpack(vim.fn.getpos("'>")) - - local node = nil - if parsers.has_parser() then - local root = parsers.get_parser():parse():root() - node = root:named_descendant_for_range(sel_start_line-1, sel_start_col-1, sel_end_line-1, sel_end_col) - local node_start_row, node_start_col, node_end_row, node_end_col = node:range() - - if (sel_start_line-1) == node_start_row and (sel_start_col-1) == node_start_col - and (sel_end_line-1) == node_end_row and sel_end_col == node_end_col then - node = increment_func(node) - end - end - - return node_range_to_vim(node) - end -end - -M.node_incremental = select_incremental(function(node) - if node then - return node:parent() or node - end -end) - -M.scope_incremental = select_incremental(function(node) - if node then - return utils.smallest_containing_scope(node:parent() or node) - end -end) - -function M.attach(bufnr) - local buf = bufnr or api.nvim_get_current_buf() - - local config = require'nvim-treesitter.configs'.get_config().textobj - for funcname, mapping in pairs(config.keymaps) do - api.nvim_buf_set_keymap(buf, 'v', mapping, - string.format(":lua require'nvim-treesitter.textobj'.%s()", funcname), { silent = true }) - api.nvim_buf_set_keymap(buf, 'o', mapping, - string.format(":normal v%s", mapping), { silent = true }) - end -end - -function M.detach(bufnr) - local buf = bufnr or api.nvim_get_current_buf() - - local config = require'nvim-treesitter.configs'.get_config().textobj - for _, mapping in pairs(config.keymaps) do - api.nvim_buf_del_keymap(buf, 'v', mapping) - api.nvim_buf_del_keymap(buf, 'o', mapping) - end -end - -return M -- cgit v1.2.3-70-g09d2 From d0b84dd89fb1cb4fc637cd3deec427745ba3145b Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 1 May 2020 16:25:06 +0200 Subject: Add 'nvim-treesitter/node-movement' --- lua/nvim-treesitter/configs.lua | 11 +++++ lua/nvim-treesitter/node_movement.lua | 91 +++++++++++++++++++++++++++++++++++ lua/nvim-treesitter/utils.lua | 59 +++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 lua/nvim-treesitter/node_movement.lua diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua index 10dcc9605..9695da5af 100644 --- a/lua/nvim-treesitter/configs.lua +++ b/lua/nvim-treesitter/configs.lua @@ -223,6 +223,17 @@ local config = { }, is_supported = function() return true end }, + node_movement = { + enable = false, + disable = {}, + is_supported = function() return true end, + keymaps = { + move_up = "", + move_down = "", + move_left = "", + move_right = "", + }, + }, -- folding = { -- enable = false, -- disable = {}, diff --git a/lua/nvim-treesitter/node_movement.lua b/lua/nvim-treesitter/node_movement.lua new file mode 100644 index 000000000..5d4813bc4 --- /dev/null +++ b/lua/nvim-treesitter/node_movement.lua @@ -0,0 +1,91 @@ +local api = vim.api +local parsers = require'nvim-treesitter.parsers' +local utils = require'nvim-treesitter.utils' +local M = {} + + +M.NodeMovementKind = { + up = 'up', + down = 'down', + left = 'left', + right = 'right', +} + +M.current_node = {} + +local function node_start_to_vim(node) + if not node then return end + + local row, col = node:start() + local exec_command = string.format('call cursor(%d, %d)', row+1, col+1) + api.nvim_exec(exec_command, false) +end + +M.do_node_movement = function(kind) + local buf, line, col = unpack(vim.fn.getpos(".")) + + local current_node = M.current_node[buf] + + if current_node then + local node_line, node_col = current_node:start() + if line-1 ~= node_line or col-1 ~= node_col then + current_node = nil + end + end + local destination_node + + if parsers.has_parser() then + local root = parsers.get_parser():parse():root() + if not current_node then + current_node = root:named_descendant_for_range(line-1, col-1, line-1, col) + end + + if kind == M.NodeMovementKind.up then + destination_node = current_node:parent() + elseif kind == M.NodeMovementKind.down then + if current_node:named_child_count() > 0 then + destination_node = current_node:named_child(0) + else + local next_node = utils.get_next_node(current_node) + if next_node and next_node:named_child_count() > 0 then + destination_node = next_node:named_child(0) + end + end + elseif kind == M.NodeMovementKind.left then + destination_node = utils.get_previous_node(current_node, true, true) + elseif kind == M.NodeMovementKind.right then + destination_node = utils.get_next_node(current_node, true, true) + end + M.current_node[buf] = destination_node or current_node + end + + if destination_node then + node_start_to_vim(destination_node) + end +end + +M.move_up = function() M.do_node_movement(M.NodeMovementKind.up) end +M.move_down = function() M.do_node_movement(M.NodeMovementKind.down) end +M.move_left = function() M.do_node_movement(M.NodeMovementKind.left) end +M.move_right = function() M.do_node_movement(M.NodeMovementKind.right) end + +function M.attach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + + local config = require'nvim-treesitter.configs'.get_module('node_movement') + for funcname, mapping in pairs(config.keymaps) do + api.nvim_buf_set_keymap(buf, 'n', mapping, + string.format(":lua require'nvim-treesitter.node_movement'.%s()", funcname), { silent = true }) + end +end + +function M.detach(bufnr) + local buf = bufnr or api.nvim_get_current_buf() + + local config = require'nvim-treesitter.configs'.get_module('node_movement') + for _, mapping in pairs(config.keymaps) do + api.nvim_buf_del_keymap(buf, 'n', mapping) + end +end + +return M diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua index 391863f0d..9d591eab6 100644 --- a/lua/nvim-treesitter/utils.lua +++ b/lua/nvim-treesitter/utils.lua @@ -93,4 +93,63 @@ function M.smallest_containing_scope(node, bufnr) return current or root end +--- Get next node with same parent +-- @param node node +-- @param allow_switch_parents allow switching parents if last node +-- @param allow_next_parent allow next parent if last node and next parent without children +function M.get_next_node(node, allow_switch_parents, allow_next_parent) + local destination_node + local parent = node:parent() + + if parent then + local found_pos = 0 + for i = 0,parent:named_child_count()-1,1 do + if parent:named_child(i) == node then + found_pos = i + break + end + end + if parent:named_child_count() > found_pos + 1 then + destination_node = parent:named_child(found_pos + 1) + elseif allow_switch_parents then + local next_node = M.get_next_node(node:parent()) + if next_node and next_node:named_child_count() > 0 then + destination_node = next_node:named_child(0) + elseif next_node and allow_next_parent then + destination_node = next_node + end + end + end + return destination_node +end + +--- Get previous node with same parent +-- @param node node +-- @param allow_switch_parents allow switching parents if first node +-- @param allow_previous_parent allow previous parent if first node and previous parent without children +function M.get_previous_node(node, allow_switch_parents, allow_previous_parent) + local destination_node + local parent = node:parent() + if parent then + local found_pos = 0 + for i = 0,parent:named_child_count()-1,1 do + if parent:named_child(i) == node then + found_pos = i + break + end + end + if 0 < found_pos then + destination_node = parent:named_child(found_pos - 1) + elseif allow_switch_parents then + local previous_node = M.get_previous_node(node:parent()) + if previous_node and previous_node:named_child_count() > 0 then + destination_node = previous_node:named_child(previous_node:named_child_count() - 1) + elseif previous_node and allow_previous_parent then + destination_node = previous_node + end + end + end + return destination_node +end + return M -- cgit v1.2.3-70-g09d2 From a33bccaaf0c69146dfe330feb52e05c975054468 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Sun, 3 May 2020 11:10:36 +0200 Subject: Add documentation for `node_movement`, rename: `textobj` -> `incremental_selection` --- README.md | 13 ++++++++++++- doc/nvim-treesitter.txt | 36 +++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3903ecb0b..67d90abbc 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ require'nvim-treesitter.configs'.setup { enable = true, -- false will disable the whole extension disable = { 'c', 'rust' }, -- list of language that will be disabled }, - textobj = { -- this enables incremental selection + incremental_selection = { -- this enables incremental selection enable = true, disable = { 'cpp', 'lua' }, keymaps = { -- mappings for incremental selection (visual mappings) @@ -100,6 +100,16 @@ require'nvim-treesitter.configs'.setup { scope_incremental = "f" -- "grc" by default } }, + node_movement = { -- this cursor movement in node hierachy + enable = true, + disable = { 'cpp', 'rust' }, + keymaps = { -- mappings for node movement (normal mappings) + move_up = "", -- default is to move with alt key hold + move_down = "", + move_left = "", + move_right = "", + } + }, ensure_installed = 'all' -- one of 'all', 'language', or a list of languages } EOF @@ -124,6 +134,7 @@ Some of these features are : - [x] Incremental selection - [ ] Syntax based code folding - [x] Consistent syntax highlighting (the api is not quite stable yet) + - [x] Cursor movement in node hierachy You can find the roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1). The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated! diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt index 55ada1596..ceb834be1 100644 --- a/doc/nvim-treesitter.txt +++ b/doc/nvim-treesitter.txt @@ -30,19 +30,29 @@ By default, everything is disabled. To enable support for features, in your `ini > lua < Date: Tue, 5 May 2020 15:04:01 +0200 Subject: feat: provide a statusline indicator It will show the current branch at the cursor going the tree as such. root->node->subnode->leaf If an argument is provided to `statusline`, then the tree will be truncated as follows : ..->subnode->subnode --- autoload/nvim_treesitter.vim | 3 +++ lua/nvim-treesitter.lua | 31 +++++++++++++++++++++++++++++++ lua/nvim-treesitter/parsers.lua | 3 ++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 autoload/nvim_treesitter.vim diff --git a/autoload/nvim_treesitter.vim b/autoload/nvim_treesitter.vim new file mode 100644 index 000000000..715befe0f --- /dev/null +++ b/autoload/nvim_treesitter.vim @@ -0,0 +1,3 @@ +function! nvim_treesitter#statusline(len) + return luaeval("require'nvim-treesitter'.statusline(_A)", a:len) +endfunction diff --git a/lua/nvim-treesitter.lua b/lua/nvim-treesitter.lua index e1c95ed31..90b5468a3 100644 --- a/lua/nvim-treesitter.lua +++ b/lua/nvim-treesitter.lua @@ -24,4 +24,35 @@ function M.setup(lang) end end +function M.statusline(indicator_size) + local indicator_size = indicator_size or 1000 + local expr = require"nvim-treesitter.utils".expression_at_point() + local current_node = + require'nvim-treesitter.node_movement'.current_node[api.nvim_get_current_buf()] + + local indicator = "" + while expr and (#indicator + #(expr:type()) + 5) < indicator_size do + + local prefix = "" + if expr:parent() then + prefix = "->" + end + + + if expr == current_node then + indicator = string.format("%s[%s]%s", prefix, expr:type(), indicator) + else + indicator = prefix .. expr:type() .. indicator + end + + expr = expr:parent() + end + + if expr then + return "..." .. indicator + else + return indicator + end +end + return M diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua index e046ca45c..07f3e9d34 100644 --- a/lua/nvim-treesitter/parsers.lua +++ b/lua/nvim-treesitter/parsers.lua @@ -5,11 +5,12 @@ local M = {} function M.has_parser(lang) local lang = lang or api.nvim_buf_get_option(0, 'filetype') + if not lang or #lang == 0 then return false end return #api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0 end function M.get_parser(bufnr, lang) - if M.has_parser() 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 -- cgit v1.2.3-70-g09d2 From 703ccbec594219e0331c434ee57a0a48c92b280e Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 7 May 2020 08:18:13 +0200 Subject: docs: add statusline indicator informations. Also document newly added parsers by adding them in the readme. --- README.md | 8 ++++++++ doc/nvim-treesitter.txt | 13 ++++++++++++- doc/tags | 2 ++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 67d90abbc..5dcfc4478 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ Some of these features are : - [ ] Syntax based code folding - [x] Consistent syntax highlighting (the api is not quite stable yet) - [x] Cursor movement in node hierachy + - [x] Statusline indicator (`require'nvim-treesitter'.statusline(size)`) You can find the roadmap [here](https://github.com/nvim-treesitter/nvim-treesitter/projects/1). The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated! @@ -166,6 +167,13 @@ List of currently supported languages: - [ ] julia - [ ] php - [ ] bash +- [ ] scala +- [ ] haskell +- [ ] toml +- [ ] vue +- [ ] elm +- [ ] yaml +- [ ] nix ## Troubleshooting Before doing anything run `:checkhealth nvim_treesitter`. This will help you find where the bug might come from. diff --git a/doc/nvim-treesitter.txt b/doc/nvim-treesitter.txt index ceb834be1..084936bad 100644 --- a/doc/nvim-treesitter.txt +++ b/doc/nvim-treesitter.txt @@ -97,5 +97,16 @@ A list of languages can be found at |:TSInstallInfo| List modules state for the current session. - vim:tw=78:ts=8:noet:ft=help:norl: +============================================================================== +FUNCTIONS~ + *nvim-treesitter-functions* + +|nvim_treesitter#statusline(size)| + *nvim_treesitter#statusline()* +Returns a string describing the current position in the syntax tree. This +could be used as a statusline indicator. +Note: The `size` argument is optionnal. When specified, the string will not be + longer than `size`. + + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/doc/tags b/doc/tags index 7d69206e3..f712ecf00 100644 --- a/doc/tags +++ b/doc/tags @@ -7,5 +7,7 @@ :TSModuleInfo nvim-treesitter.txt /*:TSModuleInfo* nvim-treesitter nvim-treesitter.txt /*nvim-treesitter* nvim-treesitter-commands nvim-treesitter.txt /*nvim-treesitter-commands* +nvim-treesitter-functions nvim-treesitter.txt /*nvim-treesitter-functions* nvim-treesitter-intro nvim-treesitter.txt /*nvim-treesitter-intro* nvim-treesitter-quickstart nvim-treesitter.txt /*nvim-treesitter-quickstart* +nvim_treesitter#statusline() nvim-treesitter.txt /*nvim_treesitter#statusline()* -- cgit v1.2.3-70-g09d2 From 2b3d4d21a815ec185ca896d83e505999ac53a047 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sat, 2 May 2020 11:23:18 +0200 Subject: docs: add contributig draft --- CONTRIBUTING.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..e828b5a90 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,99 @@ +# Contributing to `nvim-treesitter` + +First of all, thank you very much for contributing to `nvim-treesitter`. + +If you haven't already, you should really come and reach out to us on our [gitter](https://gitter.im/nvim-treesitter/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link) +room, so that we can help you contributing ! + +As you know, `nvim-treesitter` is roughly splitted in two parts : + - Parser configurations : for various things like `locals`, `highlights` + - What we like to call *modules* : tiny lua modules that provide a given featurs, based on parser configurations + +Depending on which part of the plugin you want to contribute to, please read the appropriate section. + +## Parser configurations + +Contributing to parser configurations is basically modifying one of the `queries/*/*.scm`. +Each of these `scheme` files contains a *tree-sitter query* for a given purpose. +Before going any further, we highly suggest that you [read more about tree-sitter queries](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries). + +Each query has an appropriate name, which is then used by modules to extract data from the syntax tree. +For now two types of queries are used by `nvim-treesitter`: + - `highlights.scm` : used for syntax highlighting, using the `highlight` module. + - `locals.scm` : used to exctract keyword definitions, scopes, references,... using the `locals` module. + +For both of thses types there is a *norm* you will have to follow so that features work fine. +Here are some global advices : + - If your language is listed [here](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries), + you can debug and experiment with your queries there. + - If not, you should consider installing the [tree-sitter cli](https://github.com/tree-sitter/tree-sitter/tree/master/cli), + you should then be able to open a local playground using `tree-sitter build-wasm && tree-sitter web-ui` within the + parsers repo. + +### Highlights + +As languages differ quite a lot, here is a set of captures available to you when building a `highlights.scm` query. +On important thing to note is that many of these capture groups are not supported by `neovim` for now, and will not have any +effect on highlighting. We will work on improving highlighting in the near future though. + +#### Misc +`@comment` +`@error` for error `(ERROR)` nodes. +`@punctuation.delimiter` for `;` `.` `,` +`@punctuation.bracket` for `()` or `{}` + +Some captures are related to language injection (like markdown code blocks). As this is not supported by neovim yet, these +are optionnal and will not have any effect for now. +`@embedded` +`@injection` + `language` + `content` + +#### Constants +`@constant` + `builtin` + `macro` +`@string` + `regex` + `escape` +`@character` +`@number` +`@boolean` +`@float` + +#### Functions +`@function` + `builtin` + `macro` +`@parameter` + +`@method` +`@field` or `@property` + +`@constructor` + +#### Keywords +`@conditional` +`@repeat` +`@label` for C/Lua-like labels +`@operator` +`@keyword` +`@exception` + +`@type` + `builtin` +`@structure` + +### Locals + +`@definition` for various definitions + `function` + `method` + `var` + `macro` + `type` + +`@scope` + +`@reference` + -- cgit v1.2.3-70-g09d2 From 5dc5695413a2cce19938db963984926008cde139 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Tue, 5 May 2020 15:03:00 +0200 Subject: feat: support suggested highlights --- lua/nvim-treesitter/highlight.lua | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lua/nvim-treesitter/highlight.lua b/lua/nvim-treesitter/highlight.lua index 65ab48dcb..9cf259639 100644 --- a/lua/nvim-treesitter/highlight.lua +++ b/lua/nvim-treesitter/highlight.lua @@ -6,6 +6,47 @@ local M = { highlighters = {} } +local hlmap = vim.treesitter.TSHighlighter.hl_map + +-- Misc +hlmap.error = "Error" +hlmap["punctuation.delimiter"] = "Delimiter" +hlmap["punctuation.bracket"] = "Delimiter" + +-- Constants +hlmap["constant"] = "Constant" +hlmap["constant.builtin"] = "Special" +hlmap["constant.macro"] = "Define" +hlmap["string"] = "String" +hlmap["string.regex"] = "String" +hlmap["string.escape"] = "SpecialChar" +hlmap["character"] = "Character" +hlmap["number"] = "Number" +hlmap["boolean"] = "Boolean" +hlmap["float"] = "Float" + +-- Functions +hlmap["function"] = "Function" +hlmap["function.builtin"] = "Special" +hlmap["function.macro"] = "Macro" +hlmap["parameter"] = "Identifier" +hlmap["method"] = "Function" +hlmap["field"] = "Identifier" +hlmap["property"] = "Identifier" +hlmap["constructor"] = "Special" + +-- Keywords +hlmap["conditional"] = "Conditional" +hlmap["repeat"] = "Repeat" +hlmap["label"] = "Label" +hlmap["operator"] = "Operator" +hlmap["keyword"] = "Keyword" +hlmap["exception"] = "Exception" + +hlmap["type"] = "Type" +hlmap["type.builtin"] = "Type" +hlmap["structure"] = "Structure" + function M.attach(bufnr, ft) local buf = bufnr or api.nvim_get_current_buf() local ft = ft or api.nvim_buf_get_option(buf, 'ft') -- cgit v1.2.3-70-g09d2 From 824b063d0d518dd20e09585604e923139599128f Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 7 May 2020 09:20:40 +0200 Subject: fix: change locals extraction --- lua/nvim-treesitter/locals.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/nvim-treesitter/locals.lua b/lua/nvim-treesitter/locals.lua index 3e5174548..b16408ac5 100644 --- a/lua/nvim-treesitter/locals.lua +++ b/lua/nvim-treesitter/locals.lua @@ -52,8 +52,8 @@ function M.get_definitions(bufnr) local defs = {} for _, loc in ipairs(locals) do - if loc.definition and loc.definition.node then - table.insert(defs, {node=loc.definition.node, kind=loc.kind}) + if loc.definition then + table.insert(defs, loc.definition) end end -- cgit v1.2.3-70-g09d2 From 22f73628f618465913d93e907a0a3881ed221b1d Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 7 May 2020 09:23:33 +0200 Subject: fix(lua): update queries --- queries/lua/highlights.scm | 25 +++++++++++++------------ queries/lua/locals.scm | 24 ++++++++---------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/queries/lua/highlights.scm b/queries/lua/highlights.scm index 3077be108..a674638e8 100644 --- a/queries/lua/highlights.scm +++ b/queries/lua/highlights.scm @@ -3,16 +3,16 @@ ;;; Builtins ;; Keywords "local" @keyword -"if" @keyword -"then" @keyword -"else" @keyword -"elseif" @keyword +"if" @conditional +"then" @conditional +"else" @conditional +"elseif" @conditional "end" @keyword "return" @keyword -"do" @keyword -"while" @keyword -"repeat" @keyword -"for" @keyword +"do" @repeat +"while" @repeat +"repeat" @repeat +"for" @repeat (break_statement) @keyword "goto" @keyword @@ -43,15 +43,16 @@ "#" @operator ;; Constants -(false) @constant -(true) @constant -(nil) @constant +(false) @boolean +(true) @boolean +(nil) @constant.builtin (spread) @constant ;; "..." ;; Nodes (function "function" @function "end" @function) +(function_definition "function" @function "end" @function) (local_function "function" @function "end" @function) -(table "{" @operator "}" @operator) +(table "{" @constructor "}" @constructor) (comment) @comment (string) @string (number) @number diff --git a/queries/lua/locals.scm b/queries/lua/locals.scm index 5f21e0aaf..ee2927328 100644 --- a/queries/lua/locals.scm +++ b/queries/lua/locals.scm @@ -2,25 +2,20 @@ ;; Variable and field declarations ((variable_declarator - (identifier) @definition) - (set! definition.kind "v")) + (identifier) @definition.var)) ((variable_declarator - (field_expression object:(*) @definition.associated (property_identifier) @definition)) - (set! difinition.kind "v")) + (field_expression object:(*) @definition.associated (property_identifier) @definition.var))) ;; Parameters ((local_function - (parameters (identifier) @definition)) - (set! definition.kind "v")) + (parameters (identifier) @definition.var))) ((function - (parameters (identifier) @definition)) - (set! definition.kind "v")) + (parameters (identifier) @definition.var))) ;; Loops ((loop_expression - (identifier) @definition) - (set! definition.kind "v")) + (identifier) @definition.var)) ;; Function definitions ;; Functions definitions creates both a definition and a new scope @@ -28,16 +23,13 @@ (function_name (function_name_field (identifier) @definition.associated - (property_identifier) @definition))) @scope - (set! definition.kind "m")) + (property_identifier) @definition.method))) @scope) ((function - (function_name (identifier) @definition)) @scope - (set! definition.kind "f")) + (function_name (identifier) @definition.function)) @scope) ((local_function - (identifier) @definition) @scope - (set! definition.kind "f")) + (identifier) @definition.function) @scope) ((if_statement) @scope) ((for_in_statement) @scope) -- cgit v1.2.3-70-g09d2 From c6b0a62bd6e8874925e9c3b368df4e5e12e5eaef Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 7 May 2020 09:26:02 +0200 Subject: fix(CONTRIBUTING): typos --- CONTRIBUTING.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e828b5a90..b42950b63 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,11 +3,11 @@ First of all, thank you very much for contributing to `nvim-treesitter`. If you haven't already, you should really come and reach out to us on our [gitter](https://gitter.im/nvim-treesitter/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link) -room, so that we can help you contributing ! +room, so we can help you with any question you might have! As you know, `nvim-treesitter` is roughly splitted in two parts : - Parser configurations : for various things like `locals`, `highlights` - - What we like to call *modules* : tiny lua modules that provide a given featurs, based on parser configurations + - What we like to call *modules* : tiny lua modules that provide a given feature, based on parser configurations Depending on which part of the plugin you want to contribute to, please read the appropriate section. @@ -20,9 +20,9 @@ Before going any further, we highly suggest that you [read more about tree-sitte Each query has an appropriate name, which is then used by modules to extract data from the syntax tree. For now two types of queries are used by `nvim-treesitter`: - `highlights.scm` : used for syntax highlighting, using the `highlight` module. - - `locals.scm` : used to exctract keyword definitions, scopes, references,... using the `locals` module. + - `locals.scm` : used to extract keyword definitions, scopes, references,... using the `locals` module. -For both of thses types there is a *norm* you will have to follow so that features work fine. +For both of these types there is a *norm* you will have to follow so that features work fine. Here are some global advices : - If your language is listed [here](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries), you can debug and experiment with your queries there. @@ -33,7 +33,7 @@ Here are some global advices : ### Highlights As languages differ quite a lot, here is a set of captures available to you when building a `highlights.scm` query. -On important thing to note is that many of these capture groups are not supported by `neovim` for now, and will not have any +One important thing to note is that many of these capture groups are not supported by `neovim` for now, and will not have any effect on highlighting. We will work on improving highlighting in the near future though. #### Misc -- cgit v1.2.3-70-g09d2 From 9c4099a898b5bb477f637451ff586246d15bffb0 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 8 May 2020 16:16:12 +0200 Subject: Fix typo in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dcfc4478..afedbc400 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ require'nvim-treesitter.configs'.setup { scope_incremental = "f" -- "grc" by default } }, - node_movement = { -- this cursor movement in node hierachy + node_movement = { -- this enables cursor movement in node hierarchy enable = true, disable = { 'cpp', 'rust' }, keymaps = { -- mappings for node movement (normal mappings) -- cgit v1.2.3-70-g09d2 From 0a98fd5795e7a2c105047fd5957de317a353024b Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Fri, 8 May 2020 18:03:06 +0200 Subject: Fix typo in CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b42950b63..46c7a9419 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,7 +43,7 @@ effect on highlighting. We will work on improving highlighting in the near futur `@punctuation.bracket` for `()` or `{}` Some captures are related to language injection (like markdown code blocks). As this is not supported by neovim yet, these -are optionnal and will not have any effect for now. +are optional and will not have any effect for now. `@embedded` `@injection` `language` -- cgit v1.2.3-70-g09d2