feat(highlights)!: enforce documented captures (#6232)

Problem: Allowing undocumented "secret" (sub)captures makes it harder
to write comprehensive colorschemes and catch inconsistent captures.

Solution: Only allow captures listed in CONTRIBUTING.md. Add useful
(cross-language) subcaptures and drop language-specific or too niche
ones.

Follow-up: Adding further `*.builtin` captures and changing queries to
use them.

Language-specific subcaptures should instead be added in user config or
a custom language plugin.
This commit is contained in:
Christian Clason 2024-03-03 11:00:11 +01:00 committed by GitHub
parent 22c5a0d833
commit 99ddf57353
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 108 additions and 112 deletions

View file

@ -98,10 +98,11 @@ As languages differ quite a lot, here is a set of captures available to you when
#### Identifiers
```query
@variable ; various variable names
@variable.builtin ; built-in variable names (e.g. `this`)
@variable.parameter ; parameters of a function
@variable.member ; object and struct fields
@variable ; various variable names
@variable.builtin ; built-in variable names (e.g. `this`)
@variable.parameter ; parameters of a function
@variable.parameter.builtin ; special parameters (e.g. `_`, `it`)
@variable.member ; object and struct fields
@constant ; constant identifiers
@constant.builtin ; built-in constant values
@ -111,6 +112,7 @@ As languages differ quite a lot, here is a set of captures available to you when
@module.builtin ; built-in modules or namespaces
@label ; GOTO and other labels (e.g. `label:` in C), including heredoc labels
```
#### Literals
```query
@ -139,8 +141,9 @@ As languages differ quite a lot, here is a set of captures available to you when
@type.definition ; identifiers in type definitions (e.g. `typedef <type> <identifier>` in C)
@type.qualifier ; type qualifiers (e.g. `const`)
@attribute ; attribute annotations (e.g. Python decorators)
@property ; the key in key/value pairs
@attribute ; attribute annotations (e.g. Python decorators)
@attribute.builtin ; builtin annotations (e.g. `@property` in Python)
@property ; the key in key/value pairs
```
#### Functions
@ -167,6 +170,7 @@ As languages differ quite a lot, here is a set of captures available to you when
@keyword.operator ; operators that are English words (e.g. `and` / `or`)
@keyword.import ; keywords for including modules (e.g. `import` / `from` in Python)
@keyword.storage ; modifiers that affect storage in memory or life-time
@keyword.type ; keywords describing composite types (e.g. `struct`, `enum`)
@keyword.repeat ; keywords related to loops (e.g. `for` / `while`)
@keyword.return ; keywords like `return` and `yield`
@keyword.debug ; keywords related to debugging
@ -210,10 +214,15 @@ Mainly for markup languages.
@markup.underline ; underlined text (only for literal underline markup!)
@markup.heading ; headings, titles (including markers)
@markup.heading.1 ; top-level heading
@markup.heading.2 ; section heading
@markup.heading.3 ; subsection heading
@markup.heading.4 ; and so on
@markup.heading.5 ; and so forth
@markup.heading.6 ; six levels ought to be enough for anybody
@markup.quote ; block quotes
@markup.math ; math environments (e.g. `$ ... $` in LaTeX)
@markup.environment ; environments (e.g. in LaTeX)
@markup.link ; text references, footnotes, citations, etc.
@markup.link.label ; link, reference descriptions
@ -236,6 +245,7 @@ Mainly for markup languages.
```query
@tag ; XML-style tag names (and similar)
@tag.builtin ; builtin tag names (e.g. HTML5 tags)
@tag.attribute ; XML-style tag attributes
@tag.delimiter ; XML-style tag delimiters
```

View file

@ -220,12 +220,11 @@
"constexpr"
] @keyword
"co_await" @keyword.coroutine
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine.return
] @keyword.coroutine
[
"public"

View file

@ -19,13 +19,13 @@
(package_identifier) @local.definition.namespace
(for_clause
(identifier) @local.definition.variable
(identifier) @local.definition.var
(expression))
(for_clause
(identifier)
(identifier) @local.definition.variable
(identifier) @local.definition.var
(expression))
(let_clause
(identifier) @local.definition.variable)
(identifier) @local.definition.var)

View file

@ -1,7 +1,7 @@
; Simple tokens ;;;;
(terminal) @string.grammar
(terminal) @string
(special_sequence) @string.special.grammar
(special_sequence) @string.special
(integer) @number

View file

@ -87,7 +87,7 @@
"reader"
"writer"
"readwriter"
] @variable.member.builtin
] @variable.member
((field_id) @variable.member
(#set! "priority" 105))

View file

@ -86,7 +86,7 @@
; Constants
(strength_value) @constant
(bool) @constant.boolean
(bool) @boolean
(flag) @constant

View file

@ -61,5 +61,5 @@
(let_declaration
"let"
.
(identifier) @local.definition.variable
(identifier) @local.definition.var
","?)

View file

@ -28,7 +28,7 @@
(mold) @string.special.symbol
(specialIndex) @number.builtin
(specialIndex) @number
(lark) @operator

View file

@ -118,7 +118,7 @@
identifier: (id) @variable.parameter)
(bind
(id) @variable.local)
(id) @variable)
(bind
function: (id) @function)

