Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazily Load Files #1438

Merged
merged 6 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
58798285292ED0FB0085B254 /* TerminalEmulatorView+Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58798281292ED0FB0085B254 /* TerminalEmulatorView+Coordinator.swift */; };
58798286292ED0FB0085B254 /* SwiftTerm+Color+Init.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58798283292ED0FB0085B254 /* SwiftTerm+Color+Init.swift */; };
5879828A292ED15F0085B254 /* SwiftTerm in Frameworks */ = {isa = PBXBuildFile; productRef = 58798289292ED15F0085B254 /* SwiftTerm */; };
587B60F82934124200D5CD8F /* WorkspaceClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B60F72934124100D5CD8F /* WorkspaceClientTests.swift */; };
587B60F82934124200D5CD8F /* CEWorkspaceFileManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B60F72934124100D5CD8F /* CEWorkspaceFileManagerTests.swift */; };
587B61012934170A00D5CD8F /* UnitTests_Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B61002934170A00D5CD8F /* UnitTests_Extensions.swift */; };
587B612E293419B700D5CD8F /* CodeFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B612D293419B700D5CD8F /* CodeFileTests.swift */; };
587B9D57292FC27A00AC7927 /* FolderMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B9D54292FC27A00AC7927 /* FolderMonitor.swift */; };
Expand Down Expand Up @@ -207,7 +207,7 @@
58822532292C280D00E83CDE /* UtilityAreaViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882251C292C280D00E83CDE /* UtilityAreaViewModel.swift */; };
58822534292C280D00E83CDE /* CursorLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5882251E292C280D00E83CDE /* CursorLocation.swift */; };
588847632992A2A200996D95 /* CEWorkspaceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588847622992A2A200996D95 /* CEWorkspaceFile.swift */; };
588847692992ABCA00996D95 /* Array+CEWorkspaceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588847682992ABCA00996D95 /* Array+CEWorkspaceFile.swift */; };
588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588847682992ABCA00996D95 /* Array+SortURLs.swift */; };
5894E59729FEF7740077E59C /* CEWorkspaceFile+Recursion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5894E59629FEF7740077E59C /* CEWorkspaceFile+Recursion.swift */; };
58A2E40C29C3975D005CB615 /* CEWorkspaceFileIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A2E40629C3975D005CB615 /* CEWorkspaceFileIcon.swift */; };
58A5DF7D2931787A00D1BD5D /* ShellClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A5DF7C2931787A00D1BD5D /* ShellClient.swift */; };
Expand Down Expand Up @@ -313,6 +313,7 @@
6CAAF69429BCD78600A1F48A /* (null) in Sources */ = {isa = PBXBuildFile; };
6CABB19E29C5591D00340467 /* NSTableViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */; };
6CABB1A129C5593800340467 /* OverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CABB1A029C5593800340467 /* OverlayView.swift */; };
6CB52DC92AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CB52DC82AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift */; };
6CB9144B29BEC7F100BC47F2 /* (null) in Sources */ = {isa = PBXBuildFile; };
6CBA0D512A1BF524002C6FAA /* SegmentedControlImproved.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */; };
6CBD1BC62978DE53006639D5 /* Font+Caption3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */; };
Expand Down Expand Up @@ -577,7 +578,7 @@
58798280292ED0FB0085B254 /* TerminalEmulatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TerminalEmulatorView.swift; sourceTree = "<group>"; };
58798281292ED0FB0085B254 /* TerminalEmulatorView+Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TerminalEmulatorView+Coordinator.swift"; sourceTree = "<group>"; };
58798283292ED0FB0085B254 /* SwiftTerm+Color+Init.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftTerm+Color+Init.swift"; sourceTree = "<group>"; };
587B60F72934124100D5CD8F /* WorkspaceClientTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WorkspaceClientTests.swift; sourceTree = "<group>"; };
587B60F72934124100D5CD8F /* CEWorkspaceFileManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CEWorkspaceFileManagerTests.swift; sourceTree = "<group>"; };
587B61002934170A00D5CD8F /* UnitTests_Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnitTests_Extensions.swift; sourceTree = "<group>"; };
587B612D293419B700D5CD8F /* CodeFileTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeFileTests.swift; sourceTree = "<group>"; };
587B9D54292FC27A00AC7927 /* FolderMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderMonitor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -672,7 +673,7 @@
5882251C292C280D00E83CDE /* UtilityAreaViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilityAreaViewModel.swift; sourceTree = "<group>"; };
5882251E292C280D00E83CDE /* CursorLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CursorLocation.swift; sourceTree = "<group>"; };
588847622992A2A200996D95 /* CEWorkspaceFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CEWorkspaceFile.swift; sourceTree = "<group>"; };
588847682992ABCA00996D95 /* Array+CEWorkspaceFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+CEWorkspaceFile.swift"; sourceTree = "<group>"; };
588847682992ABCA00996D95 /* Array+SortURLs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+SortURLs.swift"; sourceTree = "<group>"; };
5894E59629FEF7740077E59C /* CEWorkspaceFile+Recursion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CEWorkspaceFile+Recursion.swift"; sourceTree = "<group>"; };
589F3E342936185400E1A4DA /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
58A2E40629C3975D005CB615 /* CEWorkspaceFileIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CEWorkspaceFileIcon.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -763,6 +764,7 @@
6C97EBCB2978760400302F95 /* AcknowledgementsWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AcknowledgementsWindowController.swift; sourceTree = "<group>"; };
6CABB19C29C5591D00340467 /* NSTableViewWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NSTableViewWrapper.swift; path = CodeEdit/Features/QuickOpen/Views/NSTableViewWrapper.swift; sourceTree = SOURCE_ROOT; };
6CABB1A029C5593800340467 /* OverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverlayView.swift; sourceTree = "<group>"; };
6CB52DC82AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CEWorkspaceFileManager+FileManagement.swift"; sourceTree = "<group>"; };
6CBA0D502A1BF524002C6FAA /* SegmentedControlImproved.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentedControlImproved.swift; sourceTree = "<group>"; };
6CBD1BC52978DE53006639D5 /* Font+Caption3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Caption3.swift"; sourceTree = "<group>"; };
6CC9E4B129B5669900C97388 /* Environment+ActiveEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+ActiveEditor.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1527,17 +1529,17 @@
isa = PBXGroup;
children = (
587B61002934170A00D5CD8F /* UnitTests_Extensions.swift */,
587B60F52934124100D5CD8F /* WorkspaceClient */,
587B60F52934124100D5CD8F /* CEWorkspaceFileManager */,
);
path = Utils;
sourceTree = "<group>";
};
587B60F52934124100D5CD8F /* WorkspaceClient */ = {
587B60F52934124100D5CD8F /* CEWorkspaceFileManager */ = {
isa = PBXGroup;
children = (
587B60F72934124100D5CD8F /* WorkspaceClientTests.swift */,
587B60F72934124100D5CD8F /* CEWorkspaceFileManagerTests.swift */,
);
path = WorkspaceClient;
path = CEWorkspaceFileManager;
sourceTree = "<group>";
};
587B60FE293416C900D5CD8F /* Features */ = {
Expand Down Expand Up @@ -1870,6 +1872,7 @@
5894E59629FEF7740077E59C /* CEWorkspaceFile+Recursion.swift */,
58A2E40629C3975D005CB615 /* CEWorkspaceFileIcon.swift */,
58710158298EB80000951BA4 /* CEWorkspaceFileManager.swift */,
6CB52DC82AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift */,
6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */,
);
path = Models;
Expand All @@ -1878,7 +1881,7 @@
588847672992AAB800996D95 /* Array */ = {
isa = PBXGroup;
children = (
588847682992ABCA00996D95 /* Array+CEWorkspaceFile.swift */,
588847682992ABCA00996D95 /* Array+SortURLs.swift */,
);
path = Array;
sourceTree = "<group>";
Expand Down Expand Up @@ -3126,7 +3129,7 @@
B6EA1FF829DB78DB001BF195 /* ThemeSettingThemeRow.swift in Sources */,
587B9E7629301D8F00AC7927 /* GitTime.swift in Sources */,
587B9E5D29301D8F00AC7927 /* GitLabUserRouter.swift in Sources */,
588847692992ABCA00996D95 /* Array+CEWorkspaceFile.swift in Sources */,
588847692992ABCA00996D95 /* Array+SortURLs.swift in Sources */,
58822530292C280D00E83CDE /* FilterTextField.swift in Sources */,
6C82D6B929BFE34900495C54 /* HelpCommands.swift in Sources */,
6C147C4929A32A080089B630 /* EditorLayoutView.swift in Sources */,
Expand Down Expand Up @@ -3180,6 +3183,7 @@
6CDA84AD284C1BA000C1CC3A /* EditorTabBarContextMenu.swift in Sources */,
6C81916729B3E80700B75C92 /* ModifierKeysObserver.swift in Sources */,
587B9E8129301D8F00AC7927 /* PublicKey.swift in Sources */,
6CB52DC92AC8DC3E002E75B3 /* CEWorkspaceFileManager+FileManagement.swift in Sources */,
58F2EB0B292FB2B0004A9BDE /* AccountsSettings.swift in Sources */,
5882252A292C280D00E83CDE /* StatusBarToggleUtilityAreaButton.swift in Sources */,
B6AB09A12AAABAAE0003A3A6 /* EditorTabs.swift in Sources */,
Expand All @@ -3199,7 +3203,7 @@
buildActionMask = 2147483647;
files = (
583E528C29361B39001AB554 /* CodeEditUITests.swift in Sources */,
587B60F82934124200D5CD8F /* WorkspaceClientTests.swift in Sources */,
587B60F82934124200D5CD8F /* CEWorkspaceFileManagerTests.swift in Sources */,
587B61012934170A00D5CD8F /* UnitTests_Extensions.swift in Sources */,
283BDCC52972F236002AFF81 /* AcknowledgementsTests.swift in Sources */,
4EE96ECB2960565E00FFBEA8 /* DocumentsUnitTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/ChimeHQ/Rearrange",
"state" : {
"revision" : "8f97f721d8a08c6e01ab9f7460e53819bef72dfa",
"version" : "1.5.3"
"revision" : "0fb658e721c68495f6340c211cc6d4719e6b52d8",
"version" : "1.6.0"
}
},
{
Expand Down Expand Up @@ -248,8 +248,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/ChimeHQ/TextFormation",
"state" : {
"revision" : "2b56879bd7aa753a2ba97b271f456c59614b39d4",
"version" : "0.8.0"
"revision" : "b4987856bc860643ac2c9cdbc7d5f3e9ade68377",
"version" : "0.8.1"
}
},
{
Expand Down
131 changes: 45 additions & 86 deletions CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFile+Recursion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,113 +8,45 @@
import Foundation

extension CEWorkspaceFile {

func childrenDescription(tabCount: Int) -> String {
var myDetails = "\(String(repeating: "| ", count: max(tabCount - 1, 0)))\(tabCount != 0 ? "╰--" : "")"
myDetails += "\(url.path)"
if !self.isFolder { // if im a file, just return the url
return myDetails
} else { // if im a folder, return the url and its children's details
var childDetails = "\(myDetails)"
for child in children ?? [] {
childDetails += "\n\(child.childrenDescription(tabCount: tabCount + 1))"
}
return childDetails
}
}

/// Flattens the children of ``self`` recursively with depth.
/// Flattens the children of `self` recursively with depth.
/// - Parameters:
/// - depth: An int that indicates the how deep the tree files need to be flattened
/// - ignoringFolders: A boolean on whether to ignore files that are Folders
/// - fileManager: The workspace's file manager to use.
/// - Returns: An array of flattened `CEWorkspaceFiles`
func flattenedChildren(withDepth depth: Int, ignoringFolders: Bool) -> [CEWorkspaceFile] {
func flattenedChildren(
withDepth depth: Int,
ignoringFolders: Bool,
using fileManager: CEWorkspaceFileManager
) -> [CEWorkspaceFile] {
guard depth > 0 else { return [] }
guard self.isFolder else { return [self] }
var childItems: [CEWorkspaceFile] = ignoringFolders ? [] : [self]
children?.forEach { child in
fileManager.childrenOfFile(self)?.forEach { child in
childItems.append(contentsOf: child.flattenedChildren(
withDepth: depth - 1,
ignoringFolders: ignoringFolders
ignoringFolders: ignoringFolders,
using: fileManager
))
}
return childItems
}

/// Returns a list of `CEWorkspaceFiles` that are sibilings of ``self``.
/// Returns a list of `CEWorkspaceFiles` that are sibilings of `self`.
/// The `height` parameter lets the function navigate up the folder hierarchy to
/// select a starting point from which it should start flettening the items.
/// - Parameters:
/// - height: `Int` that tells where to start in the hierarchy
/// - ignoringFolders: Wether the sibling folders should be flattened
/// - fileManager: The workspace's file manager to use.
/// - Returns: A list of `FileSystemItems`
func flattenedSiblings(withHeight height: Int, ignoringFolders: Bool) -> [CEWorkspaceFile] {
func flattenedSiblings(
withHeight height: Int,
ignoringFolders: Bool,
using fileManager: CEWorkspaceFileManager
) -> [CEWorkspaceFile] {
let topMostParent = self.getParent(withHeight: height)
return topMostParent.flattenedChildren(withDepth: height, ignoringFolders: ignoringFolders)
}

/// Recursive function that returns the number of children
/// that contain the `searchString` in their path or their subitems' paths.
/// Returns `0` if the item is not a folder.
/// - Parameters:
/// - searchString: The string
/// - ignoredStrings: The prefixes to ignore if they prefix file names
/// - Returns: The number of children that match the conditiions
func appearanceWithinChildrenOf(searchString: String, ignoredStrings: [String] = [".", "~"]) -> Int {
var count = 0
guard self.isFolder else { return 0 }
for child in self.children ?? [] {
var isIgnored: Bool = false
for ignoredString in ignoredStrings where child.name.hasPrefix(ignoredString) {
isIgnored = true // can use regex later
}

if isIgnored {
continue
}

guard !searchString.isEmpty else { count += 1; continue }
if child.isFolder {
count += child.appearanceWithinChildrenOf(searchString: searchString) > 0 ? 1 : 0
} else {
count += child.name.lowercased().contains(searchString.lowercased()) ? 1 : 0
}
}
return count
}

/// Function that returns an array of the children
/// that contain the `searchString` in their path or their subitems' paths.
/// Similar to `appearanceWithinChildrenOf(searchString: String)`
/// Returns `[]` if the item is not a folder.
/// - Parameter searchString: The string
/// - Parameter ignoredStrings: The prefixes to ignore if they prefix file names
/// - Returns: The children that match the conditiions
func childrenSatisfying(searchString: String, ignoredStrings: [String] = [".", "~"]) -> [CEWorkspaceFile] {
var satisfyingChildren: [CEWorkspaceFile] = []
guard self.isFolder else { return [] }
for child in self.children ?? [] {
var isIgnored: Bool = false
for ignoredString in ignoredStrings where child.name.hasPrefix(ignoredString) {
isIgnored = true // can use regex later
}

if isIgnored {
continue
}

guard !searchString.isEmpty else { satisfyingChildren.append(child); continue }
if child.isFolder {
if child.appearanceWithinChildrenOf(searchString: searchString) > 0 {
satisfyingChildren.append(child)
}
} else {
if child.name.lowercased().contains(searchString.lowercased()) {
satisfyingChildren.append(child)
}
}
}
return satisfyingChildren
return topMostParent.flattenedChildren(withDepth: height, ignoringFolders: ignoringFolders, using: fileManager)
}

/// Using the current instance of `FileSystemItem` it will walk back up the Workspace file hiarchy
Expand All @@ -131,4 +63,31 @@ extension CEWorkspaceFile {
return topmostParent
}

#if DEBUG
austincondiff marked this conversation as resolved.
Show resolved Hide resolved
/// Print a debug description of the file.
/// - Parameters:
/// - tabCount: The number of tabs to tab the description over (for recursive calls)
/// - fileManager: The file manager to use to find children.
/// - Returns: A string describing the file and it's children.
/// - Authors: Mattijs Eikelenboom, KaiTheRedNinja. *Moved from 7c27b1e*
func childrenDescription(tabCount: Int = 0, using fileManager: CEWorkspaceFileManager) -> String {
var myDetails = "\(String(repeating: "| ", count: max(tabCount - 1, 0)))\(tabCount != 0 ? "╰--" : "")"
myDetails += "\(url.path(percentEncoded: false))"
if !self.isFolder { // if im a file, just return the url
return myDetails
} else { // if im a folder, return the url and its children's details
var childDetails = "\(myDetails)"
if fileManager.hasLoadedChildrenFor(file: self) {
for child in fileManager.childrenOfFile(self) ?? [] {
childDetails += "\n\(child.childrenDescription(tabCount: tabCount + 1, using: fileManager))"
}
} else {
// Disabling for debug line.
// swiftlint:disable:next line_length
childDetails += "\n\(String(repeating: "| ", count: max(tabCount - 1, 0)))\(tabCount != 0 ? "╰--" : "") Children Not Loaded"
}
return childDetails
}
}
#endif
}
Loading