Add queries for neovim

This commit is contained in:
Emmanuel Briot 2022-12-08 11:23:51 +01:00
parent 0a52f6df01
commit 1eafd432d7
20 changed files with 320 additions and 4 deletions

115
README.md
View File

@ -6,11 +6,122 @@ syntax, and slightly changed to reduce some conflicts. Tree-sitter
doesn't need a full syntax tree, so we can take some shortcuts in
the grammar.
## Installation
Execute the following commands:
You will need neovim at least version 8.0 (not tested with earlier version).
Installation is very manual at this stage, until we can integrate this package
inside nvim-treesitter itself. At the moment, assuming you are using lua
configuration and Packer for your package management:
```lua
-- file: ~/.config/nvim/init.lua
-- Merge this with any existing Packer configuration you might already
-- have. This loads packer itself, then loads the new `ada.nvim` package.
require('packer').startup(function(use)
use(require('mytreesitter.nvim'))
end)
```
Then create a new file to setup treesitter (or merge with an existing
configuration of course).
```lua
-- file: ~/.config/nvim/mytreesitter.nvim
return {
'nvim-treesitter/nvim-treesitter',
requires = {
'nvim-treesitter/nvim-treesitter-textobjects'
},
run=function()
require('nvim-treesitter.install').update({ with_sync = true })
end,
config=function()
-- Add support for our Ada parser
local parsers = require "nvim-treesitter.parsers"
local parser_config = parsers.get_parser_configs()
parser_config.ada = {
install_info = {
url = "https://github.com/briot/tree-sitter-ada",
files = {"src/parser.c"},
generate_requires_npm = false,
requires_generate_from_grammar = false,
},
filetype = "ada",
}
end,
}
```
Finally, we need to install the Ada parser with:
```vim
:PackerSync " to install treesitter itself
:TSInstall ada " to install Ada support
```
However, the above part only installs the parser itself (to generate a syntax
tree from your source files). We now need to install queries, i.e. pattern
matching against that tree to provide various capabilities like syntax
highlighting, folding, indentation, smart textobject selection,...
For this, and until we can merge with nvim-treesitter itself, you will have
to clone this github repository, then copy the `queries/` directory to
```
~/.local/share/nvim/site/pack/packer/start/nvim-treesitter/queries/
```
## Usage
### Syntax highlighting
The above default configuration will replace the default regular
expressions-based syntax highlighting in vim. Instead, the highlighting is
based on the tree build every time you type something.
The default highlighting looks pretty much like the one from the standard
Ada mode. However, the tree-based approach potentially opens the door for
smart highlighting, like "Use a different background color for a subprogram
specification", "show constant definitions in blue" or other high-level
approaches.
WIP: document how users can do this in their own configuration files.
The current approach is to modify queries/highlights.scm
Potentially (though it seems to be disabled in neovim at the moment), the
highlighting can also get smarter. Going back to the "show constants in
blue" example above, the queries/locals.scm file adds a simple approach so
that references to those constants can point to the definition, and therefore
use the same blue highlighting.
Because neovim also has support for language servers (LSP), it is likely
better to rely on the language server here.
### Block folding
If you press <kbd>za</kbd> now, this will toggle the folding of the
"current block".
This is defined in queries/folds.scm, and currently knows about package
specifications, package bodies, subprograms bodies, if statements and loops.
Other semantic blocks could be added.
### Smart Selection
The file queries/textobjects.scm defines a function textobjects, so that
you can now use commands like
- <kbd>vaf</kbd> (v)isually select (a) (f)unction or subprogram
- <kbd>vif</kbd> (v)isually select (i)nside a (f)unction or subprogram
- <kbd>vai</kbd> (v)isually select (a) (i)f statement (or loop)
- <kbd>vii</kbd> (v)isually select (i)nside an (i)f statement (or loop)
## Development
Execute the following commands:
```bash
npm install
npm run test
```

View File

