Skip to content

Commit 9a20187

Browse files
committed
Move highlight configuration from protocol into the feature
1 parent afc8cfb commit 9a20187

File tree

8 files changed

+119
-86
lines changed

8 files changed

+119
-86
lines changed

crates/ide/src/lib.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub use crate::{
9898
static_index::{StaticIndex, StaticIndexedFile, TokenId, TokenStaticData},
9999
syntax_highlighting::{
100100
tags::{Highlight, HlMod, HlMods, HlOperator, HlPunct, HlTag},
101-
HlRange,
101+
HighlightConfig, HlRange,
102102
},
103103
};
104104
pub use hir::{Documentation, Semantics};
@@ -517,8 +517,12 @@ impl Analysis {
517517
}
518518

519519
/// Computes syntax highlighting for the given file
520-
pub fn highlight(&self, file_id: FileId) -> Cancellable<Vec<HlRange>> {
521-
self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false))
520+
pub fn highlight(
521+
&self,
522+
highlight_config: HighlightConfig,
523+
file_id: FileId,
524+
) -> Cancellable<Vec<HlRange>> {
525+
self.with_db(|db| syntax_highlighting::highlight(db, highlight_config, file_id, None))
522526
}
523527

524528
/// Computes all ranges to highlight for a given item in a file.
@@ -533,9 +537,13 @@ impl Analysis {
533537
}
534538

535539
/// Computes syntax highlighting for the given file range.
536-
pub fn highlight_range(&self, frange: FileRange) -> Cancellable<Vec<HlRange>> {
540+
pub fn highlight_range(
541+
&self,
542+
highlight_config: HighlightConfig,
543+
frange: FileRange,
544+
) -> Cancellable<Vec<HlRange>> {
537545
self.with_db(|db| {
538-
syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false)
546+
syntax_highlighting::highlight(db, highlight_config, frange.file_id, Some(frange.range))
539547
})
540548
}
541549

crates/ide/src/syntax_highlighting.rs

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod html;
1414
mod tests;
1515

1616
use hir::{Name, Semantics};
17-
use ide_db::{FxHashMap, RootDatabase};
17+
use ide_db::{FxHashMap, RootDatabase, SymbolKind};
1818
use syntax::{
1919
ast, AstNode, AstToken, NodeOrToken, SyntaxKind::*, SyntaxNode, TextRange, WalkEvent, T,
2020
};
@@ -24,7 +24,7 @@ use crate::{
2424
escape::highlight_escape_string, format::highlight_format_string, highlights::Highlights,
2525
macro_::MacroHighlighter, tags::Highlight,
2626
},
27-
FileId, HlMod, HlTag,
27+
FileId, HlMod, HlOperator, HlPunct, HlTag,
2828
};
2929

3030
pub(crate) use html::highlight_as_html;
@@ -36,6 +36,16 @@ pub struct HlRange {
3636
pub binding_hash: Option<u64>,
3737
}
3838

