Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support description shards #285

Merged
merged 18 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content-script-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export {
storage,
settings,
IndexSetter,
CrateDocManager
CrateDocManager,
}
2 changes: 1 addition & 1 deletion extension/content-script-bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 15 additions & 14 deletions extension/crate-manager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import storage from "./core/storage.js";
import IndexSetter from "./index-setter.js";

export default class CrateDocManager {
static async getCrates() {
Expand Down Expand Up @@ -30,7 +31,7 @@ export default class CrateDocManager {
let crate = Object.entries(crates).find(([_, { crateName }]) => crateName == name);
if (crate) {
let libName = crate[0];
return await storage.getItem(`@${libName}`);
return new Map(await storage.getItem(`@${libName}`));
} else {
return null;
}
Expand All @@ -43,26 +44,26 @@ export default class CrateDocManager {
//
// Here is the rule: https://docs.rs/{crateName}/{crateVersion}/{libName}
//
// Ensure `searchIndex` is a Object, not a Map.
static async addCrate({ libName, crateVersion, searchIndex, crateName }) {
if (searchIndex && libName in searchIndex) {
await storage.setItem(`@${libName}`, searchIndex);
let doc = searchIndex[libName]["doc"];
let crates = await CrateDocManager.getCrates();
if (libName in crates) {
// Don't override the time if the crate exists
crates[libName] = { version: crateVersion, doc, time: crates[libName].time, crateName };
} else {
crates[libName] = { version: crateVersion, doc, time: Date.now(), crateName };
}
await storage.setItem("crates", crates);
// The caller should ensure `searchIndex` is a Map, not a Object.
static async addCrate({ libName, crateVersion, crateTitle, searchIndex, crateName, descShards }) {
await storage.setItem(`@${libName}`, searchIndex);
let doc = crateTitle;
let crates = await CrateDocManager.getCrates();
if (libName in crates) {
// Don't override the time if the crate exists
crates[libName] = { version: crateVersion, doc, time: crates[libName].time, crateName };
} else {
crates[libName] = { version: crateVersion, doc, time: Date.now(), crateName };
}
await storage.setItem("crates", crates);
IndexSetter.setDescShards(libName, descShards);
}

static async removeCrate(name) {
let crates = await CrateDocManager.getCrates();
delete crates[name];
await storage.setItem("crates", crates);
await storage.removeItem(`@${name}`);
await storage.removeItem(`desc-shards-${name}`);
}
};
28 changes: 24 additions & 4 deletions extension/index-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import rfcsIndex from "./index/rfcs.js";
import rustcIndex from "./index/rustc.js";
import targetsIndex from "./index/targets.js";
import searchIndex from "./index/std-docs.js";
import stdDescShards from "./index/desc-shards/std.js";
import { mapping, crateIndex } from "./index/crates.js";
import storage from "./core/storage.js";
import IndexSetter from "./index-setter.js";
Expand All @@ -18,13 +19,32 @@ import IndexSetter from "./index-setter.js";

export default class IndexManager extends IndexSetter {
static async getStdStableIndex() {
// Convert default map searchIndex to Object since rust 1.76.0
return await storage.getItem('index-std-stable') || Object.fromEntries(searchIndex);
let index = await storage.getItem('index-std-stable');
if (index?.length > 0) {
return new Map(index);
} else {
return searchIndex;
}
}

static async getStdNightlyIndex() {
// Convert default map searchIndex to Object since rust 1.76.0
return await storage.getItem('index-std-nightly') || Object.fromEntries(searchIndex);
let index = await storage.getItem('index-std-nightly');
if (index?.length > 0) {
return new Map(index);
} else {
// Structure clone search index is required
return structuredClone(searchIndex);
}

}

static async getDescShards(crate) {
let descShards = await storage.getItem(`desc-shards-${crate}`);
if (descShards) {
return new Map(descShards);
} else {
return stdDescShards;
}
}

static async getBookIndex() {
Expand Down
6 changes: 6 additions & 0 deletions extension/index-setter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export default class IndexSetter {
storage.setItem('index-std-nightly', index);
}

static setDescShards(crate, shards) {
if (shards) {
storage.setItem(`desc-shards-${crate}`, shards);
}
}

static setBookIndex(index) {
storage.setItem('index-book', index);
}
Expand Down
2 changes: 2 additions & 0 deletions extension/index/desc-shards/std.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions extension/index/std-docs.js

Large diffs are not rendered by default.

56 changes: 31 additions & 25 deletions extension/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,13 @@ export default class RustSearchOmnibox {
lintSearcher,
commandManager,
}) {
// All dynamic setting items. Those items will been updated
// in chrome.storage.onchange listener callback.
let isOfflineMode = await settings.isOfflineMode;

function formatDoc(index, doc) {
let content = doc.href;
let description = doc.displayPath + `<match>${doc.name}</match>`;
if (doc.desc) {
description += ` - <dim>${Compat.escape(Compat.eliminateTags(doc.desc))}</dim>`;
}

if (doc.queryType === "s" || doc.queryType === "src") {
let url = new URL(doc.href);
url.search = "?mode=src";
content = url.toString();
description = `[Source code] ${description}`;
}
return { content, description };
}

Expand All @@ -51,21 +41,18 @@ export default class RustSearchOmnibox {
];
}

const docsSearchMixins = {
onSearch: (query) => {
return stdSearcher.search(query);
omnibox.bootstrap({
onSearch: async (query) => {
const result = await stdSearcher.search(query);
return result.others || [];
},
onFormat: formatDoc,
onAppend: async (query) => {
return [{
content: stdSearcher.getSearchUrl(query),
description: `Search Rust docs <match>${query}</match> on ${await settings.isOfflineMode ? "offline mode" : stdSearcher.getRootPath()}`,
content: await stdSearcher.getSearchUrl(query),
description: `Search Rust docs <match>${query}</match> on ${await settings.isOfflineMode ? "offline mode" : await stdSearcher.rootPath}`,
}];
},
};

omnibox.bootstrap({
...docsSearchMixins,
onEmptyNavigate: (content, disposition) => {
commandManager.handleCommandEnterEvent(content, disposition);
},
Expand Down Expand Up @@ -97,25 +84,44 @@ export default class RustSearchOmnibox {

omnibox.addRegexQueryEvent(/^s(?:rc)?:/i, {
name: "Source code",
...docsSearchMixins,
onSearch: async (query) => {
query = query.replace(/^s(?:rc)?:/i, "");
const result = await stdSearcher.search(query);
return result.others || [];
},
onFormat: (index, doc) => {
let { content, description } = formatDoc(index, doc);
let url = new URL(doc.href);
url.search = "?mode=src";
content = url.toString();
description = `[Source code] ${description}`;
return { content, description };
},
onAppend: async (query) => {
return [{
content: await stdSearcher.getSearchUrl(query),
description: `Search Rust docs <match>${query}</match> on ${await settings.isOfflineMode ? "offline mode" : await stdSearcher.rootPath}`,
}];
},
});

// Nightly std docs search
omnibox.addPrefixQueryEvent("/", {
name: "Nightly docs",
onSearch: (query) => {
onSearch: async (query) => {
query = query.replaceAll("/", "").trim();
return nightlySearcher.search(query);
const result = await nightlySearcher.search(query);
return result.others || [];
},
onFormat: (index, doc) => {
let { content, description } = formatDoc(index, doc);
return { content, description: '[Nightly] ' + description };
},
onAppend: (query) => {
onAppend: async (query) => {
query = query.replaceAll("/", "").trim();
return [{
content: nightlySearcher.getSearchUrl(query),
description: `Search nightly Rust docs <match>${query}</match> on ${nightlySearcher.getRootPath()}`,
content: await nightlySearcher.getSearchUrl(query),
description: `Search nightly Rust docs <match>${query}</match> on ${nightlySearcher.rootPath}`,
}];
},
});
Expand Down
9 changes: 2 additions & 7 deletions extension/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,8 @@ async function start(omnibox) {
}),
);

let stdSearcher = new DocSearch("std", await IndexManager.getStdStableIndex(), () => {
return isOfflineMode ? offlineDocPath : "https://doc.rust-lang.org/";
});
let nightlySearcher = new DocSearch("std", await IndexManager.getStdNightlyIndex(), () => {
// Nightly docs doesn't support offline mode yet.
return "https://doc.rust-lang.org/nightly/";
});
let nightlySearcher = new DocSearch("std", await IndexManager.getStdNightlyIndex(), "https://doc.rust-lang.org/nightly/");
let stdSearcher = new DocSearch("std", await IndexManager.getStdStableIndex(), isOfflineMode ? offlineDocPath : "https://doc.rust-lang.org/");

RustSearchOmnibox.run({
omnibox,
Expand Down
Loading
Loading