1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-29 00:34:26 +03:00

GH-450 Do not share file items for file browser

This commit is contained in:
Tae Won Ha 2017-05-14 00:03:20 +02:00
parent be6dd77279
commit 6d94db4a1a
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
4 changed files with 49 additions and 91 deletions

View File

@ -24,7 +24,6 @@
1929B3557317755A43513B17 /* OpenQuicklyWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B71A92C24FEFE79A851E /* OpenQuicklyWindow.swift */; };
1929B370A275F8C70AD5AA08 /* UrlCommonsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B11D672134E52A256A7F /* UrlCommonsTest.swift */; };
1929B3AC66EFE35D68C020E3 /* PreviewToolReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BFB0F294F3714D5E095F /* PreviewToolReducer.swift */; };
1929B3CEE0C1A1850E9CCE2F /* BasicTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B2FBE11048569391E092 /* BasicTypes.swift */; };
1929B3F5743967125F357C9F /* Matcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BEEB33113B0E33C3830F /* Matcher.swift */; };
1929B462CD4935AFF6D69457 /* FileItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B7CB4863F80230C32D3C /* FileItem.swift */; };
1929B4B00D7BB191A9A6532D /* HtmlPreviewToolReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BE5AEA3D0980860EED50 /* HtmlPreviewToolReducer.swift */; };
@ -365,7 +364,6 @@
1929B15B7EDC9B0F40E5E95C /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
1929B1A51F076E088EF4CCA4 /* server_globals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = server_globals.h; sourceTree = "<group>"; };
1929B1DC584C89C477E83FA2 /* HttpServerService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpServerService.swift; sourceTree = "<group>"; };
1929B2FBE11048569391E092 /* BasicTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicTypes.swift; sourceTree = "<group>"; };
1929B34FC23D805A8B29E8F7 /* Context.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Context.swift; sourceTree = "<group>"; };
1929B364460D86F17E80943C /* PrefService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrefService.swift; sourceTree = "<group>"; };
1929B365A6434354B568B04F /* FileMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileMonitor.swift; sourceTree = "<group>"; };
@ -932,7 +930,6 @@
1929B9AF20D7BD6E5C975128 /* FoundationCommons.swift */,
4BB1BEA81D48773200463C29 /* RxSwiftCommons.swift */,
4B6A70951D6100E300E12030 /* SwiftCommons.swift */,
1929B2FBE11048569391E092 /* BasicTypes.swift */,
);
name = Commons;
sourceTree = "<group>";
@ -1500,7 +1497,6 @@
1929BD3F9E609BFADB27584B /* Scorer.swift in Sources */,
4BB409EE1DDA77E9005F39A2 /* ProxyWorkspaceBar.swift in Sources */,
1929B0E0C3BC59F52713D5A2 /* FoundationCommons.swift in Sources */,
1929B3CEE0C1A1850E9CCE2F /* BasicTypes.swift in Sources */,
1929BD2F41D93ADFF43C1C98 /* NetUtils.m in Sources */,
1929BE0DAEE9664C5BCFA211 /* States.swift in Sources */,
1929B4FEE6EB56EF3F56B805 /* Context.swift in Sources */,

View File

@ -1,13 +0,0 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
protocol Copyable {
associatedtype InstanceType
func copy() -> InstanceType
}

View File

