Merge branch 'master' into master

This commit is contained in:
Chinmay Dalal 2020-08-17 05:34:51 +05:30 committed by GitHub
commit 4235360690
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 278 additions and 114 deletions

View file

@ -75,6 +75,7 @@ effect on highlighting. We will work on improving highlighting in the near futur
@error for error (ERROR` nodes.
@punctuation.delimiter for `;` `.` `,`
@punctuation.bracket for `()` or `{}`
@punctuation.special for symbols with special meaning like `{}` in string interpolation.
```
Some captures are related to language injection (like markdown code blocks). As this is not supported by neovim yet, these
@ -109,6 +110,7 @@ are optional and will not have any effect for now.
builtin
macro
@parameter
reference references to parameters
@method
@field or @property
@ -177,3 +179,30 @@ Mainly for markup languages.
@scope
@reference
```
#### Definition Scope
You can set the scope of a definition by setting the `scope` property on the definition.
For example, a javascript function declaration creates a scope. The function name is captured as the definition.
This means that the function definition would only be available WITHIN the scope of the function, which is not the case.
The definition can be used in the scope the function was defined in.
```javascript
function doSomething() {}
doSomething(); // Should point to the declaration as the definition
```
```scheme
(function_declaration
((identifier) @definition.var)
(set! "definition.var.scope" "parent"))
```
Possible scope values are:
- `parent`: The definition is valid in the containing scope and one more scope above that scope
- `global`: The definition is valid in the root scope
- `local`: The definition is valid in the containing scope. This is the default behavior

View file

@ -358,6 +358,10 @@ Rust.
*hl-TSParameter*
For parameters of a function.
`TSParameterReference`
*hl-TSParameterReference*
For references to parameters of a function.
`TSMethod`
*hl-TSMethod*
For method calls and definitions.
@ -417,7 +421,12 @@ This is left as an exercise for the reader.
`TSInclude`
*hl-TSInclude*
For includes: `#include` in C, `use` or `extern crate` in Rust, or `require`
in Lua
in Lua.
`TSAnnotation`
*hl-TSAnnotation*
For C++/Dart attributes, annotations that can be attached to the code to
denote some kind of meta information.
`TSText`
*hl-TSText*
@ -432,10 +441,11 @@ For text to be represented with strong.
For text to be represented with emphasis.
`TSUnderline`
*hl-TSUnderline*
*hl-TSUnderline*
For text to be represented with an underline.
`TSTitle`
*hl-TSTitle*
Text that is part of a title.
@ -447,4 +457,25 @@ Literal text.
*hl-TSURI*
Any URI like a link or email.
==============================================================================
MODULE-HIGHLIGHTS *nvim-treesitter-module-highlights*
Apart from the general purpose highlights in *nvim-treesitter-highlights* ,
some submodules use their own highlight groups to visualize additional
information.
`TSDefinition`
*hl-TSDefinition*
Used by refactor.highlight_definitions to highlight the definition of the
symbol under the cursor.
`TSDefinitionUsage`
*hl-TSDefinitionUsage*
Used by refactor.highlight_definitions to highlight usages of the symbol under
the cursor.
`TSCurrentScope`
*hl-TSCurrentScope*
Used by refactor.highlight_current_scope to highlight the current scope.
vim:tw=78:ts=8:noet:ft=help:norl:

View file

@ -5,6 +5,9 @@ local info = require'nvim-treesitter.info'
local configs = require'nvim-treesitter.configs'
local parsers = require'nvim-treesitter.parsers'
-- Registers all query predicates
require"nvim-treesitter.query_predicates"
local M = {}
function M.setup()

View file

@ -35,6 +35,7 @@ hlmap["function"] = "TSFunction"
hlmap["function.builtin"] = "TSFuncBuiltin"
hlmap["function.macro"] = "TSFuncMacro"
hlmap["parameter"] = "TSParameter"
hlmap["parameter.reference"] = "TSParameterReference"
hlmap["method"] = "TSMethod"
hlmap["field"] = "TSField"
hlmap["property"] = "TSProperty"

View file

@ -111,8 +111,8 @@ end
function M.get_local_nodes(local_def)
local result = {}
M.recurse_local_nodes(local_def, function(_, node, kind)
table.insert(result, { node = node, kind = kind })
M.recurse_local_nodes(local_def, function(def, node, kind)
table.insert(result, vim.tbl_extend("keep", { kind = kind }, def))
end)
return result
@ -161,7 +161,9 @@ M.get_definitions_lookup_table = ts_utils.memoize_by_buf_tick(function(bufnr)
for _, definition in ipairs(definitions) do
for _, node_entry in ipairs(M.get_local_nodes(definition)) do
local scope = M.containing_scope(node_entry.node, bufnr, false) or parsers.get_tree_root(bufnr)
local scopes = M.get_definition_scopes(node_entry.node, bufnr, node_entry.scope)
-- Always use the highest valid scope
local scope = scopes[#scopes]
local node_text = ts_utils.get_node_text(node_entry.node, bufnr)[1]
local id = M.get_definition_id(scope, node_text)
@ -172,6 +174,40 @@ M.get_definitions_lookup_table = ts_utils.memoize_by_buf_tick(function(bufnr)
return result
end)
--- Gets all the scopes of a definition based on the scope type
-- Scope types can be
--
-- "parent": Uses the parent of the containing scope, basically, skipping a scope
-- "global": Uses the top most scope
-- "local": Uses the containg scope of the definition. This is the default
--
-- @param node: the definition node
-- @param bufnr: the buffer
-- @param scope_type: the scope type
function M.get_definition_scopes(node, bufnr, scope_type)
local scopes = {}
local scope_count = 1
-- Definition is valid for the containing scope
-- and the containing scope of that scope
if scope_type == 'parent' then
scope_count = 2
-- Definition is valid in all parent scopes
elseif scope_type == 'global' then
scope_count = nil
end
local i = 0
for scope in M.iter_scope_tree(node, bufnr) do
table.insert(scopes, scope)
i = i + 1
if scope_count and i >= scope_count then break end
end
return scopes
end
function M.find_definition(node, bufnr)
local def_lookup = M.get_definitions_lookup_table(bufnr)
local node_text = ts_utils.get_node_text(node, bufnr)[1]

View file

@ -4,12 +4,25 @@ local function error(str)
vim.api.nvim_err_writeln(str)
end
query.add_predicate("nth?", function(match, pattern, bufnr, pred)
if #pred ~= 3 then
error("nth? must hav exactly two arguments")
return
local function valid_args(name, pred, count, strict_count)
local arg_count = #pred - 1
if strict_count then
if arg_count ~= count then
error(string.format("%s must have exactly %d arguments", name, count))
return false
end
elseif arg_count < count then
error(string.format("%s must have at least %d arguments", name, count))
return false
end
return true
end
query.add_predicate("nth?", function(match, pattern, bufnr, pred)
if not valid_args("nth?", pred, 2, true) then return end
local node = match[pred[2]]
local n = pred[3] - 1
if node and node:parent() and node:named_child_count() > n then
@ -20,7 +33,7 @@ query.add_predicate("nth?", function(match, pattern, bufnr, pred)
end)
query.add_predicate('has-ancestor?', function(match, pattern, bufnr, pred)
if #pred ~= 3 then error("has-ancestor? must have exactly two arguments!") return end
if not valid_args("has-ancestor?", pred, 2, true) then return end
local node = match[pred[2]]
local ancestor_type = pred[3]
@ -35,3 +48,18 @@ query.add_predicate('has-ancestor?', function(match, pattern, bufnr, pred)
end
return false
end)
query.add_predicate('is?', function(match, pattern, bufnr, pred)
if not valid_args("is?", pred, 2) then return end
-- Avoid circular dependencies
local locals = require"nvim-treesitter.locals"
local node = match[pred[2]]
local types = {unpack(pred, 3)}
if not node then return true end
local _, _, kind = locals.find_definition(node, bufnr)
return vim.tbl_contains(types, kind)
end)

View file

@ -43,6 +43,7 @@ highlight default link TSFunction Function
highlight default link TSFuncBuiltin Special
highlight default link TSFuncMacro Macro
highlight default link TSParameter Identifier
highlight default link TSParameterReference TSParameter
highlight default link TSMethod Function
highlight default link TSField Identifier
highlight default link TSProperty Identifier

View file

@ -26,7 +26,7 @@
] @operator
[
(string)
(string)
(raw_string)
(heredoc_body)
] @string
@ -58,18 +58,18 @@
] @keyword
[
(special_variable_name)
(special_variable_name)
("$" (special_variable_name))
] @constant
((word) @constant
(#match? @constant "SIG(INT|TERM|QUIT|TIN|TOU|STP|HUP)"))
(#vim-match? @constant "SIG(INT|TERM|QUIT|TIN|TOU|STP|HUP)"))
((word) @boolean
(#match? @boolean "true|false"))
(#vim-match? @boolean "true|false"))
((word) @number
(#match? @number "^\d*$"))
(#vim-match? @number "^\d*$"))
(comment) @comment
(test_operator) @string.
@ -83,11 +83,11 @@
(command_name (word)) @function
(command
(command
argument: [
(word) @parameter
((word) @number
(#match? @number "^\d*$"))
(#vim-match? @number "^\d*$"))
(concatenation (word) @parameter)
])
@ -98,12 +98,12 @@
("$" (variable_name)) @identifier
(expansion
(expansion
[ "${" "}" ] @punctuation.bracket)
(variable_name) @identifier
(case_item
(case_item
value: (word) @parameter)
(concatenation (word) @parameter)

View file

@ -1,4 +1,4 @@
[
[
"const"
"default"
"enum"
@ -131,8 +131,10 @@
(comment) @comment
;; Parameters
(parameter_list
(parameter_declaration) @parameter)
(parameter_declaration
declarator: (identifier) @parameter)
((identifier) @parameter.reference
(#is? @parameter.reference parameter))
(preproc_params
(identifier)) @parameter

View file

@ -9,7 +9,7 @@
(pointer_declarator
declarator: (identifier) @definition.var)
(parameter_declaration
declarator: (identifier) @definition.var)
declarator: (identifier) @definition.parameter)
(init_declarator
declarator: (identifier) @definition.var)
(array_declarator

View file

@ -8,7 +8,12 @@
(#match? @field "_$"))
; function(Foo ...foo)
(variadic_parameter_declaration) @parameter
(variadic_parameter_declaration
declarator: (variadic_declarator
(identifier) @parameter))
; int foo = 0
(optional_parameter_declaration
declarator: (identifier) @parameter)
;(field_expression) @parameter ;; How to highlight this?
(template_function
@ -42,20 +47,20 @@
(#match? @constructor "^[A-Z]"))
(call_expression
function: (scoped_identifier
function: (scoped_identifier
name: (identifier) @function))
(call_expression
function: (field_expression
function: (field_expression
field: (field_identifier) @function))
((call_expression
function: (scoped_identifier
function: (scoped_identifier
name: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
((call_expression
function: (field_expression
function: (field_expression
field: (field_identifier) @constructor))
(#match? @constructor "^[A-Z]"))

View file

@ -1,3 +1,9 @@
;; Parameters
(variadic_parameter_declaration
declarator: (variadic_declarator
(identifier) @definition.parameter))
(optional_parameter_declaration
declarator: (identifier) @definition.parameter)
;; Class / struct defintions
(class_specifier) @scope
@ -10,14 +16,14 @@
(identifier) @definition.var)
(struct_specifier
name: (type_identifier) @definition.type)
name: (type_identifier) @definition.type)
(struct_specifier
name: (scoped_type_identifier
name: (type_identifier) @definition.type))
(class_specifier
name: (type_identifier) @definition.type)
name: (type_identifier) @definition.type)
(class_specifier
name: (scoped_type_identifier
@ -32,7 +38,7 @@
(template_declaration) @scope
;; Namespaces
(namespace_definition
(namespace_definition
name: (identifier) @definition.namespace
body: (_) @scope)

View file

@ -33,7 +33,7 @@
"|="
"~="
"$="
"*="
"*="
"and"
"or"
"not"

View file

@ -194,7 +194,7 @@
; when used as an identifier:
((identifier) @variable.builtin
(#match? @variable.builtin "^(abstract|as|covariant|deferred|dynamic|export|external|factory|Function|get|implements|import|interface|library|operator|mixin|part|set|static|typedef)$"))
(#vim-match? @variable.builtin "^(abstract|as|covariant|deferred|dynamic|export|external|factory|Function|get|implements|import|interface|library|operator|mixin|part|set|static|typedef)$"))
["if" "else" "switch" "default"] @conditional

View file

@ -1,4 +1,4 @@
;; Forked from tree-sitter-go
;; Forked from tree-sitter-go
;; Copyright (c) 2014 Max Brunsfeld (The MIT License)
;;
@ -12,10 +12,10 @@
(variadic_parameter_declaration (identifier) @parameter)
((identifier) @constant
(#eq? @constant "_"))
(#eq? @constant "_"))
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]+$"))
(#vim-match? @constant "^[A-Z][A-Z\\d_]+$"))
; Function calls

View file

@ -62,7 +62,7 @@
; Variables
((identifier) @constant
(#match? @constant "^_*[A-Z][A-Z\d_]+"))
(#vim-match? @constant "^_*[A-Z][A-Z\d_]+"))
(this) @constant.builtin
@ -221,4 +221,4 @@
">>>"
"<<"
"::"
] @operator
] @operator

View file

@ -1,24 +1,38 @@
; Types
; Javascript
; Properties
;-----------
(property_identifier) @property
; Special identifiers
;--------------------
(identifier) @variable
((identifier) @constant
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
(#vim-match? @constant "^[A-Z_][A-Z\\d_]+$"))
((shorthand_property_identifier) @constant
(#match? @constant "^[A-Z_][A-Z\\d_]+$"))
(#vim-match? @constant "^[A-Z_][A-Z\\d_]+$"))
((identifier) @constructor
(#match? @constructor "^[A-Z]"))
((identifier) @variable.builtin
(#match? @variable.builtin "^(arguments|module|console|window|document)$"))
(#not-is? @variable.builtin import var parameter)
(#vim-match? @variable.builtin "^(arguments|module|console|window|document)$"))
((identifier) @function.builtin
(#not-is? @function.builtin import var parameter)
(#eq? @function.builtin "require"))
((identifier) @parameter.reference
(#is? @parameter.reference parameter))
; Function and method definitions
;--------------------------------
@ -78,13 +92,6 @@
(rest_parameter
(identifier) @parameter))
(identifier) @variable
; Properties
;-----------
(property_identifier) @property
; Literals
;---------

View file

@ -14,28 +14,28 @@
;------------
(formal_parameters
(identifier) @definition.var)
(identifier) @definition.parameter)
(formal_parameters
(object_pattern
(identifier) @definition.var))
(identifier) @definition.parameter))
; function(arg = []) {
(formal_parameters
(assignment_pattern
(shorthand_property_identifier) @definition.var))
(shorthand_property_identifier) @definition.parameter))
(formal_parameters
(object_pattern
(shorthand_property_identifier) @definition.var))
(shorthand_property_identifier) @definition.parameter))
(formal_parameters
(array_pattern
(identifier) @definition.var))
(identifier) @definition.parameter))
(formal_parameters
(rest_parameter
(identifier) @definition.var))
(identifier) @definition.parameter))
(variable_declarator
name: (identifier) @definition.var)
@ -43,6 +43,10 @@
(import_specifier
(identifier) @definition.import)
(function_declaration
((identifier) @definition.var)
(#set! definition.var.scope parent))
; References
;------------

View file

@ -93,5 +93,8 @@
(number) @number
(label_statement) @label
((identifier) @parameter.reference
(#is? @parameter.reference parameter))
;; Error
(ERROR) @error

View file

@ -8,7 +8,7 @@
(field_expression object:(*) @definition.associated (property_identifier) @definition.var)))
;; Parameters
(parameters (identifier) @definition.var)
(parameters (identifier) @definition.parameter)
;; Loops
((loop_expression

View file

@ -42,7 +42,7 @@
(relative_scope) @variable.builtin
((name) @constant
(#match? @constant "^_?[A-Z][A-Z\d_]+$"))
(#vim-match? @constant "^_?[A-Z][A-Z\d_]+$"))
((name) @constructor
(#match? @constructor "^[A-Z]"))

View file

@ -4,24 +4,24 @@
; Reset highlighing in f-string interpolations
(interpolation) @Normal
; Identifier naming conventions
;; Identifier naming conventions
((identifier) @type
(match? @type "^[A-Z]"))
(#match? @type "^[A-Z]"))
((identifier) @constant
(match? @constant "^[A-Z][A-Z_0-9]*$"))
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
((identifier) @constant.builtin
(match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
(#match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
((attribute
attribute: (identifier) @field)
(match? @field "^([A-Z])@!.*$"))
(#match? @field "^([A-Z])@!.*$"))
; Function calls
(decorator) @function
((decorator (dotted_name (identifier) @function))
(match? @function "^([A-Z])@!.*$"))
(#match? @function "^([A-Z])@!.*$"))
(call
function: (identifier) @function)
@ -32,18 +32,18 @@
((call
function: (identifier) @constructor)
(match? @constructor "^[A-Z]"))
(#match? @constructor "^[A-Z]"))
((call
function: (attribute
attribute: (identifier) @constructor))
(match? @constructor "^[A-Z]"))
(#match? @constructor "^[A-Z]"))
;; Builtin functions
((call
function: (identifier) @function.builtin)
(match?
(vim-match?
@function.builtin
"^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
@ -52,19 +52,6 @@
(function_definition
name: (identifier) @function)
((function_definition
name: (identifier) @method
parameters: (parameters
(identifier) @self) )
(eq? @self "self"))
((function_definition
name: (identifier) @constructor
parameters: (parameters
(identifier) @self) )
(eq? @self "self")
(match? @constructor "(__new__|__init__)"))
(type (identifier) @type)
(type
(subscript
@ -73,13 +60,15 @@
((call
function: (identifier) @isinstance
arguments: (argument_list
(*)
(_)
(identifier) @type))
(eq? @isinstance "isinstance"))
(#eq? @isinstance "isinstance"))
; Normal parameters
(parameters
(identifier) @parameter)
((identifier) @parameter.reference
(#is? @parameter.reference parameter))
; Lambda parameters
(lambda_parameters
(identifier) @parameter)
@ -110,7 +99,7 @@
(none) @constant.builtin
[(true) (false)] @boolean
((identifier) @constant.builtin
(match? @constant.builtin "self"))
(#match? @constant.builtin "self"))
(integer) @number
(float) @float
@ -183,27 +172,31 @@
"yield"
] @keyword
[ "as" "from" "import"] @include
["as" "from" "import"] @include
[ "if" "elif" "else" ] @conditional
["if" "elif" "else"] @conditional
[ "for" "while" "break" "continue" ] @repeat
["for" "while" "break" "continue"] @repeat
[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket
["(" ")" "[" "]" "{" "}"] @punctuation.bracket
(interpolation
"{" @punctuation.special
"}" @punctuation.special) @embedded
[ "," "." ":" (ellipsis) ] @punctuation.delimiter
["," "." ":" (ellipsis)] @punctuation.delimiter
; Class definitions
;; Class definitions
(class_definition
name: (identifier) @type)
name: (identifier) @type
body: (block
(function_definition
name: (identifier) @method)))
(class_definition
superclasses: (argument_list
(identifier) @type))
(identifier) @type))
((class_definition
body: (block
@ -211,7 +204,20 @@
(assignment
left: (expression_list
(identifier) @field)))))
(match? @field "^([A-Z])@!.*$"))
(#match? @field "^([A-Z])@!.*$"))
((class_definition
(block
(function_definition
name: (identifier) @constructor)))
(#vim-match? @constructor "^(__new__|__init__)$"))
; First parameter of a method is self or cls.
((class_definition
body: (block
(function_definition
parameters: (parameters . (identifier) @constant.builtin))))
(#vim-match? @constant.builtin "^(self|obj|cls)$"))
;; Error
(ERROR) @error

View file

@ -10,24 +10,24 @@
; Imports
(aliased_import
alias: (identifier) @definition.import)
alias: (identifier) @definition.import)
(import_statement
name: (dotted_name ((identifier) @definition.import)))
name: (dotted_name ((identifier) @definition.import)))
(import_from_statement
name: (dotted_name ((identifier) @definition.import)))
name: (dotted_name ((identifier) @definition.import)))
; Function with parameters, defines parameters
(parameters
(identifier) @definition.var)
(identifier) @definition.parameter)
(default_parameter
(identifier) @definition.var)
(identifier) @definition.parameter)
(typed_parameter
(identifier) @definition.var)
(identifier) @definition.parameter)
(typed_default_parameter
(identifier) @definition.var)
(identifier) @definition.parameter)
(with_statement
(with_item
@ -36,32 +36,34 @@
; *args parameter
(parameters
(list_splat
(identifier) @definition.var))
(identifier) @definition.parameter))
; **kwargs parameter
(parameters
(dictionary_splat
(identifier) @definition.var))
(identifier) @definition.parameter))
; Function defines function and scope
(function_definition
((function_definition
name: (identifier) @definition.function
body: (block (expression_statement (string) @definition.doc)?)) @scope
(#set! definition.function.scope "parent"))
((class_definition
name: (identifier) @definition.type) @scope
(#set! definition.type.scope "parent"))
(class_definition
name: (identifier) @definition.type) @scope
(class_definition
body: (block
(function_definition
name: (identifier) @definition.method)))
name: (identifier) @definition.method)))
;;; Loops
; not a scope!
(for_statement
left: (variables
(identifier) @definition.var))
(identifier) @definition.var))
; not a scope!
;(while_statement) @scope
@ -79,7 +81,7 @@
(assignment
left: (expression_list
(identifier) @definition.var))
(identifier) @definition.var))
(assignment
left: (expression_list

View file

@ -23,7 +23,7 @@
((directive
name: (type) @function.builtin)
(#match?
(#vim-match?
@function.builtin
; https://docutils.sourceforge.io/docs/ref/rst/directives.html
"^(attention|caution|danger|error|hint|important|note|tip|warning|admonition)|(image|figure)|(topic|sidebar|line-block|parsed-literal|code|math|rubric|epigraph|highlights|pull-quote|compound|container)|(table|csv-table|list-table)|(contents|sectnum|section-numbering|header|footer)|(target-notes)|(meta)|(replace|unicode|date)|(raw|class|role|default-role|title|restructuredtext-test-directive)::$"))
@ -73,7 +73,7 @@
(role) @function
((role) @function.builtin
(#match?
(#vim-match?
@function.builtin
; https://docutils.sourceforge.io/docs/ref/rst/roles.html
"^:(emphasis|literal|code|math|pep-reference|PEP|rfc-reference|RFC|strong|subscript|sub|superscript|sup|title-reference|title|t|raw):$"))

View file

@ -38,7 +38,7 @@
((identifier) @keyword
(#match? @keyword "^(private|protected|public)$"))
(#vim-match? @keyword "^(private|protected|public)$"))
; Function calls
@ -85,14 +85,14 @@
; Identifiers
[
(class_variable)
(instance_variable)
(instance_variable)
] @label
((identifier) @constant.builtin
(#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
(#vim-match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
((constant) @constant.macro
(#match? @constant.macro "^[A-Z\\d_]+$"))
(#vim-match? @constant.macro "^[A-Z\\d_]+$"))
(constant) @constant
@ -175,7 +175,7 @@
"{"
"}"
"%w("
"%i("
"%i("
] @punctuation.bracket
(ERROR) @error

View file

@ -6,7 +6,7 @@
; Assume all-caps names are constants
((identifier) @constant
(#match? @constant "^[A-Z][A-Z\\d_]+$'"))
(#vim-match? @constant "^[A-Z][A-Z\\d_]+$'"))
; Other identifiers