mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	Add config option to exclude locals from doc search
This commit is contained in:
		
							parent
							
								
									caef0f46fd
								
							
						
					
					
						commit
						dc6e6d2b86
					
				
					 7 changed files with 350 additions and 28 deletions
				
			
		| 
						 | 
					@ -23,6 +23,11 @@ pub enum StructureNodeKind {
 | 
				
			||||||
    Region,
 | 
					    Region,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub struct FileStructureConfig {
 | 
				
			||||||
 | 
					    pub exclude_locals: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Feature: File Structure
 | 
					// Feature: File Structure
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Provides a tree of the symbols defined in the file. Can be used to
 | 
					// Provides a tree of the symbols defined in the file. Can be used to
 | 
				
			||||||
| 
						 | 
					@ -36,21 +41,24 @@ pub enum StructureNodeKind {
 | 
				
			||||||
// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
 | 
					// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 
 | 
					// 
 | 
				
			||||||
pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
 | 
					pub(crate) fn file_structure(
 | 
				
			||||||
 | 
					    file: &SourceFile,
 | 
				
			||||||
 | 
					    config: &FileStructureConfig,
 | 
				
			||||||
 | 
					) -> Vec<StructureNode> {
 | 
				
			||||||
    let mut res = Vec::new();
 | 
					    let mut res = Vec::new();
 | 
				
			||||||
    let mut stack = Vec::new();
 | 
					    let mut stack = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for event in file.syntax().preorder_with_tokens() {
 | 
					    for event in file.syntax().preorder_with_tokens() {
 | 
				
			||||||
        match event {
 | 
					        match event {
 | 
				
			||||||
            WalkEvent::Enter(NodeOrToken::Node(node)) => {
 | 
					            WalkEvent::Enter(NodeOrToken::Node(node)) => {
 | 
				
			||||||
                if let Some(mut symbol) = structure_node(&node) {
 | 
					                if let Some(mut symbol) = structure_node(&node, config) {
 | 
				
			||||||
                    symbol.parent = stack.last().copied();
 | 
					                    symbol.parent = stack.last().copied();
 | 
				
			||||||
                    stack.push(res.len());
 | 
					                    stack.push(res.len());
 | 
				
			||||||
                    res.push(symbol);
 | 
					                    res.push(symbol);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            WalkEvent::Leave(NodeOrToken::Node(node)) => {
 | 
					            WalkEvent::Leave(NodeOrToken::Node(node)) => {
 | 
				
			||||||
                if structure_node(&node).is_some() {
 | 
					                if structure_node(&node, config).is_some() {
 | 
				
			||||||
                    stack.pop().unwrap();
 | 
					                    stack.pop().unwrap();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -71,7 +79,7 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
 | 
				
			||||||
    res
 | 
					    res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
 | 
					fn structure_node(node: &SyntaxNode, config: &FileStructureConfig) -> Option<StructureNode> {
 | 
				
			||||||
    fn decl<N: HasName + HasAttrs>(node: N, kind: StructureNodeKind) -> Option<StructureNode> {
 | 
					    fn decl<N: HasName + HasAttrs>(node: N, kind: StructureNodeKind) -> Option<StructureNode> {
 | 
				
			||||||
        decl_with_detail(&node, None, kind)
 | 
					        decl_with_detail(&node, None, kind)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -187,6 +195,10 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
 | 
				
			||||||
                Some(node)
 | 
					                Some(node)
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            ast::LetStmt(it) => {
 | 
					            ast::LetStmt(it) => {
 | 
				
			||||||
 | 
					                if config.exclude_locals {
 | 
				
			||||||
 | 
					                    return None;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let pat = it.pat()?;
 | 
					                let pat = it.pat()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let mut label = String::new();
 | 
					                let mut label = String::new();
 | 
				
			||||||
| 
						 | 
					@ -254,9 +266,19 @@ mod tests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const DEFAULT_CONFIG: FileStructureConfig = FileStructureConfig { exclude_locals: true };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
 | 
					    fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
 | 
				
			||||||
 | 
					        check_with_config(ra_fixture, &DEFAULT_CONFIG, expect);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn check_with_config(
 | 
				
			||||||
 | 
					        #[rust_analyzer::rust_fixture] ra_fixture: &str,
 | 
				
			||||||
 | 
					        config: &FileStructureConfig,
 | 
				
			||||||
 | 
					        expect: Expect,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        let file = SourceFile::parse(ra_fixture, span::Edition::CURRENT).ok().unwrap();
 | 
					        let file = SourceFile::parse(ra_fixture, span::Edition::CURRENT).ok().unwrap();
 | 
				
			||||||
        let structure = file_structure(&file);
 | 
					        let structure = file_structure(&file, config);
 | 
				
			||||||
        expect.assert_debug_eq(&structure)
 | 
					        expect.assert_debug_eq(&structure)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -701,13 +723,264 @@ fn let_statements() {
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        deprecated: false,
 | 
					                        deprecated: false,
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            "#]],
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_file_structure_include_locals() {
 | 
				
			||||||
 | 
					        check_with_config(
 | 
				
			||||||
 | 
					            r#"
 | 
				
			||||||
 | 
					struct Foo {
 | 
				
			||||||
 | 
					    x: i32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod m {
 | 
				
			||||||
 | 
					    fn bar1() {}
 | 
				
			||||||
 | 
					    fn bar2<T>(t: T) -> T {}
 | 
				
			||||||
 | 
					    fn bar3<A,
 | 
				
			||||||
 | 
					        B>(a: A,
 | 
				
			||||||
 | 
					        b: B) -> Vec<
 | 
				
			||||||
 | 
					        u32
 | 
				
			||||||
 | 
					    > {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum E { X, Y(i32) }
 | 
				
			||||||
 | 
					type T = ();
 | 
				
			||||||
 | 
					static S: i32 = 42;
 | 
				
			||||||
 | 
					const C: i32 = 42;
 | 
				
			||||||
 | 
					trait Tr {}
 | 
				
			||||||
 | 
					trait Alias = Tr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_rules! mc {
 | 
				
			||||||
 | 
					    () => {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn let_statements() {
 | 
				
			||||||
 | 
					    let x = 42;
 | 
				
			||||||
 | 
					    let mut y = x;
 | 
				
			||||||
 | 
					    let Foo {
 | 
				
			||||||
 | 
					        ..
 | 
				
			||||||
 | 
					    } = Foo { x };
 | 
				
			||||||
 | 
					    _ = ();
 | 
				
			||||||
 | 
					    let _ = g();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					"#,
 | 
				
			||||||
 | 
					            &FileStructureConfig { exclude_locals: false },
 | 
				
			||||||
 | 
					            expect![[r#"
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "Foo",
 | 
				
			||||||
 | 
					                        navigation_range: 8..11,
 | 
				
			||||||
 | 
					                        node_range: 1..26,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Struct,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                    StructureNode {
 | 
					                    StructureNode {
 | 
				
			||||||
                        parent: Some(
 | 
					                        parent: Some(
 | 
				
			||||||
                            27,
 | 
					                            0,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        label: "x",
 | 
					                        label: "x",
 | 
				
			||||||
                        navigation_range: 684..685,
 | 
					                        navigation_range: 18..19,
 | 
				
			||||||
                        node_range: 680..691,
 | 
					                        node_range: 18..24,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Field,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "i32",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "m",
 | 
				
			||||||
 | 
					                        navigation_range: 32..33,
 | 
				
			||||||
 | 
					                        node_range: 28..158,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Module,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            2,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "bar1",
 | 
				
			||||||
 | 
					                        navigation_range: 43..47,
 | 
				
			||||||
 | 
					                        node_range: 40..52,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Function,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "fn()",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            2,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "bar2",
 | 
				
			||||||
 | 
					                        navigation_range: 60..64,
 | 
				
			||||||
 | 
					                        node_range: 57..81,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Function,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "fn<T>(t: T) -> T",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            2,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "bar3",
 | 
				
			||||||
 | 
					                        navigation_range: 89..93,
 | 
				
			||||||
 | 
					                        node_range: 86..156,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Function,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "fn<A, B>(a: A, b: B) -> Vec< u32 >",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "E",
 | 
				
			||||||
 | 
					                        navigation_range: 165..166,
 | 
				
			||||||
 | 
					                        node_range: 160..180,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Enum,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            6,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "X",
 | 
				
			||||||
 | 
					                        navigation_range: 169..170,
 | 
				
			||||||
 | 
					                        node_range: 169..170,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Variant,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            6,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "Y",
 | 
				
			||||||
 | 
					                        navigation_range: 172..173,
 | 
				
			||||||
 | 
					                        node_range: 172..178,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Variant,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "T",
 | 
				
			||||||
 | 
					                        navigation_range: 186..187,
 | 
				
			||||||
 | 
					                        node_range: 181..193,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            TypeAlias,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "()",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "S",
 | 
				
			||||||
 | 
					                        navigation_range: 201..202,
 | 
				
			||||||
 | 
					                        node_range: 194..213,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Static,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "i32",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "C",
 | 
				
			||||||
 | 
					                        navigation_range: 220..221,
 | 
				
			||||||
 | 
					                        node_range: 214..232,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Const,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "i32",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "Tr",
 | 
				
			||||||
 | 
					                        navigation_range: 239..241,
 | 
				
			||||||
 | 
					                        node_range: 233..244,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Trait,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "Alias",
 | 
				
			||||||
 | 
					                        navigation_range: 251..256,
 | 
				
			||||||
 | 
					                        node_range: 245..262,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            TraitAlias,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "mc",
 | 
				
			||||||
 | 
					                        navigation_range: 277..279,
 | 
				
			||||||
 | 
					                        node_range: 264..296,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Macro,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: None,
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: None,
 | 
				
			||||||
 | 
					                        label: "let_statements",
 | 
				
			||||||
 | 
					                        navigation_range: 301..315,
 | 
				
			||||||
 | 
					                        node_range: 298..429,
 | 
				
			||||||
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
 | 
					                            Function,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        detail: Some(
 | 
				
			||||||
 | 
					                            "fn()",
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        deprecated: false,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    StructureNode {
 | 
				
			||||||
 | 
					                        parent: Some(
 | 
				
			||||||
 | 
					                            15,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                        label: "x",
 | 
				
			||||||
 | 
					                        navigation_range: 328..329,
 | 
				
			||||||
 | 
					                        node_range: 324..335,
 | 
				
			||||||
                        kind: SymbolKind(
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
                            Local,
 | 
					                            Local,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
| 
						 | 
					@ -716,11 +989,11 @@ fn let_statements() {
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    StructureNode {
 | 
					                    StructureNode {
 | 
				
			||||||
                        parent: Some(
 | 
					                        parent: Some(
 | 
				
			||||||
                            27,
 | 
					                            15,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        label: "mut y",
 | 
					                        label: "mut y",
 | 
				
			||||||
                        navigation_range: 700..705,
 | 
					                        navigation_range: 344..349,
 | 
				
			||||||
                        node_range: 696..710,
 | 
					                        node_range: 340..354,
 | 
				
			||||||
                        kind: SymbolKind(
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
                            Local,
 | 
					                            Local,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
| 
						 | 
					@ -729,11 +1002,11 @@ fn let_statements() {
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    StructureNode {
 | 
					                    StructureNode {
 | 
				
			||||||
                        parent: Some(
 | 
					                        parent: Some(
 | 
				
			||||||
                            27,
 | 
					                            15,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        label: "Foo { .. }",
 | 
					                        label: "Foo { .. }",
 | 
				
			||||||
                        navigation_range: 719..741,
 | 
					                        navigation_range: 363..385,
 | 
				
			||||||
                        node_range: 715..754,
 | 
					                        node_range: 359..398,
 | 
				
			||||||
                        kind: SymbolKind(
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
                            Local,
 | 
					                            Local,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
| 
						 | 
					@ -742,11 +1015,11 @@ fn let_statements() {
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    StructureNode {
 | 
					                    StructureNode {
 | 
				
			||||||
                        parent: Some(
 | 
					                        parent: Some(
 | 
				
			||||||
                            27,
 | 
					                            15,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                        label: "_",
 | 
					                        label: "_",
 | 
				
			||||||
                        navigation_range: 804..805,
 | 
					                        navigation_range: 419..420,
 | 
				
			||||||
                        node_range: 800..812,
 | 
					                        node_range: 415..427,
 | 
				
			||||||
                        kind: SymbolKind(
 | 
					                        kind: SymbolKind(
 | 
				
			||||||
                            Local,
 | 
					                            Local,
 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ pub use crate::{
 | 
				
			||||||
    annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
 | 
					    annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
 | 
				
			||||||
    call_hierarchy::{CallHierarchyConfig, CallItem},
 | 
					    call_hierarchy::{CallHierarchyConfig, CallItem},
 | 
				
			||||||
    expand_macro::ExpandedMacro,
 | 
					    expand_macro::ExpandedMacro,
 | 
				
			||||||
    file_structure::{StructureNode, StructureNodeKind},
 | 
					    file_structure::{FileStructureConfig, StructureNode, StructureNodeKind},
 | 
				
			||||||
    folding_ranges::{Fold, FoldKind},
 | 
					    folding_ranges::{Fold, FoldKind},
 | 
				
			||||||
    highlight_related::{HighlightRelatedConfig, HighlightedRange},
 | 
					    highlight_related::{HighlightRelatedConfig, HighlightedRange},
 | 
				
			||||||
    hover::{
 | 
					    hover::{
 | 
				
			||||||
| 
						 | 
					@ -430,12 +430,16 @@ impl Analysis {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns a tree representation of symbols in the file. Useful to draw a
 | 
					    /// Returns a tree representation of symbols in the file. Useful to draw a
 | 
				
			||||||
    /// file outline.
 | 
					    /// file outline.
 | 
				
			||||||
    pub fn file_structure(&self, file_id: FileId) -> Cancellable<Vec<StructureNode>> {
 | 
					    pub fn file_structure(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        config: &FileStructureConfig,
 | 
				
			||||||
 | 
					        file_id: FileId,
 | 
				
			||||||
 | 
					    ) -> Cancellable<Vec<StructureNode>> {
 | 
				
			||||||
        // FIXME: Edition
 | 
					        // FIXME: Edition
 | 
				
			||||||
        self.with_db(|db| {
 | 
					        self.with_db(|db| {
 | 
				
			||||||
            let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
 | 
					            let editioned_file_id_wrapper = EditionedFileId::current_edition(&self.db, file_id);
 | 
				
			||||||
 | 
					            let source_file = db.parse(editioned_file_id_wrapper).tree();
 | 
				
			||||||
            file_structure::file_structure(&db.parse(editioned_file_id_wrapper).tree())
 | 
					            file_structure::file_structure(&source_file, config)
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
//! Read Rust code on stdin, print syntax tree on stdout.
 | 
					//! Read Rust code on stdin, print syntax tree on stdout.
 | 
				
			||||||
use ide::Analysis;
 | 
					use ide::{Analysis, FileStructureConfig};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::cli::{flags, read_stdin};
 | 
					use crate::cli::{flags, read_stdin};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,12 @@ impl flags::Symbols {
 | 
				
			||||||
    pub fn run(self) -> anyhow::Result<()> {
 | 
					    pub fn run(self) -> anyhow::Result<()> {
 | 
				
			||||||
        let text = read_stdin()?;
 | 
					        let text = read_stdin()?;
 | 
				
			||||||
        let (analysis, file_id) = Analysis::from_single_file(text);
 | 
					        let (analysis, file_id) = Analysis::from_single_file(text);
 | 
				
			||||||
        let structure = analysis.file_structure(file_id).unwrap();
 | 
					        let structure = analysis
 | 
				
			||||||
 | 
					            // The default setting in config.rs (document_symbol_search_excludeLocals) is to exclude
 | 
				
			||||||
 | 
					            // locals because it is unlikely that users want document search to return the names of
 | 
				
			||||||
 | 
					            // local variables, but here we include them deliberately.
 | 
				
			||||||
 | 
					            .file_structure(&FileStructureConfig { exclude_locals: false }, file_id)
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
        for s in structure {
 | 
					        for s in structure {
 | 
				
			||||||
            println!("{s:?}");
 | 
					            println!("{s:?}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -858,6 +858,9 @@ config_data! {
 | 
				
			||||||
        /// check will be performed.
 | 
					        /// check will be performed.
 | 
				
			||||||
        check_workspace: bool = true,
 | 
					        check_workspace: bool = true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Exclude all locals from document symbol search.
 | 
				
			||||||
 | 
					        document_symbol_search_excludeLocals: bool = true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// These proc-macros will be ignored when trying to expand them.
 | 
					        /// These proc-macros will be ignored when trying to expand them.
 | 
				
			||||||
        ///
 | 
					        ///
 | 
				
			||||||
        /// This config takes a map of crate names with the exported proc-macro names to ignore as values.
 | 
					        /// This config takes a map of crate names with the exported proc-macro names to ignore as values.
 | 
				
			||||||
| 
						 | 
					@ -1481,6 +1484,13 @@ pub enum FilesWatcher {
 | 
				
			||||||
    Server,
 | 
					    Server,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Configuration for document symbol search requests.
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub struct DocumentSymbolConfig {
 | 
				
			||||||
 | 
					    /// Should locals be excluded.
 | 
				
			||||||
 | 
					    pub search_exclude_locals: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub struct NotificationsConfig {
 | 
					pub struct NotificationsConfig {
 | 
				
			||||||
    pub cargo_toml_not_found: bool,
 | 
					    pub cargo_toml_not_found: bool,
 | 
				
			||||||
| 
						 | 
					@ -2438,6 +2448,12 @@ impl Config {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn document_symbol(&self, source_root: Option<SourceRootId>) -> DocumentSymbolConfig {
 | 
				
			||||||
 | 
					        DocumentSymbolConfig {
 | 
				
			||||||
 | 
					            search_exclude_locals: *self.document_symbol_search_excludeLocals(source_root),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn workspace_symbol(&self, source_root: Option<SourceRootId>) -> WorkspaceSymbolConfig {
 | 
					    pub fn workspace_symbol(&self, source_root: Option<SourceRootId>) -> WorkspaceSymbolConfig {
 | 
				
			||||||
        WorkspaceSymbolConfig {
 | 
					        WorkspaceSymbolConfig {
 | 
				
			||||||
            search_exclude_imports: *self.workspace_symbol_search_excludeImports(source_root),
 | 
					            search_exclude_imports: *self.workspace_symbol_search_excludeImports(source_root),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,9 @@ use anyhow::Context;
 | 
				
			||||||
use base64::{Engine, prelude::BASE64_STANDARD};
 | 
					use base64::{Engine, prelude::BASE64_STANDARD};
 | 
				
			||||||
use ide::{
 | 
					use ide::{
 | 
				
			||||||
    AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve,
 | 
					    AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve,
 | 
				
			||||||
    FilePosition, FileRange, HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query,
 | 
					    FilePosition, FileRange, FileStructureConfig, HoverAction, HoverGotoTypeData,
 | 
				
			||||||
    RangeInfo, ReferenceCategory, Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit,
 | 
					    InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
 | 
				
			||||||
 | 
					    SingleResolve, SourceChange, TextEdit,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use ide_db::{FxHashMap, SymbolKind};
 | 
					use ide_db::{FxHashMap, SymbolKind};
 | 
				
			||||||
use itertools::Itertools;
 | 
					use itertools::Itertools;
 | 
				
			||||||
| 
						 | 
					@ -568,7 +569,14 @@ pub(crate) fn handle_document_symbol(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut parents: Vec<(lsp_types::DocumentSymbol, Option<usize>)> = Vec::new();
 | 
					    let mut parents: Vec<(lsp_types::DocumentSymbol, Option<usize>)> = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for symbol in snap.analysis.file_structure(file_id)? {
 | 
					    let config = snap.config.document_symbol(None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let structure_nodes = snap.analysis.file_structure(
 | 
				
			||||||
 | 
					        &FileStructureConfig { exclude_locals: config.search_exclude_locals },
 | 
				
			||||||
 | 
					        file_id,
 | 
				
			||||||
 | 
					    )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for symbol in structure_nodes {
 | 
				
			||||||
        let mut tags = Vec::new();
 | 
					        let mut tags = Vec::new();
 | 
				
			||||||
        if symbol.deprecated {
 | 
					        if symbol.deprecated {
 | 
				
			||||||
            tags.push(SymbolTag::DEPRECATED)
 | 
					            tags.push(SymbolTag::DEPRECATED)
 | 
				
			||||||
| 
						 | 
					@ -588,8 +596,7 @@ pub(crate) fn handle_document_symbol(
 | 
				
			||||||
        parents.push((doc_symbol, symbol.parent));
 | 
					        parents.push((doc_symbol, symbol.parent));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Builds hierarchy from a flat list, in reverse order (so that indices
 | 
					    // Builds hierarchy from a flat list, in reverse order (so that indices make sense)
 | 
				
			||||||
    // makes sense)
 | 
					 | 
				
			||||||
    let document_symbols = {
 | 
					    let document_symbols = {
 | 
				
			||||||
        let mut acc = Vec::new();
 | 
					        let mut acc = Vec::new();
 | 
				
			||||||
        while let Some((mut node, parent_idx)) = parents.pop() {
 | 
					        while let Some((mut node, parent_idx)) = parents.pop() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -610,6 +610,13 @@ The warnings will be indicated by a blue squiggly underline in code and a blue i
 | 
				
			||||||
the `Problems Panel`.
 | 
					the `Problems Panel`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## rust-analyzer.document.symbol.search.excludeLocals {#document.symbol.search.excludeLocals}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Default: `true`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exclude all locals from document symbol search.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## rust-analyzer.files.exclude {#files.exclude}
 | 
					## rust-analyzer.files.exclude {#files.exclude}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Default: `[]`
 | 
					Default: `[]`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1585,6 +1585,16 @@
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "title": "Document",
 | 
				
			||||||
 | 
					                "properties": {
 | 
				
			||||||
 | 
					                    "rust-analyzer.document.symbol.search.excludeLocals": {
 | 
				
			||||||
 | 
					                        "markdownDescription": "Exclude all locals from document symbol search.",
 | 
				
			||||||
 | 
					                        "default": true,
 | 
				
			||||||
 | 
					                        "type": "boolean"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                "title": "Files",
 | 
					                "title": "Files",
 | 
				
			||||||
                "properties": {
 | 
					                "properties": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue