@@ -40,7 +40,9 @@ module SolutionExplorer =
4040 path: string *
4141 name: string *
4242 virtualPath: string option *
43- projectPath: string
43+ projectPath: string *
44+ itemType: string option *
45+ metadata: Map< string, string> option
4446 | PackageReference of parent : Model option ref * path : string * name : string * projectPath : string
4547 | ProjectReference of parent : Model option ref * path : string * name : string * projectPath : string
4648
@@ -97,7 +99,7 @@ module SolutionExplorer =
9799 | ProjectLanguageNotSupported( parent, _, _) -> parent
98100 | Project( parent, _, _, _, _, _, _, _) -> parent
99101 | Folder( parent, _, _, _, _) -> parent
100- | File( parent, _, _, _, _) -> parent
102+ | File( parent, _, _, _, _, _, _ ) -> parent
101103 | PackageReference( parent, _, _, _) -> parent
102104 | ProjectReference( parent, _, _, _) -> parent
103105
@@ -131,7 +133,32 @@ module SolutionExplorer =
131133 setParentRefs childs result
132134 result
133135 else
134- File( ref None, entry.FilePath, entry.Key, Some entry.VirtualPath, projPath)
136+ File( ref None, entry.FilePath, entry.Key, Some entry.VirtualPath, projPath, None, None)
137+
138+ let rec toModelWithMetadata
139+ ( projPath : string )
140+ ( files : ( string * string * string option * Map < string , string > option ) list )
141+ ( entry : NodeEntry )
142+ =
143+ if entry.Children.Length > 0 then
144+ let childs =
145+ entry.Children |> Seq.map ( toModelWithMetadata projPath files) |> Seq.toList
146+
147+ let result = Folder( ref None, entry.Key, entry.FilePath, childs, projPath)
148+ setParentRefs childs result
149+ result
150+ else
151+ let fileMetadata =
152+ files
153+ |> List.tryFind ( fun ( _ , path , _ , _ ) -> path = entry.FilePath)
154+ |> Option.map ( fun ( _ , _ , itemType , metadata ) -> ( itemType, metadata))
155+
156+ let ( itemType , metadata ) =
157+ match fileMetadata with
158+ | Some( it, md) -> ( it, md)
159+ | None -> ( None, None)
160+
161+ File( ref None, entry.FilePath, entry.Key, Some entry.VirtualPath, projPath, itemType, metadata)
135162
136163 let buildTree projPath ( files : ( string * string ) list ) =
137164 let projDir = dirName projPath
@@ -146,15 +173,67 @@ module SolutionExplorer =
146173
147174 entry.Children |> Seq.rev |> Seq.map ( toModel projPath) |> Seq.toList
148175
176+ let buildTreeWithMetadata projPath ( files : ( string * string * string option * Map < string , string > option ) list ) =
177+ let projDir = dirName projPath
178+
179+ let entry =
180+ { Key = " "
181+ FilePath = projDir
182+ VirtualPath = " "
183+ Children = [] }
184+
185+ files
186+ |> List.iter ( fun ( virtualPath , path , _ , _ ) -> add' entry virtualPath path)
187+
188+ entry.Children
189+ |> Seq.rev
190+ |> Seq.map ( toModelWithMetadata projPath files)
191+ |> Seq.toList
192+
193+ let ignoredItemTypes =
194+ Set.ofList
195+ [ " AssemblyMetadata"
196+ " BaseApplicationManifest"
197+ " CodeAnalysisImport"
198+ " COMReference"
199+ " COMFileReference"
200+ " Import"
201+ " InternalsVisibleTo"
202+ " NativeReference"
203+ " TrimmerRootAssembly"
204+ " Using"
205+ " Protobuf" ]
206+
207+ // File extension to item type mapping
208+ let getItemTypeForFile ( filePath : string ) =
209+ let ext = node.path.extname( filePath) .ToLowerInvariant()
210+
211+ match ext with
212+ | " .fs"
213+ | " .fsi" -> " Compile"
214+ | " .fsx" -> " Compile"
215+ | " .fsl" -> " FsLex"
216+ | " .fsy" -> " FsYacc"
217+ | " .txt"
218+ | " .md"
219+ | " .json"
220+ | " .xml"
221+ | " .config" -> " Content"
222+ | " .resx" -> " EmbeddedResource"
223+ | _ -> " Content" // Default fallback
224+
225+ let shouldShowItem ( item : ProjectResponseItem ) =
226+ not ( ignoredItemTypes.Contains( item.Name))
227+
149228 let private getProjectModel ( proj : Project ) =
150229 let projects = Project.getLoaded () |> Seq.toArray
151230
152231 let files =
153232 proj.Items
154- |> Seq.filter ( fun p -> p.Name = " Compile " )
155- |> Seq.map ( fun p -> p.VirtualPath, p.FilePath)
233+ |> Seq.filter shouldShowItem
234+ |> Seq.map ( fun p -> p.VirtualPath, p.FilePath, Some p.Name , Some p.Metadata )
156235 |> Seq.toList
157- |> buildTree proj.Project
236+ |> buildTreeWithMetadata proj.Project
158237
159238 let packageRefs =
160239 proj.PackageReferences
@@ -231,7 +310,7 @@ module SolutionExplorer =
231310 | WorkspacePeekFoundSolutionItemKind.Folder folder ->
232311 let files =
233312 folder.Files
234- |> Array.map ( fun f -> Model.File( ref None, f, node.path.basename ( f), None, " " ))
313+ |> Array.map ( fun f -> Model.File( ref None, f, node.path.basename ( f), None, " " , None , None ))
235314
236315 let items = folder.Items |> Array.map getItem
237316
@@ -303,7 +382,7 @@ module SolutionExplorer =
303382 | PackageReferenceList _ -> " Package References"
304383 | ProjectReferencesList(_, refs, _) -> " Project References"
305384 | Folder(_, n, _, _, _) -> n
306- | File(_, _, name, _, _) -> name
385+ | File(_, _, name, _, _, _, _ ) -> name
307386 | PackageReference(_, _, name, _) ->
308387 if name.ToLowerInvariant() .EndsWith( " .dll" ) then
309388 name.Substring( 0 , name.Length - 4 )
@@ -376,7 +455,7 @@ module SolutionExplorer =
376455
377456 let command =
378457 match element with
379- | File(_, p, _, _, _) ->
458+ | File(_, p, _, _, _, _, _ ) ->
380459 let c = createEmpty< Command>
381460 c.command <- " vscode.open"
382461 c.title <- " open"
@@ -413,7 +492,7 @@ module SolutionExplorer =
413492
414493 let icon , resourceUri =
415494 match element with
416- | File(_, path, _, _, _)
495+ | File(_, path, _, _, _, _, _ )
417496 | ProjectNotLoaded(_, path, _)
418497 | ProjectLoading(_, path, _)
419498 | ProjectFailedToLoad(_, path, _, _)
@@ -454,7 +533,7 @@ module SolutionExplorer =
454533 | PackageReference(_, _, _, pp)
455534 | ProjectReference(_, _, _, pp) -> Some( label ti + " ||" + pp)
456535 | Folder _ -> None
457- | File(_, _, _, _, pp) ->
536+ | File(_, _, _, _, pp, _, _ ) ->
458537 ( resourceUri
459538 |> Option.map ( fun u -> ( label ti + " ||" + u.toString () + " ||" + pp)))
460539 | _ -> ( resourceUri |> Option.map ( fun u -> ( label ti + " ||" + u.toString ())))
@@ -552,7 +631,7 @@ module SolutionExplorer =
552631
553632 let rec private getModelPerFile ( model : Model ) : ( string * Model ) list =
554633 match model with
555- | File(_, path, _, _, _)
634+ | File(_, path, _, _, _, _, _ )
556635 | ProjectNotLoaded(_, path, _)
557636 | ProjectLoading(_, path, _)
558637 | ProjectFailedToLoad(_, path, _, _)
@@ -664,7 +743,7 @@ module SolutionExplorer =
664743 | Folder _
665744 | PackageReference _
666745 | ProjectReference _ -> false
667- | File(_, filePath, _, _, _) ->
746+ | File(_, filePath, _, _, _, _, _ ) ->
668747 let projDir = node.path.dirname proj
669748 // Need to compute the relative path from the project in order to match the user input
670749 let relativeFilePathFromProject = node.path.relative ( projDir, filePath)
@@ -692,7 +771,7 @@ module SolutionExplorer =
692771 let rec private tryFindParentProject ( model : Model ) =
693772 match model with
694773 | Project _ -> Some model
695- | File( parent, _, _, _, _) ->
774+ | File( parent, _, _, _, _, _, _ ) ->
696775 match parent.Value with
697776 | Some parent -> tryFindParentProject parent
698777 | None -> None
@@ -831,7 +910,7 @@ module SolutionExplorer =
831910 " fsharp.explorer.moveUp" ,
832911 objfy2 ( fun m ->
833912 match unbox m with
834- | File(_, _, name, Some virtPath, proj) -> FsProjEdit.moveFileUpPath proj virtPath
913+ | File(_, _, name, Some virtPath, proj, _, _ ) -> FsProjEdit.moveFileUpPath proj virtPath
835914 | _ -> undefined
836915 |> ignore
837916
@@ -843,7 +922,7 @@ module SolutionExplorer =
843922 " fsharp.explorer.moveDown" ,
844923 objfy2 ( fun m ->
845924 match unbox m with
846- | File(_, _, name, Some virtPath, proj) -> FsProjEdit.moveFileDownPath proj virtPath
925+ | File(_, _, name, Some virtPath, proj, _, _ ) -> FsProjEdit.moveFileDownPath proj virtPath
847926 | _ -> undefined
848927 |> ignore
849928
@@ -855,7 +934,7 @@ module SolutionExplorer =
855934 " fsharp.explorer.removeFile" ,
856935 objfy2 ( fun m ->
857936 match unbox m with
858- | File(_, filePath, _, _, proj) ->
937+ | File(_, filePath, _, _, proj, _, _ ) ->
859938 promise {
860939 let projDir = node.path.dirname proj
861940 // Need to compute the relative path from the project in order to match the user input
@@ -876,7 +955,7 @@ module SolutionExplorer =
876955 " fsharp.explorer.renameFile" ,
877956 objfy2 ( fun m ->
878957 match unbox m with
879- | File( parent, filePath, _, Some virtualPath, _) ->
958+ | File( parent, filePath, _, Some virtualPath, _, _, _ ) ->
880959 match parent.Value with
881960 | Some model ->
882961 match tryFindParentProject model with
@@ -914,7 +993,7 @@ module SolutionExplorer =
914993 " fsharp.explorer.addAbove" ,
915994 objfy2 ( fun m ->
916995 match unbox m with
917- | File( parent, _, _, Some virtPath, _) ->
996+ | File( parent, _, _, Some virtPath, _, _, _ ) ->
918997 match parent.Value with
919998 | Some model ->
920999 match tryFindParentProject model with
@@ -938,7 +1017,7 @@ module SolutionExplorer =
9381017 " fsharp.explorer.addBelow" ,
9391018 objfy2 ( fun m ->
9401019 match unbox m with
941- | File( parent, _, _, Some virtPath, _) ->
1020+ | File( parent, _, _, Some virtPath, _, _, _ ) ->
9421021 match parent.Value with
9431022 | Some model ->
9441023 match tryFindParentProject model with
0 commit comments