39+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
40+
pub struct HighlightConfig {
41+
pub strings: bool,
42+
pub punctuation: bool,
43+
pub specialize_punctuation: bool,
44+
pub specialize_operator: bool,
45+
pub operator: bool,
46+
pub syntactic_name_ref_highlighting: bool,
47+
}
48+
3949
// Feature: Semantic Syntax Highlighting
4050
//
4151
// rust-analyzer highlights the code semantically.
@@ -155,9 +165,9 @@ pub struct HlRange {
155165
// image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[]
156166
pub(crate) fn highlight(
157167
db: &RootDatabase,
168+
config: HighlightConfig,
158169
file_id: FileId,
159170
range_to_highlight: Option<TextRange>,
160-
syntactic_name_ref_highlighting: bool,
161171
) -> Vec<HlRange> {
162172
let _p = profile::span("highlight");
163173
let sema = Semantics::new(db);
@@ -183,26 +193,18 @@ pub(crate) fn highlight(
183193
Some(it) => it.krate(),
184194
None => return hl.to_vec(),
185195
};
186-
traverse(
187-
&mut hl,
188-
&sema,
189-
file_id,
190-
&root,
191-
krate,
192-
range_to_highlight,
193-
syntactic_name_ref_highlighting,
194-
);
196+
traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
195197
hl.to_vec()
196198
}
197199

198200
fn traverse(
199201
hl: &mut Highlights,
200202
sema: &Semantics<'_, RootDatabase>,
203+
config: HighlightConfig,
201204
file_id: FileId,
202205
root: &SyntaxNode,
203206
krate: hir::Crate,
204207
range_to_highlight: TextRange,
205-
syntactic_name_ref_highlighting: bool,
206208
) {
207209
let is_unlinked = sema.to_module_def(file_id).is_none();
208210
let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default();
@@ -325,7 +327,7 @@ fn traverse(
325327
Leave(NodeOrToken::Node(node)) => {
326328
// Doc comment highlighting injection, we do this when leaving the node
327329
// so that we overwrite the highlighting of the doc comment itself.
328-
inject::doc_comment(hl, sema, file_id, &node);
330+
inject::doc_comment(hl, sema, config, file_id, &node);
329331
continue;
330332
}
331333
};
@@ -400,7 +402,8 @@ fn traverse(
400402
let string_to_highlight = ast::String::cast(descended_token.clone());
401403
if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
402404
if string.is_raw() {
403-
if inject::ra_fixture(hl, sema, &string, &expanded_string).is_some() {
405+
if inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
406+
{
404407
continue;
405408
}
406409
}
@@ -421,7 +424,7 @@ fn traverse(
421424
sema,
422425
krate,
423426
&mut bindings_shadow_count,
424-
syntactic_name_ref_highlighting,
427+
config.syntactic_name_ref_highlighting,
425428
name_like,
426429
),
427430
NodeOrToken::Token(token) => highlight::token(sema, token).zip(Some(None)),
@@ -439,6 +442,27 @@ fn traverse(
439442
// something unresolvable. FIXME: There should be a way to prevent that
440443
continue;
441444
}
445+
446+
// apply config filtering
447+
match &mut highlight.tag {
448+
HlTag::StringLiteral if !config.strings => continue,
449+
// If punctuation is disabled, make the macro bang part of the macro call again.
450+
tag @ HlTag::Punctuation(HlPunct::MacroBang)
451+
if !config.punctuation || !config.specialize_punctuation =>
452+
{
453+
*tag = HlTag::Symbol(SymbolKind::Macro);
454+
}
455+
HlTag::Punctuation(_) if !config.punctuation => continue,
456+
tag @ HlTag::Punctuation(_) if !config.specialize_punctuation => {
457+
*tag = HlTag::Punctuation(HlPunct::Other);
458+
}
459+
HlTag::Operator(_) if !config.operator && highlight.mods.is_empty() => continue,
460+
tag @ HlTag::Operator(_) if !config.specialize_operator => {
461+
*tag = HlTag::Operator(HlOperator::Other);
462+
}
463+
_ => (),
464+
}
465+
442466
if inside_attribute {
443467
highlight |= HlMod::Attribute
444468
}

crates/ide/src/syntax_highlighting/html.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use oorandom::Rand32;
55
use stdx::format_to;
66
use syntax::AstNode;
77

8-
use crate::{syntax_highlighting::highlight, FileId, RootDatabase};
8+
use crate::{
9+
syntax_highlighting::{highlight, HighlightConfig},
10+
FileId, RootDatabase,
11+
};
912

1013
pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
1114
let parse = db.parse(file_id);
@@ -20,7 +23,19 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
2023
)
2124
}
2225

23-
let hl_ranges = highlight(db, file_id, None, false);
26+
let hl_ranges = highlight(
27+
db,
28+
HighlightConfig {
29+
strings: true,
30+
punctuation: true,
31+
specialize_punctuation: true,
32+
specialize_operator: true,
33+
operator: true,
34+
syntactic_name_ref_highlighting: false,
35+
},
36+
file_id,
37+
None,
38+
);
2439
let text = parse.tree().syntax().to_string();
2540
let mut buf = String::new();
2641
buf.push_str(STYLE);

crates/ide/src/syntax_highlighting/inject.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ use syntax::{
1515

1616
use crate::{
1717
doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def},
18-
syntax_highlighting::{highlights::Highlights, injector::Injector},
18+
syntax_highlighting::{highlights::Highlights, injector::Injector, HighlightConfig},
1919
Analysis, HlMod, HlRange, HlTag, RootDatabase,
2020
};
2121

2222
pub(super) fn ra_fixture(
2323
hl: &mut Highlights,
2424
sema: &Semantics<'_, RootDatabase>,
25+
config: HighlightConfig,
2526
literal: &ast::String,
2627
expanded: &ast::String,
2728
) -> Option<()> {
@@ -63,7 +64,13 @@ pub(super) fn ra_fixture(
6364

6465
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
6566

66-
for mut hl_range in analysis.highlight(tmp_file_id).unwrap() {
67+
for mut hl_range in analysis
68+
.highlight(
69+
HighlightConfig { syntactic_name_ref_highlighting: false, ..config },
70+
tmp_file_id,
71+
)
72+
.unwrap()
73+
{
6774
for range in inj.map_range_up(hl_range.range) {
6875
if let Some(range) = literal.map_range_up(range) {
6976
hl_range.range = range;
@@ -86,6 +93,7 @@ const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
8693
pub(super) fn doc_comment(
8794
hl: &mut Highlights,
8895
sema: &Semantics<'_, RootDatabase>,
96+
config: HighlightConfig,
8997
src_file_id: FileId,
9098
node: &SyntaxNode,
9199
) {
@@ -206,7 +214,14 @@ pub(super) fn doc_comment(
206214

207215
let (analysis, tmp_file_id) = Analysis::from_single_file(inj.take_text());
208216

209-
if let Ok(ranges) = analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)) {
217+
if let Ok(ranges) = analysis.with_db(|db| {
218+
super::highlight(
219+
db,
220+
HighlightConfig { syntactic_name_ref_highlighting: true, ..config },
221+
tmp_file_id,
222+
None,
223+
)
224+
}) {
210225
for HlRange { range, highlight, binding_hash } in ranges {
211226
for range in inj.map_range_up(range) {
212227
hl.add(HlRange { range, highlight: highlight | HlMod::Injected, binding_hash });

crates/ide/src/syntax_highlighting/tests.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ use expect_test::{expect_file, ExpectFile};
44
use ide_db::SymbolKind;
55
use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear};
66

7-
use crate::{fixture, FileRange, HlTag, TextRange};
7+
use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange};
8+
9+
const HL_CONFIG: HighlightConfig = HighlightConfig {
10+
strings: true,
11+
punctuation: true,
12+
specialize_punctuation: true,
13+
specialize_operator: true,
14+
operator: true,
15+
syntactic_name_ref_highlighting: false,
16+
};
817

918
#[test]
1019
fn attributes() {
@@ -996,7 +1005,10 @@ struct Foo {
9961005

9971006
// The "x"
9981007
let highlights = &analysis
999-
.highlight_range(FileRange { file_id, range: TextRange::at(45.into(), 1.into()) })
1008+
.highlight_range(
1009+
HL_CONFIG,
1010+
FileRange { file_id, range: TextRange::at(45.into(), 1.into()) },
1011+
)
10001012
.unwrap();
10011013

10021014
assert_eq!(&highlights[0].highlight.to_string(), "field.declaration.public");
@@ -1011,7 +1023,7 @@ macro_rules! test {}
10111023
}"#
10121024
.trim(),
10131025
);
1014-
let _ = analysis.highlight(file_id).unwrap();
1026+
let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
10151027
}
10161028

10171029
/// Highlights the code given by the `ra_fixture` argument, renders the
@@ -1035,7 +1047,7 @@ fn benchmark_syntax_highlighting_long_struct() {
10351047
let hash = {
10361048
let _pt = bench("syntax highlighting long struct");
10371049
analysis
1038-
.highlight(file_id)
1050+
.highlight(HL_CONFIG, file_id)
10391051
.unwrap()
10401052
.iter()
10411053
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1061,7 +1073,7 @@ fn syntax_highlighting_not_quadratic() {
10611073
let time = Instant::now();
10621074

10631075
let hash = analysis
1064-
.highlight(file_id)
1076+
.highlight(HL_CONFIG, file_id)
10651077
.unwrap()
10661078
.iter()
10671079
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
@@ -1086,7 +1098,7 @@ fn benchmark_syntax_highlighting_parser() {
10861098
let hash = {
10871099
let _pt = bench("syntax highlighting parser");
10881100
analysis
1089-
.highlight(file_id)
1101+
.highlight(HL_CONFIG, file_id)
10901102
.unwrap()
10911103
.iter()
10921104
.filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))

crates/rust-analyzer/src/config.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use std::{ffi::OsString, fmt, iter, path::PathBuf};
1212
use flycheck::FlycheckConfig;
1313
use ide::{
1414
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
15-
HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig,
16-
Snippet, SnippetScope,
15+
HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayHintsConfig,
16+
JoinLinesConfig, Snippet, SnippetScope,
1717
};
1818
use ide_db::{
1919
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -543,15 +543,6 @@ impl HoverActionsConfig {
543543
}
544544
}
545545

546-
#[derive(Clone, Debug, PartialEq, Eq)]
547-
pub struct HighlightingConfig {
548-
pub strings: bool,
549-
pub punctuation: bool,
550-
pub specialize_punctuation: bool,
551-
pub specialize_operator: bool,
552-
pub operator: bool,
553-
}
554-
555546
#[derive(Debug, Clone)]
556547
pub struct FilesConfig {
557548
pub watcher: FilesWatcher,
@@ -1200,15 +1191,16 @@ impl Config {
12001191
}
12011192
}
12021193

1203-
pub fn highlighting_config(&self) -> HighlightingConfig {
1204-
HighlightingConfig {
1194+
pub fn highlighting_config(&self) -> HighlightConfig {
1195+
HighlightConfig {
12051196
strings: self.data.semanticHighlighting_strings_enable,
12061197
punctuation: self.data.semanticHighlighting_punctuation_enable,
12071198
specialize_punctuation: self
12081199
.data
12091200
.semanticHighlighting_punctuation_specialization_enable,
12101201
operator: self.data.semanticHighlighting_operator_enable,
12111202
specialize_operator: self.data.semanticHighlighting_operator_specialization_enable,
1203+
syntactic_name_ref_highlighting: false,
12121204
}
12131205
}
12141206

0 commit comments

Comments
 (0)