1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 17:12:28 +01:00

Make autocompletion generally more reasonable

This commit is contained in:
Kris Maglione
2008-10-06 18:48:08 +00:00
parent 4860ff32fe
commit 899fa605e6
8 changed files with 97 additions and 66 deletions

View File

@@ -311,7 +311,8 @@ liberator.Bookmarks = function () //{{{
{ {
if (bypassCache) // Is this really necessary anymore? if (bypassCache) // Is this really necessary anymore?
cache.load(); cache.load();
return liberator.completion.filterURLArray(cache.bookmarks, filter, tags); return liberator.completion.cached(cache.bookmarks, filter, function () cache.bookmarks,
"filterURLArray", tags);
}, },
// if starOnly = true it is saved in the unfiledBookmarksFolder, otherwise in the bookmarksMenuFolder // if starOnly = true it is saved in the unfiledBookmarksFolder, otherwise in the bookmarksMenuFolder
@@ -709,8 +710,8 @@ liberator.History = function () //{{{
if (!history) if (!history)
load(); load();
return liberator.completion.filterURLArray(cachedHistory, filter).concat( return liberator.completion.cached("history", filter, function() cachedHistory.concat(history),
liberator.completion.filterURLArray(history, filter)); "filterURLArray");
}, },
// the history is automatically added to the Places global history // the history is automatically added to the Places global history

View File

