mirror of
https://github.com/qvacua/vimr.git
synced 2024-11-24 03:25:03 +03:00
GH-264 Play around with scoring
This commit is contained in:
parent
8ea4a958cd
commit
0f0ccf542a
@ -40,17 +40,22 @@ class Matcher {
|
||||
}
|
||||
|
||||
static func numberOfUppercaseMatches(target: String, pattern: String) -> Int {
|
||||
let tscalars = target.unicodeScalars.filter { uppercaseCharSet.longCharacterIsMember($0.value) }
|
||||
var tscalars = target.unicodeScalars.filter { uppercaseCharSet.longCharacterIsMember($0.value) }
|
||||
|
||||
guard tscalars.count > 0 else {
|
||||
let count = tscalars.count
|
||||
guard count > 0 else {
|
||||
return 0
|
||||
}
|
||||
|
||||
let pscalars = pattern.uppercaseString.unicodeScalars
|
||||
let pidxStart = pscalars.startIndex
|
||||
let pidx = tscalars.reduce(pidxStart) { pscalars[$0] == $1 ? $0.successor() : $0 }
|
||||
|
||||
return pidxStart.distanceTo(pidx)
|
||||
|
||||
pscalars.forEach { scalar in
|
||||
if let idx = tscalars.indexOf(scalar) {
|
||||
tscalars.removeAtIndex(idx)
|
||||
}
|
||||
}
|
||||
|
||||
return count - tscalars.count
|
||||
}
|
||||
|
||||
/// Matches `pattern` to `target` in a fuzzy way.
|
||||
|
@ -52,6 +52,10 @@ class OpenQuicklyFilterOperation: NSOperation {
|
||||
|
||||
var result = [ScoredFileItem]()
|
||||
var spinLock = OS_SPINLOCK_INIT
|
||||
|
||||
let cleanedPattern = useFullPath ? self.pattern.stringByReplacingOccurrencesOfString("/", withString: "")
|
||||
: self.pattern
|
||||
|
||||
dispatch_apply(chunksCount, dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] idx in
|
||||
if self.cancelled {
|
||||
return
|
||||
@ -67,10 +71,15 @@ class OpenQuicklyFilterOperation: NSOperation {
|
||||
}
|
||||
|
||||
let url = $0.url
|
||||
let target = useFullPath ? url.path!.stringByReplacingOccurrencesOfString(cwdPath, withString: "")
|
||||
: url.lastPathComponent!
|
||||
|
||||
return ScoredFileItem(score: Scorer.score(target, pattern: self.pattern), url: url)
|
||||
|
||||
if useFullPath {
|
||||
let target = url.path!.stringByReplacingOccurrencesOfString(cwdPath, withString: "")
|
||||
.stringByReplacingOccurrencesOfString("/", withString: "")
|
||||
|
||||
return ScoredFileItem(score: Scorer.score(target, pattern: cleanedPattern), url: url)
|
||||
}
|
||||
|
||||
return ScoredFileItem(score: Scorer.score(url.lastPathComponent!, pattern: cleanedPattern), url: url)
|
||||
}
|
||||
|
||||
if self.cancelled {
|
||||
|
@ -7,10 +7,10 @@ import Foundation
|
||||
import RxSwift
|
||||
|
||||
class ScoredFileItem: Comparable {
|
||||
let score: Float
|
||||
let score: Int
|
||||
unowned let url: NSURL
|
||||
|
||||
init(score: Float, url: NSURL) {
|
||||
init(score: Int, url: NSURL) {
|
||||
self.score = score
|
||||
self.url = url
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import Foundation
|
||||
|
||||
class Scorer {
|
||||
|
||||
static func score(target: String, pattern: String) -> Float {
|
||||
static func score(target: String, pattern: String) -> Int {
|
||||
let wf = Matcher.wagnerFisherDistance(target, pattern: pattern)
|
||||
let fuzzy = Matcher.fuzzyIgnoringCase(target, pattern: pattern)
|
||||
let upper = Matcher.numberOfUppercaseMatches(target, pattern: pattern)
|
||||
let exactMatch = Matcher.exactMatchIgnoringCase(target, pattern: pattern)
|
||||
|
||||
let exactScore: Float
|
||||
let exactScore: Int
|
||||
switch exactMatch {
|
||||
case .none:
|
||||
exactScore = 0
|
||||
@ -22,10 +22,12 @@ class Scorer {
|
||||
case .prefix, .contains, .suffix:
|
||||
exactScore = 5
|
||||
}
|
||||
|
||||
return (wf == 0 ? 0 : 2.5 / Float(wf))
|
||||
+ Float(fuzzy.matches)
|
||||
+ Float(upper)
|
||||
+ exactScore
|
||||
|
||||
let wfScore = 0 - (wf / 10)
|
||||
|
||||
return exactScore
|
||||
+ wfScore
|
||||
+ fuzzy.matches
|
||||
+ 2 * upper
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ class MatcherTest: XCTestCase {
|
||||
}
|
||||
|
||||
func testUppercaseMatcher() {
|
||||
expect(Matcher.numberOfUppercaseMatches(self.target, pattern: "xct")).to(equal(0))
|
||||
expect(Matcher.numberOfUppercaseMatches("SwiftNeoVimNeoVimView.swift", pattern: "swnvv")).to(equal(4))
|
||||
expect(Matcher.numberOfUppercaseMatches(self.target, pattern: "xct")).to(equal(2))
|
||||
expect(Matcher.numberOfUppercaseMatches(self.target, pattern: "uct")).to(equal(3))
|
||||
expect(Matcher.numberOfUppercaseMatches(self.target, pattern: "uDcT")).to(equal(4))
|
||||
expect(Matcher.numberOfUppercaseMatches(self.target, pattern: "dct")).to(equal(3))
|
||||
|
@ -7,14 +7,26 @@ import XCTest
|
||||
import Nimble
|
||||
|
||||
class ScorerTest: XCTestCase {
|
||||
|
||||
func testScore() {
|
||||
let pattern = "s/nvv"
|
||||
|
||||
func testScore1() {
|
||||
let pattern = "sw/nvv".stringByReplacingOccurrencesOfString("/", withString: "")
|
||||
let targets = [
|
||||
"SwiftNeoVim/NeoVimView.swift",
|
||||
"build/Release/NeoVimServer.dSYM/Contents/Resources/DWARF/NeoVimServer"
|
||||
]
|
||||
"build/Release/NeoVimServer.dSYM/Contents/Resources/DWARF/NeoVimServer",
|
||||
].map { $0.stringByReplacingOccurrencesOfString("/", withString: "") }
|
||||
|
||||
expect(Scorer.score(targets[0], pattern: pattern)).to(beGreaterThan(Scorer.score(targets[1], pattern: pattern)))
|
||||
}
|
||||
|
||||
func testScore2() {
|
||||
let pattern = "nvv"
|
||||
let targets = [
|
||||
"NeoVimView.swift",
|
||||
"NeoVimViewDelegate.swift",
|
||||
"NeoVimServer",
|
||||
]
|
||||
|
||||
expect(Scorer.score(targets[0], pattern: pattern)).to(beGreaterThan(Scorer.score(targets[1], pattern: pattern)))
|
||||
expect(Scorer.score(targets[1], pattern: pattern)).to(beGreaterThan(Scorer.score(targets[2], pattern: pattern)))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user