1
1
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:
Tae Won Ha 2016-09-08 20:16:37 +02:00
parent 8ea4a958cd
commit 0f0ccf542a
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
6 changed files with 54 additions and 25 deletions

View File

@ -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.

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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))

View File

@ -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)))
}
}