mirror of
https://github.com/huhu/rust-search-extension
synced 2024-11-14 23:57:07 +00:00
Add fallback search strategy for @crate search. Fix #96
This commit is contained in:
parent
ca22e0e8bb
commit
21d9ef9f4c
3 changed files with 53 additions and 20 deletions
2
core
2
core
|
@ -1 +1 @@
|
|||
Subproject commit cff98bdb4fb3b66b473ec789eb102812b9b6bebf
|
||||
Subproject commit e834c1c330e06cfd67456d812e7cbdcf52ac83f5
|
|
@ -24,9 +24,10 @@ class CrateDocSearchManager {
|
|||
this.allCrateSearcher = new CrateDocSearch("~", "*", searchIndex);
|
||||
}
|
||||
|
||||
// Search specific crate docs by prefix `@` sigil.
|
||||
// If that crate not been indexed, fallback to the list of all indexed crates.
|
||||
search(query) {
|
||||
query = query.replace("@", "").trim();
|
||||
let [crateName, keyword] = query.split(" ");
|
||||
let [crateName, keyword] = CrateDocSearchManager.parseCrateDocsSearchKeyword(query);
|
||||
|
||||
let searcher = null;
|
||||
if (this.cachedCrateSearcher && this.cachedCrateSearcher.name === crateName) {
|
||||
|
@ -47,10 +48,17 @@ class CrateDocSearchManager {
|
|||
|
||||
list = list.filter(item => !crateName || item.name.toLowerCase().indexOf(crateName) > -1)
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
list.unshift({
|
||||
content: crateName, // Non-empty value is required for content, so maybe give it a crate name.
|
||||
description: `Following ${list.length} crate(s) were added by you, select one to search their docs exclusively.`
|
||||
});
|
||||
if (list.length > 0) {
|
||||
list.unshift({
|
||||
content: crateName, // Non-empty value is required for content, so maybe give it a crate name.
|
||||
description: `Following ${list.length} crate(s) were indexed by you, select one to search their docs exclusively.`
|
||||
});
|
||||
} else {
|
||||
list.unshift({
|
||||
content: `https://docs.rs/${crateName}/?search=${encodeURIComponent(keyword)}`,
|
||||
description: `Crate ${c.match(crateName)} has not been indexed, search ${keyword ? c.match(keyword) : 'keyword'} on ${c.dim(`https://docs.rs/${crateName}`)} directly`,
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +67,7 @@ class CrateDocSearchManager {
|
|||
// Push result footer.
|
||||
results.push({
|
||||
content: searcher.getSearchUrl(keyword),
|
||||
description: `Input keyword to search ${c.match(crateName)}'s docs...`,
|
||||
description: `Search ${keyword ? c.match(keyword) : 'keyword'} on ${c.dim(`https://docs.rs/${crateName}`)} directly`,
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
@ -73,6 +81,12 @@ class CrateDocSearchManager {
|
|||
return this.allCrateSearcher.search(keyword);
|
||||
}
|
||||
|
||||
static parseCrateDocsSearchKeyword(query) {
|
||||
query = query.replaceAll("@", "").trim();
|
||||
let [crateName, ...keyword] = query.split(/\s|:+/i);
|
||||
return [crateName, keyword.filter(k => k).join('::')];
|
||||
}
|
||||
|
||||
static getCrates() {
|
||||
return JSON.parse(localStorage.getItem("crates") || "{}");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
describe("CrateDocSearchManager", function() {
|
||||
before(function() {
|
||||
describe("CrateDocSearchManager", function () {
|
||||
before(function () {
|
||||
this.crateName = "matches";
|
||||
this.crateVersion = "0.1.8";
|
||||
this.searchIndex = {
|
||||
|
@ -10,39 +10,58 @@ describe("CrateDocSearchManager", function() {
|
|||
}
|
||||
};
|
||||
});
|
||||
|
||||
after(function() {
|
||||
|
||||
after(function () {
|
||||
CrateDocSearchManager.removeCrate(this.crateName);
|
||||
});
|
||||
|
||||
describe("crates", function() {
|
||||
it("getCrates()", function() {
|
||||
describe("crates", function () {
|
||||
it("getCrates()", function () {
|
||||
CrateDocSearchManager.getCrates().should.deep.equal({});
|
||||
});
|
||||
it("addCrate()", function() {
|
||||
it("addCrate()", function () {
|
||||
CrateDocSearchManager.addCrate(this.crateName, this.crateVersion, this.searchIndex);
|
||||
let crates = CrateDocSearchManager.getCrates();
|
||||
Object.keys(crates).should.contains(this.crateName);
|
||||
});
|
||||
it("getSearchIndex()", function() {
|
||||
it("getSearchIndex()", function () {
|
||||
let searchIndex = CrateDocSearchManager.getCrateSearchIndex(this.crateName);
|
||||
searchIndex.should.deep.equal(this.searchIndex);
|
||||
});
|
||||
it("removeCrate()", function() {
|
||||
it("removeCrate()", function () {
|
||||
CrateDocSearchManager.removeCrate(this.crateName);
|
||||
CrateDocSearchManager.getCrates().should.deep.equal({});
|
||||
});
|
||||
});
|
||||
|
||||
describe("search", function() {
|
||||
describe("search", function () {
|
||||
let manager = new CrateDocSearchManager();
|
||||
[["@match", 2], ["@matches", 1], ["@matches m", 5], ["@matches z", 1]]
|
||||
.forEach(function([keyword, len]) {
|
||||
it(`"${keyword}" search()`, function() {
|
||||
.forEach(function ([keyword, len]) {
|
||||
it(`"${keyword}" search()`, function () {
|
||||
CrateDocSearchManager.addCrate(this.crateName, this.crateVersion, this.searchIndex);
|
||||
let result = manager.search(keyword);
|
||||
result.should.have.lengthOf(len);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseCrateDocsSearchKeyword", function () {
|
||||
[
|
||||
["@tokio", ["tokio", ""]],
|
||||
["@tokio spawn", ["tokio", "spawn"]],
|
||||
["@@tokio spawn", ["tokio", "spawn"]],
|
||||
["@tokio spawn", ["tokio", "spawn"]],
|
||||
["@tokio::spawn", ["tokio", "spawn"]],
|
||||
["@tokio:spawn", ["tokio", "spawn"]],
|
||||
["@tokio task::spawn", ["tokio", "task::spawn"]],
|
||||
["@tokio::task::spawn", ["tokio", "task::spawn"]],
|
||||
["@tokio time::sleep::poll", ["tokio", "time::sleep::poll"]],
|
||||
].forEach(function ([keyword, expected]) {
|
||||
it(`parseCrateDocsSearchKeyword("${keyword}")`, function () {
|
||||
let result = CrateDocSearchManager.parseCrateDocsSearchKeyword(keyword);
|
||||
result.should.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue