1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-01-08 15:34:13 +01:00
This commit is contained in:
Kris Maglione
2009-01-06 23:15:57 -05:00
10 changed files with 106 additions and 112 deletions

View File

@@ -8,7 +8,7 @@ happy to accept your patches.
First of all, all new features and all user-visible changes to existing First of all, all new features and all user-visible changes to existing
features need to be documented. That means editing the appropriate help files features need to be documented. That means editing the appropriate help files
and adding a NEWS enty where appropriate. When editing the NEWS file, you and adding a NEWS entry where appropriate. When editing the NEWS file, you
should add your change to the top of the list of changes. If your change should add your change to the top of the list of changes. If your change
alters an interface (key binding, command) and is likely to cause trouble, alters an interface (key binding, command) and is likely to cause trouble,
prefix it with 'IMPORTANT:', otherwise, place it below the other 'IMPORTANT' prefix it with 'IMPORTANT:', otherwise, place it below the other 'IMPORTANT'
@@ -116,9 +116,11 @@ We try to be quite consistent, but of course, that's not always possible.
CompletionContext() could return a cached object. What's thesnowdog's CompletionContext() could return a cached object. What's thesnowdog's
opinion and why do you, Kris, think it's better/cleaner? opinion and why do you, Kris, think it's better/cleaner?
I don't think it's better/cleaner, it just seemed to be a concensus. I don't think it's better/cleaner, it just seemed to be a consensus.
--Kris --Kris
I don't like unnecessary use of 'new', I don't like 'new'. --djk
== Testing/Optimization == == Testing/Optimization ==
TODO: Add some information here about testing/validation/etc. TODO: Add some information here about testing/validation/etc.

View File

@@ -1082,12 +1082,12 @@ function Buffer() //{{{
return false; return false;
} }
let retVal = followFrame(window.content); let ret = followFrame(window.content);
if (!retVal) if (!ret)
// only loop through frames if the main content didnt match // only loop through frames if the main content didn't match
retVal = Array.some(window.content.frames, followFrame); ret = Array.some(window.content.frames, followFrame);
if (!retVal) if (!ret)
liberator.beep(); liberator.beep();
}, },

View File

