-
-
Notifications
You must be signed in to change notification settings - Fork 475
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It's disabled by default and you can enable it by setting `fuzzySearch` preference to true. Closes #25.
- Loading branch information
Showing
29 changed files
with
1,479 additions
and
324 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import AppKit | ||
import Fuse | ||
|
||
class Search { | ||
private let fuzzySearchPref = "fuzzySearch" | ||
private let fuse = Fuse(threshold: 0.7) // threshold found by trial-and-error | ||
|
||
init() { | ||
UserDefaults.standard.register(defaults: [fuzzySearchPref: false]) | ||
} | ||
|
||
func search(string: String, within: [NSMenuItem]) -> [NSMenuItem] { | ||
guard !string.isEmpty else { | ||
return within | ||
} | ||
|
||
if UserDefaults.standard.bool(forKey: fuzzySearchPref) { | ||
return fuzzySearch(string: string, within: within) | ||
} else { | ||
return simpleSearch(string: string, within: within) | ||
} | ||
} | ||
|
||
private func fuzzySearch(string: String, within: [NSMenuItem]) -> [NSMenuItem] { | ||
let searchResults = within.map({ (score: fuse.search(string, in: $0.title)?.score, object: $0) }) | ||
let matchedResults = searchResults.filter({ $0.score != nil }) | ||
let sortedResults = matchedResults.sorted(by: { ($0.score ?? 0) < ($1.score ?? 0) }) | ||
return sortedResults.map({ $0.object }) | ||
} | ||
|
||
private func simpleSearch(string: String, within: [NSMenuItem]) -> [NSMenuItem] { | ||
return within.filter({ item in | ||
let range = item.title.range( | ||
of: string, | ||
options: .caseInsensitive, | ||
range: nil, | ||
locale: nil | ||
) | ||
|
||
return (range != nil) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import XCTest | ||
@testable import Maccy | ||
|
||
class SearchTests: XCTestCase { | ||
let savedFuzzySearch = UserDefaults.standard.bool(forKey: "fuzzySearch") | ||
|
||
let items = [ | ||
NSMenuItem(title: "foo bar baz", action: nil, keyEquivalent: ""), | ||
NSMenuItem(title: "foo bar zaz", action: nil, keyEquivalent: ""), | ||
NSMenuItem(title: "xxx yyy zzz", action: nil, keyEquivalent: "") | ||
] | ||
|
||
override func tearDown() { | ||
super.tearDown() | ||
UserDefaults.standard.set(savedFuzzySearch, forKey: "fuzzySearch") | ||
} | ||
|
||
func testSimpleSearch() { | ||
UserDefaults.standard.set(false, forKey: "fuzzySearch") | ||
|
||
XCTAssertEqual(search(""), items) | ||
XCTAssertEqual(search("z"), items) | ||
XCTAssertEqual(search("foo"), [items[0], items[1]]) | ||
XCTAssertEqual(search("za"), [items[1]]) | ||
XCTAssertEqual(search("yyy"), [items[2]]) | ||
XCTAssertEqual(search("fbb"), []) | ||
XCTAssertEqual(search("m"), []) | ||
} | ||
|
||
func testFuzzySearch() { | ||
UserDefaults.standard.set(true, forKey: "fuzzySearch") | ||
|
||
XCTAssertEqual(search(""), items) | ||
XCTAssertEqual(search("z"), [items[1], items[2], items[0]]) | ||
XCTAssertEqual(search("foo"), [items[0], items[1]]) | ||
XCTAssertEqual(search("za"), [items[1], items[0], items[2]]) | ||
XCTAssertEqual(search("yyy"), [items[2]]) | ||
XCTAssertEqual(search("fbb"), [items[0], items[1]]) | ||
XCTAssertEqual(search("m"), []) | ||
} | ||
|
||
private func search(_ string: String) -> [NSMenuItem] { | ||
return Search().search(string: string, within: items) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,24 @@ | ||
PODS: | ||
- Fuse (1.2.0) | ||
- HotKey (0.1.2) | ||
- SwiftHEXColors (1.3.0) | ||
|
||
DEPENDENCIES: | ||
- Fuse (~> 1.2) | ||
- HotKey (>= 0.1.2) | ||
- SwiftHEXColors (~> 1.3) | ||
|
||
SPEC REPOS: | ||
https://github.com/cocoapods/specs.git: | ||
- Fuse | ||
- HotKey | ||
- SwiftHEXColors | ||
|
||
SPEC CHECKSUMS: | ||
Fuse: 287bd95a5c8dbfe6c41af519eaf48856aa1a28f6 | ||
HotKey: ad59450195936c10992438c4210f673de5aee43e | ||
SwiftHEXColors: 15ab5242cc2efeab548c4c74793b173b78dbae1c | ||
|
||
PODFILE CHECKSUM: 7044fc9787ba9dcf0006e69334c57a73a05b8191 | ||
PODFILE CHECKSUM: d27bca7be5578c064699e96986f8af7f0995ce88 | ||
|
||
COCOAPODS: 1.5.2 |
Oops, something went wrong.