mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
Allow configuration of annotation location.
Previously, annotations would only appear above the name of an item (function signature, struct declaration, etc). Now, rust-analyzer can be configured to show annotations either above the name or above the whole item (including doc comments and attributes).
This commit is contained in:
parent
2e9f1204ca
commit
8a2803d9ae
6 changed files with 132 additions and 19 deletions
|
@ -41,6 +41,12 @@ pub struct AnnotationConfig {
|
|||
pub annotate_references: bool,
|
||||
pub annotate_method_references: bool,
|
||||
pub annotate_enum_variant_references: bool,
|
||||
pub annotation_location: AnnotationLocation,
|
||||
}
|
||||
|
||||
pub enum AnnotationLocation {
|
||||
AboveName,
|
||||
AboveWholeItem,
|
||||
}
|
||||
|
||||
pub(crate) fn annotations(
|
||||
|
@ -65,10 +71,10 @@ pub(crate) fn annotations(
|
|||
visit_file_defs(&Semantics::new(db), file_id, &mut |def| {
|
||||
let range = match def {
|
||||
Definition::Const(konst) if config.annotate_references => {
|
||||
konst.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
konst.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
}
|
||||
Definition::Trait(trait_) if config.annotate_references || config.annotate_impls => {
|
||||
trait_.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
trait_.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
}
|
||||
Definition::Adt(adt) => match adt {
|
||||
hir::Adt::Enum(enum_) => {
|
||||
|
@ -77,7 +83,9 @@ pub(crate) fn annotations(
|
|||
.variants(db)
|
||||
.into_iter()
|
||||
.map(|variant| {
|
||||
variant.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
variant
|
||||
.source(db)
|
||||
.and_then(|node| name_range(db, config, node, file_id))
|
||||
})
|
||||
.flatten()
|
||||
.for_each(|range| {
|
||||
|
@ -88,14 +96,14 @@ pub(crate) fn annotations(
|
|||
})
|
||||
}
|
||||
if config.annotate_references || config.annotate_impls {
|
||||
enum_.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
enum_.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if config.annotate_references || config.annotate_impls {
|
||||
adt.source(db).and_then(|node| name_range(db, node, file_id))
|
||||
adt.source(db).and_then(|node| name_range(db, config, node, file_id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -113,6 +121,7 @@ pub(crate) fn annotations(
|
|||
annotations
|
||||
.push(Annotation { range, kind: AnnotationKind::HasImpls { file_id, data: None } });
|
||||
}
|
||||
|
||||
if config.annotate_references {
|
||||
annotations.push(Annotation {
|
||||
range,
|
||||
|
@ -122,12 +131,18 @@ pub(crate) fn annotations(
|
|||
|
||||
fn name_range<T: HasName>(
|
||||
db: &RootDatabase,
|
||||
config: &AnnotationConfig,
|
||||
node: InFile<T>,
|
||||
source_file_id: FileId,
|
||||
) -> Option<TextRange> {
|
||||
if let Some(InFile { file_id, value }) = node.original_ast_node(db) {
|
||||
if file_id == source_file_id.into() {
|
||||
return value.name().map(|it| it.syntax().text_range());
|
||||
return match config.annotation_location {
|
||||
AnnotationLocation::AboveName => {
|
||||
value.name().map(|name| name.syntax().text_range())
|
||||
}
|
||||
AnnotationLocation::AboveWholeItem => Some(value.syntax().text_range()),
|
||||
};
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -188,21 +203,23 @@ mod tests {
|
|||
|
||||
use crate::{fixture, Annotation, AnnotationConfig};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
use super::AnnotationLocation;
|
||||
|
||||
const DEFAULT_CONFIG: AnnotationConfig = AnnotationConfig {
|
||||
binary_target: true,
|
||||
annotate_runnables: true,
|
||||
annotate_impls: true,
|
||||
annotate_references: true,
|
||||
annotate_method_references: true,
|
||||
annotate_enum_variant_references: true,
|
||||
annotation_location: AnnotationLocation::AboveName,
|
||||
};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect, config: &AnnotationConfig) {
|
||||
let (analysis, file_id) = fixture::file(ra_fixture);
|
||||
|
||||
let annotations: Vec<Annotation> = analysis
|
||||
.annotations(
|
||||
&AnnotationConfig {
|
||||
binary_target: true,
|
||||
annotate_runnables: true,
|
||||
annotate_impls: true,
|
||||
annotate_references: true,
|
||||
annotate_method_references: true,
|
||||
annotate_enum_variant_references: true,
|
||||
},
|
||||
file_id,
|
||||
)
|
||||
.annotations(config, file_id)
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|annotation| analysis.resolve_annotation(annotation).unwrap())
|
||||
|
@ -286,6 +303,7 @@ fn main() {
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -362,6 +380,7 @@ fn main() {
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -497,6 +516,7 @@ fn main() {
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -540,6 +560,7 @@ fn main() {}
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -654,6 +675,7 @@ fn main() {
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -750,6 +772,7 @@ mod tests {
|
|||
},
|
||||
]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -765,6 +788,7 @@ struct Foo;
|
|||
expect![[r#"
|
||||
[]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -784,6 +808,46 @@ m!();
|
|||
expect![[r#"
|
||||
[]
|
||||
"#]],
|
||||
&DEFAULT_CONFIG,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_annotations_appear_above_whole_item_when_configured_to_do_so() {
|
||||
check(
|
||||
r#"
|
||||
/// This is a struct named Foo, obviously.
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
"#,
|
||||
expect![[r#"
|
||||
[
|
||||
Annotation {
|
||||
range: 0..71,
|
||||
kind: HasImpls {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
data: Some(
|
||||
[],
|
||||
),
|
||||
},
|
||||
},
|
||||
Annotation {
|
||||
range: 0..71,
|
||||
kind: HasReferences {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
data: None,
|
||||
},
|
||||
},
|
||||
]
|
||||
"#]],
|
||||
&AnnotationConfig {
|
||||
annotation_location: AnnotationLocation::AboveWholeItem,
|
||||
..DEFAULT_CONFIG
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ use syntax::SourceFile;
|
|||
use crate::navigation_target::{ToNav, TryToNav};
|
||||
|
||||
pub use crate::{
|
||||
annotations::{Annotation, AnnotationConfig, AnnotationKind},
|
||||
annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
|
||||
call_hierarchy::CallItem,
|
||||
expand_macro::ExpandedMacro,
|
||||
file_structure::{StructureNode, StructureNodeKind},
|
||||
|
|
|
@ -307,6 +307,8 @@ config_data! {
|
|||
/// Join lines unwraps trivial blocks.
|
||||
joinLines_unwrapTrivialBlock: bool = "true",
|
||||
|
||||
/// Where to render annotations.
|
||||
lens_annotationLocation: AnnotationLocation = "\"above_name\"",
|
||||
/// Whether to show `Debug` lens. Only applies when
|
||||
/// `#rust-analyzer.lens.enable#` is set.
|
||||
lens_debug_enable: bool = "true",
|
||||
|
@ -494,6 +496,25 @@ pub struct LensConfig {
|
|||
pub refs_adt: bool, // for Struct, Enum, Union and Trait
|
||||
pub refs_trait: bool, // for Struct, Enum, Union and Trait
|
||||
pub enum_variant_refs: bool,
|
||||
|
||||
// annotations
|
||||
pub annotation_location: AnnotationLocation,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AnnotationLocation {
|
||||
AboveName,
|
||||
AboveWholeItem,
|
||||
}
|
||||
|
||||
impl From<AnnotationLocation> for ide::AnnotationLocation {
|
||||
fn from(location: AnnotationLocation) -> Self {
|
||||
match location {
|
||||
AnnotationLocation::AboveName => ide::AnnotationLocation::AboveName,
|
||||
AnnotationLocation::AboveWholeItem => ide::AnnotationLocation::AboveWholeItem,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LensConfig {
|
||||
|
@ -1185,6 +1206,7 @@ impl Config {
|
|||
refs_trait: self.data.lens_enable && self.data.lens_references_trait_enable,
|
||||
enum_variant_refs: self.data.lens_enable
|
||||
&& self.data.lens_references_enumVariant_enable,
|
||||
annotation_location: self.data.lens_annotationLocation,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1921,6 +1943,14 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
|
|||
"Use server-side file watching",
|
||||
],
|
||||
},
|
||||
"AnnotationLocation" => set! {
|
||||
"type": "string",
|
||||
"enum": ["above_name", "above_whole_item"],
|
||||
"enumDescriptions": [
|
||||
"Render annotations above the name of the item.",
|
||||
"Render annotations above the whole item, including documentation comments and attributes."
|
||||
],
|
||||
},
|
||||
_ => panic!("missing entry for {}: {}", ty, default),
|
||||
}
|
||||
|
||||
|
|
|
@ -1234,6 +1234,7 @@ pub(crate) fn handle_code_lens(
|
|||
annotate_references: lens_config.refs_adt,
|
||||
annotate_method_references: lens_config.method_refs,
|
||||
annotate_enum_variant_references: lens_config.enum_variant_refs,
|
||||
annotation_location: lens_config.annotation_location.into(),
|
||||
},
|
||||
file_id,
|
||||
)?;
|
||||
|
|
|
@ -451,6 +451,11 @@ Join lines removes trailing commas.
|
|||
--
|
||||
Join lines unwraps trivial blocks.
|
||||
--
|
||||
[[rust-analyzer.lens.annotation.location]]rust-analyzer.lens.annotation.location (default: `above_name`)::
|
||||
+
|
||||
--
|
||||
Where to render annotations.
|
||||
--
|
||||
[[rust-analyzer.lens.debug.enable]]rust-analyzer.lens.debug.enable (default: `true`)::
|
||||
+
|
||||
--
|
||||
|
|
|
@ -943,6 +943,19 @@
|
|||
"default": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"rust-analyzer.lens.annotationLocation": {
|
||||
"markdownDescription": "Where to render annotations.",
|
||||
"default": "above_name",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"above_name",
|
||||
"above_whole_item"
|
||||
],
|
||||
"enumDescriptions": [
|
||||
"Render annotations above the name of the item.",
|
||||
"Render annotations above the whole item, including documentation comments and attributes."
|
||||
]
|
||||
},
|
||||
"rust-analyzer.lens.debug.enable": {
|
||||
"markdownDescription": "Whether to show `Debug` lens. Only applies when\n`#rust-analyzer.lens.enable#` is set.",
|
||||
"default": true,
|
||||
|
|
Loading…
Reference in a new issue