@@ -227,188 +227,6 @@ class IssueNavigatorViewModel: ObservableObject {
227227 }
228228}
229229
230- /// Protocol defining the common interface for nodes in the issue navigator
231- protocol IssueNode : Identifiable , Hashable {
232- var id : UUID { get }
233- var name : String { get }
234- var isExpandable : Bool { get }
235- var nsIcon : NSImage { get }
236- }
237-
238- /// Represents the project (root) node in the issue navigator
239- class ProjectIssueNode : IssueNode , ObservableObject , Equatable {
240- let id : UUID = UUID ( )
241- let name : String
242-
243- @Published var files : [ FileIssueNode ]
244- @Published var isExpanded : Bool
245-
246- var nsIcon : NSImage {
247- return NSImage ( systemSymbolName: " folder.fill " , accessibilityDescription: " Root folder " ) !
248- }
249-
250- var isExpandable : Bool {
251- !files. isEmpty
252- }
253-
254- var diagnosticsCount : Int {
255- files. reduce ( 0 ) { $0 + $1. diagnostics. count }
256- }
257-
258- var errorCount : Int {
259- files. reduce ( 0 ) { $0 + $1. diagnostics. filter { $0. diagnostic. severity == . error } . count }
260- }
261-
262- var warningCount : Int {
263- files. reduce ( 0 ) { $0 + $1. diagnostics. filter { $0. diagnostic. severity == . warning } . count }
264- }
265-
266- init ( name: String , files: [ FileIssueNode ] = [ ] , isExpanded: Bool = true ) {
267- self . name = name
268- self . files = files
269- self . isExpanded = isExpanded
270- }
271-
272- static func == ( lhs: ProjectIssueNode , rhs: ProjectIssueNode ) -> Bool {
273- lhs. id == rhs. id
274- }
275-
276- func hash( into hasher: inout Hasher ) {
277- hasher. combine ( id)
278- }
279- }
280-
281- /// Represents a file node in the issue navigator
282- class FileIssueNode : IssueNode , ObservableObject , Equatable {
283- let id : UUID = UUID ( )
284- let uri : DocumentUri
285- let name : String
286-
287- @Published var diagnostics : [ DiagnosticIssueNode ]
288- @Published var isExpanded : Bool
289-
290- /// Returns the extension of the file or an empty string if no extension is present.
291- var type : FileIcon . FileType {
292- let fileExtension = ( uri as NSString ) . pathExtension. lowercased ( )
293- if !fileExtension. isEmpty {
294- if let type = FileIcon . FileType ( rawValue: fileExtension) {
295- return type
296- }
297- }
298- return . txt
299- }
300-
301- /// Returns a `Color` for a specific `fileType`
302- ///
303- /// If not specified otherwise this will return `Color.accentColor`
304- var iconColor : SwiftUI . Color {
305- FileIcon . iconColor ( fileType: type)
306- }
307-
308- /// Return the icon of the file as `NSImage`
309- var nsIcon : NSImage {
310- let systemImage = FileIcon . fileIcon ( fileType: type)
311- if let customImage = NSImage . symbol ( named: systemImage) {
312- return customImage
313- } else {
314- return NSImage ( systemSymbolName: systemImage, accessibilityDescription: systemImage)
315- ?? NSImage ( systemSymbolName: " doc " , accessibilityDescription: " doc " ) !
316- }
317- }
318-
319- var isExpandable : Bool {
320- !diagnostics. isEmpty
321- }
322-
323- var errorCount : Int {
324- diagnostics. filter { $0. diagnostic. severity == . error } . count
325- }
326-
327- var warningCount : Int {
328- diagnostics. filter { $0. diagnostic. severity == . warning } . count
329- }
330-
331- init ( uri: DocumentUri , name: String ? = nil , diagnostics: [ DiagnosticIssueNode ] = [ ] , isExpanded: Bool = false ) {
332- self . uri = uri
333- self . name = name ?? ( URL ( string: uri) ? . lastPathComponent ?? " Unknown " )
334- self . diagnostics = diagnostics
335- self . isExpanded = isExpanded
336- }
337-
338- static func == ( lhs: FileIssueNode , rhs: FileIssueNode ) -> Bool {
339- lhs. id == rhs. id
340- }
341-
342- func hash( into hasher: inout Hasher ) {
343- hasher. combine ( id)
344- }
345- }
346-
347- /// Represents a diagnostic node in the issue navigator
348- class DiagnosticIssueNode : IssueNode , ObservableObject , Equatable {
349- let id : UUID = UUID ( )
350- let diagnostic : Diagnostic
351- let fileUri : DocumentUri
352-
353- var name : String {
354- diagnostic. message. trimmingCharacters ( in: . newlines)
355- }
356-
357- var isExpandable : Bool {
358- false
359- }
360-
361- var nsIcon : NSImage {
362- switch diagnostic. severity {
363- case . error:
364- return NSImage (
365- systemSymbolName: " xmark.octagon.fill " ,
366- accessibilityDescription: " Error "
367- ) !
368- case . warning:
369- return NSImage ( systemSymbolName: " exclamationmark.triangle.fill " , accessibilityDescription: " Warning " ) !
370- case . information:
371- return NSImage ( systemSymbolName: " exclamationmark.triangle.fill " , accessibilityDescription: " Information " ) !
372- case . hint:
373- return NSImage ( systemSymbolName: " lightbulb.fill " , accessibilityDescription: " Hint " ) !
374- case nil :
375- return NSImage ( systemSymbolName: " circle.fill " , accessibilityDescription: " Unknown Issue Type " ) !
376- }
377- }
378-
379- var severityColor : NSColor {
380- switch diagnostic. severity {
381- case . error:
382- return . errorRed
383- case . warning:
384- return . warningYellow
385- case . information:
386- return . blue
387- case . hint:
388- return . gray
389- case nil :
390- return . secondaryLabelColor
391- }
392- }
393-
394- var locationString : String {
395- " Line \( diagnostic. range. start. line + 1 ) , Column \( diagnostic. range. start. character + 1 ) "
396- }
397-
398- init ( diagnostic: Diagnostic , fileUri: DocumentUri ) {
399- self . diagnostic = diagnostic
400- self . fileUri = fileUri
401- }
402-
403- static func == ( lhs: DiagnosticIssueNode , rhs: DiagnosticIssueNode ) -> Bool {
404- lhs. id == rhs. id
405- }
406-
407- func hash( into hasher: inout Hasher ) {
408- hasher. combine ( id)
409- }
410- }
411-
412230/// Options for filtering diagnostics in the issue navigator
413231struct IssueFilterOptions {
414232 var showErrors : Bool = true
0 commit comments