@@ -307,7 +307,7 @@ function Commands() //{{{
completion.setFunctionCompleter(commands.get, [function () ([c.name, c.description] for (c in commands))]); completion.setFunctionCompleter(commands.get, [function () ([c.name, c.description] for (c in commands))]);
}); });
var commandManager = { const self = {
// FIXME: remove later, when our option handler is better // FIXME: remove later, when our option handler is better
OPTION_ANY: 0, // can be given no argument or an argument of any type, OPTION_ANY: 0, // can be given no argument or an argument of any type,
@@ -796,7 +796,7 @@ function Commands() //{{{
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s // TODO: Vim allows commands to be defined without {rep} if there are {attr}s
// specified - useful? // specified - useful?
commandManager.add(["com[mand]"], self.add(["com[mand]"],
"List and define commands", "List and define commands",
function (args) function (args)
{ {
@@ -903,11 +903,11 @@ function Commands() //{{{
bang: true, bang: true,
completer: function (context) completion.userCommand(context), completer: function (context) completion.userCommand(context),
options: [ options: [
[["-nargs"], commandManager.OPTION_STRING, [["-nargs"], self.OPTION_STRING,
function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]], function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
[["-bang"], commandManager.OPTION_NOARG], [["-bang"], self.OPTION_NOARG],
[["-count"], commandManager.OPTION_NOARG], [["-count"], self.OPTION_NOARG],
[["-complete"], commandManager.OPTION_STRING, [["-complete"], self.OPTION_STRING,
function (arg) arg in completeOptionMap || /custom,\w+/.test(arg), function (arg) arg in completeOptionMap || /custom,\w+/.test(arg),
function (context) [[k, ""] for ([k, v] in Iterator(completeOptionMap))]] function (context) [[k, ""] for ([k, v] in Iterator(completeOptionMap))]]
], ],
@@ -930,7 +930,7 @@ function Commands() //{{{
] ]
}); });
commandManager.add(["comc[lear]"], self.add(["comc[lear]"],
"Delete all user-defined commands", "Delete all user-defined commands",
function () function ()
{ {
@@ -938,7 +938,7 @@ function Commands() //{{{
}, },
{ argCount: "0" }); { argCount: "0" });
commandManager.add(["delc[ommand]"], self.add(["delc[ommand]"],
"Delete the specified user-defined command", "Delete the specified user-defined command",
function (args) function (args)
{ {
@@ -956,7 +956,7 @@ function Commands() //{{{
//}}} //}}}
return commandManager; return self;
}; //}}} }; //}}}

View File

@@ -155,7 +155,9 @@ function CompletionContext(editor, name, offset) //{{{
/** /**
* @property {Object} A map of all contexts, keyed on their names. * @property {Object} A map of all contexts, keyed on their names.
* Names are assigned when a context is forked, with its specified * Names are assigned when a context is forked, with its specified
* name appended, after a '/', to its parent's name. * name appended, after a '/', to its parent's name. May
* contain inactive contexts. For active contexts, see
* {@link #contextList}.
*/ */
this.contexts = { "/": this }; this.contexts = { "/": this };
/** /**
@@ -528,9 +530,7 @@ CompletionContext.prototype = {
cancelAll: function () cancelAll: function ()
{ {
// Kris: contextList gives undefined. And why do we have contexts and contextList? for (let [,context] in Iterator(this.contextList))
// I am not too much of a fan of a huge API for classes
for (let [,context] in Iterator(this.top.contexts))
{ {
if (context.cancel) if (context.cancel)
context.cancel(); context.cancel();
@@ -640,6 +640,11 @@ CompletionContext.prototype = {
for (let type in this.selectionTypes) for (let type in this.selectionTypes)
this.highlight(0, 0, type); this.highlight(0, 0, type);
/**
* @property {[CompletionContext]} A list of active
* completion contexts, in the order in which they were
* instantiated.
*/
this.contextList = []; this.contextList = [];
this.offset = 0; this.offset = 0;
this.process = []; this.process = [];
@@ -1265,7 +1270,7 @@ function Completion() //{{{
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
let self = { const self = {
setFunctionCompleter: function setFunctionCompleter(funcs, completers) setFunctionCompleter: function setFunctionCompleter(funcs, completers)
{ {
@@ -1578,7 +1583,6 @@ function Completion() //{{{
context.filterFunc = null; context.filterFunc = null;
context.cancel = function () services.get("autoCompleteSearch").stopSearch(); context.cancel = function () services.get("autoCompleteSearch").stopSearch();
context.compare = null; context.compare = null;
// TODO: shouldn't this timer be deleted by context.cancel?
let timer = new Timer(50, 100, function (result) { let timer = new Timer(50, 100, function (result) {
context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING; context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
context.completions = [ context.completions = [
@@ -1586,28 +1590,16 @@ function Completion() //{{{
for (i in util.range(0, result.matchCount)) for (i in util.range(0, result.matchCount))
]; ];
}); });
context.generate = function () { services.get("autoCompleteSearch").stopSearch();
let minItems = context.minItems || 1; services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, {
services.get("autoCompleteSearch").stopSearch(); onSearchResult: function onSearchResult(search, result)
services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, { {
onSearchResult: function (search, result) context.result = result;
{ timer.tell(result);
context.result = result; if (result.searchResult <= result.RESULT_SUCCESS)
timer.tell(result); timer.flush();
if (result.searchResult <= result.RESULT_SUCCESS) }
timer.flush(); });
}
});
let end = Date.now() + 5000;
while (context.incomplete && context.completions.length < minItems && Date.now() < end)
liberator.threadYield(false, true);
// context.message = "More results..."; // very very strange, if I enable this line, completions don't work;
services.get("autoCompleteSearch").stopSearch();
return context.completions;
}
}, },
macro: function macro(context) macro: function macro(context)

View File

@@ -612,7 +612,7 @@ function Events() //{{{
{ {
try try
{ {
eventManager[method](event); self[method](event);
} }
catch (e) catch (e)
{ {
@@ -758,7 +758,7 @@ function Events() //{{{
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
var eventManager = { const self = {
feedingKeys: false, feedingKeys: false,
@@ -1014,7 +1014,7 @@ function Events() //{{{
if (event.metaKey) if (event.metaKey)
modifier += "M-"; modifier += "M-";
if (event.type == "keypress") if (/^key/.test(event.type))
{ {
if (event.charCode == 0) if (event.charCode == 0)
{ {
@@ -1723,7 +1723,7 @@ function Events() //{{{
} }
}; //}}} }; //}}}
window.XULBrowserWindow = eventManager.progressListener; window.XULBrowserWindow = self.progressListener;
window.QueryInterface(Ci.nsIInterfaceRequestor) window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation) .getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
@@ -1732,21 +1732,21 @@ function Events() //{{{
.XULBrowserWindow = window.XULBrowserWindow; .XULBrowserWindow = window.XULBrowserWindow;
try try
{ {
getBrowser().addProgressListener(eventManager.progressListener, Ci.nsIWebProgress.NOTIFY_ALL); getBrowser().addProgressListener(self.progressListener, Ci.nsIWebProgress.NOTIFY_ALL);
} }
catch (e) {} catch (e) {}
eventManager.prefObserver.register(); self.prefObserver.register();
liberator.registerObserver("shutdown", function () { liberator.registerObserver("shutdown", function () {
eventManager.destroy(); self.destroy();
eventManager.prefObserver.unregister(); self.prefObserver.unregister();
}); });
window.addEventListener("keypress", wrapListener("onKeyPress"), true); window.addEventListener("keypress", wrapListener("onKeyPress"), true);
window.addEventListener("keydown", wrapListener("onKeyUpOrDown"), true); window.addEventListener("keydown", wrapListener("onKeyUpOrDown"), true);
window.addEventListener("keyup", wrapListener("onKeyUpOrDown"), true); window.addEventListener("keyup", wrapListener("onKeyUpOrDown"), true);
return eventManager; return self;
}; //}}} }; //}}}

View File

@@ -114,10 +114,10 @@ function IO() //{{{
function joinPaths(head, tail) function joinPaths(head, tail)
{ {
let path = ioManager.getFile(head); let path = self.getFile(head);
try try
{ {
path.appendRelativePath(ioManager.expandPath(tail, true)); // FIXME: should only expand env vars and normalise path separators path.appendRelativePath(self.expandPath(tail, true)); // FIXME: should only expand env vars and normalise path separators
if (path.exists() && path.normalize) if (path.exists() && path.normalize)
path.normalize(); path.normalize();
} }
@@ -385,14 +385,14 @@ function IO() //{{{
liberator.registerObserver("load_completion", function () liberator.registerObserver("load_completion", function ()
{ {
completion.setFunctionCompleter([ioManager.getFile, ioManager.expandPath], completion.setFunctionCompleter([self.getFile, self.expandPath],
[function (context, obj, args) { [function (context, obj, args) {
context.quote[2] = ""; context.quote[2] = "";
completion.file(context, true); completion.file(context, true);
}]); }]);
}); });
var ioManager = { const self = {
MODE_RDONLY: 0x01, MODE_RDONLY: 0x01,
MODE_WRONLY: 0x02, MODE_WRONLY: 0x02,
@@ -413,7 +413,7 @@ function IO() //{{{
// Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953 // Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953
getCurrentDirectory: function () getCurrentDirectory: function ()
{ {
let dir = ioManager.getFile(cwd.path); let dir = self.getFile(cwd.path);
// NOTE: the directory could have been deleted underneath us so // NOTE: the directory could have been deleted underneath us so
// fallback to Firefox's CWD // fallback to Firefox's CWD
@@ -433,7 +433,7 @@ function IO() //{{{
} }
else else
{ {
let dir = ioManager.getFile(newdir); let dir = self.getFile(newdir);
if (!dir.exists() || !dir.isDirectory()) if (!dir.exists() || !dir.isDirectory())
{ {
@@ -444,7 +444,7 @@ function IO() //{{{
[cwd, oldcwd] = [dir, this.getCurrentDirectory()]; [cwd, oldcwd] = [dir, this.getCurrentDirectory()];
} }
return ioManager.getCurrentDirectory(); return self.getCurrentDirectory();
}, },
getRuntimeDirectories: function (specialDirectory) getRuntimeDirectories: function (specialDirectory)
@@ -489,10 +489,10 @@ function IO() //{{{
} }
else else
{ {
let expandedPath = ioManager.expandPath(path); let expandedPath = self.expandPath(path);
if (!isAbsolutePath(expandedPath) && !noCheckPWD) if (!isAbsolutePath(expandedPath) && !noCheckPWD)
file = joinPaths(ioManager.getCurrentDirectory().path, expandedPath); file = joinPaths(self.getCurrentDirectory().path, expandedPath);
else else
file.initWithPath(expandedPath); file.initWithPath(expandedPath);
} }
@@ -536,7 +536,7 @@ function IO() //{{{
readDirectory: function (file, sort) readDirectory: function (file, sort)
{ {
if (typeof file == "string") if (typeof file == "string")
file = ioManager.getFile(file); file = self.getFile(file);
else if (!(file instanceof Ci.nsILocalFile)) else if (!(file instanceof Ci.nsILocalFile))
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
@@ -567,7 +567,7 @@ function IO() //{{{
let toCharset = "UTF-8"; let toCharset = "UTF-8";
if (typeof file == "string") if (typeof file == "string")
file = ioManager.getFile(file); file = self.getFile(file);
else if (!(file instanceof Ci.nsILocalFile)) else if (!(file instanceof Ci.nsILocalFile))
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
@@ -595,14 +595,14 @@ function IO() //{{{
let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
if (typeof file == "string") if (typeof file == "string")
file = ioManager.getFile(file); file = self.getFile(file);
else if (!(file instanceof Ci.nsILocalFile)) else if (!(file instanceof Ci.nsILocalFile))
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
if (mode == ">>") if (mode == ">>")
mode = ioManager.MODE_WRONLY | ioManager.MODE_CREATE | ioManager.MODE_APPEND; mode = self.MODE_WRONLY | self.MODE_CREATE | self.MODE_APPEND;
else if (!mode || mode == ">") else if (!mode || mode == ">")
mode = ioManager.MODE_WRONLY | ioManager.MODE_CREATE | ioManager.MODE_TRUNCATE; mode = self.MODE_WRONLY | self.MODE_CREATE | self.MODE_TRUNCATE;
if (!perms) if (!perms)
perms = 0644; perms = 0644;
@@ -624,7 +624,7 @@ function IO() //{{{
if (isAbsolutePath(program)) if (isAbsolutePath(program))
{ {
file = ioManager.getFile(program, true); file = self.getFile(program, true);
} }
else else
{ {
@@ -701,9 +701,9 @@ lookup:
} }
if (res > 0) // FIXME: Is this really right? Shouldn't we always show both? if (res > 0) // FIXME: Is this really right? Shouldn't we always show both?
var output = ioManager.readFile(stderr) + "\nshell returned " + res; var output = self.readFile(stderr) + "\nshell returned " + res;
else else
output = ioManager.readFile(stdout); output = self.readFile(stdout);
// if there is only one \n at the end, chop it off // if there is only one \n at the end, chop it off
if (output && output.indexOf("\n") == output.length - 1) if (output && output.indexOf("\n") == output.length - 1)
@@ -752,11 +752,11 @@ lookup:
// no need (actually forbidden) to add: js <<EOF ... EOF around those files // no need (actually forbidden) to add: js <<EOF ... EOF around those files
source: function (filename, silent) source: function (filename, silent)
{ {
let wasSourcing = ioManager.sourcing; let wasSourcing = self.sourcing;
try try
{ {
var file = ioManager.getFile(filename); var file = self.getFile(filename);
ioManager.sourcing = { self.sourcing = {
file: file.path, file: file.path,
line: 0 line: 0
}; };
@@ -778,7 +778,7 @@ lookup:
liberator.echomsg("sourcing " + filename.quote(), 2); liberator.echomsg("sourcing " + filename.quote(), 2);
let str = ioManager.readFile(file); let str = self.readFile(file);
let uri = ioService.newFileURI(file); let uri = ioService.newFileURI(file);
// handle pure JavaScript files specially // handle pure JavaScript files specially
@@ -824,7 +824,7 @@ lookup:
} }
else else
{ {
ioManager.sourcing.line = i + 1; self.sourcing.line = i + 1;
// skip line comments and blank lines // skip line comments and blank lines
line = line.replace(/\r$/, ""); line = line.replace(/\r$/, "");
@@ -899,7 +899,7 @@ lookup:
} }
finally finally
{ {
ioManager.sourcing = wasSourcing; self.sourcing = wasSourcing;
} }
}, },
@@ -919,7 +919,7 @@ lookup:
} }
}; //}}} }; //}}}
return ioManager; return self;
}; //}}} }; //}}}

View File

@@ -1362,7 +1362,6 @@ const liberator = (function () //{{{
callback.call(self); callback.call(self);
}, },
// TODO: interruptable not used?
threadYield: function (flush, interruptable) threadYield: function (flush, interruptable)
{ {
let mainThread = services.get("threadManager").mainThread; let mainThread = services.get("threadManager").mainThread;

View File

@@ -85,6 +85,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
<label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/> <label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
<textbox class="plain" id="liberator-commandline-command" flex="1" type="timed" timeout="100" <textbox class="plain" id="liberator-commandline-command" flex="1" type="timed" timeout="100"
oninput="liberator.modules.commandline.onEvent(event);" oninput="liberator.modules.commandline.onEvent(event);"
onkeyup="liberator.modules.commandline.onEvent(event);"
onfocus="liberator.modules.commandline.onEvent(event);" onfocus="liberator.modules.commandline.onEvent(event);"
onblur="liberator.modules.commandline.onEvent(event);"/> onblur="liberator.modules.commandline.onEvent(event);"/>
</hbox> </hbox>

View File

@@ -126,7 +126,8 @@ const modes = (function () //{{{
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
var self = { const self = {
NONE: 0, NONE: 0,
__iterator__: function () util.Array.iterator(this.all), __iterator__: function () util.Array.iterator(this.all),

View File

@@ -352,7 +352,7 @@ function CommandLine() //{{{
{ {
case this.UP: case this.UP:
if (this.selected == null) if (this.selected == null)
idx = this.items.length - 1; idx = -2
else else
idx = this.selected - 1; idx = this.selected - 1;
break; break;
@@ -362,15 +362,15 @@ function CommandLine() //{{{
else else
idx = this.selected + 1; idx = this.selected + 1;
break; break;
case this.RESET: // TODO: never used for now case this.RESET:
idx = null; idx = null;
break; break;
default: default:
idx = Math.max(0, Math.min(this.items.length - 1, idx)); idx = Math.max(0, Math.min(this.items.length - 1, idx));
break; break;
} }
this.itemList.selectItem(idx);
if (idx < 0 || idx >= this.items.length || idx == null) if (idx == -1 || this.items.length && idx >= this.items.length || idx == null)
{ {
// Wrapped. Start again. // Wrapped. Start again.
this.selected = null; this.selected = null;
@@ -378,46 +378,40 @@ function CommandLine() //{{{
} }
else else
{ {
// Wait for contexts to complete if necessary.
// FIXME: Need to make idx relative to individual contexts.
let list = this.context.contextList.reverse();
if (idx == -2)
list = list.slice().reverse();
let n = 0;
for (let [,context] in Iterator(list))
{
function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
while (context.incomplete && !done())
liberator.threadYield(true, true);
if (done())
break;
n += context.items.length;
}
// See previous FIXME. This will break if new items in
// a previous context come in.
if (idx < 0)
idx = this.items.length - 1;
this.selected = idx; this.selected = idx;
this.completion = this.items[idx].text; this.completion = this.items[idx].text;
} }
this.itemList.selectItem(idx);
}, },
tab: function tab(reverse) tab: function tab(reverse)
{ {
autocompleteTimer.flush(); autocompleteTimer.flush();
// Check if we need to run the completer. // Check if we need to run the completer.
let numElementsNeeded;
if (this.selected == null)
numElementsNeeded = reverse ? 100000 : 1; // better way to specify give me all items than setting to a very large number?
else
numElementsNeeded = reverse ? this.selected : this.selected + 2; // this.selected is zero-based
if (this.context.waitingForTab || this.wildIndex == -1) if (this.context.waitingForTab || this.wildIndex == -1)
{
this.complete(true, true); this.complete(true, true);
}
else if (this.context.incomplete && numElementsNeeded > this.items.length)
{
for (let [, context] in Iterator(this.context.contexts))
{
if (context.incomplete && context.generate)
{
// regenerate twice as many items as needed, as regenerating
// to often looks visually bad
context.minItems = numElementsNeeded * 2; // TODO: document minItems, or find a better way
context.regenerate = true;
context._generate(); // HACK
}
if (this.items.length >= numElementsNeeded)
break;
}
}
if (this.items.length == 0)
return liberator.beep();
switch (this.wildtype.replace(/.*:/, "")) switch (this.wildtype.replace(/.*:/, ""))
{ {
@@ -437,6 +431,9 @@ function CommandLine() //{{{
break; break;
} }
if (this.items.length == 0)
return void liberator.beep();
if (this.type.list) if (this.type.list)
completionList.show(); completionList.show();
@@ -1292,6 +1289,7 @@ function CommandLine() //{{{
} }
else if (event.type == "keyup") else if (event.type == "keyup")
{ {
let key = events.toString(event);
if (key == "<Tab>" || key == "<S-Tab>") if (key == "<Tab>" || key == "<S-Tab>")
tabTimer.flush(); tabTimer.flush();
} }
@@ -1620,6 +1618,7 @@ function CommandLine() //{{{
{ {
autocompleteTimer.reset(); autocompleteTimer.reset();
// liberator.dump("Resetting completions...");
if (completions) if (completions)
{ {
completions.context.cancelAll(); completions.context.cancelAll();