@@ -23,6 +23,11 @@ pub enum StructureNodeKind {
2323 Region ,
2424}
2525
26+ #[ derive( Debug , Clone ) ]
27+ pub struct FileStructureConfig {
28+ pub exclude_locals : bool ,
29+ }
30+
2631// Feature: File Structure
2732//
2833// Provides a tree of the symbols defined in the file. Can be used to
@@ -36,21 +41,24 @@ pub enum StructureNodeKind {
3641// | VS Code | <kbd>Ctrl+Shift+O</kbd> |
3742//
3843// 
39- pub ( crate ) fn file_structure ( file : & SourceFile ) -> Vec < StructureNode > {
44+ pub ( crate ) fn file_structure (
45+ file : & SourceFile ,
46+ config : & FileStructureConfig ,
47+ ) -> Vec < StructureNode > {
4048 let mut res = Vec :: new ( ) ;
4149 let mut stack = Vec :: new ( ) ;
4250
4351 for event in file. syntax ( ) . preorder_with_tokens ( ) {
4452 match event {
4553 WalkEvent :: Enter ( NodeOrToken :: Node ( node) ) => {
46- if let Some ( mut symbol) = structure_node ( & node) {
54+ if let Some ( mut symbol) = structure_node ( & node, config ) {
4755 symbol. parent = stack. last ( ) . copied ( ) ;
4856 stack. push ( res. len ( ) ) ;
4957 res. push ( symbol) ;
5058 }
5159 }
5260 WalkEvent :: Leave ( NodeOrToken :: Node ( node) ) => {
53- if structure_node ( & node) . is_some ( ) {
61+ if structure_node ( & node, config ) . is_some ( ) {
5462 stack. pop ( ) . unwrap ( ) ;
5563 }
5664 }
@@ -71,7 +79,7 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
7179 res
7280}
7381
74- fn structure_node ( node : & SyntaxNode ) -> Option < StructureNode > {
82+ fn structure_node ( node : & SyntaxNode , config : & FileStructureConfig ) -> Option < StructureNode > {
7583 fn decl < N : HasName + HasAttrs > ( node : N , kind : StructureNodeKind ) -> Option < StructureNode > {
7684 decl_with_detail ( & node, None , kind)
7785 }
@@ -187,6 +195,10 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
187195 Some ( node)
188196 } ,
189197 ast:: LetStmt ( it) => {
198+ if config. exclude_locals {
199+ return None ;
200+ }
201+
190202 let pat = it. pat( ) ?;
191203
192204 let mut label = String :: new( ) ;
@@ -254,9 +266,19 @@ mod tests {
254266
255267 use super :: * ;
256268
269+ const DEFAULT_CONFIG : FileStructureConfig = FileStructureConfig { exclude_locals : true } ;
270+
257271 fn check ( #[ rust_analyzer:: rust_fixture] ra_fixture : & str , expect : Expect ) {
272+ check_with_config ( ra_fixture, & DEFAULT_CONFIG , expect) ;
273+ }
274+
275+ fn check_with_config (
276+ #[ rust_analyzer:: rust_fixture] ra_fixture : & str ,
277+ config : & FileStructureConfig ,
278+ expect : Expect ,
279+ ) {
258280 let file = SourceFile :: parse ( ra_fixture, span:: Edition :: CURRENT ) . ok ( ) . unwrap ( ) ;
259- let structure = file_structure ( & file) ;
281+ let structure = file_structure ( & file, config ) ;
260282 expect. assert_debug_eq ( & structure)
261283 }
262284
@@ -701,13 +723,264 @@ fn let_statements() {
701723 ),
702724 deprecated: false,
703725 },
726+ ]
727+ "# ] ] ,
728+ ) ;
729+ }
730+
731+ #[ test]
732+ fn test_file_structure_include_locals ( ) {
733+ check_with_config (
734+ r#"
735+ struct Foo {
736+ x: i32
737+ }
738+
739+ mod m {
740+ fn bar1() {}
741+ fn bar2<T>(t: T) -> T {}
742+ fn bar3<A,
743+ B>(a: A,
744+ b: B) -> Vec<
745+ u32
746+ > {}
747+ }
748+
749+ enum E { X, Y(i32) }
750+ type T = ();
751+ static S: i32 = 42;
752+ const C: i32 = 42;
753+ trait Tr {}
754+ trait Alias = Tr;
755+
756+ macro_rules! mc {
757+ () => {}
758+ }
759+
760+ fn let_statements() {
761+ let x = 42;
762+ let mut y = x;
763+ let Foo {
764+ ..
765+ } = Foo { x };
766+ _ = ();
767+ let _ = g();
768+ }
769+ "# ,
770+ & FileStructureConfig { exclude_locals : false } ,
771+ expect ! [ [ r#"
772+ [
773+ StructureNode {
774+ parent: None,
775+ label: "Foo",
776+ navigation_range: 8..11,
777+ node_range: 1..26,
778+ kind: SymbolKind(
779+ Struct,
780+ ),
781+ detail: None,
782+ deprecated: false,
783+ },
784+ StructureNode {
785+ parent: Some(
786+ 0,
787+ ),
788+ label: "x",
789+ navigation_range: 18..19,
790+ node_range: 18..24,
791+ kind: SymbolKind(
792+ Field,
793+ ),
794+ detail: Some(
795+ "i32",
796+ ),
797+ deprecated: false,
798+ },
799+ StructureNode {
800+ parent: None,
801+ label: "m",
802+ navigation_range: 32..33,
803+ node_range: 28..158,
804+ kind: SymbolKind(
805+ Module,
806+ ),
807+ detail: None,
808+ deprecated: false,
809+ },
810+ StructureNode {
811+ parent: Some(
812+ 2,
813+ ),
814+ label: "bar1",
815+ navigation_range: 43..47,
816+ node_range: 40..52,
817+ kind: SymbolKind(
818+ Function,
819+ ),
820+ detail: Some(
821+ "fn()",
822+ ),
823+ deprecated: false,
824+ },
825+ StructureNode {
826+ parent: Some(
827+ 2,
828+ ),
829+ label: "bar2",
830+ navigation_range: 60..64,
831+ node_range: 57..81,
832+ kind: SymbolKind(
833+ Function,
834+ ),
835+ detail: Some(
836+ "fn<T>(t: T) -> T",
837+ ),
838+ deprecated: false,
839+ },
840+ StructureNode {
841+ parent: Some(
842+ 2,
843+ ),
844+ label: "bar3",
845+ navigation_range: 89..93,
846+ node_range: 86..156,
847+ kind: SymbolKind(
848+ Function,
849+ ),
850+ detail: Some(
851+ "fn<A, B>(a: A, b: B) -> Vec< u32 >",
852+ ),
853+ deprecated: false,
854+ },
855+ StructureNode {
856+ parent: None,
857+ label: "E",
858+ navigation_range: 165..166,
859+ node_range: 160..180,
860+ kind: SymbolKind(
861+ Enum,
862+ ),
863+ detail: None,
864+ deprecated: false,
865+ },
866+ StructureNode {
867+ parent: Some(
868+ 6,
869+ ),
870+ label: "X",
871+ navigation_range: 169..170,
872+ node_range: 169..170,
873+ kind: SymbolKind(
874+ Variant,
875+ ),
876+ detail: None,
877+ deprecated: false,
878+ },
879+ StructureNode {
880+ parent: Some(
881+ 6,
882+ ),
883+ label: "Y",
884+ navigation_range: 172..173,
885+ node_range: 172..178,
886+ kind: SymbolKind(
887+ Variant,
888+ ),
889+ detail: None,
890+ deprecated: false,
891+ },
892+ StructureNode {
893+ parent: None,
894+ label: "T",
895+ navigation_range: 186..187,
896+ node_range: 181..193,
897+ kind: SymbolKind(
898+ TypeAlias,
899+ ),
900+ detail: Some(
901+ "()",
902+ ),
903+ deprecated: false,
904+ },
905+ StructureNode {
906+ parent: None,
907+ label: "S",
908+ navigation_range: 201..202,
909+ node_range: 194..213,
910+ kind: SymbolKind(
911+ Static,
912+ ),
913+ detail: Some(
914+ "i32",
915+ ),
916+ deprecated: false,
917+ },
918+ StructureNode {
919+ parent: None,
920+ label: "C",
921+ navigation_range: 220..221,
922+ node_range: 214..232,
923+ kind: SymbolKind(
924+ Const,
925+ ),
926+ detail: Some(
927+ "i32",
928+ ),
929+ deprecated: false,
930+ },
931+ StructureNode {
932+ parent: None,
933+ label: "Tr",
934+ navigation_range: 239..241,
935+ node_range: 233..244,
936+ kind: SymbolKind(
937+ Trait,
938+ ),
939+ detail: None,
940+ deprecated: false,
941+ },
942+ StructureNode {
943+ parent: None,
944+ label: "Alias",
945+ navigation_range: 251..256,
946+ node_range: 245..262,
947+ kind: SymbolKind(
948+ TraitAlias,
949+ ),
950+ detail: None,
951+ deprecated: false,
952+ },
953+ StructureNode {
954+ parent: None,
955+ label: "mc",
956+ navigation_range: 277..279,
957+ node_range: 264..296,
958+ kind: SymbolKind(
959+ Macro,
960+ ),
961+ detail: None,
962+ deprecated: false,
963+ },
964+ StructureNode {
965+ parent: None,
966+ label: "let_statements",
967+ navigation_range: 301..315,
968+ node_range: 298..429,
969+ kind: SymbolKind(
970+ Function,
971+ ),
972+ detail: Some(
973+ "fn()",
974+ ),
975+ deprecated: false,
976+ },
704977 StructureNode {
705978 parent: Some(
706- 27 ,
979+ 15 ,
707980 ),
708981 label: "x",
709- navigation_range: 684..685 ,
710- node_range: 680..691 ,
982+ navigation_range: 328..329 ,
983+ node_range: 324..335 ,
711984 kind: SymbolKind(
712985 Local,
713986 ),
@@ -716,11 +989,11 @@ fn let_statements() {
716989 },
717990 StructureNode {
718991 parent: Some(
719- 27 ,
992+ 15 ,
720993 ),
721994 label: "mut y",
722- navigation_range: 700..705 ,
723- node_range: 696..710 ,
995+ navigation_range: 344..349 ,
996+ node_range: 340..354 ,
724997 kind: SymbolKind(
725998 Local,
726999 ),
@@ -729,11 +1002,11 @@ fn let_statements() {
7291002 },
7301003 StructureNode {
7311004 parent: Some(
732- 27 ,
1005+ 15 ,
7331006 ),
7341007 label: "Foo { .. }",
735- navigation_range: 719..741 ,
736- node_range: 715..754 ,
1008+ navigation_range: 363..385 ,
1009+ node_range: 359..398 ,
7371010 kind: SymbolKind(
7381011 Local,
7391012 ),
@@ -742,11 +1015,11 @@ fn let_statements() {
7421015 },
7431016 StructureNode {
7441017 parent: Some(
745- 27 ,
1018+ 15 ,
7461019 ),
7471020 label: "_",
748- navigation_range: 804..805 ,
749- node_range: 800..812 ,
1021+ navigation_range: 419..420 ,
1022+ node_range: 415..427 ,
7501023 kind: SymbolKind(
7511024 Local,
7521025 ),
0 commit comments