Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

99 lines (87 sloc) 3.201 kB
{
name: 'find',
description: 'Go to a tab (fuzzy matched)',
params: [
{
name: 'tabName',
type: 'string',
description: 'Fuzzy matching of a tab name',
}
],
returnType: "string",
exec: function (args, context) {
let gBrowser = context.environment.chromeDocument.defaultView.gBrowser;
// Get all the URIS and titles.
let tablen = gBrowser.tabs.length;
let tabNames = new Array(tablen);
let tab;
for (let i = 0; i < tablen; i++) {
tab = gBrowser.tabs[i];
tabNames[i] = gBrowser.getBrowserForTab(tab).currentURI.spec + ' '
gBrowser.getBrowserForTab(tab).contentTitle;
}
// All the fuzzy matching primitives are pasted in here.
var leafs = [];
function sorter (file1, file2) { return file2[1] - file1[1]; };
// Return [leaf, stars, indexes]:
//
// - `leaf` is a String of the path.
// - `stars` is a Number to compare leafs according to the query.
// - `indexes` is the positions of matched letters.
//
// `leaf` is a String of the path from here to the leaf.
// `query` is a String to fuzzy match.
function score(leaf, query) {
var stars = 0,
index = query.length - 1,
indexes = [], // Position of matched letters.
countlettersmatched = 0, // Consecutive letters matched.
alpha = /[a-zA-Z0-9]/,
lookingAhead = false; // Grant one last run and terminate.
// The idea is to begin with the end of the `query`, and for each letter
// matched, the letter is captured, its position influences the score, and we
// go to the next letter.
for (var i = leaf.length - 1; i >= 0; i--) {
var l = leaf[i]; // letter
if (countlettersmatched > 0 && !alpha.test(l)) {
stars += 2; // first letter after non-alphanumeric character is good.
}
if (l === query[index]) {
indexes.push(i);
stars++; // match!
stars += countlettersmatched; // Consecutive matches is good.
countlettersmatched++;
index--;
} else {
countlettersmatched = 0;
}
if (lookingAhead) break; // The last run was already granted.
else if (index < 0) lookingAhead = true; // Grant last run now.
}
if (lookingAhead) stars++;
return [leaf, stars, indexes];
}
// List of [leafpath, stars, indexes], ordered by the stars.
// Leafs that do not match the whole query are discarded.
//
// `leafs` is an Array of Strings of paths from here to the leaf.
// `query` is a String to fuzzy match.
function fuzzy (leafs, query) {
var fuzzied = [];
for (var i = 0; i < leafs.length; i++) {
var sc = score(leafs[i], query);
if (sc[2].length === query.length) {
fuzzied.push(sc);
}
}
return fuzzied.sort(sorter);
}
// Fuzzy match those titles.
let fuzznames = fuzzy(tabNames, args.tabName);
if (fuzznames.length > 0) {
gBrowser.selectedTab = gBrowser.tabs[tabNames.indexOf(fuzznames[0][0])];
} else {
return "No tab was found.";
}
}
}
Jump to Line
Something went wrong with that request. Please try again.