Merge #8071
8071: Semantic highlight intradoclinks in documentation r=Veykril a=Veykril Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
bba474bb52
@ -65,6 +65,8 @@ pub(crate) fn extract_definitions_from_markdown(
|
||||
) -> Vec<(String, Option<hir::Namespace>, Range<usize>)> {
|
||||
let mut res = vec![];
|
||||
let mut cb = |link: BrokenLink| {
|
||||
// These allocations are actually unnecessary but the lifetimes on BrokenLinkCallback are wrong
|
||||
// this is fixed in the repo but not on the crates.io release yet
|
||||
Some((
|
||||
/*url*/ link.reference.to_owned().into(),
|
||||
/*title*/ link.reference.to_owned().into(),
|
||||
@ -72,13 +74,10 @@ pub(crate) fn extract_definitions_from_markdown(
|
||||
};
|
||||
let doc = Parser::new_with_broken_link_callback(markdown, Options::empty(), Some(&mut cb));
|
||||
for (event, range) in doc.into_offset_iter() {
|
||||
match event {
|
||||
Event::Start(Tag::Link(_link_type, ref target, ref title)) => {
|
||||
let link = if target.is_empty() { title } else { target };
|
||||
let (link, ns) = parse_link(link);
|
||||
res.push((link.to_string(), ns, range));
|
||||
}
|
||||
_ => {}
|
||||
if let Event::Start(Tag::Link(_, target, title)) = event {
|
||||
let link = if target.is_empty() { title } else { target };
|
||||
let (link, ns) = parse_link(&link);
|
||||
res.push((link.to_string(), ns, range));
|
||||
}
|
||||
}
|
||||
res
|
||||
|
@ -59,6 +59,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -1,16 +1,18 @@
|
||||
//! "Recursive" Syntax highlighting for code in doctests and fixtures.
|
||||
|
||||
use std::mem;
|
||||
use std::{mem, ops::Range};
|
||||
|
||||
use either::Either;
|
||||
use hir::{HasAttrs, Semantics};
|
||||
use ide_db::call_info::ActiveParameter;
|
||||
use ide_db::{call_info::ActiveParameter, defs::Definition};
|
||||
use syntax::{
|
||||
ast::{self, AstNode, AttrsOwner, DocCommentsOwner},
|
||||
match_ast, AstToken, NodeOrToken, SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||
};
|
||||
|
||||
use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase};
|
||||
use crate::{
|
||||
doc_links::extract_definitions_from_markdown, Analysis, HlMod, HlRange, HlTag, RootDatabase,
|
||||
};
|
||||
|
||||
use super::{highlights::Highlights, injector::Injector};
|
||||
|
||||
@ -120,24 +122,24 @@ impl AstNode for AttrsOwnerNode {
|
||||
fn doc_attributes<'node>(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
node: &'node SyntaxNode,
|
||||
) -> Option<(AttrsOwnerNode, hir::Attrs)> {
|
||||
) -> Option<(AttrsOwnerNode, hir::Attrs, Definition)> {
|
||||
match_ast! {
|
||||
match node {
|
||||
ast::SourceFile(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Fn(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Struct(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Union(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::RecordField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::TupleField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Enum(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Variant(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Trait(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Module(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Static(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Const(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::Impl(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::MacroRules(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db))),
|
||||
ast::SourceFile(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
||||
ast::Module(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Module(def)))),
|
||||
ast::Fn(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Function(def)))),
|
||||
ast::Struct(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Struct(def))))),
|
||||
ast::Union(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Union(def))))),
|
||||
ast::Enum(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(def))))),
|
||||
ast::Variant(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Variant(def)))),
|
||||
ast::Trait(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Trait(def)))),
|
||||
ast::Static(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Static(def)))),
|
||||
ast::Const(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::Const(def)))),
|
||||
ast::TypeAlias(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::ModuleDef(hir::ModuleDef::TypeAlias(def)))),
|
||||
ast::Impl(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::SelfType(def))),
|
||||
ast::RecordField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::Field(def))),
|
||||
ast::TupleField(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::Field(def))),
|
||||
ast::MacroRules(it) => sema.to_def(&it).map(|def| (AttrsOwnerNode::new(it), def.attrs(sema.db), Definition::Macro(def))),
|
||||
// ast::MacroDef(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))),
|
||||
// ast::Use(it) => sema.to_def(&it).map(|def| (Box::new(it) as _, def.attrs(sema.db))),
|
||||
_ => return None
|
||||
@ -147,25 +149,23 @@ fn doc_attributes<'node>(
|
||||
|
||||
/// Injection of syntax highlighting of doctests.
|
||||
pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, node: &SyntaxNode) {
|
||||
let (owner, attributes) = match doc_attributes(sema, node) {
|
||||
let (owner, attributes, def) = match doc_attributes(sema, node) {
|
||||
Some(it) => it,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if attributes.docs().map_or(true, |docs| !String::from(docs).contains(RUSTDOC_FENCE)) {
|
||||
return;
|
||||
}
|
||||
let attrs_source_map = attributes.source_map(&owner);
|
||||
|
||||
let mut inj = Injector::default();
|
||||
inj.add_unmapped("fn doctest() {\n");
|
||||
|
||||
let attrs_source_map = attributes.source_map(&owner);
|
||||
|
||||
let mut is_codeblock = false;
|
||||
let mut is_doctest = false;
|
||||
|
||||
// Replace the original, line-spanning comment ranges by new, only comment-prefix
|
||||
// spanning comment ranges.
|
||||
let mut new_comments = Vec::new();
|
||||
let mut intra_doc_links = Vec::new();
|
||||
let mut string;
|
||||
for attr in attributes.by_key("doc").attrs() {
|
||||
let src = attrs_source_map.source_of(&attr);
|
||||
@ -209,7 +209,22 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
|
||||
is_doctest = is_codeblock && is_rust;
|
||||
continue;
|
||||
}
|
||||
None if !is_doctest => continue,
|
||||
None if !is_doctest => {
|
||||
intra_doc_links.extend(
|
||||
extract_definitions_from_markdown(line)
|
||||
.into_iter()
|
||||
.filter(|(link, ns, _)| {
|
||||
validate_intra_doc_link(sema.db, &def, link, *ns)
|
||||
})
|
||||
.map(|(.., Range { start, end })| {
|
||||
TextRange::at(
|
||||
prev_range_start + TextSize::from(start as u32),
|
||||
TextSize::from((end - start) as u32),
|
||||
)
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
|
||||
@ -227,17 +242,28 @@ pub(super) fn doc_comment(hl: &mut Highlights, sema: &Semantics<RootDatabase>, n
|
||||
inj.add_unmapped("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for range in intra_doc_links {
|
||||
hl.add(HlRange {
|
||||
range,
|
||||
highlight: HlTag::IntraDocLink | HlMod::Documentation,
|
||||
binding_hash: None,
|
||||
});
|
||||
}
|
||||
|
||||
if new_comments.is_empty() {
|
||||
return; // no need to run an analysis on an empty file
|
||||
}
|
||||
|
||||
inj.add_unmapped("\n}");
|
||||
|
||||
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.text().to_string());
|
||||
|
||||
for h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() {
|
||||
for r in inj.map_range_up(h.range) {
|
||||
hl.add(HlRange {
|
||||
range: r,
|
||||
highlight: h.highlight | HlMod::Injected,
|
||||
binding_hash: h.binding_hash,
|
||||
});
|
||||
for HlRange { range, highlight, binding_hash } in
|
||||
analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap()
|
||||
{
|
||||
for range in inj.map_range_up(range) {
|
||||
hl.add(HlRange { range, highlight: highlight | HlMod::Injected, binding_hash });
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,3 +299,31 @@ fn find_doc_string_in_attr(attr: &hir::Attr, it: &ast::Attr) -> Option<ast::Stri
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_intra_doc_link(
|
||||
db: &RootDatabase,
|
||||
def: &Definition,
|
||||
link: &str,
|
||||
ns: Option<hir::Namespace>,
|
||||
) -> bool {
|
||||
match def {
|
||||
Definition::ModuleDef(def) => match def {
|
||||
hir::ModuleDef::Module(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Function(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Adt(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Variant(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Const(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Static(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::Trait(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, &link, ns),
|
||||
hir::ModuleDef::BuiltinType(_) => None,
|
||||
},
|
||||
Definition::Macro(it) => it.resolve_doc_path(db, &link, ns),
|
||||
Definition::Field(it) => it.resolve_doc_path(db, &link, ns),
|
||||
Definition::SelfType(_)
|
||||
| Definition::Local(_)
|
||||
| Definition::GenericParam(_)
|
||||
| Definition::Label(_) => None,
|
||||
}
|
||||
.is_some()
|
||||
}
|
||||
|
@ -18,19 +18,20 @@ pub struct HlMods(u32);
|
||||
pub enum HlTag {
|
||||
Symbol(SymbolKind),
|
||||
|
||||
Attribute,
|
||||
BoolLiteral,
|
||||
BuiltinType,
|
||||
ByteLiteral,
|
||||
CharLiteral,
|
||||
NumericLiteral,
|
||||
StringLiteral,
|
||||
Attribute,
|
||||
Comment,
|
||||
EscapeSequence,
|
||||
FormatSpecifier,
|
||||
IntraDocLink,
|
||||
Keyword,
|
||||
Punctuation(HlPunct),
|
||||
NumericLiteral,
|
||||
Operator,
|
||||
Punctuation(HlPunct),
|
||||
StringLiteral,
|
||||
UnresolvedReference,
|
||||
|
||||
// For things which don't have a specific highlight.
|
||||
@ -116,6 +117,7 @@ impl HlTag {
|
||||
HlTag::Comment => "comment",
|
||||
HlTag::EscapeSequence => "escape_sequence",
|
||||
HlTag::FormatSpecifier => "format_specifier",
|
||||
HlTag::IntraDocLink => "intra_doc_link",
|
||||
HlTag::Keyword => "keyword",
|
||||
HlTag::Punctuation(punct) => match punct {
|
||||
HlPunct::Bracket => "bracket",
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
@ -98,6 +99,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="comment documentation">/// </span><span class="intra_doc_link documentation">[`Foo`](Foo)</span><span class="comment documentation"> is a struct</span>
|
||||
<span class="comment documentation">/// </span><span class="intra_doc_link documentation">[`all_the_links`](all_the_links)</span><span class="comment documentation"> is this function</span>
|
||||
<span class="comment documentation">/// [`noop`](noop) is a macro below</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration">all_the_links</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -7,6 +7,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||
.label { color: #DFAF8F; font-style: italic; }
|
||||
.comment { color: #7F9F7F; }
|
||||
.documentation { color: #629755; }
|
||||
.intra_doc_link { color: #A9C577; }
|
||||
.injected { opacity: 0.65 ; }
|
||||
.struct, .enum { color: #7CB8BB; }
|
||||
.enum_variant { color: #BDE0F3; }
|
||||
|
@ -468,7 +468,7 @@ fn main() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_highlight_doctest() {
|
||||
fn test_highlight_doc_comment() {
|
||||
check_highlighting(
|
||||
r#"
|
||||
/// ```
|
||||
@ -533,6 +533,11 @@ impl Foo {
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Foo`](Foo) is a struct
|
||||
/// [`all_the_links`](all_the_links) is this function
|
||||
/// [`noop`](noop) is a macro below
|
||||
pub fn all_the_links() {}
|
||||
|
||||
/// ```
|
||||
/// noop!(1);
|
||||
/// ```
|
||||
|
@ -45,15 +45,16 @@ define_semantic_token_types![
|
||||
(BRACKET, "bracket"),
|
||||
(BUILTIN_TYPE, "builtinType"),
|
||||
(CHAR_LITERAL, "characterLiteral"),
|
||||
(COMMA, "comma"),
|
||||
(COLON, "colon"),
|
||||
(COMMA, "comma"),
|
||||
(CONST_PARAMETER, "constParameter"),
|
||||
(DOT, "dot"),
|
||||
(ESCAPE_SEQUENCE, "escapeSequence"),
|
||||
(FORMAT_SPECIFIER, "formatSpecifier"),
|
||||
(GENERIC, "generic"),
|
||||
(CONST_PARAMETER, "constParameter"),
|
||||
(LIFETIME, "lifetime"),
|
||||
(INTRA_DOC_LINK, "intraDocLink"),
|
||||
(LABEL, "label"),
|
||||
(LIFETIME, "lifetime"),
|
||||
(PARENTHESIS, "parenthesis"),
|
||||
(PUNCTUATION, "punctuation"),
|
||||
(SELF_KEYWORD, "selfKeyword"),
|
||||
|
@ -435,19 +435,20 @@ fn semantic_token_type_and_modifiers(
|
||||
SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
|
||||
SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
|
||||
},
|
||||
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
|
||||
HlTag::None => semantic_tokens::GENERIC,
|
||||
HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
|
||||
HlTag::Attribute => semantic_tokens::ATTRIBUTE,
|
||||
HlTag::BoolLiteral => semantic_tokens::BOOLEAN,
|
||||
HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
|
||||
HlTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
|
||||
HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
|
||||
HlTag::CharLiteral => semantic_tokens::CHAR_LITERAL,
|
||||
HlTag::Comment => lsp_types::SemanticTokenType::COMMENT,
|
||||
HlTag::Attribute => semantic_tokens::ATTRIBUTE,
|
||||
HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
|
||||
HlTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
|
||||
HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
|
||||
HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
|
||||
HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE,
|
||||
HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER,
|
||||
HlTag::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
|
||||
HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
|
||||
HlTag::None => semantic_tokens::GENERIC,
|
||||
HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR,
|
||||
HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
|
||||
HlTag::UnresolvedReference => semantic_tokens::UNRESOLVED_REFERENCE,
|
||||
HlTag::Punctuation(punct) => match punct {
|
||||
HlPunct::Bracket => semantic_tokens::BRACKET,
|
||||
HlPunct::Brace => semantic_tokens::BRACE,
|
||||
|
Loading…
x
Reference in New Issue
Block a user