View file

@ -41,16 +41,16 @@
; General environments
(begin
command: _ @markup.environment
command: _ @module
name:
(curly_group_text
(text) @markup.environment.name))
(text) @label))
(end
command: _ @markup.environment
command: _ @module
name:
(curly_group_text
(text) @markup.environment.name))
(text) @label))
; Definitions and references
(new_command_definition
@ -77,7 +77,7 @@
command: _ @function.macro
name:
(curly_group_text
(_) @markup.environment.name))
(_) @label))
(paired_delimiter_definition
command: _ @function.macro
@ -260,8 +260,8 @@
(begin
name:
(curly_group_text
(text) @markup.environment.name)
(#any-of? @markup.environment.name "frame"))
(text) @label)
(#any-of? @label "frame"))
.
(curly_group
(_) @markup.heading))

View file

@ -63,7 +63,7 @@
"LENGTH"
"len"
"l"
] @variable.member.builtin
] @variable.member
; Constants
((symbol) @constant

View file

@ -1,34 +1,34 @@
;From MDeiml/tree-sitter-markdown & Helix
(setext_heading
(paragraph) @markup.heading.1
(setext_h1_underline) @markup.heading.1.marker)
(setext_h1_underline) @markup.heading.1)
(setext_heading
(paragraph) @markup.heading.2
(setext_h2_underline) @markup.heading.2.marker)
(setext_h2_underline) @markup.heading.2)
(atx_heading
(atx_h1_marker) @markup.heading.1.marker
(atx_h1_marker) @markup.heading.1
(inline) @markup.heading.1)
(atx_heading
(atx_h2_marker) @markup.heading.2.marker
(atx_h2_marker) @markup.heading.2
(inline) @markup.heading.2)
(atx_heading
(atx_h3_marker) @markup.heading.3.marker
(atx_h3_marker) @markup.heading.3
(inline) @markup.heading.3)
(atx_heading
(atx_h4_marker) @markup.heading.4.marker
(atx_h4_marker) @markup.heading.4
(inline) @markup.heading.4)
(atx_heading
(atx_h5_marker) @markup.heading.5.marker
(atx_h5_marker) @markup.heading.5
(inline) @markup.heading.5)
(atx_heading
(atx_h6_marker) @markup.heading.6.marker
(atx_h6_marker) @markup.heading.6
(inline) @markup.heading.6)
(info_string) @label
@ -54,12 +54,12 @@
(#set! "priority" 90))
(fenced_code_block
(fenced_code_block_delimiter) @markup.raw.delimiter
(fenced_code_block_delimiter) @markup.raw.block
(#set! conceal ""))
(fenced_code_block
(info_string
(language) @conceal
(language) @label
(#set! conceal "")))
(link_destination) @markup.link.url

View file

@ -16,10 +16,10 @@
] @string.escape
; Conceal codeblock and text style markers
((code_span_delimiter) @markup.raw.delimiter
(#set! conceal ""))
((emphasis_delimiter) @conceal
([
(code_span_delimiter)
(emphasis_delimiter)
] @conceal
(#set! conceal ""))
; Conceal inline links

View file

@ -174,12 +174,12 @@
"__unsafe_unretained"
"__unused"
"__weak"
]) @function.macro.builtin
]) @function.macro
[
"__real"
"__imag"
] @function.macro.builtin
] @function.macro
((call_expression
function: (identifier) @function.macro)

View file

@ -65,7 +65,7 @@
(yadayada) @keyword.exception
(phaser_statement
phase: _ @keyword.phaser)
phase: _ @keyword)
[
"or"
@ -207,50 +207,50 @@
; highlights punc vars and also numeric only like $11
(#lua-match? @variable.builtin "^%A+$"))
(scalar) @variable.scalar
(scalar) @variable
(scalar_deref_expression
[
"$"
"*"
] @variable.scalar)
] @variable)
[
(array)
(arraylen)
] @variable.array
] @variable
(array_deref_expression
[
"@"
"*"
] @variable.array)
] @variable)
(hash) @variable.hash
(hash) @variable
(hash_deref_expression
[
"%"
"*"
] @variable.hash)
] @variable)
(array_element_expression
array: (_) @variable.array)
array: (_) @variable)
(slice_expression
array: (_) @variable.array)
array: (_) @variable)
(keyval_expression
array: (_) @variable.array)
array: (_) @variable)
(hash_element_expression
hash: (_) @variable.hash)
hash: (_) @variable)
(slice_expression
hash: (_) @variable.hash)
hash: (_) @variable)
(keyval_expression
hash: (_) @variable.hash)
hash: (_) @variable)
(comment) @comment

