mirror of
https://github.com/qvacua/vimr.git
synced 2024-11-28 02:54:31 +03:00
GH-264 Implement filter
This commit is contained in:
parent
c9e4626c32
commit
32e564cd3d
@ -288,7 +288,8 @@ static CFDataRef local_server_callback(CFMessagePortRef local, SInt32 msgid, CFD
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [NSData dataWithData:(__bridge NSData *) responseData];
|
||||
NSData *result = (__bridge_transfer NSData *) responseData;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *)neoVimServerExecutablePath {
|
||||
|
@ -39,6 +39,8 @@
|
||||
4B0C905B1D5DED69007753A3 /* NeoVimBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0C905A1D5DED69007753A3 /* NeoVimBuffer.m */; };
|
||||
4B0E22581D5DEDC700C072E6 /* NeoVimBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B0C90591D5DED69007753A3 /* NeoVimBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4B0E22591D5DF62E00C072E6 /* NeoVimBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0C905A1D5DED69007753A3 /* NeoVimBuffer.m */; };
|
||||
4B22F7F01D7C029400929B0E /* ScorerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B22F7EF1D7C029400929B0E /* ScorerTest.swift */; };
|
||||
4B22F7F21D7C6B9000929B0E /* ImageAndTextTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B22F7F11D7C6B9000929B0E /* ImageAndTextTableCell.swift */; };
|
||||
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B238BE01D3BF24200CBDD98 /* Application.swift */; };
|
||||
4B238BEC1D3ED54D00CBDD98 /* AppearancePrefPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B238BEB1D3ED54D00CBDD98 /* AppearancePrefPane.swift */; };
|
||||
4B2A2BEC1D02261F0074CE9A /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B2A2BE21D0225800074CE9A /* RxCocoa.framework */; };
|
||||
@ -227,6 +229,8 @@
|
||||
4B0C90591D5DED69007753A3 /* NeoVimBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeoVimBuffer.h; sourceTree = "<group>"; };
|
||||
4B0C905A1D5DED69007753A3 /* NeoVimBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NeoVimBuffer.m; sourceTree = "<group>"; };
|
||||
4B1BB3521D16C5E500CA4FEF /* InputTestView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTestView.swift; sourceTree = "<group>"; };
|
||||
4B22F7EF1D7C029400929B0E /* ScorerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScorerTest.swift; sourceTree = "<group>"; };
|
||||
4B22F7F11D7C6B9000929B0E /* ImageAndTextTableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageAndTextTableCell.swift; sourceTree = "<group>"; };
|
||||
4B238BE01D3BF24200CBDD98 /* Application.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||
4B238BEB1D3ED54D00CBDD98 /* AppearancePrefPane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppearancePrefPane.swift; sourceTree = "<group>"; };
|
||||
4B2A2BE21D0225800074CE9A /* RxCocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxCocoa.framework; path = Carthage/Build/Mac/RxCocoa.framework; sourceTree = SOURCE_ROOT; };
|
||||
@ -482,6 +486,7 @@
|
||||
4BD3BF921D32A95800082605 /* MainWindowComponent.swift */,
|
||||
4BDF501A1D77596500D8FBC3 /* OpenQuicklyWindowManager.swift */,
|
||||
4BDF50131D7617EA00D8FBC3 /* OpenQuicklyWindowComponent.swift */,
|
||||
4B22F7F11D7C6B9000929B0E /* ImageAndTextTableCell.swift */,
|
||||
4B238BED1D3ED55300CBDD98 /* Preferences */,
|
||||
);
|
||||
name = UI;
|
||||
@ -559,6 +564,7 @@
|
||||
1929BBC84557C8351EC6183E /* FileItemIgnorePatternTest.swift */,
|
||||
1929B5D977261F1EBFA9E8F1 /* FileUtilsTest.swift */,
|
||||
1929BC19C1BC19246AFF1621 /* MatcherTests.swift */,
|
||||
4B22F7EF1D7C029400929B0E /* ScorerTest.swift */,
|
||||
1929B41F745CDCDFE09ACDCF /* resources */,
|
||||
);
|
||||
path = VimRTests;
|
||||
@ -845,6 +851,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4B238BE11D3BF24200CBDD98 /* Application.swift in Sources */,
|
||||
4B22F7F21D7C6B9000929B0E /* ImageAndTextTableCell.swift in Sources */,
|
||||
4BDF50141D7617EA00D8FBC3 /* OpenQuicklyWindowComponent.swift in Sources */,
|
||||
4B6A70941D60E04200E12030 /* AppKitCommons.swift in Sources */,
|
||||
4BD3BF971D32B0DB00082605 /* MainWindowManager.swift in Sources */,
|
||||
@ -883,6 +890,7 @@
|
||||
1929B3BF1DB87B57559DC27D /* Matcher.swift in Sources */,
|
||||
1929B63CD9CBB9C122BD99A5 /* ScoredFileItem.swift in Sources */,
|
||||
1929B10DD8CD7EE0B8BE529F /* Scorer.swift in Sources */,
|
||||
4B22F7F01D7C029400929B0E /* ScorerTest.swift in Sources */,
|
||||
1929B4D3A4429651C2AF55E5 /* FoundationCommons.swift in Sources */,
|
||||
1929BEFEABA0448306CDB6D4 /* FileItemIgnorePatternTest.swift in Sources */,
|
||||
1929B7A2F2B423AA9740FD45 /* FileUtilsTest.swift in Sources */,
|
||||
|
@ -23,7 +23,7 @@ extension NSTableView {
|
||||
static func standardSourceListTableView() -> NSTableView {
|
||||
let tableView = NSTableView(frame: CGRect.zero)
|
||||
|
||||
tableView.addTableColumn(NSTableColumn.standardCellBasedColumn(withName: "name"))
|
||||
tableView.addTableColumn(NSTableColumn(identifier: "name"))
|
||||
tableView.rowSizeStyle = .Default
|
||||
tableView.sizeLastColumnToFit()
|
||||
tableView.allowsEmptySelection = false
|
||||
@ -36,20 +36,6 @@ extension NSTableView {
|
||||
}
|
||||
}
|
||||
|
||||
extension NSTableColumn {
|
||||
|
||||
static func standardCellBasedColumn(withName name: String) -> NSTableColumn {
|
||||
let tableColumn = NSTableColumn(identifier: name)
|
||||
|
||||
let textFieldCell = NSTextFieldCell()
|
||||
textFieldCell.allowsEditingTextAttributes = false
|
||||
textFieldCell.lineBreakMode = .ByTruncatingTail
|
||||
tableColumn.dataCell = textFieldCell
|
||||
|
||||
return tableColumn
|
||||
}
|
||||
}
|
||||
|
||||
extension NSScrollView {
|
||||
|
||||
static func standardScrollView() -> NSScrollView {
|
||||
|
@ -13,10 +13,10 @@
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Open Quickly" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" topStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="420" width="365" height="255"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="365" height="255"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
|
@ -3,7 +3,7 @@
|
||||
* See LICENSE
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
import Cocoa
|
||||
import RxSwift
|
||||
import EonilFileSystemEvents
|
||||
|
||||
@ -25,7 +25,7 @@ class FileItemService {
|
||||
private var ignoreToken = Token()
|
||||
|
||||
/// When at least this much of non-directory and visible files are scanned, they are emitted.
|
||||
private let emitChunkSize = 200
|
||||
private let emitChunkSize = 1000
|
||||
|
||||
private let scanDispatchQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
|
||||
private let monitorDispatchQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
|
||||
@ -34,10 +34,30 @@ class FileItemService {
|
||||
|
||||
private let fileSystemEventsLatency = Double(2)
|
||||
private var monitors = [NSURL: FileSystemEventMonitor]()
|
||||
|
||||
private let workspace = NSWorkspace.sharedWorkspace()
|
||||
private let iconsCache = NSCache()
|
||||
|
||||
init() {
|
||||
self.iconsCache.countLimit = 2000
|
||||
self.iconsCache.name = "icon-cache"
|
||||
}
|
||||
|
||||
func set(ignorePatterns patterns: Set<FileItemIgnorePattern>) {
|
||||
self.ignorePatterns = patterns
|
||||
}
|
||||
|
||||
func icon(forUrl url: NSURL) -> NSImage? {
|
||||
guard let path = url.path else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let icon = workspace.iconForFile(path)
|
||||
icon.size = CGSize(width: 16, height: 16)
|
||||
self.iconsCache.setObject(icon, forKey: url)
|
||||
|
||||
return icon
|
||||
}
|
||||
|
||||
func monitor(url url: NSURL) {
|
||||
guard let path = url.path else {
|
||||
|
45
VimR/ImageAndTextTableCell.swift
Normal file
45
VimR/ImageAndTextTableCell.swift
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Tae Won Ha - http://taewon.de - @hataewon
|
||||
* See LICENSE
|
||||
*/
|
||||
|
||||
import Cocoa
|
||||
import PureLayout
|
||||
|
||||
class ImageAndTextTableCell: NSView {
|
||||
|
||||
let textField: NSTextField = NSTextField(forAutoLayout: ())
|
||||
let imageView: NSImageView = NSImageView(forAutoLayout: ())
|
||||
|
||||
init(withIdentifier identifier: String) {
|
||||
super.init(frame: CGRect.zero)
|
||||
|
||||
self.identifier = identifier
|
||||
|
||||
let textField = self.textField
|
||||
textField.bordered = false
|
||||
textField.editable = false
|
||||
textField.lineBreakMode = .ByTruncatingTail
|
||||
textField.drawsBackground = false
|
||||
|
||||
let imageView = self.imageView
|
||||
|
||||
self.addSubview(textField)
|
||||
self.addSubview(imageView)
|
||||
|
||||
imageView.autoPinEdgeToSuperviewEdge(.Top, withInset: 2)
|
||||
imageView.autoPinEdgeToSuperviewEdge(.Left, withInset: 2)
|
||||
imageView.autoSetDimension(.Width, toSize: 16)
|
||||
imageView.autoSetDimension(.Height, toSize: 16)
|
||||
|
||||
// textField.autoSetDimension(.Height, toSize: 23)
|
||||
textField.autoPinEdgeToSuperviewEdge(.Top, withInset: 2)
|
||||
textField.autoPinEdgeToSuperviewEdge(.Right, withInset: 2)
|
||||
textField.autoPinEdgeToSuperviewEdge(.Bottom, withInset: 2)
|
||||
textField.autoPinEdge(.Left, toEdge: .Right, ofView: imageView, withOffset: 4)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
@ -25,11 +25,15 @@ class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableView
|
||||
private var scoredItems = [ScoredFileItem]()
|
||||
private var sortedScoredItems = [ScoredFileItem]()
|
||||
|
||||
private var cwdPathCompsCount = 0
|
||||
private var cwd = NSURL(fileURLWithPath: NSHomeDirectory(), isDirectory: true) {
|
||||
didSet {
|
||||
self.cwdPathCompsCount = self.cwd.pathComponents!.count
|
||||
self.cwdControl.URL = self.cwd
|
||||
}
|
||||
}
|
||||
|
||||
private let filterOpQueue = NSOperationQueue()
|
||||
|
||||
init(source: Observable<Any>, fileItemService: FileItemService) {
|
||||
self.fileItemService = fileItemService
|
||||
@ -37,40 +41,69 @@ class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableView
|
||||
super.init(source: source, nibName: "OpenQuicklyWindow")
|
||||
|
||||
self.window.delegate = self
|
||||
self.filterOpQueue.qualityOfService = .UserInitiated
|
||||
self.filterOpQueue.name = "open-quickly-filter-operation-queue"
|
||||
|
||||
self.searchField.rx_text
|
||||
.throttle(0.2, scheduler: MainScheduler.instance)
|
||||
.distinctUntilChanged()
|
||||
.subscribeOn(self.userInitiatedScheduler)
|
||||
.doOnNext { _ in
|
||||
self.scoredItems = []
|
||||
self.sortedScoredItems = []
|
||||
}
|
||||
.flatMapLatest { [unowned self] pattern -> Observable<[ScoredFileItem]> in
|
||||
if pattern.characters.count == 0 {
|
||||
return self.flatFiles
|
||||
.map { fileItems in
|
||||
return fileItems.concurrentChunkMap(50) { item in
|
||||
return ScoredFileItem(score: 0, url: item.url)
|
||||
}
|
||||
}
|
||||
.flatMapLatest { [unowned self] pattern in
|
||||
self.flatFiles.
|
||||
self.filterOpQueue.addOperationWithBlock {
|
||||
|
||||
}
|
||||
|
||||
let useFullPath = pattern.containsString("/")
|
||||
|
||||
return self.flatFiles
|
||||
.map { fileItems in
|
||||
return fileItems.concurrentChunkMap(50) { item in
|
||||
let url = item.url
|
||||
let target = useFullPath ? url.path! : url.lastPathComponent!
|
||||
return ScoredFileItem(score: Scorer.score(target, pattern: pattern), url: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribeNext { [unowned self] items in
|
||||
self.scoredItems.appendContentsOf(items)
|
||||
self.sortedScoredItems = Array(self.scoredItems.sort(>)[0...min(500, self.scoredItems.count - 1)])
|
||||
self.fileView.reloadData()
|
||||
}
|
||||
.subscribe(onNext: { [unowned self] pattern in
|
||||
NSLog("filtering \(pattern)")
|
||||
|
||||
})
|
||||
|
||||
// .subscribeOn(self.userInitiatedScheduler)
|
||||
// .doOnNext { _ in
|
||||
// self.scoredItems = []
|
||||
// self.sortedScoredItems = []
|
||||
// }
|
||||
// .subscribeOn(MainScheduler.instance)
|
||||
// .doOnNext { _ in
|
||||
// self.fileView.reloadData()
|
||||
// }
|
||||
// .subscribeOn(self.userInitiatedScheduler)
|
||||
// .flatMapLatest { [unowned self] pattern -> Observable<[ScoredFileItem]> in
|
||||
// NSLog("Flat map start: \(pattern)")
|
||||
// if pattern.characters.count == 0 {
|
||||
// return self.flatFiles
|
||||
// .map { fileItems in
|
||||
// return fileItems.concurrentChunkMap(200) { ScoredFileItem(score: 0, url: $0.url) }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// let useFullPath = pattern.containsString("/")
|
||||
// let cwdPath = self.cwd.path! + "/"
|
||||
//
|
||||
// let result: Observable<[ScoredFileItem]> = self.flatFiles
|
||||
// .map { fileItems in
|
||||
// return fileItems.concurrentChunkMap(200) { item in
|
||||
// let url = item.url
|
||||
// let target = useFullPath ? url.path!.stringByReplacingOccurrencesOfString(cwdPath, withString: "")
|
||||
// : url.lastPathComponent!
|
||||
//
|
||||
// return ScoredFileItem(score: Scorer.score(target, pattern: pattern), url: url)
|
||||
// }
|
||||
// }
|
||||
// NSLog("Flat map end: \(pattern)")
|
||||
//
|
||||
// return result
|
||||
// }
|
||||
// .doOnNext { [unowned self] items in
|
||||
// self.scoredItems.appendContentsOf(items)
|
||||
// self.sortedScoredItems = Array(self.scoredItems.sort(>)[0..<min(201, self.scoredItems.count)])
|
||||
// }
|
||||
// .observeOn(MainScheduler.instance)
|
||||
// .subscribe(onNext: { [unowned self] items in
|
||||
// self.fileView.reloadData()
|
||||
// })
|
||||
.addDisposableTo(self.disposeBag)
|
||||
}
|
||||
|
||||
@ -78,9 +111,10 @@ class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableView
|
||||
let searchField = self.searchField
|
||||
|
||||
let fileView = self.fileView
|
||||
fileView.intercellSpacing = CGSize(width: 4, height: 4)
|
||||
fileView.setDataSource(self)
|
||||
fileView.setDelegate(self)
|
||||
|
||||
|
||||
let fileScrollView = NSScrollView.standardScrollView()
|
||||
fileScrollView.autoresizesSubviews = true
|
||||
fileScrollView.documentView = fileView
|
||||
@ -133,14 +167,14 @@ class OpenQuicklyWindowComponent: WindowComponent, NSWindowDelegate, NSTableView
|
||||
let flatFiles = self.fileItemService.flatFileItems(ofUrl: self.cwd)
|
||||
.subscribeOn(self.userInitiatedScheduler)
|
||||
.replayAll()
|
||||
flatFiles.connect()
|
||||
flatFiles.connect().addDisposableTo(self.flatFilesDisposeBag)
|
||||
|
||||
flatFiles
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribeNext { [unowned self] items in
|
||||
.subscribe(onNext: { [unowned self] items in
|
||||
self.count += items.count
|
||||
self.countField.stringValue = "\(self.count) items"
|
||||
}
|
||||
})
|
||||
.addDisposableTo(self.flatFilesDisposeBag)
|
||||
|
||||
self.flatFiles = flatFiles
|
||||
@ -156,30 +190,70 @@ extension OpenQuicklyWindowComponent {
|
||||
func numberOfRowsInTableView(_: NSTableView) -> Int {
|
||||
return self.sortedScoredItems.count
|
||||
}
|
||||
|
||||
func tableView(_: NSTableView, objectValueForTableColumn _: NSTableColumn?, row: Int) -> AnyObject? {
|
||||
return self.sortedScoredItems[row].url.lastPathComponent!
|
||||
|
||||
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||
let url = self.sortedScoredItems[row].url
|
||||
let pathComps = url.pathComponents!
|
||||
let truncatedPathComps = pathComps[self.cwdPathCompsCount..<pathComps.count]
|
||||
let name = truncatedPathComps.last!
|
||||
let pathInfo = truncatedPathComps.dropLast().reverse().joinWithSeparator(" / ")
|
||||
|
||||
let result = NSMutableAttributedString(string: "\(name) — \(pathInfo)")
|
||||
result.addAttribute(NSForegroundColorAttributeName, value: NSColor.lightGrayColor(),
|
||||
range: NSRange(location:name.characters.count, length: pathInfo.characters.count + 3))
|
||||
|
||||
let cell = tableView.makeViewWithIdentifier("file-view-row", owner: self) as? ImageAndTextTableCell
|
||||
?? ImageAndTextTableCell(withIdentifier: "file-view-row")
|
||||
|
||||
cell.textField.attributedStringValue = result
|
||||
cell.imageView.image = self.fileItemService.icon(forUrl: url)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
// func tableView(_: NSTableView, objectValueForTableColumn _: NSTableColumn?, row: Int) -> AnyObject? {
|
||||
// let url = self.sortedScoredItems[row].url
|
||||
// let pathComps = self.sortedScoredItems[row].url.pathComponents!
|
||||
// let truncatedPathComps = pathComps[self.cwdPathCompsCount..<pathComps.count]
|
||||
// let name = truncatedPathComps.last!
|
||||
// let pathInfo = truncatedPathComps.dropLast().reverse().joinWithSeparator("/")
|
||||
//
|
||||
// let textAttachment = NSTextAttachment()
|
||||
// textAttachment.image = self.fileItemService.icon(forUrl: url)
|
||||
//
|
||||
// let result: NSMutableAttributedString = NSAttributedString(attachment: textAttachment).mutableCopy() as! NSMutableAttributedString
|
||||
// result.mutableString.appendString("\(name) — \(pathInfo)")
|
||||
// result.addAttribute(NSForegroundColorAttributeName, value: NSColor.lightGrayColor(),
|
||||
// range: NSRange(location:name.characters.count, length: pathInfo.characters.count + 3))
|
||||
//
|
||||
// return result
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: - NSTableViewDelegate
|
||||
extension OpenQuicklyWindowComponent {
|
||||
|
||||
func tableViewSelectionDidChange(_: NSNotification) {
|
||||
Swift.print("selection changed")
|
||||
// NSLog("\(#function): selection changed")
|
||||
}
|
||||
|
||||
// func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
|
||||
// return 34
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: - NSWindowDelegate
|
||||
extension OpenQuicklyWindowComponent {
|
||||
|
||||
func windowDidClose(notification: NSNotification) {
|
||||
self.searchField.stringValue = ""
|
||||
self.countField.stringValue = "0 items"
|
||||
func windowWillClose(notification: NSNotification) {
|
||||
self.flatFilesDisposeBag = DisposeBag()
|
||||
self.flatFiles = Observable.empty()
|
||||
self.count = 0
|
||||
|
||||
self.scoredItems = []
|
||||
self.sortedScoredItems = []
|
||||
self.flatFiles = Observable.empty()
|
||||
self.flatFilesDisposeBag = DisposeBag()
|
||||
|
||||
self.searchField.stringValue = ""
|
||||
self.countField.stringValue = "0 items"
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import RxSwift
|
||||
|
||||
class ScoredFileItem: Comparable {
|
||||
let score: Float
|
||||
let url: NSURL
|
||||
unowned let url: NSURL
|
||||
|
||||
init(score: Float, url: NSURL) {
|
||||
self.score = score
|
||||
|
@ -9,7 +9,7 @@ class Scorer {
|
||||
|
||||
static func score(target: String, pattern: String) -> Float {
|
||||
let wf = Matcher.wagnerFisherDistance(target, pattern: pattern)
|
||||
let fuzzy = Matcher.fuzzyIgnoringCase(target, pattern: pattern)
|
||||
// let fuzzy = Matcher.fuzzyIgnoringCase(target, pattern: pattern)
|
||||
let upper = Matcher.numberOfUppercaseMatches(target, pattern: pattern)
|
||||
let exactMatch = Matcher.exactMatchIgnoringCase(target, pattern: pattern)
|
||||
|
||||
@ -24,7 +24,7 @@ class Scorer {
|
||||
}
|
||||
|
||||
return (wf == 0 ? 0 : 5.0 / Float(wf))
|
||||
+ Float(fuzzy.matches)
|
||||
// + Float(fuzzy.matches)
|
||||
+ Float(upper)
|
||||
+ exactScore
|
||||
}
|
||||
|
20
VimRTests/ScorerTest.swift
Normal file
20
VimRTests/ScorerTest.swift
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Tae Won Ha - http://taewon.de - @hataewon
|
||||
* See LICENSE
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
import Nimble
|
||||
|
||||
class ScorerTest: XCTestCase {
|
||||
|
||||
func testScore() {
|
||||
let pattern = "s/nvv"
|
||||
let targets = [
|
||||
"SwiftNeoVim/NeoVimView.swift",
|
||||
"build/Release/NeoVimServer.dSYM/Contents/Resources/DWARF/NeoVimServer"
|
||||
]
|
||||
|
||||
expect(Scorer.score(targets[0], pattern: pattern)).to(beGreaterThan(Scorer.score(targets[1], pattern: pattern)))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user