@ -5,9 +5,7 @@
import Foundation
class FileItem : CustomStringConvertible, Hashable, Comparable, Copyable {
typealias InstanceType = FileItem
class FileItem : CustomStringConvertible, Hashable, Comparable {
static func ==(left: FileItem, right: FileItem) -> Bool {
return left.url == right.url
@ -55,20 +53,7 @@ class FileItem : CustomStringConvertible, Hashable, Comparable, Copyable {
self.url = url
}
func copy() -> FileItem {
let item = FileItem(self.url)
item.needsScanChildren = self.needsScanChildren
item.childrenScanned = self.childrenScanned
item.children = self.children
return item
}
func child(with url: URL) -> FileItem? {
guard let idx = self.children.index(where: { $0.url == url }) else {
return nil
}
return self.children[idx]
return self.children.first { $0.url == url }
}
}

View File

@ -18,8 +18,7 @@ class FileOutlineView: NSOutlineView,
self.emit = emitter.typedEmit()
self.uuid = state.uuid
self.root = FileBrowserItem(fileItem: state.root)
self.fileSystemRoot = state.root
self.root = FileBrowserItem(state.cwd)
self.isShowHidden = state.fileBrowserShowHidden
super.init(frame: .zero)
@ -49,7 +48,7 @@ class FileOutlineView: NSOutlineView,
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [unowned self] state in
self.lastFileSystemUpdateMark = state.lastFileSystemUpdate.mark
self.update(state.lastFileSystemUpdate.payload)
self.update(state.lastFileSystemUpdate.payload.url)
})
.disposed(by: self.disposeBag)
@ -69,7 +68,7 @@ class FileOutlineView: NSOutlineView,
if state.cwd != self.cwd {
self.lastFileSystemUpdateMark = state.lastFileSystemUpdate.mark
self.cwd = state.cwd
self.root = FileBrowserItem(state.cwd)
reloadData = true
}
@ -89,21 +88,20 @@ class FileOutlineView: NSOutlineView,
while let item = stack.popLast() {
if item.isChildrenScanned == false {
item.children = FileItemUtils.sortedChildren(for: item.fileItem.url, root: self.fileSystemRoot)
.map(FileBrowserItem.init)
item.children = FileUtils.directDescendants(of: item.url).map(FileBrowserItem.init)
item.isChildrenScanned = true
}
itemsToExpand.append(item)
if item.fileItem.url.isDirectParent(of: url) {
if let targetItem = item.children.first(where: { $0.fileItem.url == url }) {
if item.url.isDirectParent(of: url) {
if let targetItem = item.children.first(where: { $0.url == url }) {
itemsToExpand.append(targetItem)
}
break
}
stack.append(contentsOf: item.children.filter { $0.fileItem.url.isParent(of: url) })
stack.append(contentsOf: item.children.filter { $0.url.isParent(of: url) })
}
itemsToExpand.forEach { self.expandItem($0) }
@ -119,19 +117,18 @@ class FileOutlineView: NSOutlineView,
fileprivate let uuid: String
fileprivate var lastFileSystemUpdateMark = Token()
fileprivate var cwd: URL = FileUtils.userHomeUrl
fileprivate var cwd: URL {
return self.root.url
}
fileprivate var isShowHidden: Bool
fileprivate var root: FileBrowserItem
fileprivate let fileSystemRoot: FileItem
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func update(_ fileItem: FileItem) {
let url = fileItem.url
fileprivate func update(_ url: URL) {
guard let fileBrowserItem = self.fileBrowserItem(with: url) else {
return
}
@ -189,12 +186,15 @@ class FileOutlineView: NSOutlineView,
childrenToRecurse.forEach(self.update)
}
fileprivate func sortedChildren(of url: URL) -> [FileBrowserItem] {
return FileUtils.directDescendants(of: url).map(FileBrowserItem.init).sorted()
}
fileprivate func update(_ fileBrowserItem: FileBrowserItem) {
let url = fileBrowserItem.fileItem.url
NSLog("\(#function) updating \(url.lastPathComponent)")
let url = fileBrowserItem.url
// Sort the array to keep the order.
let newChildren = FileItemUtils.sortedChildren(for: url, root: self.fileSystemRoot).map(FileBrowserItem.init)
let newChildren = self.sortedChildren(of: url)
self.handleRemovals(for: fileBrowserItem, new: newChildren)
self.handleAdditions(for: fileBrowserItem, new: newChildren)
@ -219,7 +219,7 @@ class FileOutlineView: NSOutlineView,
return nil
}
return parent.child(with: parent.fileItem.url.appendingPathComponent(childName))
return parent.child(with: parent.url.appendingPathComponent(childName))
}
}
}
@ -228,17 +228,13 @@ class FileOutlineView: NSOutlineView,
extension FileOutlineView {
fileprivate func prepare(_ children: [FileBrowserItem]) -> [FileBrowserItem] {
return self.isShowHidden ? children : children.filter { !$0.fileItem.isHidden }
return self.isShowHidden ? children : children.filter { !$0.url.isHidden }
}
func outlineView(_: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
if item == nil {
let rootFileItem = FileItemUtils.item(for: self.cwd, root: self.fileSystemRoot)
?? FileItemUtils.item(for: FileUtils.userHomeUrl, root: self.fileSystemRoot)!
self.root = FileBrowserItem(fileItem: rootFileItem)
if self.root.isChildrenScanned == false {
self.root.children = FileItemUtils.sortedChildren(for: self.cwd, root: self.fileSystemRoot)
.map(FileBrowserItem.init)
self.root.children = sortedChildren(of: self.cwd)
self.root.isChildrenScanned = true
}
@ -249,12 +245,9 @@ extension FileOutlineView {
return 0
}
let fileItem = fileBrowserItem.fileItem
if fileItem.isDir {
if fileBrowserItem.url.isDir {
if fileBrowserItem.isChildrenScanned == false {
let fileItemChildren = FileItemUtils.sortedChildren(for: fileItem.url, root: self.fileSystemRoot)
fileBrowserItem.fileItem.children = fileItemChildren
fileBrowserItem.children = fileItemChildren.map(FileBrowserItem.init)
fileBrowserItem.children = self.sortedChildren(of: fileBrowserItem.url)
fileBrowserItem.isChildrenScanned = true
}
@ -285,7 +278,7 @@ extension FileOutlineView {
return false
}
return fileBrowserItem.fileItem.isDir
return fileBrowserItem.url.isDir
}
@objc(outlineView: objectValueForTableColumn:byItem:)
@ -309,7 +302,7 @@ extension FileOutlineView {
return 0
}
return ImageAndTextTableCell.width(with: fileBrowserItem.fileItem.url.lastPathComponent)
return ImageAndTextTableCell.width(with: fileBrowserItem.url.lastPathComponent)
+ (CGFloat($0.level + 2) * (self.indentationPerLevel + 2)) // + 2 just to have a buffer... -_-
}.max() ?? column.width
@ -326,7 +319,7 @@ extension FileOutlineView {
// It seems like that caching the widths is slower due to thread-safeness of NSCache...
let cellWidth = items.concurrentChunkMap(20) {
let result = ImageAndTextTableCell.width(with: $0.fileItem.url.lastPathComponent)
let result = ImageAndTextTableCell.width(with: $0.url.lastPathComponent)
return result
}.max() ?? column.width
@ -353,9 +346,9 @@ extension FileOutlineView {
let cachedCell = (self.make(withIdentifier: "file-view-row", owner: self) as? ImageAndTextTableCell)?.reset()
let cell = cachedCell ?? ImageAndTextTableCell(withIdentifier: "file-view-row")
cell.text = fileBrowserItem.fileItem.url.lastPathComponent
let icon = FileUtils.icon(forUrl: fileBrowserItem.fileItem.url)
cell.image = fileBrowserItem.fileItem.isHidden ? icon?.tinting(with: NSColor.white.withAlphaComponent(0.4)) : icon
cell.text = fileBrowserItem.url.lastPathComponent
let icon = FileUtils.icon(forUrl: fileBrowserItem.url)
cell.image = fileBrowserItem.url.isHidden ? icon?.tinting(with: NSColor.white.withAlphaComponent(0.4)) : icon
return cell
}
@ -377,11 +370,11 @@ extension FileOutlineView {
return
}
if item.fileItem.isDir {
if item.url.isDir {
self.toggle(item: item)
} else {
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .default))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .default))
)
}
}
@ -392,7 +385,7 @@ extension FileOutlineView {
}
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .newTab))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .newTab))
)
}
@ -402,7 +395,7 @@ extension FileOutlineView {
}
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .currentTab))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .currentTab))
)
}
@ -412,7 +405,7 @@ extension FileOutlineView {
}
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .horizontalSplit))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .horizontalSplit))
)
}
@ -422,7 +415,7 @@ extension FileOutlineView {
}
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .verticalSplit))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .verticalSplit))
)
}
@ -431,12 +424,12 @@ extension FileOutlineView {
return
}
guard item.fileItem.isDir else {
guard item.url.isDir else {
return
}
self.emit(
UuidAction(uuid: self.uuid, action: .setAsWorkingDirectory(item.fileItem.url))
UuidAction(uuid: self.uuid, action: .setAsWorkingDirectory(item.url))
)
}
}
@ -450,7 +443,7 @@ extension FileOutlineView {
}
if item.action == #selector(setAsWorkingDirectory(_:)) {
return clickedItem.fileItem.isDir
return clickedItem.url.isDir
}
return true
@ -473,11 +466,11 @@ extension FileOutlineView {
switch char {
case " ", "\r": // Why "\r" and not "\n"?
if item.fileItem.isDir || item.fileItem.isPackage {
if item.url.isDir || item.url.isPackage {
self.toggle(item: item)
} else {
self.emit(
UuidAction(uuid: self.uuid, action: .open(url: item.fileItem.url, mode: .newTab))
UuidAction(uuid: self.uuid, action: .open(url: item.url, mode: .newTab))
)
}
@ -490,33 +483,30 @@ extension FileOutlineView {
fileprivate class FileBrowserItem: Hashable, Comparable, CustomStringConvertible {
static func ==(left: FileBrowserItem, right: FileBrowserItem) -> Bool {
return left.fileItem == right.fileItem
return left.url == right.url
}
static func <(left: FileBrowserItem, right: FileBrowserItem) -> Bool {
return left.fileItem.url.lastPathComponent < right.fileItem.url.lastPathComponent
return left.url.lastPathComponent < right.url.lastPathComponent
}
var hashValue: Int {
return self.fileItem.hashValue
return self.url.hashValue
}
var description: String {
return self.fileItem.url.path
return self.url.path
}
let fileItem: FileItem
let url: URL
var children: [FileBrowserItem] = []
var isChildrenScanned = false
/**
`fileItem` is copied. Children are _not_ populated.
*/
init(fileItem: FileItem) {
self.fileItem = fileItem.copy()
init(_ url: URL) {
self.url = url
}
func child(with url: URL) -> FileBrowserItem? {
return self.children.first { $0.fileItem.url == url }
return self.children.first { $0.url == url }
}
}