View file

@ -80,7 +80,7 @@
(const_name
(constant) @constant)
(global_name) @variable.global
(global_name) @variable
; Standard Arguments
(parameter

View file

@ -41,15 +41,7 @@
(body
(arguments) @injection.language
(content) @injection.content))
(#any-of? @_type "code" "code-block" "sourcecode"))
((directive
name: (type) @_type
body:
(body
(arguments) @injection.language
(content) @injection.content))
(#eq? @_type "raw"))
(#any-of? @_type "raw" "code" "code-block" "sourcecode"))
((directive
name: (type) @_type
@ -59,7 +51,6 @@
(#set! injection.language "latex")
(#eq? @_type "math"))
; TODO: re-add when a parser for csv is added.
((directive
name: (type) @_type
body:

View file

@ -1,7 +1,8 @@
; Variables
(identifier) @variable
(global_variable) @variable.global
[
(identifier)
(global_variable)
] @variable
; Keywords
[

View file

@ -288,7 +288,7 @@
[
"'"
(identifier)
] @keyword.storage.lifetime)
] @keyword.storage)
"fn" @keyword.function

View file

@ -16,7 +16,7 @@
(argument) @local.definition.var
(callback
name: (_) @local.definition.member)
name: (_) @local.definition.field)
(component_definition
name: (_) @local.definition.type)

View file

@ -82,9 +82,10 @@
(string_literal) @string
(date) @variable.readonly
(date_time) @variable.readonly
[
(date)
(date_time)
] @string.special
[
"TRUE"

View file

@ -64,15 +64,16 @@
] @type.qualifier
; Variables
(identifier) @variable
[
(identifier)
(global_variable)
] @variable
(local_declaration
(identifier) @variable.local
(identifier) @variable
.
"=")
(global_variable) @variable.global
((identifier) @variable.builtin
(#any-of? @variable.builtin "base" "this" "vargv"))

View file

@ -67,9 +67,9 @@
(var_statement
"var"
.
(identifier) @local.definition.variable)
(identifier) @local.definition.var)
(local_declaration
(identifier) @local.definition.variable
(identifier) @local.definition.var
.
"=")

View file

@ -16,9 +16,10 @@
(syscall) @function.builtin
; Literals
(integer) @number
(pointer) @number.special
[
(integer)
(pointer)
] @number
(value) @label

View file

@ -1,7 +1,8 @@
(grammar) @local.scope
(definition) @local.definition
(label_name) @local.definition.label
[
(definition)
(label_name)
] @local.definition
(identifier) @local.reference

View file

@ -7,11 +7,11 @@
(column_heading) @markup.heading.4
(column_heading
"~" @markup.heading.4.marker
"~" @markup.heading.4
(#set! conceal ""))
(tag
"*" @markup.heading.5.marker
"*" @label
(#set! conceal "")
text: (_) @label)
@ -24,7 +24,7 @@
text: (_) @markup.link)
(codespan
"`" @markup.raw.delimiter
"`" @markup.raw
(#set! conceal "")
text: (_) @markup.raw)
@ -32,14 +32,15 @@
(#set! "priority" 90))
(codeblock
[
">"
(language)
] @markup.raw.delimiter
">" @markup.raw
(#set! conceal ""))
(codeblock
(language) @label
(#set! conceal ""))
(block
"<" @markup.raw.delimiter
"<" @markup.raw
(#set! conceal ""))
(argument) @variable.parameter

View file

@ -51,9 +51,9 @@
(CharData) @none @spell
((CDSect
(CDStart) @markup.environment
(CDStart) @module
(CData) @markup.raw
"]]>" @markup.environment)
"]]>" @module)
(#set! "priority" 105))
; Delimiters & punctuation

View file

@ -1,4 +1,5 @@
#!/usr/bin/env -S nvim -l
vim.opt.rtp:prepend "./"
-- Equivalent to print(), but this will ensure consistent output regardless of
-- operating system.
@ -35,15 +36,6 @@ local function extract_captures()
return captures
end
local function list_any(list, predicate)
for _, v in pairs(list) do
if predicate(v) then
return true
end
end
return false
end
local function do_check()
local timings = {}
local queries = require "nvim-treesitter.query"
@ -72,9 +64,7 @@ local function do_check()
for _, capture in ipairs(query.captures) do
local is_valid = (
vim.startswith(capture, "_") -- Helpers.
or list_any(captures[query_type], function(documented_capture)
return vim.startswith(capture, documented_capture)
end)
or vim.tbl_contains(captures[query_type], capture)
)
if not is_valid then
local error = string.format("(x) Invalid capture @%s in %s for %s.", capture, query_type, lang)

View file

@ -1,8 +1,8 @@
# H1
<!-- <- @markup.heading.1.marker -->
<!-- <- @markup.heading.1 -->
## H2
<!-- <- @markup.heading.2.marker -->
<!-- <- @markup.heading.2 -->
- Item 1
- Item 2