@@ -36,6 +36,8 @@ liberator.Completion = function () //{{{
.getService(Components.interfaces.nsIAutoCompleteSearch); .getService(Components.interfaces.nsIAutoCompleteSearch);
// the completion substrings, used for showing the longest common match // the completion substrings, used for showing the longest common match
var cacheFilter = {};
var cacheResults = {};
var substrings = []; var substrings = [];
var historyCache = []; var historyCache = [];
var historyResult = null; var historyResult = null;
@@ -184,6 +186,17 @@ liberator.Completion = function () //{{{
return buildLongestCommonSubstring(array, filter, favicon); return buildLongestCommonSubstring(array, filter, favicon);
}, },
cached: function (key, filter, generate, method)
{
let oldFilter = cacheFilter[key];
cacheFilter[key] = filter;
let results = cacheResults[key];
if (!oldFilter || filter.indexOf(oldFilter) != 0)
results = generate(filter);
cacheResults[key] = this[method].apply(this, [results, filter].concat(Array.splice(arguments, 4)));
return cacheResults[key];
},
autocommand: function (filter) autocommand: function (filter)
{ {
let autoCmds = liberator.config.autocommands; let autoCmds = liberator.config.autocommands;
@@ -288,12 +301,11 @@ liberator.Completion = function () //{{{
javascript: function (str) javascript: function (str)
{ {
var matches = str.match(/^(.*?)(\s*\.\s*)?(\w*)$/); var matches = str.match(/^(.*?)((?:\s*\.\s*)?)(\w*)$/);
var objects = []; var objects = [];
var filter = matches[3] || "";
var start = matches[1].length - 1; var start = matches[1].length - 1;
var offset = matches[1] ? matches[1].length : 0; var offset = matches[1].length + matches[2].length;
offset += matches[2] ? matches[2].length : 0; var filter = matches[3];
if (matches[2]) if (matches[2])
{ {
@@ -338,22 +350,28 @@ liberator.Completion = function () //{{{
var completions = []; var completions = [];
try try
{ {
for (let o = 0; o < objects.length; o++) for (let [,object] in Iterator(objects))
{ {
completions = completions.concat(eval( /* Why the double eval? --Kris */
"var comp = [];" + completions.push(eval(<![CDATA[
"var type = '';" + let comp = [];
"var value = '';" + let type = "";
"var obj = eval('with (liberator) {" + objects[o] + "}');" + let value = "";
"for (var i in obj) {" + let obj = eval("with (liberator) {" + object + "}");
" try { type = typeof(obj[i]); } catch (e) { type = 'unknown type'; };" + for (let i in obj)
" if (type == 'number' || type == 'string' || type == 'boolean') {" + {
" value = obj[i];" + type = "unknown type";
" comp.push([[i], type + ': ' + value]); }" + try
" else {" + {
" comp.push([[i], type]); }" + type = typeof obj[i];
"} comp;" }
)); catch (e) {};
if (type == "number" || type == "string" || type == "boolean")
type += ": " + obj[i];
comp.push([[i], type]);
}
comp;
]]>.toString()));
} }
} }
catch (e) catch (e)
@@ -361,7 +379,7 @@ liberator.Completion = function () //{{{
completions = []; completions = [];
} }
return [offset, buildLongestStartingSubstring(completions, filter)]; return [offset, buildLongestStartingSubstring(liberator.util.flatten(completions), filter)];
}, },
macro: function (filter) macro: function (filter)
@@ -373,9 +391,11 @@ liberator.Completion = function () //{{{
search: function (filter) search: function (filter)
{ {
var keywords = [[k[0], k[1], k[3]] for each (k in liberator.bookmarks.getKeywords())]; let results = this.cached("search", filter,
var engines = liberator.bookmarks.getSearchEngines(); function () Array.concat(liberator.bookmarks.getKeywords().map(function (k) [k[0], k[1], k[3]]),
return [0, this.filter(engines.concat(keywords), filter, false, true)]; liberator.bookmarks.getSearchEngines()),
"filter", false, true);
return [0, results];
}, },
// XXX: Move to bookmarks.js? // XXX: Move to bookmarks.js?
@@ -466,7 +486,6 @@ liberator.Completion = function () //{{{
} }
var cpt = complete || liberator.options["complete"]; var cpt = complete || liberator.options["complete"];
var autoCompletions = liberator.options["wildoptions"].indexOf("auto") >= 0;
var suggestEngineAlias = liberator.options["suggestengines"] || "google"; var suggestEngineAlias = liberator.options["suggestengines"] || "google";
// join all completion arrays together // join all completion arrays together
for (let c in liberator.util.arrayIter(cpt)) for (let c in liberator.util.arrayIter(cpt))
@@ -477,9 +496,9 @@ liberator.Completion = function () //{{{
completions.push(this.file(filter, false)[1]); completions.push(this.file(filter, false)[1]);
else if (c == "S") else if (c == "S")
completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]); completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
else if (c == "b" && !autoCompletions) else if (c == "b")
completions.push(liberator.bookmarks.get(filter).map(function (a) [a[0], a[1], a[5]])); completions.push(liberator.bookmarks.get(filter).map(function (a) [a[0], a[1], a[5]]));
else if (c == "h" && !autoCompletions) else if (c == "h")
completions.push(liberator.history.get(filter)); completions.push(liberator.history.get(filter));
else if (c == "l") // add completions like Firefox's smart location bar else if (c == "l") // add completions like Firefox's smart location bar
{ {

View File

@@ -49,6 +49,7 @@ const liberator = (function () //{{{
} }
catch (e) catch (e)
{ {
toJavaScriptConsole();
Components.utils.reportError(e); Components.utils.reportError(e);
liberator.dump(e + "\n"); liberator.dump(e + "\n");
} }

View File

@@ -105,9 +105,9 @@ liberator.CommandLine = function () //{{{
var wildIndex = 0; // keep track how often we press <Tab> in a row var wildIndex = 0; // keep track how often we press <Tab> in a row
var startHints = false; // whether we're waiting to start hints mode var startHints = false; // whether we're waiting to start hints mode
var statusTimer = new liberator.util.Timer(51, 100, function () var statusTimer = new liberator.util.Timer(5, 100, function ()
liberator.statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length)); liberator.statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length));
var autocompleteTimer = new liberator.util.Timer(50, 100, function (command) { var autocompleteTimer = new liberator.util.Timer(201, 300, function (command) {
let res = liberator.completion.ex(command); let res = liberator.completion.ex(command);
liberator.commandline.setCompletions(res[1], res[0]); liberator.commandline.setCompletions(res[1], res[0]);
}); });

