mirror of
https://github.com/helix-editor/tree-house.git
synced 2025-10-06 00:12:46 +02:00
highlighter: Use layer end as the highlight end while deactivating
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,3 +1,5 @@
|
||||
# See <https://github.com/github-linguist/linguist/blob/main/docs/overrides.md>
|
||||
test-grammars/*/*.scm linguist-vendored
|
||||
test-grammars/*/src/** linguist-vendored
|
||||
test-grammars/*/src/{parser.c,grammar.json,scanner.*} binary
|
||||
fixtures/** -linguist-detectable
|
||||
|
12
fixtures/highlighter/html_in_edoc_in_erlang.erl
Normal file
12
fixtures/highlighter/html_in_edoc_in_erlang.erl
Normal file
@@ -0,0 +1,12 @@
|
||||
%% <li>foo
|
||||
// ┡━┛╿┡┛╿┗━┹─ comment
|
||||
// │ ││ ╰─ comment punctuation.bracket
|
||||
// │ │╰─ comment tag
|
||||
// │ ╰─ comment punctuation.bracket
|
||||
// ╰─ comment
|
||||
%% bar</li>
|
||||
// ┡━━━━┛┡┛┡┛╿╰─ comment
|
||||
// │ │ │ ╰─ comment punctuation.bracket
|
||||
// │ │ ╰─ comment tag
|
||||
// │ ╰─ comment punctuation.bracket
|
||||
// ╰─ comment
|
8
fixtures/injections/html_in_edoc_in_erlang.erl
Normal file
8
fixtures/injections/html_in_edoc_in_erlang.erl
Normal file
@@ -0,0 +1,8 @@
|
||||
%% <li>foo
|
||||
// ╿┡━━┛┗━┹─ edoc
|
||||
// │╰─ edoc html
|
||||
// ╰─ edoc
|
||||
%% bar</li>
|
||||
// ┡━━┛┡━━━┛╰─ edoc
|
||||
// │ ╰─ edoc html
|
||||
// ╰─ edoc
|
@@ -396,7 +396,9 @@ pub fn injections_fixture(
|
||||
line_end = src
|
||||
.try_line_to_byte(line_idx + 1)
|
||||
.unwrap_or(src.len_bytes()) as u32;
|
||||
line_labels.is_empty();
|
||||
if line_start == line_end {
|
||||
break;
|
||||
}
|
||||
if pos > line_start && !injection_stack.is_empty() {
|
||||
line_labels.push((line_start..pos.min(line_end), Vec::new()))
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ use std::sync::Arc;
|
||||
use crate::config::{LanguageConfig, LanguageLoader};
|
||||
use crate::locals::ScopeCursor;
|
||||
use crate::query_iter::{MatchedNode, QueryIter, QueryIterEvent, QueryLoader};
|
||||
use crate::{Language, Layer, Syntax};
|
||||
use crate::{Injection, Language, Layer, Syntax};
|
||||
use arc_swap::ArcSwap;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use ropey::RopeSlice;
|
||||
@@ -258,7 +258,7 @@ impl<'a, 'tree: 'a, Loader: LanguageLoader> Highlighter<'a, 'tree, Loader> {
|
||||
// state is returned if the layer is finished, if it isn't we have
|
||||
// a combined injection and need to deactivate its highlights
|
||||
if state.is_none() {
|
||||
self.deactivate_layer(injection.layer);
|
||||
self.deactivate_layer(injection);
|
||||
refresh = true;
|
||||
} else {
|
||||
self.layer_states.remove(&injection.layer);
|
||||
@@ -319,15 +319,15 @@ impl<'a, 'tree: 'a, Loader: LanguageLoader> Highlighter<'a, 'tree, Loader> {
|
||||
self.active_highlights.append(&mut state.dormant_highlights);
|
||||
}
|
||||
|
||||
fn deactivate_layer(&mut self, layer: Layer) {
|
||||
fn deactivate_layer(&mut self, injection: Injection) {
|
||||
let LayerData {
|
||||
mut parent_highlights,
|
||||
ref mut dormant_highlights,
|
||||
..
|
||||
} = self.layer_states.get_mut(&layer).unwrap();
|
||||
} = self.layer_states.get_mut(&injection.layer).unwrap();
|
||||
parent_highlights = parent_highlights.min(self.active_highlights.len());
|
||||
dormant_highlights.extend(self.active_highlights.drain(parent_highlights..));
|
||||
self.process_highlight_end(self.next_highlight_start);
|
||||
self.process_highlight_end(injection.range.end);
|
||||
}
|
||||
|
||||
fn start_highlight(&mut self, node: MatchedNode, first_highlight: &mut bool) {
|
||||
|
@@ -193,6 +193,7 @@ fn lang_for_path(path: &Path, loader: &TestLanguageLoader) -> Language {
|
||||
{
|
||||
"rs" => loader.get("rust"),
|
||||
"html" => loader.get("html"),
|
||||
"erl" => loader.get("erlang"),
|
||||
extension => unreachable!("unknown file type .{extension}"),
|
||||
}
|
||||
}
|
||||
@@ -253,6 +254,16 @@ fn parameters_within_injections_within_injections() {
|
||||
injection_fixture(&loader, "injections/injectionception.rs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn html_in_edoc_in_erlang() {
|
||||
let loader = TestLanguageLoader::new();
|
||||
// This fixture exhibited a bug (which has been fixed) where a combined injection became
|
||||
// dormant at the same time as a new highlight started, causing a total reset of all
|
||||
// highlights (incorrectly).
|
||||
highlight_fixture(&loader, "highlighter/html_in_edoc_in_erlang.erl");
|
||||
injection_fixture(&loader, "injections/html_in_edoc_in_erlang.erl");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_local_pattern() {
|
||||
let mut loader = TestLanguageLoader::new();
|
||||
|
21
test-grammars/edoc/LICENSE
Normal file
21
test-grammars/edoc/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Michael Davis
|
||||
|
||||
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.
|
52
test-grammars/edoc/highlights.scm
vendored
Normal file
52
test-grammars/edoc/highlights.scm
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
((section
|
||||
(section_marker) @markup.heading.marker
|
||||
(section_content) @markup.heading.1
|
||||
(section_marker) @markup.heading.marker)
|
||||
(#eq? @markup.heading.marker "=="))
|
||||
|
||||
((section
|
||||
(section_marker) @markup.heading.marker
|
||||
(section_content) @markup.heading.2
|
||||
(section_marker) @markup.heading.marker)
|
||||
(#eq? @markup.heading.marker "==="))
|
||||
|
||||
((section
|
||||
(section_marker) @markup.heading.marker
|
||||
(section_content) @markup.heading.3
|
||||
(section_marker) @markup.heading.marker)
|
||||
(#eq? @markup.heading.marker "===="))
|
||||
|
||||
(tag) @keyword
|
||||
(macro (tag) @function.macro)
|
||||
(macro_escape) @constant.character.escape
|
||||
(inline_quote) @markup.raw.inline
|
||||
(email_address) @markup.link.url
|
||||
|
||||
(em_xhtml_tag
|
||||
(open_xhtml_tag) @tag
|
||||
(xhtml_tag_content) @markup.italic
|
||||
(close_xhtml_tag) @tag)
|
||||
|
||||
(strong_xhtml_tag
|
||||
(open_xhtml_tag) @tag
|
||||
(xhtml_tag_content) @markup.bold
|
||||
(close_xhtml_tag) @tag)
|
||||
|
||||
(module) @namespace
|
||||
(function) @function
|
||||
(type) @type
|
||||
|
||||
; could be @constant.numeric.integer but this looks similar to a capture
|
||||
(arity) @operator
|
||||
|
||||
(expression [":" "/"] @operator)
|
||||
(expression ["(" ")"] @punctuation.delimiter)
|
||||
(macro ["{" "}"] @function.macro)
|
||||
|
||||
[
|
||||
(quote_marker)
|
||||
(language_identifier)
|
||||
(quote_content)
|
||||
] @markup.raw.block
|
||||
|
||||
(parameter) @variable.parameter
|
20
test-grammars/edoc/injections.scm
vendored
Normal file
20
test-grammars/edoc/injections.scm
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
((xhtml_tag) @injection.content
|
||||
(#set! injection.combined)
|
||||
(#set! injection.include-children)
|
||||
(#set! injection.language "html"))
|
||||
|
||||
((block_quote
|
||||
!language
|
||||
(quote_content) @injection.content)
|
||||
(#set! injection.language "erlang"))
|
||||
|
||||
(block_quote
|
||||
language: (language_identifier) @injection.language
|
||||
(quote_content) @injection.content)
|
||||
|
||||
((macro
|
||||
(tag) @_tag
|
||||
(argument) @injection.content)
|
||||
(#eq? @_tag "@type")
|
||||
(#set! injection.language "erlang")
|
||||
(#set! injection.include-children))
|
6
test-grammars/edoc/metadata.json
Normal file
6
test-grammars/edoc/metadata.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"repo": "https://github.com/the-mikedavis/tree-sitter-edoc",
|
||||
"rev": "74774af7b45dd9cefbf9510328fc6ff2374afc50",
|
||||
"license": "MIT",
|
||||
"compressed": true
|
||||
}
|
BIN
test-grammars/edoc/src/grammar.json
vendored
Normal file
BIN
test-grammars/edoc/src/grammar.json
vendored
Normal file
Binary file not shown.
BIN
test-grammars/edoc/src/parser.c
vendored
Normal file
BIN
test-grammars/edoc/src/parser.c
vendored
Normal file
Binary file not shown.
224
test-grammars/edoc/src/tree_sitter/parser.h
vendored
Normal file
224
test-grammars/edoc/src/tree_sitter/parser.h
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
#ifndef TREE_SITTER_PARSER_H_
|
||||
#define TREE_SITTER_PARSER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
TSFieldId field_id;
|
||||
uint8_t child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
typedef struct {
|
||||
bool visible;
|
||||
bool named;
|
||||
bool supertype;
|
||||
} TSSymbolMetadata;
|
||||
|
||||
typedef struct TSLexer TSLexer;
|
||||
|
||||
struct TSLexer {
|
||||
int32_t lookahead;
|
||||
TSSymbol result_symbol;
|
||||
void (*advance)(TSLexer *, bool);
|
||||
void (*mark_end)(TSLexer *);
|
||||
uint32_t (*get_column)(TSLexer *);
|
||||
bool (*is_at_included_range_start)(const TSLexer *);
|
||||
bool (*eof)(const TSLexer *);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TSParseActionTypeShift,
|
||||
TSParseActionTypeReduce,
|
||||
TSParseActionTypeAccept,
|
||||
TSParseActionTypeRecover,
|
||||
} TSParseActionType;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t type;
|
||||
TSStateId state;
|
||||
bool extra;
|
||||
bool repetition;
|
||||
} shift;
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint8_t child_count;
|
||||
TSSymbol symbol;
|
||||
int16_t dynamic_precedence;
|
||||
uint16_t production_id;
|
||||
} reduce;
|
||||
uint8_t type;
|
||||
} TSParseAction;
|
||||
|
||||
typedef struct {
|
||||
uint16_t lex_state;
|
||||
uint16_t external_lex_state;
|
||||
} TSLexMode;
|
||||
|
||||
typedef union {
|
||||
TSParseAction action;
|
||||
struct {
|
||||
uint8_t count;
|
||||
bool reusable;
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
struct TSLanguage {
|
||||
uint32_t version;
|
||||
uint32_t symbol_count;
|
||||
uint32_t alias_count;
|
||||
uint32_t token_count;
|
||||
uint32_t external_token_count;
|
||||
uint32_t state_count;
|
||||
uint32_t large_state_count;
|
||||
uint32_t production_id_count;
|
||||
uint32_t field_count;
|
||||
uint16_t max_alias_sequence_length;
|
||||
const uint16_t *parse_table;
|
||||
const uint16_t *small_parse_table;
|
||||
const uint32_t *small_parse_table_map;
|
||||
const TSParseActionEntry *parse_actions;
|
||||
const char * const *symbol_names;
|
||||
const char * const *field_names;
|
||||
const TSFieldMapSlice *field_map_slices;
|
||||
const TSFieldMapEntry *field_map_entries;
|
||||
const TSSymbolMetadata *symbol_metadata;
|
||||
const TSSymbol *public_symbol_map;
|
||||
const uint16_t *alias_map;
|
||||
const TSSymbol *alias_sequences;
|
||||
const TSLexMode *lex_modes;
|
||||
bool (*lex_fn)(TSLexer *, TSStateId);
|
||||
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
|
||||
TSSymbol keyword_capture_token;
|
||||
struct {
|
||||
const bool *states;
|
||||
const TSSymbol *symbol_map;
|
||||
void *(*create)(void);
|
||||
void (*destroy)(void *);
|
||||
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
|
||||
unsigned (*serialize)(void *, char *);
|
||||
void (*deserialize)(void *, const char *, unsigned);
|
||||
} external_scanner;
|
||||
const TSStateId *primary_state_ids;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lexer Macros
|
||||
*/
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
bool eof = false; \
|
||||
int32_t lookahead; \
|
||||
goto start; \
|
||||
next_state: \
|
||||
lexer->advance(lexer, skip); \
|
||||
start: \
|
||||
skip = false; \
|
||||
lookahead = lexer->lookahead;
|
||||
|
||||
#define ADVANCE(state_value) \
|
||||
{ \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define SKIP(state_value) \
|
||||
{ \
|
||||
skip = true; \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define ACCEPT_TOKEN(symbol_value) \
|
||||
result = true; \
|
||||
lexer->result_symbol = symbol_value; \
|
||||
lexer->mark_end(lexer);
|
||||
|
||||
#define END_STATE() return result;
|
||||
|
||||
/*
|
||||
* Parse Table Macros
|
||||
*/
|
||||
|
||||
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
|
||||
|
||||
#define STATE(id) id
|
||||
|
||||
#define ACTIONS(id) id
|
||||
|
||||
#define SHIFT(state_value) \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = state_value \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define SHIFT_REPEAT(state_value) \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = state_value, \
|
||||
.repetition = true \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define SHIFT_EXTRA() \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.extra = true \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define REDUCE(symbol_val, child_count_val, ...) \
|
||||
{{ \
|
||||
.reduce = { \
|
||||
.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_val, \
|
||||
.child_count = child_count_val, \
|
||||
__VA_ARGS__ \
|
||||
}, \
|
||||
}}
|
||||
|
||||
#define RECOVER() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeRecover \
|
||||
}}
|
||||
|
||||
#define ACCEPT_INPUT() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeAccept \
|
||||
}}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_PARSER_H_
|
176
test-grammars/erlang/LICENSE
Normal file
176
test-grammars/erlang/LICENSE
Normal file
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
166
test-grammars/erlang/highlights.scm
vendored
Normal file
166
test-grammars/erlang/highlights.scm
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
; Comments
|
||||
(tripledot) @comment.discard
|
||||
|
||||
[(comment) (line_comment) (shebang)] @comment
|
||||
|
||||
; Basic types
|
||||
(variable) @variable
|
||||
(atom) @string.special.symbol
|
||||
((atom) @constant.builtin.boolean
|
||||
(#match? @constant.builtin.boolean "^(true|false)$"))
|
||||
[(string) (sigil)] @string
|
||||
(character) @constant.character
|
||||
(escape_sequence) @constant.character.escape
|
||||
|
||||
(integer) @constant.numeric.integer
|
||||
(float) @constant.numeric.float
|
||||
|
||||
; Punctuation
|
||||
["," "." "-" ";"] @punctuation.delimiter
|
||||
["(" ")" "#" "{" "}" "[" "]" "<<" ">>"] @punctuation.bracket
|
||||
|
||||
; Operators
|
||||
(binary_operator operator: _ @operator)
|
||||
(unary_operator operator: _ @operator)
|
||||
["/" ":" "->"] @operator
|
||||
|
||||
(binary_operator
|
||||
left: (atom) @function
|
||||
operator: "/"
|
||||
right: (integer) @constant.numeric.integer)
|
||||
|
||||
((binary_operator operator: _ @keyword.operator)
|
||||
(#match? @keyword.operator "^\\w+$"))
|
||||
((unary_operator operator: _ @keyword.operator)
|
||||
(#match? @keyword.operator "^\\w+$"))
|
||||
|
||||
|
||||
; Keywords
|
||||
(attribute name: (atom) @keyword)
|
||||
|
||||
["case" "fun" "if" "of" "when" "end" "receive" "try" "catch" "after" "begin" "maybe"] @keyword
|
||||
|
||||
; Attributes
|
||||
; module declaration
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments (atom) @namespace)
|
||||
(#any-of? @keyword "module" "behaviour" "behavior"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
.
|
||||
(atom) @namespace)
|
||||
(#eq? @keyword "import"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
.
|
||||
[(atom) @type (macro)]
|
||||
[
|
||||
(tuple (atom)? @variable.other.member)
|
||||
(tuple
|
||||
(binary_operator
|
||||
left: (atom) @variable.other.member
|
||||
operator: ["=" "::"]))
|
||||
(tuple
|
||||
(binary_operator
|
||||
left:
|
||||
(binary_operator
|
||||
left: (atom) @variable.other.member
|
||||
operator: "=")
|
||||
operator: "::"))
|
||||
])
|
||||
(#eq? @keyword "record"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
.
|
||||
[
|
||||
(atom) @constant
|
||||
(variable) @constant
|
||||
(call
|
||||
function:
|
||||
[(variable) (atom)] @keyword.directive)
|
||||
])
|
||||
(#eq? @keyword "define"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
(_) @keyword.directive)
|
||||
(#any-of? @keyword "ifndef" "ifdef"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
module: (atom) @namespace
|
||||
(#any-of? @keyword "spec" "callback"))
|
||||
|
||||
(attribute
|
||||
name: (atom) @keyword
|
||||
(arguments [
|
||||
(string)
|
||||
(sigil)
|
||||
] @comment.block.documentation)
|
||||
(#any-of? @keyword "doc" "moduledoc"))
|
||||
|
||||
; Functions
|
||||
(function_clause name: (atom) @function)
|
||||
(call module: (atom) @namespace)
|
||||
(call function: (atom) @function)
|
||||
(stab_clause name: (atom) @function)
|
||||
(function_capture module: (atom) @namespace)
|
||||
(function_capture function: (atom) @function)
|
||||
|
||||
; Ignored variables
|
||||
((variable) @comment.discard
|
||||
(#match? @comment.discard "^_"))
|
||||
|
||||
; Macros
|
||||
(macro
|
||||
"?"+ @constant
|
||||
name: (_) @constant
|
||||
!arguments)
|
||||
|
||||
(macro
|
||||
"?"+ @keyword.directive
|
||||
name: (_) @keyword.directive)
|
||||
|
||||
; Parameters
|
||||
; specs
|
||||
((attribute
|
||||
name: (atom) @keyword
|
||||
(stab_clause
|
||||
pattern: (arguments (variable)? @variable.parameter)
|
||||
body: (variable)? @variable.parameter))
|
||||
(#match? @keyword "(spec|callback)"))
|
||||
; functions
|
||||
(function_clause pattern: (arguments (variable) @variable.parameter))
|
||||
; anonymous functions
|
||||
(stab_clause pattern: (arguments (variable) @variable.parameter))
|
||||
; parametric types
|
||||
((attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
(binary_operator
|
||||
left: (call (arguments (variable) @variable.parameter))
|
||||
operator: "::")))
|
||||
(#match? @keyword "(type|opaque)"))
|
||||
; macros
|
||||
((attribute
|
||||
name: (atom) @keyword
|
||||
(arguments
|
||||
(call (arguments (variable) @variable.parameter))))
|
||||
(#eq? @keyword "define"))
|
||||
|
||||
; Records
|
||||
(record_content
|
||||
(binary_operator
|
||||
left: (atom) @variable.other.member
|
||||
operator: "="))
|
||||
|
||||
(record field: (atom) @variable.other.member)
|
||||
(record name: (atom) @type)
|
17
test-grammars/erlang/injections.scm
vendored
Normal file
17
test-grammars/erlang/injections.scm
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
((line_comment (comment_content) @injection.content)
|
||||
(#set! injection.language "edoc")
|
||||
(#set! injection.include-children)
|
||||
(#set! injection.combined))
|
||||
|
||||
((comment (comment_content) @injection.content)
|
||||
(#set! injection.language "comment"))
|
||||
|
||||
; EEP-59 doc attributes use markdown by default.
|
||||
(attribute
|
||||
name: (atom) @_attribute
|
||||
(arguments [
|
||||
(string (quoted_content) @injection.content)
|
||||
(sigil (quoted_content) @injection.content)
|
||||
])
|
||||
(#set! injection.language "markdown")
|
||||
(#any-of? @_attribute "doc" "moduledoc"))
|
23
test-grammars/erlang/locals.scm
vendored
Normal file
23
test-grammars/erlang/locals.scm
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
; Specs and Callbacks
|
||||
(attribute
|
||||
(stab_clause
|
||||
pattern: (arguments (variable)? @local.definition.variable.parameter)
|
||||
; If a spec uses a variable as the return type (and later a `when` clause to type it):
|
||||
body: (variable)? @local.definition.variable.parameter)) @local.scope
|
||||
|
||||
; parametric `-type`s
|
||||
((attribute
|
||||
name: (atom) @_type
|
||||
(arguments
|
||||
(binary_operator
|
||||
left: (call (arguments (variable) @local.definition.variable.parameter))
|
||||
operator: "::") @local.scope))
|
||||
(#match? @_type "(type|opaque)"))
|
||||
|
||||
; `fun`s
|
||||
(anonymous_function (stab_clause pattern: (arguments (variable) @local.definition.variable.parameter))) @local.scope
|
||||
|
||||
; Ordinary functions
|
||||
(function_clause pattern: (arguments (variable) @local.definition.variable.parameter)) @local.scope
|
||||
|
||||
(variable) @local.reference
|
6
test-grammars/erlang/metadata.json
Normal file
6
test-grammars/erlang/metadata.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"repo": "https://github.com/the-mikedavis/tree-sitter-erlang",
|
||||
"rev": "33a3e4f1fa77a3e1a2736813f4b27c358f6c0b63",
|
||||
"license": "Apache-2.0",
|
||||
"compressed": true
|
||||
}
|
BIN
test-grammars/erlang/src/grammar.json
vendored
Normal file
BIN
test-grammars/erlang/src/grammar.json
vendored
Normal file
Binary file not shown.
BIN
test-grammars/erlang/src/parser.c
vendored
Normal file
BIN
test-grammars/erlang/src/parser.c
vendored
Normal file
Binary file not shown.
224
test-grammars/erlang/src/tree_sitter/parser.h
vendored
Normal file
224
test-grammars/erlang/src/tree_sitter/parser.h
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
#ifndef TREE_SITTER_PARSER_H_
|
||||
#define TREE_SITTER_PARSER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
typedef uint16_t TSStateId;
|
||||
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
TSFieldId field_id;
|
||||
uint8_t child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct {
|
||||
uint16_t index;
|
||||
uint16_t length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
typedef struct {
|
||||
bool visible;
|
||||
bool named;
|
||||
bool supertype;
|
||||
} TSSymbolMetadata;
|
||||
|
||||
typedef struct TSLexer TSLexer;
|
||||
|
||||
struct TSLexer {
|
||||
int32_t lookahead;
|
||||
TSSymbol result_symbol;
|
||||
void (*advance)(TSLexer *, bool);
|
||||
void (*mark_end)(TSLexer *);
|
||||
uint32_t (*get_column)(TSLexer *);
|
||||
bool (*is_at_included_range_start)(const TSLexer *);
|
||||
bool (*eof)(const TSLexer *);
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TSParseActionTypeShift,
|
||||
TSParseActionTypeReduce,
|
||||
TSParseActionTypeAccept,
|
||||
TSParseActionTypeRecover,
|
||||
} TSParseActionType;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t type;
|
||||
TSStateId state;
|
||||
bool extra;
|
||||
bool repetition;
|
||||
} shift;
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint8_t child_count;
|
||||
TSSymbol symbol;
|
||||
int16_t dynamic_precedence;
|
||||
uint16_t production_id;
|
||||
} reduce;
|
||||
uint8_t type;
|
||||
} TSParseAction;
|
||||
|
||||
typedef struct {
|
||||
uint16_t lex_state;
|
||||
uint16_t external_lex_state;
|
||||
} TSLexMode;
|
||||
|
||||
typedef union {
|
||||
TSParseAction action;
|
||||
struct {
|
||||
uint8_t count;
|
||||
bool reusable;
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
struct TSLanguage {
|
||||
uint32_t version;
|
||||
uint32_t symbol_count;
|
||||
uint32_t alias_count;
|
||||
uint32_t token_count;
|
||||
uint32_t external_token_count;
|
||||
uint32_t state_count;
|
||||
uint32_t large_state_count;
|
||||
uint32_t production_id_count;
|
||||
uint32_t field_count;
|
||||
uint16_t max_alias_sequence_length;
|
||||
const uint16_t *parse_table;
|
||||
const uint16_t *small_parse_table;
|
||||
const uint32_t *small_parse_table_map;
|
||||
const TSParseActionEntry *parse_actions;
|
||||
const char * const *symbol_names;
|
||||
const char * const *field_names;
|
||||
const TSFieldMapSlice *field_map_slices;
|
||||
const TSFieldMapEntry *field_map_entries;
|
||||
const TSSymbolMetadata *symbol_metadata;
|
||||
const TSSymbol *public_symbol_map;
|
||||
const uint16_t *alias_map;
|
||||
const TSSymbol *alias_sequences;
|
||||
const TSLexMode *lex_modes;
|
||||
bool (*lex_fn)(TSLexer *, TSStateId);
|
||||
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
|
||||
TSSymbol keyword_capture_token;
|
||||
struct {
|
||||
const bool *states;
|
||||
const TSSymbol *symbol_map;
|
||||
void *(*create)(void);
|
||||
void (*destroy)(void *);
|
||||
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
|
||||
unsigned (*serialize)(void *, char *);
|
||||
void (*deserialize)(void *, const char *, unsigned);
|
||||
} external_scanner;
|
||||
const TSStateId *primary_state_ids;
|
||||
};
|
||||
|
||||
/*
|
||||
* Lexer Macros
|
||||
*/
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
bool eof = false; \
|
||||
int32_t lookahead; \
|
||||
goto start; \
|
||||
next_state: \
|
||||
lexer->advance(lexer, skip); \
|
||||
start: \
|
||||
skip = false; \
|
||||
lookahead = lexer->lookahead;
|
||||
|
||||
#define ADVANCE(state_value) \
|
||||
{ \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define SKIP(state_value) \
|
||||
{ \
|
||||
skip = true; \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define ACCEPT_TOKEN(symbol_value) \
|
||||
result = true; \
|
||||
lexer->result_symbol = symbol_value; \
|
||||
lexer->mark_end(lexer);
|
||||
|
||||
#define END_STATE() return result;
|
||||
|
||||
/*
|
||||
* Parse Table Macros
|
||||
*/
|
||||
|
||||
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
|
||||
|
||||
#define STATE(id) id
|
||||
|
||||
#define ACTIONS(id) id
|
||||
|
||||
#define SHIFT(state_value) \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = state_value \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define SHIFT_REPEAT(state_value) \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.state = state_value, \
|
||||
.repetition = true \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define SHIFT_EXTRA() \
|
||||
{{ \
|
||||
.shift = { \
|
||||
.type = TSParseActionTypeShift, \
|
||||
.extra = true \
|
||||
} \
|
||||
}}
|
||||
|
||||
#define REDUCE(symbol_val, child_count_val, ...) \
|
||||
{{ \
|
||||
.reduce = { \
|
||||
.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_val, \
|
||||
.child_count = child_count_val, \
|
||||
__VA_ARGS__ \
|
||||
}, \
|
||||
}}
|
||||
|
||||
#define RECOVER() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeRecover \
|
||||
}}
|
||||
|
||||
#define ACCEPT_INPUT() \
|
||||
{{ \
|
||||
.type = TSParseActionTypeAccept \
|
||||
}}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TREE_SITTER_PARSER_H_
|
16
test-grammars/erlang/textobjects.scm
vendored
Normal file
16
test-grammars/erlang/textobjects.scm
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
(function_clause
|
||||
pattern: (arguments (_)? @parameter.inside)
|
||||
body: (_) @function.inside) @function.around
|
||||
|
||||
(anonymous_function
|
||||
(stab_clause body: (_) @function.inside)) @function.around
|
||||
|
||||
(comment (comment_content) @comment.inside) @comment.around
|
||||
|
||||
; EUnit test names.
|
||||
; (CommonTest cases are not recognizable by syntax alone.)
|
||||
((function_clause
|
||||
name: (atom) @_name
|
||||
pattern: (arguments (_)? @parameter.inside)
|
||||
body: (_) @test.inside) @test.around
|
||||
(#match? @_name "_test$"))
|
Reference in New Issue
Block a user