Skip to content

Commit 4107106

Browse files
bors[bot]kdelorey
andauthored
Merge #9678
9678: Add Configuration for Highlight Related Feature r=kdelorey a=kdelorey # Summary Adds basic configuration that allows you to control when the highlight related feature is activated. You can control this for references, break points, exit points, and yield points. Resolves #9618 ![config](https://user-images.githubusercontent.com/2295721/126728849-a38b560c-b687-42c1-9c41-7584ad718469.gif) Co-authored-by: Kevin DeLorey <[email protected]>
2 parents 1dd1814 + 5b9f173 commit 4107106

File tree

7 files changed

+278
-27
lines changed

7 files changed

+278
-27
lines changed

crates/ide/src/highlight_related.rs

Lines changed: 212 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ pub struct HighlightedRange {
1818
pub access: Option<ReferenceAccess>,
1919
}
2020

21+
#[derive(Default, Clone)]
22+
pub struct HighlightRelatedConfig {
23+
pub references: bool,
24+
pub exit_points: bool,
25+
pub break_points: bool,
26+
pub yield_points: bool,
27+
}
28+
2129
// Feature: Highlight Related
2230
//
2331
// Highlights constructs related to the thing under the cursor:
@@ -27,6 +35,7 @@ pub struct HighlightedRange {
2735
// - if on a `break`, `loop`, `while` or `for` token, highlights all break points for that loop or block context
2836
pub(crate) fn highlight_related(
2937
sema: &Semantics<RootDatabase>,
38+
config: HighlightRelatedConfig,
3039
position: FilePosition,
3140
) -> Option<Vec<HighlightedRange>> {
3241
let _p = profile::span("highlight_related");
@@ -46,10 +55,13 @@ pub(crate) fn highlight_related(
4655
})?;
4756

4857
match token.kind() {
49-
T![return] | T![?] | T![->] => highlight_exit_points(sema, token),
50-
T![await] | T![async] => highlight_yield_points(token),
51-
T![break] | T![loop] | T![for] | T![while] => highlight_break_points(token),
52-
_ => highlight_references(sema, &syntax, position),
58+
T![return] | T![?] | T![->] if config.exit_points => highlight_exit_points(sema, token),
59+
T![await] | T![async] if config.yield_points => highlight_yield_points(token),
60+
T![break] | T![loop] | T![for] | T![while] if config.break_points => {
61+
highlight_break_points(token)
62+
}
63+
_ if config.references => highlight_references(sema, &syntax, position),
64+
_ => None,
5365
}
5466
}
5567