View File

@@ -37,9 +37,9 @@ liberator.util = { //{{{
this.notify = function (aTimer) this.notify = function (aTimer)
{ {
timer.cancel(); timer.cancel();
this.doneAt = Date.now() + minInterval;
this.latest = 0; this.latest = 0;
callback(this.arg); callback(this.arg);
this.doneAt = Date.now() + minInterval;
} }
this.tell = function (arg) this.tell = function (arg)
{ {
@@ -49,7 +49,7 @@ liberator.util = { //{{{
let now = Date.now(); let now = Date.now();
if (this.doneAt == -1) if (this.doneAt == -1)
timer.cancel(); timer.cancel();
else if (now >= this.doneAt || now >= this.latest) else if (now >= this.doneAt || this.latest && now >= this.latest)
return this.notify(); return this.notify();
let timeout = minInterval; let timeout = minInterval;

View File

@@ -107,11 +107,7 @@ function ObjectStore(name, store, data)
object = {}; object = {};
}; };
this.__iterator__ = function () this.__iterator__ = function () Iterator(object);
{
for (let key in object)
yield [key, object[key]];
};
} }
ObjectStore.prototype = prototype; ObjectStore.prototype = prototype;
@@ -170,11 +166,7 @@ function ArrayStore(name, store, data)
return index >= 0 ? array[index] : array[array.length + index]; return index >= 0 ? array[index] : array[array.length + index];
}; };
this.__iterator__ = function () this.__iterator__ = function () Iterator(array);
{
for (let i = 0; i < array.length; i++)
yield [i, array[i]];
};
} }
ArrayStore.prototype = prototype; ArrayStore.prototype = prototype;
@@ -208,9 +200,8 @@ var storage = {
{ {
if (!(key in observers)) if (!(key in observers))
observers[key] = []; observers[key] = [];
if (observers[key].indexOf(callback) >= 0) if (observers[key].indexOf(callback) == -1)
return; observers[key].push(callback);
observers[key].push(callback);
}, },
removeObserver: function (key, callback) removeObserver: function (key, callback)

View File

@@ -1,16 +0,0 @@
.liberator-frame-indicator {
-moz-binding: url(chrome://vimperator/content/bindings.xml#frame);
}
#liberator-frame-indicator {
background-color: red;
opacity: 0.5;
z-index: 999
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}

View File

@@ -26,18 +26,53 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
/* Applied to all content */
.liberator-frame-indicator {
-moz-binding: url(chrome://vimperator/content/bindings.xml#frame);
}
#liberator-frame-indicator {
background-color: red;
opacity: 0.5;
z-index: 999
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
/* Applied only to completion buffer and MOW */
@-moz-document @-moz-document
url-prefix(chrome://vimperator/), url-prefix(chrome://vimperator/),
url-prefix(chrome://muttator/) { url-prefix(chrome://muttator/) {
*:-moz-loading, *:-moz-broken { display: none !important; }
.compitem[selected=true] { background-color: yellow; } .compitem[selected=true] { background-color: yellow; }
.compitem .favicon { width: 16px; } .compitem > .favicon { width: 16px; }
.compitem .favicon img { width: 16px; height: 16px; } .compitem > .favicon > img { width: 16px; height: 16px; }
.compitem .completion { width: 45%; overflow: hidden; } .compitem > .completion { width: 45%; overflow: hidden; }
.compitem .description { color: gray; } .compitem > .description { color: gray; }
.extra-info { color: gray; }
.times-executed, .time-average { color: green; }
.time-total { color: red; }
.indicator { color: blue; }
.hl-Number { color: red; }
.hl-String { color: green; }
.hl-Boolean { color: blue; }
.hl-Null { color: blue; }
.hl-Keyword { color: red; }
.hl-Tag { color: blue; }
} }
/* Applied to completion buffer, MOW, browser window */
@-moz-document @-moz-document
url-prefix(chrome://vimperator/), url-prefix(chrome://vimperator/),
url-prefix(chrome://muttator/), url-prefix(chrome://muttator/),