Skip to content

Commit dbb8fed

Browse files
committed
Auto merge of #13221 - mdx97:mdx97/annotations-above-whole-item, r=Veykril
Allow configuration of annotation location. I've added the ability to configure where lens annotations render relevant to the item they describe. Previously, these would render directly above the line the item is declared on. Now, there is the ability to render these annotations above the entire item (including doc comments, and attributes). The names of the config options are up for debate, I did what seemed best to me but if anyone has better ideas let me know. This is my first contribution so if I've missed anything please let me know. Here's a preview of what the new option looks like: <img width="577" alt="Screen Shot 2022-09-11 at 10 39 51 PM" src="https://user-images.githubusercontent.com/33100798/189570298-b4fcbf9c-ee49-4b79-aae6-1037ae4f26af.png"> closes #13218
2 parents ba15f75 + f57c15f commit dbb8fed

File tree

6 files changed

+126
-19
lines changed

6 files changed

+126
-19
lines changed

crates/ide/src/annotations.rs

+75-18
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ pub struct AnnotationConfig {
4141
pub annotate_references: bool,
4242
pub annotate_method_references: bool,
4343
pub annotate_enum_variant_references: bool,
44+
pub location: AnnotationLocation,
45+
}
46+
47+
pub enum AnnotationLocation {
48+
AboveName,
49+
AboveWholeItem,
4450
}
4551