@@ -260,8 +272,20 @@ mod tests {
260272
use super::*;
261273

262274
fn check(ra_fixture: &str) {
275+
let config = HighlightRelatedConfig {
276+
break_points: true,
277+
exit_points: true,
278+
references: true,
279+
yield_points: true,
280+
};
281+
282+
check_with_config(ra_fixture, config);
283+
}
284+
285+
fn check_with_config(ra_fixture: &str, config: HighlightRelatedConfig) {
263286
let (analysis, pos, annotations) = fixture::annotations(ra_fixture);
264-
let hls = analysis.highlight_related(pos).unwrap().unwrap();
287+
288+
let hls = analysis.highlight_related(config, pos).unwrap().unwrap_or(Vec::default());
265289

266290
let mut expected = annotations
267291
.into_iter()
@@ -726,4 +750,187 @@ fn foo() {
726750
"#,
727751
);
728752
}
753+
754+
#[test]
755+
fn test_hl_disabled_ref_local() {
756+
let config = HighlightRelatedConfig {
757+
references: false,
758+
break_points: true,
759+
exit_points: true,
760+
yield_points: true,
761+
};
762+
763+
let ra_fixture = r#"
764+
fn foo() {
765+
let x$0 = 5;
766+
let y = x * 2;
767+
}"#;
768+
769+
check_with_config(ra_fixture, config);
770+
}
771+
772+
#[test]
773+
fn test_hl_disabled_ref_local_preserved_break() {
774+
let config = HighlightRelatedConfig {
775+
references: false,
776+
break_points: true,
777+
exit_points: true,
778+
yield_points: true,
779+
};
780+
781+
let ra_fixture = r#"
782+
fn foo() {
783+
let x$0 = 5;
784+
let y = x * 2;
785+
786+
loop {
787+
break;
788+
}
789+
}"#;
790+
791+
check_with_config(ra_fixture, config.clone());
792+
793+
let ra_fixture = r#"
794+
fn foo() {
795+
let x = 5;
796+
let y = x * 2;
797+
798+
loop$0 {
799+
// ^^^^
800+
break;
801+
// ^^^^^
802+
}
803+
}"#;
804+
805+
check_with_config(ra_fixture, config);
806+
}
807+
808+
#[test]
809+
fn test_hl_disabled_ref_local_preserved_yield() {
810+
let config = HighlightRelatedConfig {
811+
references: false,
812+
break_points: true,
813+
exit_points: true,
814+
yield_points: true,
815+
};
816+
817+
let ra_fixture = r#"
818+
async fn foo() {
819+
let x$0 = 5;
820+
let y = x * 2;
821+
822+
0.await;
823+
}"#;
824+
825+
check_with_config(ra_fixture, config.clone());
826+
827+
let ra_fixture = r#"
828+
async fn foo() {
829+
// ^^^^^
830+
let x = 5;
831+
let y = x * 2;
832+
833+
0.await$0;
834+
// ^^^^^
835+
}"#;
836+
837+
check_with_config(ra_fixture, config);
838+
}
839+
840+
#[test]
841+
fn test_hl_disabled_ref_local_preserved_exit() {
842+
let config = HighlightRelatedConfig {
843+
references: false,
844+
break_points: true,
845+
exit_points: true,
846+
yield_points: true,
847+
};
848+
849+
let ra_fixture = r#"
850+
fn foo() -> i32 {
851+
let x$0 = 5;
852+
let y = x * 2;
853+
854+
if true {
855+
return y;
856+
}
857+
858+
0?
859+
}"#;
860+
861+
check_with_config(ra_fixture, config.clone());
862+
863+
let ra_fixture = r#"
864+
fn foo() ->$0 i32 {
865+
let x = 5;
866+
let y = x * 2;
867+
868+
if true {
869+
return y;
870+
// ^^^^^^
871+
}
872+
873+
0?
874+
// ^
875+
"#;
876+
877+
check_with_config(ra_fixture, config);
878+
}
879+
880+
#[test]
881+
fn test_hl_disabled_break() {
882+
let config = HighlightRelatedConfig {
883+
references: true,
884+
break_points: false,
885+
exit_points: true,
886+
yield_points: true,
887+
};
888+
889+
let ra_fixture = r#"
890+
fn foo() {
891+
loop {
892+
break$0;
893+
}
894+
}"#;
895+
896+
check_with_config(ra_fixture, config);
897+
}
898+
899+
#[test]
900+
fn test_hl_disabled_yield() {
901+
let config = HighlightRelatedConfig {
902+
references: true,
903+
break_points: true,
904+
exit_points: true,
905+
yield_points: false,
906+
};
907+
908+
let ra_fixture = r#"
909+
async$0 fn foo() {
910+
0.await;
911+
}"#;
912+
913+
check_with_config(ra_fixture, config);
914+
}
915+
916+
#[test]
917+
fn test_hl_disabled_exit() {
918+
let config = HighlightRelatedConfig {
919+
references: true,
920+
break_points: true,
921+
exit_points: false,
922+
yield_points: true,
923+
};
924+
925+
let ra_fixture = r#"
926+
fn foo() ->$0 i32 {
927+
if true {
928+
return -1;
929+
}
930+
931+
42
932+
}"#;
933+
934+
check_with_config(ra_fixture, config);
935+
}
729936
}

crates/ide/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub use crate::{
7676
expand_macro::ExpandedMacro,
7777
file_structure::{StructureNode, StructureNodeKind},
7878
folding_ranges::{Fold, FoldKind},
79-
highlight_related::HighlightedRange,
79+
highlight_related::{HighlightRelatedConfig, HighlightedRange},
8080
hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult},
8181
inlay_hints::{InlayHint, InlayHintsConfig, InlayKind},
8282
join_lines::JoinLinesConfig,
@@ -496,9 +496,12 @@ impl Analysis {
496496
/// Computes all ranges to highlight for a given item in a file.
497497
pub fn highlight_related(
498498
&self,
499+
config: HighlightRelatedConfig,
499500
position: FilePosition,
500501
) -> Cancellable<Option<Vec<HighlightedRange>>> {
501-
self.with_db(|db| highlight_related::highlight_related(&Semantics::new(db), position))
502+
self.with_db(|db| {
503+
highlight_related::highlight_related(&Semantics::new(db), config, position)
504+
})
502505
}
503506

504507
/// Computes syntax highlighting for the given file range.

crates/rust-analyzer/src/config.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use std::{ffi::OsString, iter, path::PathBuf};
1111

1212
use flycheck::FlycheckConfig;
1313
use ide::{
14-
AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, HoverDocFormat,
15-
InlayHintsConfig, JoinLinesConfig,
14+
AssistConfig, CompletionConfig, DiagnosticsConfig, HighlightRelatedConfig, HoverConfig,
15+
HoverDocFormat, InlayHintsConfig, JoinLinesConfig,
1616
};
1717
use ide_db::helpers::{
1818
insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -147,6 +147,15 @@ config_data! {
147147
/// also need to add the folders to Code's `files.watcherExclude`.
148148
files_excludeDirs: Vec<PathBuf> = "[]",
149149

150+
/// Enables highlighting of related references while hovering your mouse above any identifier.
151+
highlightRelated_references: bool = "true",
152+
/// Enables highlighting of all exit points while hovering your mouse above any `return`, `?`, or return type arrow (`->`).
153+
highlightRelated_exitPoints: bool = "true",
154+
/// Enables highlighting of related references while hovering your mouse `break`, `loop`, `while`, or `for` keywords.
155+
highlightRelated_breakPoints: bool = "true",
156+
/// Enables highlighting of all break points for a loop or block context while hovering your mouse above any `async` or `await` keywords.
157+
highlightRelated_yieldPoints: bool = "true",
158+
150159
/// Use semantic tokens for strings.
151160
///
152161
/// In some editors (e.g. vscode) semantic tokens override other highlighting grammars.
@@ -852,6 +861,15 @@ impl Config {
852861
false
853862
)
854863
}
864+
865+
pub fn highlight_related(&self) -> HighlightRelatedConfig {
866+
HighlightRelatedConfig {
867+
references: self.data.highlightRelated_references,
868+
break_points: self.data.highlightRelated_breakPoints,
869+
exit_points: self.data.highlightRelated_exitPoints,
870+
yield_points: self.data.highlightRelated_yieldPoints,
871+
}
872+
}
855873
}
856874

857875
#[derive(Deserialize, Debug, Clone)]

crates/rust-analyzer/src/handlers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ pub(crate) fn handle_document_highlight(
11881188
let position = from_proto::file_position(&snap, params.text_document_position_params)?;
11891189
let line_index = snap.file_line_index(position.file_id)?;
11901190

1191-
let refs = match snap.analysis.highlight_related(position)? {
1191+
let refs = match snap.analysis.highlight_related(snap.config.highlight_related(), position)? {
11921192
None => return Ok(None),
11931193
Some(refs) => refs,
11941194
};

docs/user/generated_config.adoc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,26 @@ These directories will be ignored by rust-analyzer. They are
208208
relative to the workspace root, and globs are not supported. You may
209209
also need to add the folders to Code's `files.watcherExclude`.
210210
--
211+
[[rust-analyzer.highlightRelated.references]]rust-analyzer.highlightRelated.references (default: `true`)::
212+
+
213+
--
214+
Enables highlighting of related references while hovering your mouse above any identifier.
215+
--
216+
[[rust-analyzer.highlightRelated.exitPoints]]rust-analyzer.highlightRelated.exitPoints (default: `true`)::
217+
+
218+
--
219+
Enables highlighting of all exit points while hovering your mouse above any `return`, `?`, or return type arrow (`->`).
220+
--
221+
[[rust-analyzer.highlightRelated.breakPoints]]rust-analyzer.highlightRelated.breakPoints (default: `true`)::
222+
+
223+
--
224+
Enables highlighting of related references while hovering your mouse `break`, `loop`, `while`, or `for` keywords.
225+
--
226+
[[rust-analyzer.highlightRelated.yieldPoints]]rust-analyzer.highlightRelated.yieldPoints (default: `true`)::
227+
+
228+
--
229+
Enables highlighting of all break points for a loop or block context while hovering your mouse above any `async` or `await` keywords.
230+
--
211231
[[rust-analyzer.highlighting.strings]]rust-analyzer.highlighting.strings (default: `true`)::
212232
+
213233
--

editors/code/package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,26 @@
655655
"type": "string"
656656
}
657657
},
658+
"rust-analyzer.highlightRelated.references": {
659+
"markdownDescription": "Enables highlighting of related references while hovering your mouse above any identifier.",
660+
"default": true,
661+
"type": "boolean"
662+
},
663+
"rust-analyzer.highlightRelated.exitPoints": {
664+
"markdownDescription": "Enables highlighting of all exit points while hovering your mouse above any `return`, `?`, or return type arrow (`->`).",
665+
"default": true,
666+
"type": "boolean"
667+
},
668+
"rust-analyzer.highlightRelated.breakPoints": {
669+
"markdownDescription": "Enables highlighting of related references while hovering your mouse `break`, `loop`, `while`, or `for` keywords.",
670+
"default": true,
671+
"type": "boolean"
672+
},
673+
"rust-analyzer.highlightRelated.yieldPoints": {
674+
"markdownDescription": "Enables highlighting of all break points for a loop or block context while hovering your mouse above any `async` or `await` keywords.",
675+
"default": true,
676+
"type": "boolean"
677+
},
658678
"rust-analyzer.highlighting.strings": {
659679
"markdownDescription": "Use semantic tokens for strings.\n\nIn some editors (e.g. vscode) semantic tokens override other highlighting grammars.\nBy disabling semantic tokens for strings, other grammars can be used to highlight\ntheir contents.",
660680
"default": true,

0 commit comments

Comments
 (0)