@ -360,7 +360,7 @@ module.exports = grammar({
package_body: $ => seq(
reservedWord('package'),
reservedWord('body'),
$.name,
field('name', $.name),
optional($.aspect_specification),
reservedWord('is'),
optional($.non_empty_declarative_part),

View File

@ -12,5 +12,16 @@
"testquick": "time tree-sitter test",
"update-test": "tree-sitter test --update"
},
"main": "bindings/node"
"main": "bindings/node",
"tree-sitter": [
{
"scope": "source.ada",
"file-types": [
"ada"
],
"highlights": [
"queries/highlights.scm"
]
}
]
}

11
queries/folds.scm Normal file
View File

@ -0,0 +1,11 @@
;; Support for folding in Ada
;; za toggles folding a package, subprogram, if statement or loop
[
(package_specification)
(package_body)
(subprogram_body)
(block_statement)
(if_statement)
(loop_statement)
] @fold

147
queries/highlights.scm Normal file
View File

@ -0,0 +1,147 @@
;; highlight queries.
;; See the syntax at https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries
;; See also https://github.com/nvim-treesitter/nvim-treesitter/blob/master/CONTRIBUTING.md#parser-configurations
;; for a list of recommended @ tags, though not all of them have matching
;; highlights in neovim.
[
"abort"
"abs"
"accept"
"all"
"at"
"begin"
"declare"
"delay"
"until"
"do"
"end"
"entry"
"exit"
"generic"
"is"
"null"
"others"
"out"
"pragma"
"renames"
"when"
] @keyword
[
"abstract"
"access"
"aliased"
"array"
"constant"
"delta"
"digits"
"interface"
"limited"
"of"
"private"
"range"
"synchronized"
"tagged"
] @StorageClass
[
"mod"
"new"
"protected"
"record"
"subtype"
"task"
"type"
] @type.definition
[
"with"
"use"
] @include
[
"body"
"function"
"overriding"
"procedure"
"package"
"separate"
] @keyword.function
[
"and"
"in"
"not"
"or"
"xor"
] @keyword.operator
[
"while"
"loop"
"for"
"parallel"
"reverse"
"some"
] @keyword.repeat
[
"return"
] @keyword.return
[
"case"
"if"
"else"
"then"
"elsif"
"select"
] @conditional
[
"exception"
"raise"
] @exception
(comment) @comment
(comment) @spell ;; spell-check comments
(string_literal) @string
(string_literal) @spell ;; spell-check strings
(identifier) @variable
(numeric_literal) @number
;; Highlight the name of subprograms
(procedure_specification
(name) @function
)
(function_specification
(name) @function
)
(package_specification
name: (name) @function ;; Should use @module, but no default highlight
)
(package_body
(name) @function ;; Should use @module, but no default highlight
)
(generic_instantiation
. (name) @function
)
;; Change keyword categories inside type definitions.
;; WIP: waiting for simplified tree.
; [
; "is"
; "abstract"
; "access"
; "array"
; "tagged"
; "constant"
; "range"
; "mod"
; "digits"
; "delta"
; "limited"
; "synchronized"
; ]* @keyword.type
(full_type_declaration
(identifier) @type
"is" @type.definition
; (access_type_definition "access" @keyword.type)
)
;; Highlight errors in red. This is not very useful in practice, as text will
;; be highlighted as user types, and the error could be elsewhere in the code.
;; This also requires defining :hi @error guifg=Red for instance.
(ERROR) @error

17
queries/locals.scm Normal file
View File

@ -0,0 +1,17 @@
;; Better highlighting by referencing to the definition, for variable
;; references. However, this is not yet supported by neovim
;; See https://tree-sitter.github.io/tree-sitter/syntax-highlighting#local-variables
(package_specification) @scope
(subprogram_specification) @scope
(block_statement) @scope
(procedure_specification (name) @definition.var)
(function_specification (name) @definition.var)
(package_specification name: (name) @definition.var)
(package_body (name) @definition.var)
(generic_instantiation . (name) @definition.var)
(defining_identifier_list (identifier) @definition.var)
(identifier) @reference
(name) @reference

19
queries/textobjects.scm Normal file
View File

@ -0,0 +1,19 @@
;; Support for high-level text objects selections.
;; For instance:
;; vaf (v)isually select (a) (f)unction or subprogram
;; vif (v)isually select (i)nside a (f)unction or subprogram
;; vai (v)isually select (a) (i)f statement (or loop)
;; vii (v)isually select (i)nside an (i)f statement (or loop)
;;
;; https://github.com/nvim-treesitter/nvim-treesitter-textobjects/blob/master/README.md
(subprogram_body) @function.outer
(subprogram_body (non_empty_declarative_part) @function.inner)
(subprogram_body (handled_sequence_of_statements) @function.inner)
(subprogram_specification) @function.outer
(package_specification) @function.outer
(package_body) @function.outer
(if_statement) @block.outer
(if_statement (sequence_of_statements) @block.inner)
(loop_statement) @block.outer
(loop_statement (sequence_of_statements) @block.inner)