4652
pub(crate) fn annotations(
@@ -65,10 +71,10 @@ pub(crate) fn annotations(
6571
visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
6672
let range = match def {
6773
Definition::Const(konst) if config.annotate_references => {
68-
konst.source(db).and_then(|node| name_range(db, node, file_id))
74+
konst.source(db).and_then(|node| name_range(db, config, node, file_id))
6975
}
7076
Definition::Trait(trait_) if config.annotate_references || config.annotate_impls => {
71-
trait_.source(db).and_then(|node| name_range(db, node, file_id))
77+
trait_.source(db).and_then(|node| name_range(db, config, node, file_id))
7278
}
7379
Definition::Adt(adt) => match adt {
7480
hir::Adt::Enum(enum_) => {
@@ -77,7 +83,9 @@ pub(crate) fn annotations(
7783
.variants(db)
7884
.into_iter()
7985
.map(|variant| {
80-
variant.source(db).and_then(|node| name_range(db, node, file_id))
86+
variant
87+
.source(db)
88+
.and_then(|node| name_range(db, config, node, file_id))
8189
})
8290
.flatten()
8391
.for_each(|range| {
@@ -88,14 +96,14 @@ pub(crate) fn annotations(
8896
})
8997
}
9098
if config.annotate_references || config.annotate_impls {
91-
enum_.source(db).and_then(|node| name_range(db, node, file_id))
99+
enum_.source(db).and_then(|node| name_range(db, config, node, file_id))
92100
} else {
93101
None
94102
}
95103
}
96104
_ => {
97105
if config.annotate_references || config.annotate_impls {
98-
adt.source(db).and_then(|node| name_range(db, node, file_id))
106+
adt.source(db).and_then(|node| name_range(db, config, node, file_id))
99107
} else {
100108
None
101109
}
@@ -113,6 +121,7 @@ pub(crate) fn annotations(
113121
annotations
114122
.push(Annotation { range, kind: AnnotationKind::HasImpls { file_id, data: None } });
115123
}
124+
116125
if config.annotate_references {
117126
annotations.push(Annotation {
118127
range,
@@ -122,12 +131,18 @@ pub(crate) fn annotations(
122131

123132
fn name_range<T: HasName>(
124133
db: &RootDatabase,
134+
config: &AnnotationConfig,
125135
node: InFile<T>,
126136
source_file_id: FileId,
127137
) -> Option<TextRange> {
128138
if let Some(InFile { file_id, value }) = node.original_ast_node(db) {
129139
if file_id == source_file_id.into() {
130-
return value.name().map(|it| it.syntax().text_range());
140+
return match config.location {
141+
AnnotationLocation::AboveName => {
142+
value.name().map(|name| name.syntax().text_range())
143+
}
144+
AnnotationLocation::AboveWholeItem => Some(value.syntax().text_range()),
145+
};
131146
}
132147
}
133148
None
@@ -188,21 +203,23 @@ mod tests {
188203

189204
use crate::{fixture, Annotation, AnnotationConfig};
190205

191-
fn check(ra_fixture: &str, expect: Expect) {
206+
use super::AnnotationLocation;
207+
208+
const DEFAULT_CONFIG: AnnotationConfig = AnnotationConfig {
209+
binary_target: true,
210+
annotate_runnables: true,
211+
annotate_impls: true,
212+
annotate_references: true,
213+
annotate_method_references: true,
214+
annotate_enum_variant_references: true,
215+
location: AnnotationLocation::AboveName,
216+
};
217+
218+
fn check_with_config(ra_fixture: &str, expect: Expect, config: &AnnotationConfig) {
192219
let (analysis, file_id) = fixture::file(ra_fixture);
193220

194221
let annotations: Vec<Annotation> = analysis
195-
.annotations(
196-
&AnnotationConfig {
197-
binary_target: true,
198-
annotate_runnables: true,
199-
annotate_impls: true,
200-
annotate_references: true,
201-
annotate_method_references: true,
202-
annotate_enum_variant_references: true,
203-
},
204-
file_id,
205-
)
222+
.annotations(config, file_id)
206223
.unwrap()
207224
.into_iter()
208225
.map(|annotation| analysis.resolve_annotation(annotation).unwrap())
@@ -211,6 +228,10 @@ mod tests {
211228
expect.assert_debug_eq(&annotations);
212229
}
213230

231+
fn check(ra_fixture: &str, expect: Expect) {
232+
check_with_config(ra_fixture, expect, &DEFAULT_CONFIG);
233+
}
234+
214235
#[test]
215236
fn const_annotations() {
216237
check(
@@ -786,4 +807,40 @@ m!();
786807
"#]],
787808
);
788809
}
810+
811+
#[test]
812+
fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
813+
check_with_config(
814+
r#"
815+
/// This is a struct named Foo, obviously.
816+
#[derive(Clone)]
817+
struct Foo;
818+
"#,
819+
expect![[r#"
820+
[
821+
Annotation {
822+
range: 0..71,
823+
kind: HasImpls {
824+
file_id: FileId(
825+
0,
826+
),
827+
data: Some(
828+
[],
829+
),
830+
},
831+
},
832+
Annotation {
833+
range: 0..71,
834+
kind: HasReferences {
835+
file_id: FileId(
836+
0,
837+
),
838+
data: None,
839+
},
840+
},
841+
]
842+
"#]],
843+
&AnnotationConfig { location: AnnotationLocation::AboveWholeItem, ..DEFAULT_CONFIG },
844+
);
845+
}
789846
}

crates/ide/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use syntax::SourceFile;
7474
use crate::navigation_target::{ToNav, TryToNav};
7575

7676
pub use crate::{
77-
annotations::{Annotation, AnnotationConfig, AnnotationKind},
77+
annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
7878
call_hierarchy::CallItem,
7979
expand_macro::ExpandedMacro,
8080
file_structure::{StructureNode, StructureNodeKind},

crates/rust-analyzer/src/config.rs

+31
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ config_data! {
308308
/// Join lines unwraps trivial blocks.
309309
joinLines_unwrapTrivialBlock: bool = "true",
310310

311+
311312
/// Whether to show `Debug` lens. Only applies when
312313
/// `#rust-analyzer.lens.enable#` is set.
313314
lens_debug_enable: bool = "true",
@@ -319,6 +320,8 @@ config_data! {
319320
/// Whether to show `Implementations` lens. Only applies when
320321
/// `#rust-analyzer.lens.enable#` is set.
321322
lens_implementations_enable: bool = "true",
323+
/// Where to render annotations.
324+
lens_location: AnnotationLocation = "\"above_name\"",
322325
/// Whether to show `References` lens for Struct, Enum, and Union.
323326
/// Only applies when `#rust-analyzer.lens.enable#` is set.
324327
lens_references_adt_enable: bool = "false",
@@ -498,6 +501,25 @@ pub struct LensConfig {
498501
pub refs_adt: bool, // for Struct, Enum, Union and Trait
499502
pub refs_trait: bool, // for Struct, Enum, Union and Trait
500503
pub enum_variant_refs: bool,
504+
505+
// annotations
506+
pub location: AnnotationLocation,
507+
}
508+
509+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
510+
#[serde(rename_all = "snake_case")]
511+
pub enum AnnotationLocation {
512+
AboveName,
513+
AboveWholeItem,
514+
}
515+
516+
impl From<AnnotationLocation> for ide::AnnotationLocation {
517+
fn from(location: AnnotationLocation) -> Self {
518+
match location {
519+
AnnotationLocation::AboveName => ide::AnnotationLocation::AboveName,
520+
AnnotationLocation::AboveWholeItem => ide::AnnotationLocation::AboveWholeItem,
521+
}
522+
}
501523
}
502524

503525
impl LensConfig {
@@ -1196,6 +1218,7 @@ impl Config {
11961218
refs_trait: self.data.lens_enable && self.data.lens_references_trait_enable,
11971219
enum_variant_refs: self.data.lens_enable
11981220
&& self.data.lens_references_enumVariant_enable,
1221+
location: self.data.lens_location,
11991222
}
12001223
}
12011224

@@ -1932,6 +1955,14 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
19321955
"Use server-side file watching",
19331956
],
19341957
},
1958+
"AnnotationLocation" => set! {
1959+
"type": "string",
1960+
"enum": ["above_name", "above_whole_item"],
1961+
"enumDescriptions": [
1962+
"Render annotations above the name of the item.",
1963+
"Render annotations above the whole item, including documentation comments and attributes."
1964+
],
1965+
},
19351966
_ => panic!("missing entry for {}: {}", ty, default),
19361967
}
19371968

crates/rust-analyzer/src/handlers.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,7 @@ pub(crate) fn handle_code_lens(
12401240
annotate_references: lens_config.refs_adt,
12411241
annotate_method_references: lens_config.method_refs,
12421242
annotate_enum_variant_references: lens_config.enum_variant_refs,
1243+
location: lens_config.location.into(),
12431244
},
12441245
file_id,
12451246
)?;

docs/user/generated_config.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ client doesn't set the corresponding capability.
479479
Whether to show `Implementations` lens. Only applies when
480480
`#rust-analyzer.lens.enable#` is set.
481481
--
482+
[[rust-analyzer.lens.location]]rust-analyzer.lens.location (default: `"above_name"`)::
483+
+
484+
--
485+
Where to render annotations.
486+
--
482487
[[rust-analyzer.lens.references.adt.enable]]rust-analyzer.lens.references.adt.enable (default: `false`)::
483488
+
484489
--

editors/code/package.json

+13
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,19 @@
963963
"default": true,
964964
"type": "boolean"
965965
},
966+
"rust-analyzer.lens.location": {
967+
"markdownDescription": "Where to render annotations.",
968+
"default": "above_name",
969+
"type": "string",
970+
"enum": [
971+
"above_name",
972+
"above_whole_item"
973+
],
974+
"enumDescriptions": [
975+
"Render annotations above the name of the item.",
976+
"Render annotations above the whole item, including documentation comments and attributes."
977+
]
978+
},
966979
"rust-analyzer.lens.references.adt.enable": {
967980
"markdownDescription": "Whether to show `References` lens for Struct, Enum, and Union.\nOnly applies when `#rust-analyzer.lens.enable#` is set.",
968981
"default": false,

0 commit comments

Comments
 (0)