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:
parent
be6dd77279
commit
6d94db4a1a
@ -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 */,
|
||||
|
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Tae Won Ha - http://taewon.de - @hataewon
|
||||
* See LICENSE
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol Copyable {
|
||||
|
||||
associatedtype InstanceType
|
||||
|
||||
func copy() -> InstanceType
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user