Skip to content

Commit 698b75e

Browse files
authored
Project navigator files watch fixes (#1452)
* project navigator files watch * add comments * fix lint
1 parent f8627cf commit 698b75e

File tree

4 files changed

+43
-34
lines changed

4 files changed

+43
-34
lines changed

CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFileManager.swift

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -187,33 +187,28 @@ final class CEWorkspaceFileManager {
187187
/// - Parameter events: An array of events that occurred.
188188
private func fileSystemEventReceived(events: [DirectoryEventStream.Event]) {
189189
DispatchQueue.main.async {
190-
var eventHandledCount = 0
190+
var files: Set<CEWorkspaceFile> = []
191191
for event in events {
192-
var directory = event.directory
193-
if directory.last == "/" {
194-
directory.removeLast()
195-
}
196-
guard let item = self.getFile(directory) else {
192+
// Event returns file/folder that was changed, but in tree we need to update it's parent
193+
let parent = "/" + event.path.split(separator: "/").dropLast().joined(separator: "/")
194+
guard let parentItem = self.getFile(parent) else {
197195
return
198196
}
197+
199198
switch event.eventType {
200-
case .changeInDirectory, .itemChangedOwner, .itemCloned, .itemModified, .itemRenamed, .itemCreated:
201-
try? self.rebuildFiles(fromItem: item)
199+
case .changeInDirectory, .itemChangedOwner, .itemModified:
200+
// Can be ignored for now, these I think not related to tree changes
201+
continue
202202
case .rootChanged:
203203
// TODO: Handle workspace root changing.
204204
continue
205-
case .itemRemoved:
206-
// Update the file's parent.
207-
if let parent = item.parent {
208-
try? self.rebuildFiles(fromItem: parent)
209-
} else {
210-
try? self.rebuildFiles(fromItem: item)
211-
}
205+
case .itemCreated, .itemCloned, .itemRemoved, .itemRenamed:
206+
try? self.rebuildFiles(fromItem: parentItem)
207+
files.insert(parentItem)
212208
}
213-
eventHandledCount += 1
214209
}
215-
if eventHandledCount > 0 {
216-
self.notifyObservers(updatedItems: Set(events.compactMap { self.getFile($0.directory) }))
210+
if !files.isEmpty {
211+
self.notifyObservers(updatedItems: files)
217212
}
218213
}
219214
}
@@ -237,8 +232,10 @@ final class CEWorkspaceFileManager {
237232
)
238233

239234
// test for deleted children, and remove them from the index
235+
// Folders may or may not have slash at the end, this will normalize check
236+
let directoryContentsUrlsRelativePaths = directoryContentsUrls.map({ $0.relativePath })
240237
for (idx, oldURL) in (childrenMap[fileItem.id] ?? []).map({ URL(filePath: $0) }).enumerated().reversed()
241-
where !directoryContentsUrls.contains(oldURL) {
238+
where !directoryContentsUrlsRelativePaths.contains(oldURL.relativePath) {
242239
flattenedFileItems.removeValue(forKey: oldURL.relativePath)
243240
childrenMap[fileItem.id]?.remove(at: idx)
244241
}

CodeEdit/Features/CEWorkspace/Models/DirectoryEventStream.swift

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ class DirectoryEventStream {
4141
private let debounceDuration: TimeInterval
4242

4343
struct Event {
44-
let directory: String
44+
let path: String
4545
let eventType: FSEvent
46-
let deepRebuild: Bool
4746
}
4847

4948
/// Initialize the event stream and begin listening for events.
@@ -85,9 +84,14 @@ class DirectoryEventStream {
8584
pathsToWatch,
8685
UInt64(kFSEventStreamEventIdSinceNow),
8786
debounceDuration,
88-
UInt32(
89-
kFSEventStreamCreateFlagNoDefer
90-
& kFSEventStreamCreateFlagWatchRoot
87+
FSEventStreamCreateFlags(
88+
kFSEventStreamCreateFlagUseCFTypes
89+
// This will listen for file changes
90+
| kFSEventStreamCreateFlagFileEvents
91+
// This provides additional information, like fileId,
92+
// it is useful when file renamed, because it's firing to separate events with old and new path,
93+
// but they can be linked by file id
94+
| kFSEventStreamCreateFlagUseExtendedData
9195
)
9296
) {
9397
self.streamRef = ref
@@ -124,18 +128,23 @@ class DirectoryEventStream {
124128
_ eventFlags: UnsafePointer<FSEventStreamEventFlags>,
125129
_ eventIds: UnsafePointer<FSEventStreamEventId>
126130
) {
127-
let eventPaths = eventPaths.bindMemory(to: UnsafePointer<CChar>.self, capacity: numEvents)
131+
guard let eventDictionaries = unsafeBitCast(eventPaths, to: NSArray.self) as? [NSDictionary] else {
132+
return
133+
}
134+
128135
var events: [Event] = []
129-
for idx in 0..<numEvents {
130-
let pathPtr = eventPaths.advanced(by: idx).pointee
131-
let path = String(cString: pathPtr)
132-
let flags = eventFlags.advanced(by: idx).pointee
133-
let deepScan = Int(flags) & kFSEventStreamEventFlagMustScanSubDirs > 0 ? true : false // Deep scan?
134-
guard let event = getEventFromFlags(flags) else {
136+
137+
for (index, dictionary) in eventDictionaries.enumerated() {
138+
// Get get file id use dictionary[kFSEventStreamEventExtendedFileIDKey] as? UInt64
139+
guard let path = dictionary[kFSEventStreamEventExtendedDataPathKey] as? String,
140+
let event = getEventFromFlags(eventFlags[index])
141+
else {
135142
continue
136143
}
137-
events.append(Event(directory: path, eventType: event, deepRebuild: deepScan))
144+
145+
events.append(.init(path: path, eventType: event))
138146
}
147+
139148
callback(events)
140149
}
141150

CodeEdit/Features/NavigatorArea/FindNavigator/FindNavigatorModeSelector.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct FindNavigatorModeSelector: View {
3939
if let firstMode = selectedMode.first {
4040
newSelectedMode.append(contentsOf: [firstMode, searchMode])
4141
if let thirdMode = searchMode.children.first {
42-
if let selectedThirdMode = selectedMode.third, (searchMode.children.contains(selectedThirdMode)) {
42+
if let selectedThirdMode = selectedMode.third, searchMode.children.contains(selectedThirdMode) {
4343
newSelectedMode.append(selectedThirdMode)
4444
} else {
4545
newSelectedMode.append(thirdMode)

CodeEdit/Features/NavigatorArea/ProjectNavigator/OutlineView/ProjectNavigatorOutlineView.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ struct ProjectNavigatorOutlineView: NSViewControllerRepresentable {
6868
var controller: ProjectNavigatorViewController?
6969

7070
func fileManagerUpdated(updatedItems: Set<CEWorkspaceFile>) {
71+
guard let outlineView = controller?.outlineView else { return }
72+
7173
for item in updatedItems {
72-
controller?.outlineView?.reloadItem(item)
74+
outlineView.reloadItem(item, reloadChildren: true)
7375
}
76+
7477
controller?.updateSelection(itemID: workspace.editorManager.activeEditor.selectedTab?.id)
7578
}
7679

0 commit comments

Comments
 (0)