mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 12:47:58 +01:00
Merge branch 'master' into vimperator-2.1
Conflicts: common/content/io.js vimperator/locale/en-US/starting.txt
This commit is contained in:
29
.gitignore
vendored
29
.gitignore
vendored
@@ -1,8 +1,31 @@
|
||||
## To see if new rules exclude any existing files, run
|
||||
##
|
||||
## git ls-files -i --exclude-standard
|
||||
##
|
||||
## after modifying this file.
|
||||
|
||||
## Generated by the build process
|
||||
*.xpi
|
||||
*/locale/*/*.html
|
||||
*/chrome
|
||||
|
||||
## Editor backup and swap files
|
||||
*~
|
||||
.*.swp
|
||||
.*.swo
|
||||
.swp
|
||||
.\#*
|
||||
\#**\#
|
||||
.*.sw[op]
|
||||
.sw[op]
|
||||
|
||||
## Generated by Mac filesystem
|
||||
.DS_Store
|
||||
|
||||
## For rejects
|
||||
*.orig
|
||||
*.rej
|
||||
*.ancestor
|
||||
*.current
|
||||
*.patched
|
||||
|
||||
## Generated by StGit
|
||||
patches-*
|
||||
.stgit-edit.txt
|
||||
|
||||
56
HACKING
56
HACKING
@@ -79,7 +79,9 @@ We try to be quite consistent, but of course, that's not always possible.
|
||||
* Prefer // over /* */ comments (exceptions for big comments are usually OK)
|
||||
Right: if (HACK) // TODO: remove hack
|
||||
Wrong: if (HACK) /* TODO: remove hack */
|
||||
Documentation comment blocks use /** ... */
|
||||
|
||||
* Documentation comment blocks use /** ... */ Wrap these lines at 80
|
||||
characters.
|
||||
|
||||
* Only wrap lines if it makes the code obviously clearer. Lines longer than 132
|
||||
characters should probably be broken up rather than wrapped anyway.
|
||||
@@ -121,6 +123,43 @@ We try to be quite consistent, but of course, that's not always possible.
|
||||
|
||||
I don't like unnecessary use of 'new', I don't like 'new'. --djk
|
||||
|
||||
There is semantic value to using "new." It's good CBSE. --Ted
|
||||
|
||||
There's no semantic value. It's reasonable to infer that any function
|
||||
named in CamelCase is a constructor. That's the case with all such
|
||||
internal functions. As far as I'm concerned, 'new' is a hack. Actually,
|
||||
most of JS is a hack...
|
||||
--Kris
|
||||
|
||||
What he said. Although, I would have said "a pretty nifty language
|
||||
with some regrettable design decisions" now that I'm in therapy.
|
||||
--djk
|
||||
|
||||
There is semantic value: With new you know for SURE it's calling the
|
||||
constructor of a class, with CamelCase only you just ASSUME you do.
|
||||
I am all about making code clearer also to new developers. And this
|
||||
includes getting rid of as many assumptions as possible, by making
|
||||
things explicit, when they don't hurt readability (and new doesn't
|
||||
for me). It's not so important, that i'll change all instances to
|
||||
new immediately, but will probably do so over time, when I see it.
|
||||
--mst
|
||||
|
||||
JavaScript doesn't have classes... What about all the other
|
||||
'constructor' functions such as Commands? And I think it does hurt
|
||||
readability because it's pointless.
|
||||
Anyway, if it's important enough to change it should all be
|
||||
changed at once. I've removed most of these sorts of
|
||||
inconsistencies and I wouldn't like to see them reintroduced.
|
||||
--djk
|
||||
|
||||
Actually, you're not sure of anything. You can call new (function (a)
|
||||
a.substr(2)), and you don't get a new object. The only difference is
|
||||
that it's called with 'this' set. Given that it's uncouth to name a
|
||||
non-constructor function in CamelCase, and that most internal
|
||||
constructors don't require new (and some, like String, break when
|
||||
you use it), it just seems superfluous and distracting.
|
||||
--Kris
|
||||
|
||||
== Testing/Optimization ==
|
||||
|
||||
TODO: Add some information here about testing/validation/etc.
|
||||
@@ -142,7 +181,16 @@ TODO: Document the existence of remote branches and discuss when and how
|
||||
countless git walkthroughs, FAQs, tips pages (not to mention 'git
|
||||
help') that I don't see the need to duplicate them here. As for
|
||||
branches, 'git branch' should be sufficient, and, if not, there's
|
||||
a list on gitweb.
|
||||
--Kris
|
||||
a list on gitweb. --Kris
|
||||
|
||||
# vim: set fdm=marker sw=4 ts=4 et ai:
|
||||
I wasn't trying to say that git was a problem (though other DVCS
|
||||
have more accessible help systems; except for very complex
|
||||
projects, I think Mercurial is a much more comfortable DVCS to
|
||||
learn, use, and navigate). I was saying that it might be nice if
|
||||
the remote branches (and related polices) were documented. Yes,
|
||||
anyone can do a "git branch -r", but seeing that a branch exists
|
||||
is not the same as understanding why it's there. --Ted
|
||||
|
||||
Sure, I agree. --djk
|
||||
|
||||
// vim: set ft=asciidoc fdm=marker sw=4 ts=4 et ai:
|
||||
|
||||
@@ -10,7 +10,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
1
Makefile
1
Makefile
@@ -8,4 +8,3 @@ $(TARGETS:%=\%.%):
|
||||
$(MAKE) -C $* $(@:$*.%=%)
|
||||
|
||||
$(TARGETS): %: $(DIRS:%=%.%)
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ OS = $(shell uname -s)
|
||||
BUILD_DATE = $(shell date "+%Y/%m/%d %H:%M:%S")
|
||||
BASE = $(TOP)/../common
|
||||
|
||||
DOC_SRC_FILES = $(wildcard locale/*/*.txt)
|
||||
DOC_FILES = ${DOC_SRC_FILES:%.txt=%.html}
|
||||
DOC_SRC_FILES = $(wildcard locale/*/*.txt) $(wildcard locale/*/*.t2t)
|
||||
LOCALES = $(wildcard locale/*)
|
||||
|
||||
MAKE_JAR = VERSION="$(VERSION)" DATE="$(BUILD_DATE)" sh $(BASE)/make_jar.sh
|
||||
|
||||
@@ -63,8 +63,6 @@ info:
|
||||
@echo -e "jar files $(shell echo ${JAR_FILES} | sed 's/ /\\n /g' )"
|
||||
@echo "xpi files ${XPI_FILES}"
|
||||
|
||||
.PHONY: check-asciidoc
|
||||
doc: check-asciidoc ${DOC_FILES}
|
||||
xpi: ${XPI}
|
||||
jar: ${JAR}
|
||||
|
||||
@@ -80,11 +78,10 @@ ${RDF}: ${RDF_IN} Makefile
|
||||
clean:
|
||||
@echo "Cleanup..."
|
||||
rm -f ${JAR} ${XPI}
|
||||
find . -name '*~' -exec rm -f {} \;
|
||||
|
||||
distclean: clean
|
||||
@echo "More cleanup..."
|
||||
rm -f ${DOC_FILES}
|
||||
@set -e; for locale in $(LOCALES); do $(MAKE) -C clean; doc; done
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
#### xpi
|
||||
@@ -103,21 +100,7 @@ $(JAR): doc
|
||||
$(MAKE_JAR) "$(JAR)" "$(JAR_BASES)" "$(JAR_DIRS)" "$(JAR_TEXTS)" "$(JAR_BINS)" "$(JAR_FILES)"
|
||||
@echo "SUCCESS: $@"
|
||||
|
||||
#### doc
|
||||
|
||||
check-asciidoc:
|
||||
@asciidoc --version | awk '{ exit $$2 !~ /^8\.2\./ }' || \
|
||||
echo >&2 "Warning: asciidoc versions other than 8.2.x are unsupported"
|
||||
|
||||
${DOC_FILES}: %.html: %.txt $(BASE)/Makefile.common locale/en-US/asciidoc.conf
|
||||
@echo "DOC $@"
|
||||
${ASCIIDOC} --unsafe -a linkcss -a quirks! -a doctitle="$(shell basename $@)" -o $@ $<
|
||||
|
||||
T2T = $(wildcard locale/*/*.t2t)
|
||||
t2t: $(T2T:%.t2t=%.xhtml)
|
||||
$(T2T:%.t2t=%.xhtml): locale/en-US/config.t2t
|
||||
|
||||
%.xhtml: %.t2t
|
||||
@echo "T2T $@"
|
||||
txt2tags --quiet $<
|
||||
#### doc (see Makefile.doc)
|
||||
|
||||
doc:
|
||||
@set -e; for locale in $(LOCALES); do $(MAKE) -C $$locale doc; done
|
||||
|
||||
75
common/Makefile.doc
Normal file
75
common/Makefile.doc
Normal file
@@ -0,0 +1,75 @@
|
||||
# Symlink me to locale/*/Makefile
|
||||
|
||||
#### configuration
|
||||
|
||||
BASE = ../../../common
|
||||
|
||||
THIS_LOCALE = $(notdir $(shell pwd))
|
||||
|
||||
ADC_SRC_FILES = $(wildcard *.txt)
|
||||
ADC_FILES = $(ADC_SRC_FILES:%.txt=%.html)
|
||||
ADC_DEPS = $(wildcard asciidoc.conf)
|
||||
|
||||
T2T_SRC_FILES = $(wildcard *.t2t)
|
||||
T2T_FILES = $(T2T_SRC_FILES:%.t2t=%.xhtml)
|
||||
T2T_DEPS = $(wildcard config.t2t)
|
||||
|
||||
DOC_FILES = $(ADC_FILES) $(T2T_FILES)
|
||||
|
||||
ASCIIDOC = asciidoc
|
||||
TXT2TAGS = txt2tags
|
||||
AWK = awk
|
||||
|
||||
.SILENT:
|
||||
|
||||
#### rules
|
||||
|
||||
.PHONY: all help doc asciidoc check-asciidoc clean distclean
|
||||
all: doc
|
||||
|
||||
doc: asciidoc t2t
|
||||
|
||||
help:
|
||||
@echo "${NAME} ${VERSION} build"
|
||||
@echo
|
||||
@echo " make help - display this help"
|
||||
@echo " make doc - build doc files"
|
||||
@echo " make asciidoc - build asciidoc'd files only"
|
||||
@echo " make t2t - build txt2tags'd files only"
|
||||
@echo " make clean - clean up"
|
||||
@echo " make distclean - clean up more"
|
||||
|
||||
clean:
|
||||
@echo "Cleanup..."
|
||||
|
||||
distclean: clean
|
||||
@echo "More cleanup..."
|
||||
rm -f $(DOC_FILES)
|
||||
|
||||
#### Makes single-file makes easier to type
|
||||
|
||||
%: %.html %.t2t %.xhtml %.t2t ;
|
||||
|
||||
%: %.html %.txt ;
|
||||
|
||||
%: %.xhtml %.t2t ;
|
||||
|
||||
#### asciidoc
|
||||
|
||||
asciidoc: check-asciidoc $(ADC_FILES)
|
||||
|
||||
check-asciidoc:
|
||||
@$(ASCIIDOC) --version | $(AWK) '{ exit $$2 !~ /^8\.2\./ }' || \
|
||||
echo >&2 "Warning: asciidoc versions other than 8.2.x are unsupported"
|
||||
|
||||
$(ADC_FILES): %.html: %.txt $(BASE)/Makefile.doc $(ADC_DEPS)
|
||||
@echo "DOC locale/$(THIS_LOCALE)/$@"
|
||||
$(ASCIIDOC) --unsafe -a linkcss -a quirks! -a doctitle="$(shell basename $@)" -o $@ $<
|
||||
|
||||
#### txt2tags
|
||||
|
||||
t2t: $(T2T_FILES)
|
||||
|
||||
$(T2T_FILES): %.xhtml: %.t2t $(BASE)/Makefile.doc $(T2T_DEPS)
|
||||
@echo "T2T locale/$(THIS_LOCALE)/$@"
|
||||
txt2tags --quiet $<
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -157,7 +157,7 @@ function Buffer() //{{{
|
||||
|
||||
options.add(["pageinfo", "pa"], "Desired info on :pa[geinfo]", "charlist", "gfm",
|
||||
{
|
||||
completer: function (filter) [[k, v[1]] for ([k, v] in Iterator(pageInfo))],
|
||||
completer: function (context) [[k, v[1]] for ([k, v] in Iterator(pageInfo))],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -170,7 +170,7 @@ function Buffer() //{{{
|
||||
"Show the destination of the link under the cursor in the status bar",
|
||||
"number", 1,
|
||||
{
|
||||
completer: function (filter) [
|
||||
completer: function (context) [
|
||||
["0", "Don't show link destination"],
|
||||
["1", "Show the link in the status line"],
|
||||
["2", "Show the link in the command line"]
|
||||
@@ -356,8 +356,7 @@ function Buffer() //{{{
|
||||
function ()
|
||||
{
|
||||
liberator.open(util.readFromClipboard(),
|
||||
/\bpaste\b/.test(options["activate"]) ?
|
||||
liberator.NEW_BACKGROUND_TAB : liberator.NEW_TAB);
|
||||
liberator[options.get("activate").has("paste") ? "NEW_BACKGROUND_TAB" : "NEW_TAB"]);
|
||||
});
|
||||
|
||||
mappings.add(myModes, ["p", "<MiddleMouse>"],
|
||||
@@ -849,7 +848,7 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* @property {Object} The last focused input field in the buffer. Used
|
||||
* @property {Node} The last focused input field in the buffer. Used
|
||||
* by the "gi" key binding.
|
||||
*/
|
||||
get lastInputField()
|
||||
@@ -987,6 +986,7 @@ function Buffer() //{{{
|
||||
selController.wordMove(false, false);
|
||||
selController.wordMove(true, true);
|
||||
selController.setCaretEnabled(caretmode);
|
||||
return String.match(selection, /\w*/)[0];
|
||||
}
|
||||
let range = selection.getRangeAt(0);
|
||||
if (util.computedStyle(range.startContainer).whiteSpace == "pre"
|
||||
@@ -1139,15 +1139,18 @@ function Buffer() //{{{
|
||||
elem.focus();
|
||||
|
||||
let evt = doc.createEvent("MouseEvents");
|
||||
options.withContext(function () {
|
||||
options.setPref("browser.tabs.loadInBackground", true);
|
||||
["mousedown", "mouseup", "click"].forEach(function (event) {
|
||||
evt.initMouseEvent(event, true, true, view, 1, offsetX, offsetY, 0, 0,
|
||||
ctrlKey, /*altKey*/0, shiftKey, /*metaKey*/ ctrlKey, 0, null);
|
||||
elem.dispatchEvent(evt);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @property {Object} The current document's selection controller.
|
||||
* @property {nsISelectionController} The current document's selection controller.
|
||||
*/
|
||||
get selectionController() getBrowser().docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
@@ -1157,8 +1160,8 @@ function Buffer() //{{{
|
||||
/**
|
||||
* Saves a page link to disk.
|
||||
*
|
||||
* @param {Object} elem The page link to save.
|
||||
* @param {boolean} skipPrompt Whether to open the "Save Link As..." dialog
|
||||
* @param {HTMLAnchorElement} elem The page link to save.
|
||||
* @param {boolean} skipPrompt Whether to open the "Save Link As..." dialog.
|
||||
*/
|
||||
saveLink: function (elem, skipPrompt)
|
||||
{
|
||||
@@ -1381,7 +1384,7 @@ function Buffer() //{{{
|
||||
/**
|
||||
* Displays information about the specified element.
|
||||
*
|
||||
* @param {Object} elem
|
||||
* @param {Node} elem
|
||||
*/
|
||||
showElementInfo: function (elem)
|
||||
{
|
||||
@@ -1662,7 +1665,10 @@ function Marks() //{{{
|
||||
|
||||
marks.remove(args, special);
|
||||
},
|
||||
{ bang: true });
|
||||
{
|
||||
bang: true,
|
||||
completer: function (context) completion.mark(context)
|
||||
});
|
||||
|
||||
commands.add(["ma[rk]"],
|
||||
"Mark current location within the web page",
|
||||
@@ -1707,6 +1713,8 @@ function Marks() //{{{
|
||||
|
||||
return {
|
||||
|
||||
get all() getSortedMarks(),
|
||||
|
||||
/**
|
||||
* Add a named mark for the current buffer, at its current position.
|
||||
* If mark matches [A-Z], it's considered a URL mark, and will jump to
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -150,7 +150,7 @@ Command.prototype = {
|
||||
* @param {number} count @deprecated Whether this command was
|
||||
* executed with a leading count.
|
||||
* @param modifiers Any modifiers to be passed to
|
||||
* {@link action}
|
||||
* {@link #action}.
|
||||
*/
|
||||
execute: function (args, bang, count, modifiers)
|
||||
{
|
||||
@@ -233,15 +233,6 @@ function Commands() //{{{
|
||||
|
||||
var exCommands = [];
|
||||
|
||||
function parseBool(arg)
|
||||
{
|
||||
if (arg == "true" || arg == "1" || arg == "on")
|
||||
return true;
|
||||
if (arg == "false" || arg == "0" || arg == "off")
|
||||
return false;
|
||||
return NaN;
|
||||
}
|
||||
|
||||
const QUOTE_STYLE = "vimperator";
|
||||
|
||||
const quoteMap = {
|
||||
@@ -264,16 +255,24 @@ function Commands() //{{{
|
||||
"": quote("", "\\\\ ")
|
||||
};
|
||||
|
||||
function parseBool(arg)
|
||||
{
|
||||
if (/^(true|1|on)$/i.test(arg))
|
||||
return true;
|
||||
if (/^(false|0|off)$/i.test(arg))
|
||||
return false;
|
||||
return NaN;
|
||||
}
|
||||
const ArgType = new Struct("description", "parse");
|
||||
const argTypes = [
|
||||
null,
|
||||
["no arg", function (arg) !arg],
|
||||
["boolean", parseBool],
|
||||
["string", function (val) val],
|
||||
["int", parseInt],
|
||||
["float", parseFloat],
|
||||
["list", function (arg) arg && arg.split(/\s*,\s*/)]
|
||||
].map(function (x) x && ArgType.apply(null, x));
|
||||
ArgType("no arg", function (arg) !arg || null),
|
||||
ArgType("boolean", parseBool),
|
||||
ArgType("string", function (val) val),
|
||||
ArgType("int", parseInt),
|
||||
ArgType("float", parseFloat),
|
||||
ArgType("list", function (arg) arg && arg.split(/\s*,\s*/))
|
||||
];
|
||||
|
||||
function addCommand(command, isUserCommand, replace)
|
||||
{
|
||||
@@ -358,7 +357,7 @@ function Commands() //{{{
|
||||
|
||||
let str = args.literalArg;
|
||||
if (str)
|
||||
res.push(/\n/.test(str) ? "<<EOF\n" + str + "EOF" : str);
|
||||
res.push(/\n/.test(str) ? "<<EOF\n" + str.replace(/\n$/, "") + "\nEOF" : str);
|
||||
return res.join(" ");
|
||||
},
|
||||
|
||||
@@ -843,7 +842,7 @@ function Commands() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
completeFunc = function () completion[completeOptionMap[completeOpt]].apply(this, Array.slice(arguments));
|
||||
completeFunc = completion[completeOptionMap[completeOpt]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,11 +853,7 @@ function Commands() //{{{
|
||||
argCount: nargsOpt,
|
||||
bang: bangOpt,
|
||||
count: countOpt,
|
||||
completer: function (context, args)
|
||||
{
|
||||
if (completeFunc)
|
||||
return completeFunc(context, args)
|
||||
},
|
||||
completer: completeFunc,
|
||||
replacementText: args.literalArg
|
||||
}, args.bang);
|
||||
|
||||
@@ -870,8 +865,7 @@ function Commands() //{{{
|
||||
function completerToString(completer)
|
||||
{
|
||||
if (completer)
|
||||
return [k for ([k, v] in Iterator(completeOptionMap))
|
||||
if (v == completer.name)][0] || "custom";
|
||||
return [k for ([k, v] in Iterator(completeOptionMap)) if (completer == completion[v])][0] || "custom";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
@@ -907,6 +901,7 @@ function Commands() //{{{
|
||||
function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
|
||||
[["-bang"], self.OPTION_NOARG],
|
||||
[["-count"], self.OPTION_NOARG],
|
||||
// TODO: "E180: invalid complete value: " + arg
|
||||
[["-complete"], self.OPTION_STRING,
|
||||
function (arg) arg in completeOptionMap || /custom,\w+/.test(arg),
|
||||
function (context) [[k, ""] for ([k, v] in Iterator(completeOptionMap))]]
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -159,7 +159,7 @@ function CompletionContext(editor, name, offset) //{{{
|
||||
* contain inactive contexts. For active contexts, see
|
||||
* {@link #contextList}.
|
||||
*/
|
||||
this.contexts = { "/": this };
|
||||
this.contexts = { "": this };
|
||||
/**
|
||||
* @property {Object} A mapping of keys, for {@link #getKey}. Given
|
||||
* { key: value }, getKey(item, key) will return values as such:
|
||||
@@ -285,7 +285,7 @@ CompletionContext.prototype = {
|
||||
set completions(items)
|
||||
{
|
||||
// Accept a generator
|
||||
if (!(items instanceof Array))
|
||||
if (!("length" in items))
|
||||
items = [x for (x in Iterator(items))];
|
||||
delete this.cache.filtered;
|
||||
delete this.cache.filter;
|
||||
@@ -1388,7 +1388,6 @@ function Completion() //{{{
|
||||
{ process.call(this, item, text) }
|
||||
</>];
|
||||
|
||||
|
||||
context.completions = util.map(tabs.browsers, function ([i, browser]) {
|
||||
let indicator = " ";
|
||||
if (i == tabs.index())
|
||||
@@ -1608,7 +1607,23 @@ function Completion() //{{{
|
||||
context.completions = [item for (item in events.getMacros())];
|
||||
},
|
||||
|
||||
menuItem: function menuItem(filter) commands.get("emenu").completer(filter), // XXX
|
||||
mark: function mark(context)
|
||||
{
|
||||
function percent(i) Math.round(i * 100);
|
||||
|
||||
// FIXME: Line/Column doesn't make sense with %
|
||||
context.title = ["Mark", "Line Column File"];
|
||||
context.keys.description = function ([,m]) percent(m.position.y) + "% " + percent(m.position.x) + "% " + m.location;
|
||||
context.completions = marks.all;
|
||||
},
|
||||
|
||||
menuItem: function menuItem(context)
|
||||
{
|
||||
context.title = ["Menu Path", "Label"];
|
||||
context.anchored = false;
|
||||
context.keys = { text: "fullMenuPath", description: "label" };
|
||||
context.completions = liberator.menuItems;
|
||||
},
|
||||
|
||||
option: function option(context, scope)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -189,8 +189,8 @@ function AutoCommands() //{{{
|
||||
*
|
||||
* @param {Array} events The array of event names for which this
|
||||
* autocommand should be executed.
|
||||
* @param {string} regex The URL pattern to match against the buffer URL
|
||||
* @param {string} cmd The Ex command to run
|
||||
* @param {string} regex The URL pattern to match against the buffer URL.
|
||||
* @param {string} cmd The Ex command to run.
|
||||
*/
|
||||
add: function (events, regex, cmd)
|
||||
{
|
||||
@@ -630,7 +630,7 @@ function Events() //{{{
|
||||
|
||||
// load all macros inside ~/.vimperator/macros/
|
||||
// setTimeout needed since io. is loaded after events.
|
||||
setTimeout (function () {
|
||||
setTimeout(function () {
|
||||
try
|
||||
{
|
||||
let dirs = io.getRuntimeDirectories("macros");
|
||||
@@ -769,8 +769,11 @@ function Events() //{{{
|
||||
// removeEventListeners() to avoid mem leaks
|
||||
liberator.dump("TODO: remove all eventlisteners");
|
||||
|
||||
if (typeof getBrowser != "undefined")
|
||||
try
|
||||
{
|
||||
getBrowser().removeProgressListener(this.progressListener);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
window.removeEventListener("popupshown", enterPopupMode, true);
|
||||
window.removeEventListener("popuphidden", exitPopupMode, true);
|
||||
@@ -915,7 +918,7 @@ function Events() //{{{
|
||||
//if (keys[i] == "\\") // FIXME: support the escape key
|
||||
if (keys[i] == "<" && !escapeKey) // start a complex key
|
||||
{
|
||||
let [match, modifier, keyname] = keys.substr(i).match(/<([CSMA]-)*(.+?)>/i) || [];
|
||||
let [match, modifier, keyname] = keys.substr(i).match(/<((?:[CSMA]-)*)(.+?)>/i) || [];
|
||||
if (keyname)
|
||||
{
|
||||
if (modifier) // check for modifiers
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -123,8 +123,8 @@ function Search() //{{{
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
* Portions created by the Initial Developer are Copyright (c) 2003
|
||||
* by the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Blake Ross <blake@cs.stanford.edu> (Original Author)
|
||||
@@ -436,7 +436,6 @@ function Search() //{{{
|
||||
// escape while typing a search
|
||||
searchCanceled: function ()
|
||||
{
|
||||
this.clear();
|
||||
// TODO: code to reposition the document to the place before search started
|
||||
},
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -73,10 +73,10 @@ function Hints() //{{{
|
||||
t: Mode("Follow hint in a new tab", function (elem) buffer.followLink(elem, liberator.NEW_TAB)),
|
||||
b: Mode("Follow hint in a background tab", function (elem) buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB)),
|
||||
w: Mode("Follow hint in a new window", function (elem) buffer.followLink(elem, liberator.NEW_WINDOW), extended),
|
||||
F: Mode("Follow hint sequence in tabs", hintSequenceElement),
|
||||
O: Mode("Preselect hint in an :open query", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
|
||||
T: Mode("Preselect hint in a :tabopen query", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
|
||||
W: Mode("Preselect hint in a :winopen query", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
|
||||
F: Mode("Open multiple hints in tabs", hintAction_F),
|
||||
O: Mode(":open URL based on hint location", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
|
||||
T: Mode(":tabopen URL based on hint location", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
|
||||
W: Mode(":winopen URL based on hint location", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
|
||||
v: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, false), extended),
|
||||
V: Mode("View hint source in external editor", function (elem, loc) buffer.viewSource(loc, true), extended),
|
||||
y: Mode("Yank hint location", function (elem, loc) util.copyToClipboard(loc, true)),
|
||||
@@ -84,17 +84,10 @@ function Hints() //{{{
|
||||
};
|
||||
|
||||
// Used to open multiple hints
|
||||
function hintSequenceElement(elem)
|
||||
function hintAction_F(elem)
|
||||
{
|
||||
// Want to always open sequence hints in background
|
||||
// (remember: NEW_BACKGROUND_TAB and NEW_TAB semantics assume
|
||||
// that loadInBackground=true)
|
||||
if (options.getPref("browser.tabs.loadInBackground"))
|
||||
buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB);
|
||||
else
|
||||
buffer.followLink(elem, liberator.NEW_TAB);
|
||||
|
||||
// Move to next element in sequence
|
||||
// TODO: Maybe we find a *simple* way to keep the hints displayed rather than
|
||||
// showing them again, or is this short flash actually needed as a "usability
|
||||
// feature"? --mst
|
||||
@@ -580,10 +573,12 @@ function Hints() //{{{
|
||||
"How links are matched",
|
||||
"string", "contains",
|
||||
{
|
||||
completer: function (filter)
|
||||
{
|
||||
return [[m, ""] for each (m in ["contains", "wordstartswith", "firstletters", "custom"])];
|
||||
},
|
||||
completer: function (context) [
|
||||
["contains", "The typed characters are split on whitespace. The resulting groups must all appear in the hint."],
|
||||
["wordstartswith", "The typed characters are split on whitespace. The resulting groups must all match the beginings of words, in order."],
|
||||
["firstletters", "Behaves like wordstartswith, but all groups much match a sequence of words."],
|
||||
["custom", "Delegate to a custom function: liberator.plugins.customHintMatcher(hintString)"],
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -599,9 +594,19 @@ function Hints() //{{{
|
||||
"Start QuickHint mode",
|
||||
function () { hints.show("o"); });
|
||||
|
||||
// At the moment, "F" calls
|
||||
// buffer.followLink(clicked_element, DO_WHAT_FIREFOX_DOES_WITH_CNTRL_CLICK)
|
||||
// It is not clear that it shouldn't be:
|
||||
// buffer.followLink(clicked_element, !DO_WHAT_FIREFOX_DOES_WITH_CNTRL_CLICK)
|
||||
// In fact, it might be nice if there was a "dual" to F (like H and
|
||||
// gH, except that gF is already taken). --tpp
|
||||
//
|
||||
// Likewise, it might be nice to have a liberator.NEW_FOREGROUND_TAB
|
||||
// and then make liberator.NEW_TAB always do what a Cntrl+Click
|
||||
// does. --tpp
|
||||
mappings.add(myModes, ["F"],
|
||||
"Start QuickHint mode, but open link in a new tab",
|
||||
function () { hints.show("t"); });
|
||||
function () { hints.show(options.getPref("browser.tabs.loadInBackground") ? "b" : "t"); });
|
||||
|
||||
mappings.add(myModes, [";"],
|
||||
"Start an extended hint mode",
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Code based on venkman
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
@@ -40,7 +40,7 @@ function Script(file)
|
||||
return self;
|
||||
}
|
||||
plugins.contexts[file.path] = this;
|
||||
this.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/, function (_0, _1) _1.toUpperCase());
|
||||
this.NAME = file.leafName.replace(/\..*/, "").replace(/-([a-z])/g, function (m, n1) n1.toUpperCase());
|
||||
this.PATH = file.path;
|
||||
this.__context__ = this;
|
||||
|
||||
@@ -48,13 +48,14 @@ function Script(file)
|
||||
for (let [,dir] in Iterator(io.getRuntimeDirectories("plugin")))
|
||||
{
|
||||
if (dir.contains(file, false))
|
||||
plugins[name] = this.NAME;
|
||||
plugins[this.NAME] = this;
|
||||
}
|
||||
}
|
||||
Script.prototype = plugins;
|
||||
|
||||
// TODO: why are we passing around strings rather than file objects?
|
||||
/**
|
||||
* Provides a basic interface to common system I/O operations.
|
||||
* @instance io
|
||||
*/
|
||||
function IO() //{{{
|
||||
@@ -388,21 +389,94 @@ function IO() //{{{
|
||||
|
||||
const self = {
|
||||
|
||||
/**
|
||||
* @property {number} Open for reading only.
|
||||
* @final
|
||||
*/
|
||||
MODE_RDONLY: 0x01,
|
||||
|
||||
/**
|
||||
* @property {number} Open for writing only.
|
||||
* @final
|
||||
*/
|
||||
MODE_WRONLY: 0x02,
|
||||
|
||||
/**
|
||||
* @property {number} Open for reading and writing.
|
||||
* @final
|
||||
*/
|
||||
MODE_RDWR: 0x04,
|
||||
|
||||
/**
|
||||
* @property {number} If the file does not exist, the file is created.
|
||||
* If the file exists, this flag has no effect.
|
||||
* @final
|
||||
*/
|
||||
MODE_CREATE: 0x08,
|
||||
|
||||
/**
|
||||
* @property {number} The file pointer is set to the end of the file
|
||||
* prior to each write.
|
||||
* @final
|
||||
*/
|
||||
MODE_APPEND: 0x10,
|
||||
|
||||
/**
|
||||
* @property {number} If the file exists, its length is truncated to 0.
|
||||
* @final
|
||||
*/
|
||||
MODE_TRUNCATE: 0x20,
|
||||
|
||||
/**
|
||||
* @property {number} If set, each write will wait for both the file
|
||||
* data and file status to be physically updated.
|
||||
* @final
|
||||
*/
|
||||
MODE_SYNC: 0x40,
|
||||
|
||||
/**
|
||||
* @property {number} With MODE_CREATE, if the file does not exist, the
|
||||
* file is created. If the file already exists, no action and NULL
|
||||
* is returned.
|
||||
* @final
|
||||
*/
|
||||
MODE_EXCL: 0x80,
|
||||
|
||||
/**
|
||||
* @property {Object} The current file sourcing context. As a file is
|
||||
* being sourced the 'file' and 'line' properties of this context
|
||||
* object are updated appropriately.
|
||||
*/
|
||||
sourcing: null,
|
||||
|
||||
/**
|
||||
* Expands "~" and environment variables in <b>path</b>.
|
||||
*
|
||||
* "~" is expanded to to the value of $HOME. On Windows if this is not
|
||||
* set then the following are tried in order:
|
||||
* $USERPROFILE
|
||||
* ${HOMDRIVE}$HOMEPATH
|
||||
*
|
||||
* The variable notation is $VAR (terminated by a non-word character)
|
||||
* or ${VAR}. %VAR% is also supported on Windows.
|
||||
*
|
||||
* @param {string} path The unexpanded path string.
|
||||
* @param {boolean} relative Whether the path is relative or absolute.
|
||||
* @returns {string}
|
||||
*/
|
||||
expandPath: IO.expandPath,
|
||||
|
||||
// TODO: there seems to be no way, short of a new component, to change
|
||||
// Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953
|
||||
/**
|
||||
* Returns the current working directory.
|
||||
*
|
||||
* It's not possible to change the real CWD of Firefox so this state is
|
||||
* maintained internally. External commands run via {@link #system} are
|
||||
* executed in this directory.
|
||||
*
|
||||
* @returns {nsIFile}
|
||||
*/
|
||||
getCurrentDirectory: function ()
|
||||
{
|
||||
let dir = self.getFile(cwd.path);
|
||||
@@ -415,17 +489,23 @@ function IO() //{{{
|
||||
return processDir;
|
||||
},
|
||||
|
||||
setCurrentDirectory: function (newdir)
|
||||
/**
|
||||
* Sets the current working directory.
|
||||
*
|
||||
* @param {string} newDir The new CWD. This may be a relative or
|
||||
* absolute path and is expanded by {@link #expandPath}.
|
||||
*/
|
||||
setCurrentDirectory: function (newDir)
|
||||
{
|
||||
newdir = newdir || "~";
|
||||
newDir = newDir || "~";
|
||||
|
||||
if (newdir == "-")
|
||||
if (newDir == "-")
|
||||
{
|
||||
[cwd, oldcwd] = [oldcwd, this.getCurrentDirectory()];
|
||||
}
|
||||
else
|
||||
{
|
||||
let dir = self.getFile(newdir);
|
||||
let dir = self.getFile(newDir);
|
||||
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
{
|
||||
@@ -439,16 +519,30 @@ function IO() //{{{
|
||||
return self.getCurrentDirectory();
|
||||
},
|
||||
|
||||
getRuntimeDirectories: function (specialDirectory)
|
||||
/**
|
||||
* Returns all directories named <b>name<b/> in 'runtimepath'.
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {nsIFile[])
|
||||
*/
|
||||
getRuntimeDirectories: function (name)
|
||||
{
|
||||
let dirs = getPathsFromPathList(options["runtimepath"]);
|
||||
|
||||
dirs = dirs.map(function (dir) joinPaths(dir, specialDirectory))
|
||||
dirs = dirs.map(function (dir) joinPaths(dir, name))
|
||||
.filter(function (dir) dir.exists() && dir.isDirectory() && dir.isReadable());
|
||||
|
||||
return dirs;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the first user RC file found in <b>dir</b>.
|
||||
*
|
||||
* @param {string} dir The directory to search.
|
||||
* @param {boolean} always When true, return a path whether
|
||||
* the file exists or not.
|
||||
* @default $HOME.
|
||||
*/
|
||||
getRCFile: function (dir, always)
|
||||
{
|
||||
dir = dir || "~";
|
||||
@@ -471,6 +565,14 @@ function IO() //{{{
|
||||
// return a nsILocalFile for path where you can call isDirectory(), etc. on
|
||||
// caller must check with .exists() if the returned file really exists
|
||||
// also expands relative paths
|
||||
/**
|
||||
* Returns an nsIFile object for <b>path</b>, which is expanded
|
||||
* according to {@link #expandPath}.
|
||||
*
|
||||
* @param {string} path The path used to create the file object.
|
||||
* @param {boolean} noCheckPWD Whether to allow a relative path.
|
||||
* @returns {nsIFile}
|
||||
*/
|
||||
getFile: function (path, noCheckPWD)
|
||||
{
|
||||
let file = services.create("file");
|
||||
@@ -494,7 +596,11 @@ function IO() //{{{
|
||||
},
|
||||
|
||||
// TODO: make secure
|
||||
// returns a nsILocalFile or null if it could not be created
|
||||
/**
|
||||
* Creates a temporary file.
|
||||
*
|
||||
* @returns {nsIFile}
|
||||
*/
|
||||
createTempFile: function ()
|
||||
{
|
||||
let tmpName = EXTENSION_NAME + ".tmp";
|
||||
@@ -525,17 +631,25 @@ function IO() //{{{
|
||||
|
||||
},
|
||||
|
||||
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
||||
readDirectory: function (file, sort)
|
||||
/**
|
||||
* Returns the list of files in <b>dir</b>.
|
||||
*
|
||||
* @param {nsIFile|string} dir The directory to read, either a full
|
||||
* pathname or an instance of nsIFile.
|
||||
* @param {boolean} sort Whether to sort the returned directory
|
||||
* entries.
|
||||
* @returns {nsIFile[]}
|
||||
*/
|
||||
readDirectory: function (dir, sort)
|
||||
{
|
||||
if (typeof file == "string")
|
||||
file = self.getFile(file);
|
||||
else if (!(file instanceof Ci.nsILocalFile))
|
||||
if (typeof dir == "string")
|
||||
dir = self.getFile(dir);
|
||||
else if (!(dir instanceof Ci.nsILocalFile))
|
||||
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
|
||||
|
||||
if (file.isDirectory())
|
||||
if (dir.isDirectory())
|
||||
{
|
||||
let entries = file.directoryEntries;
|
||||
let entries = dir.directoryEntries;
|
||||
let array = [];
|
||||
while (entries.hasMoreElements())
|
||||
{
|
||||
@@ -551,8 +665,13 @@ function IO() //{{{
|
||||
// Yes --djk
|
||||
},
|
||||
|
||||
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
||||
// reads a file in "text" mode and returns the string
|
||||
/**
|
||||
* Reads a file in "text" mode and returns the content as a string.
|
||||
*
|
||||
* @param {nsIFile|string} file The file to read, either a full
|
||||
* pathname or an instance of nsIFile.
|
||||
* @returns {string}
|
||||
*/
|
||||
readFile: function (file)
|
||||
{
|
||||
let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
|
||||
@@ -578,9 +697,30 @@ function IO() //{{{
|
||||
return buffer;
|
||||
},
|
||||
|
||||
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
||||
// default permission = 0644, only used when creating a new file, does not change permissions if the file exists
|
||||
// mode can be ">" or ">>" in addition to the normal MODE_* flags
|
||||
/**
|
||||
* Writes the string <b>buf</b> to a file.
|
||||
*
|
||||
* @param {nsIFile|string} file The file to write, either a full
|
||||
* pathname or an instance of nsIFile.
|
||||
* @param {string} buf The file content.
|
||||
* @param {string|number} mode The file access mode, a bitwise OR of
|
||||
* the following flags:
|
||||
* {@link #MODE_RDONLY}: 0x01
|
||||
* {@link #MODE_WRONLY}: 0x02
|
||||
* {@link #MODE_RDWR}: 0x04
|
||||
* {@link #MODE_CREATE}: 0x08
|
||||
* {@link #MODE_APPEND}: 0x10
|
||||
* {@link #MODE_TRUNCATE}: 0x20
|
||||
* {@link #MODE_SYNC}: 0x40
|
||||
* Alternatively, the following abbreviations may be used:
|
||||
* ">" is equivalent to {@link #MODE_WRONLY} | {@link #MODE_CREATE} | {@link #MODE_TRUNCATE}
|
||||
* ">>" is equivalent to {@link #MODE_WRONLY} | {@link #MODE_CREATE} | {@link #MODE_APPEND}
|
||||
* @default ">"
|
||||
* @param {number} perms The file mode bits of the created file. This
|
||||
* is only used when creating a new file and does not change
|
||||
* permissions if the file exists.
|
||||
* @default 0644
|
||||
*/
|
||||
writeFile: function (file, buf, mode, perms)
|
||||
{
|
||||
let ofstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
|
||||
@@ -608,6 +748,13 @@ function IO() //{{{
|
||||
ofstream.close();
|
||||
},
|
||||
|
||||
/**
|
||||
* Runs an external program.
|
||||
*
|
||||
* @param {string} program The program to run.
|
||||
* @param {string[]} args An array of arguments to pass to <b>program</b>.
|
||||
* @param {boolean} blocking Whether to wait until the process terminates.
|
||||
*/
|
||||
run: function (program, args, blocking)
|
||||
{
|
||||
args = args || [];
|
||||
@@ -666,47 +813,17 @@ lookup:
|
||||
return process.exitValue;
|
||||
},
|
||||
|
||||
// when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is fixed
|
||||
// is fixed, should use that instead of a tmpfile
|
||||
system: function (command, input)
|
||||
{
|
||||
liberator.echomsg("Calling shell to execute: " + command, 4);
|
||||
|
||||
function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"';
|
||||
|
||||
return this.withTempFiles(function (stdin, stdout, stderr, cmd) {
|
||||
|
||||
if (input)
|
||||
this.writeFile(stdin, input);
|
||||
|
||||
if (WINDOWS)
|
||||
{
|
||||
command = "cd /D " + cwd.path + " && " + command + " > " + stdout.path + " 2> " + stderr.path + " < " + stdin.path;
|
||||
var res = this.run(options["shell"], options["shellcmdflag"].split(/\s+/).concat(command), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
this.writeFile(cmd, "cd " + escape(cwd.path) + "\n" +
|
||||
["exec", ">" + escape(stdout.path), "2>" + escape(stderr.path), "<" + escape(stdin.path),
|
||||
escape(options["shell"]), options["shellcmdflag"], escape(command)].join(" "));
|
||||
res = this.run("/bin/sh", ["-e", cmd.path], true);
|
||||
}
|
||||
|
||||
if (res > 0) // FIXME: Is this really right? Shouldn't we always show both?
|
||||
var output = self.readFile(stderr) + "\nshell returned " + res;
|
||||
else
|
||||
output = self.readFile(stdout);
|
||||
|
||||
// if there is only one \n at the end, chop it off
|
||||
if (output && output.indexOf("\n") == output.length - 1)
|
||||
output = output.substr(0, output.length - 1);
|
||||
|
||||
return output;
|
||||
}) || "";
|
||||
},
|
||||
|
||||
// FIXME: multiple paths?
|
||||
/**
|
||||
* Sources files found in 'runtimepath'. For each relative path in
|
||||
* <b>paths</b> each directory in 'runtimepath' is searched and if a
|
||||
* matching file is found it is sourced. Only the first file found (per
|
||||
* specified path) is sourced unless <b>all</b> is specified, then
|
||||
* all found files are sourced.
|
||||
*
|
||||
* @param {string[]} paths An array of relative paths to source.
|
||||
* @param {boolean} all Whether all found files should be sourced.
|
||||
*/
|
||||
sourceFromRuntimePath: function (paths, all)
|
||||
{
|
||||
let dirs = getPathsFromPathList(options["runtimepath"]);
|
||||
@@ -741,8 +858,12 @@ lookup:
|
||||
return found;
|
||||
},
|
||||
|
||||
// files which end in .js are sourced as pure JavaScript files,
|
||||
// no need (actually forbidden) to add: js <<EOF ... EOF around those files
|
||||
/**
|
||||
* Reads Ex commands, JavaScript or CSS from <b>filename</b>.
|
||||
*
|
||||
* @param {string} filename The name of the file to source.
|
||||
* @param {boolean} silent Whether errors should be reported.
|
||||
*/
|
||||
source: function (filename, silent)
|
||||
{
|
||||
let wasSourcing = self.sourcing;
|
||||
@@ -772,7 +893,7 @@ lookup:
|
||||
liberator.echomsg("sourcing " + filename.quote(), 2);
|
||||
|
||||
let str = self.readFile(file);
|
||||
let uri = ioService.newFileURI(file);
|
||||
let uri = services.get("io").newFileURI(file);
|
||||
|
||||
// handle pure JavaScript files specially
|
||||
if (/\.js$/.test(filename))
|
||||
@@ -896,11 +1017,68 @@ lookup:
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is
|
||||
// fixed is fixed, should use that instead of a tmpfile
|
||||
/**
|
||||
* Runs <b>command</b> in a subshell and returns the output in a
|
||||
* string. The shell used is that specified by the 'shell' option.
|
||||
*
|
||||
* @param {string} command The command to run.
|
||||
* @param {string} input Any input to be provided to the command on stdin.
|
||||
* @returns {string}
|
||||
*/
|
||||
system: function (command, input)
|
||||
{
|
||||
liberator.echomsg("Calling shell to execute: " + command, 4);
|
||||
|
||||
function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"';
|
||||
|
||||
return this.withTempFiles(function (stdin, stdout, cmd) {
|
||||
if (input)
|
||||
this.writeFile(stdin, input);
|
||||
|
||||
// TODO: implement 'shellredir'
|
||||
if (WINDOWS)
|
||||
{
|
||||
command = "cd /D " + cwd.path + " && " + command + " > " + stdout.path + " 2>&1" + " < " + stdin.path;
|
||||
var res = this.run(options["shell"], options["shellcmdflag"].split(/\s+/).concat(command), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.writeFile(cmd, "cd " + escape(cwd.path) + "\n" +
|
||||
["exec", ">" + escape(stdout.path), "2>&1", "<" + escape(stdin.path),
|
||||
escape(options["shell"]), options["shellcmdflag"], escape(command)].join(" "));
|
||||
res = this.run("/bin/sh", ["-e", cmd.path], true);
|
||||
}
|
||||
|
||||
let output = self.readFile(stdout);
|
||||
if (res > 0)
|
||||
output += "\nshell returned " + res;
|
||||
// if there is only one \n at the end, chop it off
|
||||
else if (output && output.indexOf("\n") == output.length - 1)
|
||||
output = output.substr(0, output.length - 1);
|
||||
|
||||
return output;
|
||||
}) || "";
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a temporary file context for executing external commands.
|
||||
* <b>fn</b> is called with a temp file, created with
|
||||
* {@link #createTempFile}, for each explicit argument. Ensures that
|
||||
* all files are removed when <b>fn</b> returns.
|
||||
*
|
||||
* @param {function} fn The function to execute.
|
||||
* @param {Object} self The 'this' object used when executing fn.
|
||||
* @return {boolean} false if temp files couldn't be created,
|
||||
* otherwise, the return value of <b>fn</b>.
|
||||
*/
|
||||
withTempFiles: function (fn, self)
|
||||
{
|
||||
let args = util.map(util.range(0, fn.length), this.createTempFile);
|
||||
if (!args.every(util.identity))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
return fn.apply(self || this, args);
|
||||
@@ -922,6 +1100,10 @@ IO.PATH_SEP = (function () {
|
||||
return file.path[0];
|
||||
})();
|
||||
|
||||
/**
|
||||
* @property {string} The value of the $VIMPERATOR_RUNTIME environment
|
||||
* variable.
|
||||
*/
|
||||
IO.__defineGetter__("runtimePath", function () {
|
||||
const rtpvar = config.name.toUpperCase() + "_RUNTIME";
|
||||
let rtp = services.get("environment").get(rtpvar);
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -28,7 +28,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
/** @scope modules */
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm", modules);
|
||||
|
||||
const plugins = {};
|
||||
plugins.__proto__ = modules;
|
||||
@@ -153,7 +153,7 @@ const liberator = (function () //{{{
|
||||
group.setter(value);
|
||||
return value;
|
||||
},
|
||||
completer: function (filter)
|
||||
completer: function (context)
|
||||
{
|
||||
let opts = [v.opts for ([k, v] in Iterator(groups))];
|
||||
opts = opts.map(function (opt) [[k, v[0]] for ([k, v] in Iterator(opt))]);
|
||||
@@ -206,6 +206,34 @@ const liberator = (function () //{{{
|
||||
function () { liberator.quit(true); });
|
||||
});
|
||||
|
||||
// TODO: move this
|
||||
function getMenuItems()
|
||||
{
|
||||
function addChildren(node, parent)
|
||||
{
|
||||
for (let [,item] in Iterator(node.childNodes))
|
||||
{
|
||||
if (item.childNodes.length == 0 && item.localName == "menuitem"
|
||||
&& !/rdf:http:/.test(item.label)) // FIXME
|
||||
{
|
||||
item.fullMenuPath = parent + item.label;
|
||||
items.push(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
let path = parent;
|
||||
if (item.localName == "menu")
|
||||
path += item.label + ".";
|
||||
addChildren(item, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let items = [];
|
||||
addChildren(document.getElementById(config.guioptions["m"][1]), "");
|
||||
return items;
|
||||
}
|
||||
|
||||
registerObserver("load_commands", function ()
|
||||
{
|
||||
commands.add(["addo[ns]"],
|
||||
@@ -256,34 +284,6 @@ const liberator = (function () //{{{
|
||||
completer: function (context, args) completion.dialog(context)
|
||||
});
|
||||
|
||||
// TODO: move this
|
||||
function getMenuItems()
|
||||
{
|
||||
function addChildren(node, parent)
|
||||
{
|
||||
for (let [,item] in Iterator(node.childNodes))
|
||||
{
|
||||
if (item.childNodes.length == 0 && item.localName == "menuitem"
|
||||
&& !/rdf:http:/.test(item.label)) // FIXME
|
||||
{
|
||||
item.fullMenuPath = parent + item.label;
|
||||
items.push(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
let path = parent;
|
||||
if (item.localName == "menu")
|
||||
path += item.label + ".";
|
||||
addChildren(item, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let items = [];
|
||||
addChildren(document.getElementById(config.guioptions["m"][1]), "");
|
||||
return items;
|
||||
}
|
||||
|
||||
commands.add(["em[enu]"],
|
||||
"Execute the specified menu item from the command line",
|
||||
function (args)
|
||||
@@ -305,13 +305,7 @@ const liberator = (function () //{{{
|
||||
},
|
||||
{
|
||||
argCount: "1",
|
||||
// TODO: add this as a standard menu completion function
|
||||
completer: function (context)
|
||||
{
|
||||
context.title = ["Menu Path", "Label"];
|
||||
context.keys = { text: "fullMenuPath", description: "label" };
|
||||
context.completions = getMenuItems();
|
||||
},
|
||||
completer: function (context) completion.menuItem(context),
|
||||
literal: 0
|
||||
});
|
||||
|
||||
@@ -597,6 +591,8 @@ const liberator = (function () //{{{
|
||||
get mode() modes.main,
|
||||
set mode(value) modes.main = value,
|
||||
|
||||
get menuItems() getMenuItems(),
|
||||
|
||||
// Global constants
|
||||
CURRENT_TAB: 1,
|
||||
NEW_TAB: 2,
|
||||
@@ -652,8 +648,9 @@ const liberator = (function () //{{{
|
||||
|
||||
triggerObserver: function (type)
|
||||
{
|
||||
let args = Array.slice(arguments, 1);
|
||||
for (let [,fn] in Iterator(observers[type] || []))
|
||||
fn.apply(null, Array.slice(arguments, 1));
|
||||
fn.apply(null, args);
|
||||
},
|
||||
|
||||
beep: function ()
|
||||
|
||||
@@ -13,7 +13,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -113,8 +113,7 @@ const modes = (function () //{{{
|
||||
if (newMode == modes.NORMAL)
|
||||
{
|
||||
// disable caret mode when we want to switch to normal mode
|
||||
let value = options.getPref("accessibility.browsewithcaret", false);
|
||||
if (value)
|
||||
if (options.getPref("accessibility.browsewithcaret"))
|
||||
options.setPref("accessibility.browsewithcaret", false);
|
||||
|
||||
statusline.updateUrl();
|
||||
@@ -171,7 +170,7 @@ const modes = (function () //{{{
|
||||
|
||||
// helper function to set both modes in one go
|
||||
// if silent == true, you also need to take care of the mode handling changes yourself
|
||||
set: function (mainMode, extendedMode, silent)
|
||||
set: function (mainMode, extendedMode, silent, stack)
|
||||
{
|
||||
silent = (silent || main == mainMode && extended == extendedMode);
|
||||
// if a main mode is set, the extended is always cleared
|
||||
@@ -187,6 +186,7 @@ const modes = (function () //{{{
|
||||
if (main != oldMain)
|
||||
handleModeChange(oldMain, mainMode, oldExtended);
|
||||
}
|
||||
liberator.triggerObserver("modeChange", [oldMain, oldExtended], [main, extended], stack);
|
||||
|
||||
if (!silent)
|
||||
this.show();
|
||||
@@ -195,18 +195,19 @@ const modes = (function () //{{{
|
||||
push: function (mainMode, extendedMode, silent)
|
||||
{
|
||||
modeStack.push([main, extended]);
|
||||
this.set(mainMode, extendedMode, silent);
|
||||
this.set(mainMode, extendedMode, silent, { push: modeStack[modeStack.length - 1] });
|
||||
},
|
||||
|
||||
pop: function (silent)
|
||||
{
|
||||
let a = modeStack.pop();
|
||||
if (a)
|
||||
this.set(a[0], a[1], silent);
|
||||
this.set(a[0], a[1], silent, { pop: a });
|
||||
else
|
||||
this.reset(silent);
|
||||
},
|
||||
|
||||
// TODO: Deprecate this in favor of addMode? --Kris
|
||||
setCustomMode: function (modestr, oneventfunc, stopfunc)
|
||||
{
|
||||
// TODO this.plugin[id]... ('id' maybe submode or what..)
|
||||
@@ -247,18 +248,10 @@ const modes = (function () //{{{
|
||||
set isReplaying(value) { isReplaying = value; this.show(); },
|
||||
|
||||
get main() main,
|
||||
set main(value) {
|
||||
if (value != main)
|
||||
handleModeChange(main, value);
|
||||
|
||||
main = value;
|
||||
// setting the main mode always resets any extended mode
|
||||
extended = modes.NONE;
|
||||
this.show();
|
||||
},
|
||||
set main(value) { this.set(value); },
|
||||
|
||||
get extended() extended,
|
||||
set extended(value) { extended = value; this.show(); }
|
||||
set extended(value) { this.set(null, value) }
|
||||
|
||||
};
|
||||
|
||||
@@ -285,7 +278,6 @@ const modes = (function () //{{{
|
||||
self.addMode("SEARCH_BACKWARD", true);
|
||||
self.addMode("MENU", true); // a popupmenu is active
|
||||
self.addMode("LINE", true); // linewise visual mode
|
||||
self.addMode("RECORDING", true);
|
||||
self.addMode("PROMPT", true);
|
||||
|
||||
return self;
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -1015,17 +1015,38 @@ function Options() //{{{
|
||||
liberator.echoerr("E488: Trailing characters: " + name + "!");
|
||||
},
|
||||
|
||||
/**
|
||||
* Pushes a new preference context onto the context stack.
|
||||
*
|
||||
* @see #withContext
|
||||
*/
|
||||
pushContext: function ()
|
||||
{
|
||||
prefContexts.push({});
|
||||
},
|
||||
|
||||
/**
|
||||
* Pops the top preference context from the stack.
|
||||
*
|
||||
* @see #withContext
|
||||
*/
|
||||
popContext: function ()
|
||||
{
|
||||
for (let [k, v] in Iterator(prefContexts.pop()))
|
||||
storePreference(k, v);
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes <b>fn</b> with a new preference context. When <b>fn</b>
|
||||
* returns, the context is popped and any preferences set via
|
||||
* {@link #setPref} or {@link #invertPref} are restored to their
|
||||
* previous values.
|
||||
*
|
||||
* @param {function} fn The function to call.
|
||||
* @param {object} fn The 'this' object with which to call <b>fn</b>
|
||||
* @see #pushContext
|
||||
* @see #popContext
|
||||
*/
|
||||
withContext: function (fn, self)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||
©2008 Kris Maglione <maglione.k at Gmail>
|
||||
Copyright © 2008-2009 by Kris Maglione <maglione.k at Gmail>
|
||||
Distributable under the terms of the MIT license, which allows
|
||||
for sublicensing under any compatible license, including the MPL,
|
||||
GPL, and MPL. Anyone who changes this file is welcome to relicense
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||
©2008 Kris Maglione <maglione.k at Gmail>
|
||||
Copyright © 2008-2009 by Kris Maglione <maglione.k at Gmail>
|
||||
Distributable under the terms of the MIT license, which allows
|
||||
for sublicensing under any compatible license, including the MPL,
|
||||
GPL, and MPL. Anyone who changes this file is welcome to relicense
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -140,14 +140,11 @@ function Tabs() //{{{
|
||||
|
||||
return value;
|
||||
},
|
||||
completer: function (filter)
|
||||
{
|
||||
return [
|
||||
completer: function (context) [
|
||||
["0", "Never show tab bar"],
|
||||
["1", "Show tab bar only if more than one tab is open"],
|
||||
["2", "Always show tab bar"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -157,15 +154,12 @@ function Tabs() //{{{
|
||||
"Define when tabs are automatically activated",
|
||||
"stringlist", "homepage,quickmark,tabopen,paste",
|
||||
{
|
||||
completer: function (filter)
|
||||
{
|
||||
return [
|
||||
completer: function (context) [
|
||||
["homepage", "gH mapping"],
|
||||
["quickmark", "go and gn mappings"],
|
||||
["tabopen", ":tabopen[!] command"],
|
||||
["paste", "P and gP mappings"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -173,17 +167,14 @@ function Tabs() //{{{
|
||||
"Define which commands should output in a new tab by default",
|
||||
"stringlist", "",
|
||||
{
|
||||
completer: function (filter)
|
||||
{
|
||||
return [
|
||||
completer: function (context) [
|
||||
["all", "All commands"],
|
||||
["addons", ":addo[ns] command"],
|
||||
["downloads", ":downl[oads] command"],
|
||||
["help", ":h[elp] command"],
|
||||
["javascript", ":javascript! or :js! command"],
|
||||
["prefs", ":pref[erences]! or :prefs! command"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -204,16 +195,13 @@ function Tabs() //{{{
|
||||
|
||||
return value;
|
||||
},
|
||||
completer: function (filter)
|
||||
{
|
||||
return [
|
||||
completer: function (context) [
|
||||
["0", "Force to open in the current tab"],
|
||||
["1", "Always open in a new tab"],
|
||||
["2", "Open in a new window if it has a specific requested size (default in Firefox)"],
|
||||
["3", "Always open in a new window"],
|
||||
["4", "Open in the same tab unless it has a specific requested size"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
let fragment = liberator.has("MacUnix") ? "tab-mac" : "tab";
|
||||
@@ -629,6 +617,7 @@ function Tabs() //{{{
|
||||
argCount: "?",
|
||||
completer: function (context)
|
||||
{
|
||||
context.anchored = false;
|
||||
context.keys = { text: function (item) item.state.entries[0].url, description: "title" };
|
||||
context.completions = tabs.closedTabs;
|
||||
},
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
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.
|
||||
}}} ***** END LICENSE BLOCK *****/
|
||||
|
||||
/** @scope modules */
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -29,10 +29,10 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
/** @scope modules */
|
||||
|
||||
/**
|
||||
* This class is used for prompting of user input and echoing of messages
|
||||
* This class is used for prompting of user input and echoing of messages.
|
||||
*
|
||||
* it consists of a prompt and command field
|
||||
* be sure to only create objects of this class when the chrome is ready
|
||||
* It consists of a prompt and command field be sure to only create objects of
|
||||
* this class when the chrome is ready.
|
||||
*/
|
||||
function CommandLine() //{{{
|
||||
{
|
||||
@@ -43,7 +43,7 @@ function CommandLine() //{{{
|
||||
storage.newArray("history-search", true);
|
||||
storage.newArray("history-command", true);
|
||||
|
||||
var messageHistory = {
|
||||
var messageHistory = { // {{{
|
||||
_messages: [],
|
||||
get messages()
|
||||
{
|
||||
@@ -68,7 +68,7 @@ function CommandLine() //{{{
|
||||
|
||||
this._messages.push(message);
|
||||
}
|
||||
};
|
||||
}; // }}}
|
||||
var lastMowOutput = null;
|
||||
|
||||
var silent = false;
|
||||
@@ -76,12 +76,12 @@ function CommandLine() //{{{
|
||||
var lastEcho = null;
|
||||
|
||||
/**
|
||||
* A class for managing the history of an inputField
|
||||
* A class for managing the history of an inputField.
|
||||
*
|
||||
* @param {Object} inputField
|
||||
* @param {string} mode
|
||||
* @param {HTMLInputElement} inputField
|
||||
* @param {string} mode The mode for which we need history.
|
||||
*/
|
||||
function History(inputField, mode)
|
||||
function History(inputField, mode) // {{{
|
||||
{
|
||||
if (!(this instanceof arguments.callee))
|
||||
return new arguments.callee(inputField, mode);
|
||||
@@ -92,14 +92,15 @@ function CommandLine() //{{{
|
||||
}
|
||||
History.prototype = {
|
||||
/**
|
||||
* Empties the history.
|
||||
* Reset the history index to the first entry.
|
||||
*/
|
||||
reset: function ()
|
||||
{
|
||||
this.index = null;
|
||||
},
|
||||
/**
|
||||
* Permanently save the history
|
||||
* Save the last entry to the permanent store. All duplicate entries
|
||||
* are removed and the list is truncated, if necessary.
|
||||
*/
|
||||
save: function ()
|
||||
{
|
||||
@@ -111,9 +112,9 @@ function CommandLine() //{{{
|
||||
this.store.truncate(options["history"], true);
|
||||
},
|
||||
/**
|
||||
* Set the current match to val
|
||||
* Replace the current input field value.
|
||||
*
|
||||
* @param {string} val
|
||||
* @param {string} val The new value.
|
||||
*/
|
||||
replace: function (val)
|
||||
{
|
||||
@@ -122,10 +123,11 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* move up or (if backward) down in the history
|
||||
* Move forward or backward in history.
|
||||
*
|
||||
* @param {boolean} backward
|
||||
* @param {boolean} matchCurrent XXX: what?
|
||||
* @param {boolean} backward Direction to move.
|
||||
* @param {boolean} matchCurrent Search for matches starting
|
||||
* with the current input value.
|
||||
*/
|
||||
select: function (backward, matchCurrent)
|
||||
{
|
||||
@@ -173,14 +175,14 @@ function CommandLine() //{{{
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}; // }}}
|
||||
|
||||
/**
|
||||
* A class for tab completions on an input field
|
||||
* A class for tab completions on an input field.
|
||||
*
|
||||
* @param {Object} input
|
||||
*/
|
||||
function Completions(input)
|
||||
function Completions(input) // {{{
|
||||
{
|
||||
if (!(this instanceof arguments.callee))
|
||||
return new arguments.callee(input);
|
||||
@@ -380,24 +382,53 @@ function CommandLine() //{{{
|
||||
{
|
||||
// Wait for contexts to complete if necessary.
|
||||
// FIXME: Need to make idx relative to individual contexts.
|
||||
let list = this.context.contextList.reverse();
|
||||
let list = this.context.contextList;
|
||||
if (idx == -2)
|
||||
list = list.slice().reverse();
|
||||
let n = 0;
|
||||
try
|
||||
{
|
||||
this.waiting = true;
|
||||
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);
|
||||
// threadYield(true, true) would be better, but it does not return on my
|
||||
// machine until all awesomebar completions were reported, making
|
||||
// :open foo<tab> nearly unusable, if the first 2 foo-completions would
|
||||
// be there fast, but it takes up to 20 sec to find more foo-completions
|
||||
//
|
||||
// The strange thing is, I tested the 2009-01-07 nightly at work in Windows
|
||||
// and it seemed to work perfectly there. Will have to see if it's a
|
||||
// hardware (dual core there, vs. P4 at home) issue or an OS issue.
|
||||
//
|
||||
// While I *really* prefer this solution over my hack
|
||||
// when it works, we can't have a nearly-defect :open
|
||||
// prompt when releasing vimp 2.0, even not just on certain
|
||||
// computers, as :open is probably the most often used ex-command
|
||||
// in vimperator
|
||||
//
|
||||
// liberator.threadYield(false, true); is just a temporary measure as
|
||||
// it has other problems (hitting tab often in a row), until we find the
|
||||
// source of the problem (which we hopefully do, as I really don't want to
|
||||
// have to revert to my hack when better solutions exist)
|
||||
liberator.threadYield(false, true);
|
||||
if (done())
|
||||
break;
|
||||
n += context.items.length;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.waiting = false;
|
||||
}
|
||||
|
||||
// See previous FIXME. This will break if new items in
|
||||
// a previous context come in.
|
||||
if (idx < 0)
|
||||
idx = this.items.length - 1;
|
||||
if (this.items.length == 0)
|
||||
return;
|
||||
|
||||
this.selected = idx;
|
||||
this.completion = this.items[idx].text;
|
||||
@@ -406,6 +437,8 @@ function CommandLine() //{{{
|
||||
this.itemList.selectItem(idx);
|
||||
},
|
||||
|
||||
tabs: [],
|
||||
|
||||
tab: function tab(reverse)
|
||||
{
|
||||
autocompleteTimer.flush();
|
||||
@@ -413,6 +446,13 @@ function CommandLine() //{{{
|
||||
if (this.context.waitingForTab || this.wildIndex == -1)
|
||||
this.complete(true, true);
|
||||
|
||||
this.tabs.push(reverse);
|
||||
if (this.waiting)
|
||||
return;
|
||||
|
||||
while (this.tabs.length)
|
||||
{
|
||||
reverse = this.tabs.shift();
|
||||
switch (this.wildtype.replace(/.*:/, ""))
|
||||
{
|
||||
case "":
|
||||
@@ -431,9 +471,6 @@ function CommandLine() //{{{
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.items.length == 0)
|
||||
return void liberator.beep();
|
||||
|
||||
if (this.type.list)
|
||||
completionList.show();
|
||||
|
||||
@@ -442,7 +479,11 @@ function CommandLine() //{{{
|
||||
|
||||
statusTimer.tell();
|
||||
}
|
||||
|
||||
if (this.items.length == 0)
|
||||
liberator.beep();
|
||||
}
|
||||
}; // }}}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
////////////////////// TIMERS //////////////////////////////////////////////////
|
||||
@@ -455,13 +496,18 @@ function CommandLine() //{{{
|
||||
statusline.updateProgress("match " + (completions.selected + 1) + " of " + completions.items.length);
|
||||
});
|
||||
|
||||
var autocompleteTimer = new Timer(201, 500, function autocompleteTell(tabPressed) {
|
||||
if (events.feedingKeys || !completions)
|
||||
return;
|
||||
var autocompleteTimer = new Timer(200, 500, function autocompleteTell(tabPressed) {
|
||||
if (!events.feedingKeys && completions && options.get("wildoptions").has("auto"))
|
||||
{
|
||||
completions.complete(true, false);
|
||||
completions.itemList.show();
|
||||
}
|
||||
});
|
||||
|
||||
// This timer just prevents <Tab>s from queueing up when the
|
||||
// system is under load (and, thus, giving us several minutes of
|
||||
// the completion list scrolling). Multiple <Tab> presses are
|
||||
// still processed normally, as the time is flushed on "keyup".
|
||||
var tabTimer = new Timer(0, 0, function tabTell(event) {
|
||||
if (completions)
|
||||
completions.tab(event.shiftKey);
|
||||
@@ -471,10 +517,7 @@ function CommandLine() //{{{
|
||||
////////////////////// CALLBACKS ///////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
// callback for prompt mode
|
||||
var promptSubmitCallback = null;
|
||||
var promptChangeCallback = null;
|
||||
var promptCompleter = null;
|
||||
var input = {};
|
||||
|
||||
liberator.registerCallback("submit", modes.EX, function (command) {
|
||||
liberator.execute(command);
|
||||
@@ -483,28 +526,28 @@ function CommandLine() //{{{
|
||||
context.fork("ex", 0, completion, "ex");
|
||||
});
|
||||
liberator.registerCallback("change", modes.EX, function (command) {
|
||||
if (options.get("wildoptions").has("auto"))
|
||||
autocompleteTimer.tell(false);
|
||||
});
|
||||
|
||||
liberator.registerCallback("cancel", modes.PROMPT, closePrompt);
|
||||
liberator.registerCallback("submit", modes.PROMPT, closePrompt);
|
||||
liberator.registerCallback("change", modes.PROMPT, function (str) {
|
||||
liberator.triggerCallback("change", modes.EX, str);
|
||||
if (promptChangeCallback)
|
||||
return promptChangeCallback.call(commandline, str);
|
||||
if (input.complete)
|
||||
autocompleteTimer.tell(false);
|
||||
if (input.change)
|
||||
return input.change.call(commandline, str);
|
||||
});
|
||||
liberator.registerCallback("complete", modes.PROMPT, function (context) {
|
||||
if (promptCompleter)
|
||||
context.fork("input", 0, commandline, promptCompleter);
|
||||
if (input.complete)
|
||||
context.fork("input", 0, commandline, input.complete);
|
||||
});
|
||||
|
||||
function closePrompt(value)
|
||||
{
|
||||
let callback = promptSubmitCallback;
|
||||
promptSubmitCallback = null;
|
||||
let callback = input.submit;
|
||||
input = {};
|
||||
if (callback)
|
||||
callback.call(commandline, value == null ? commandline.command : value);
|
||||
callback.call(commandline, value != null ? value : commandline.command);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
@@ -554,7 +597,7 @@ function CommandLine() //{{{
|
||||
var multilineCallback = null;
|
||||
|
||||
/**
|
||||
* @private - highlight the messageBox according to group
|
||||
* Highlight the messageBox according to <b>group</b>.
|
||||
*/
|
||||
function setHighlightGroup(group)
|
||||
{
|
||||
@@ -562,7 +605,7 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - Determines whether the command line should be visible.
|
||||
* Determines whether the command-line should be visible.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
@@ -570,7 +613,7 @@ function CommandLine() //{{{
|
||||
!(modes.extended & (modes.INPUT_MULTILINE | modes.OUTPUT_MULTILINE));
|
||||
|
||||
/**
|
||||
* @private - set the prompt to val styled with highlightGroup
|
||||
* Set the command-line prompt.
|
||||
*
|
||||
* @param {string} val
|
||||
* @param {string} highlightGroup
|
||||
@@ -584,7 +627,8 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - set the command to cmd and move the user's cursor to the end.
|
||||
* Set the command-line input value. The caret is reset to the
|
||||
* end of the line.
|
||||
*
|
||||
* @param {string} cmd
|
||||
*/
|
||||
@@ -596,12 +640,12 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - display a message styled with highlightGroup
|
||||
* and, if forceSingle is true, ensure it takes only one line.
|
||||
* Display a message in the command-line area.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
* @param {boolean} forceSingle
|
||||
* @param {boolean} forceSingle If provided, don't let over-long
|
||||
* messages move to the MOW.
|
||||
*/
|
||||
function echoLine(str, highlightGroup, forceSingle)
|
||||
{
|
||||
@@ -619,13 +663,12 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a multiline message, possible through a "more" like interface
|
||||
*
|
||||
* TODO: resize upon a window resize
|
||||
* Display a multiline message.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
*/
|
||||
// TODO: resize upon a window resize
|
||||
function echoMultiline(str, highlightGroup)
|
||||
{
|
||||
let doc = multilineOutputWidget.contentDocument;
|
||||
@@ -642,7 +685,6 @@ function CommandLine() //{{{
|
||||
let output = util.xmlToDom(lastMowOutput, doc);
|
||||
XML.ignoreWhitespace = true;
|
||||
|
||||
|
||||
// FIXME: need to make sure an open MOW is closed when commands
|
||||
// that don't generate output are executed
|
||||
if (outputContainer.collapsed)
|
||||
@@ -671,8 +713,7 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - ensure that the Multiline input widget is the
|
||||
* correct size.
|
||||
* Ensure that the multiline input widget is the correct size.
|
||||
*/
|
||||
function autosizeMultilineInputWidget()
|
||||
{
|
||||
@@ -682,14 +723,12 @@ function CommandLine() //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - eval()s a javascript expression
|
||||
* and returns a string suitable to be echo'd.
|
||||
*
|
||||
* If useColor is true, util.objectToString will
|
||||
* colorize object output.
|
||||
* eval() a JavaScript expression and return a string suitable
|
||||
* to be echoed.
|
||||
*
|
||||
* @param {string} arg
|
||||
* @param {boolean} useColor
|
||||
* @param {boolean} useColor When true, the result is a
|
||||
* highlighted XML object.
|
||||
*/
|
||||
function echoArgumentToString(arg, useColor)
|
||||
{
|
||||
@@ -757,7 +796,7 @@ function CommandLine() //{{{
|
||||
"Items which are completed at the :[tab]open prompt",
|
||||
"charlist", "sfl",
|
||||
{
|
||||
completer: function completer(filter) [k for each (k in completion.urlCompleters)],
|
||||
completer: function (context) [k for each (k in completion.urlCompleters)],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -796,9 +835,7 @@ function CommandLine() //{{{
|
||||
"Define how command line completion works",
|
||||
"stringlist", "list:full",
|
||||
{
|
||||
completer: function completer(filter)
|
||||
{
|
||||
return [
|
||||
completer: function (context) [
|
||||
// Why do we need ""?
|
||||
["", "Complete only the first match"],
|
||||
["full", "Complete the next full match"],
|
||||
@@ -806,8 +843,7 @@ function CommandLine() //{{{
|
||||
["list", "If more than one match, list all matches"],
|
||||
["list:full", "List all and complete first match"],
|
||||
["list:longest", "List all and complete common string"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter,
|
||||
checkHas: function (value, val)
|
||||
{
|
||||
@@ -837,7 +873,7 @@ function CommandLine() //{{{
|
||||
|
||||
var myModes = [modes.COMMAND_LINE];
|
||||
|
||||
// TODO: move "<Esc>", "<C-[" here from mappings
|
||||
// TODO: move "<Esc>", "<C-[>" here from mappings
|
||||
mappings.add(myModes,
|
||||
["<C-c>"], "Focus content",
|
||||
function () { events.onEscape(); });
|
||||
@@ -941,14 +977,14 @@ function CommandLine() //{{{
|
||||
|
||||
return {
|
||||
|
||||
HL_NORMAL : "Normal",
|
||||
HL_ERRORMSG : "ErrorMsg",
|
||||
HL_MODEMSG : "ModeMsg",
|
||||
HL_MOREMSG : "MoreMsg",
|
||||
HL_QUESTION : "Question",
|
||||
HL_INFOMSG : "InfoMsg",
|
||||
HL_WARNINGMSG : "WarningMsg",
|
||||
HL_LINENR : "LineNr",
|
||||
HL_NORMAL: "Normal",
|
||||
HL_ERRORMSG: "ErrorMsg",
|
||||
HL_MODEMSG: "ModeMsg",
|
||||
HL_MOREMSG: "MoreMsg",
|
||||
HL_QUESTION: "Question",
|
||||
HL_INFOMSG: "InfoMsg",
|
||||
HL_WARNINGMSG: "WarningMsg",
|
||||
HL_LINENR: "LineNr",
|
||||
|
||||
FORCE_MULTILINE : 1 << 0,
|
||||
FORCE_SINGLELINE : 1 << 1,
|
||||
@@ -962,7 +998,8 @@ function CommandLine() //{{{
|
||||
get mode() (modes.extended == modes.EX) ? "cmd" : "search",
|
||||
|
||||
get silent() silent,
|
||||
set silent(val) {
|
||||
set silent(val)
|
||||
{
|
||||
silent = val;
|
||||
if (silent)
|
||||
storage.styles.addSheet(true, "silent-mode", "chrome://*", "#liberator-commandline > * { opacity: 0 }");
|
||||
@@ -970,9 +1007,6 @@ function CommandLine() //{{{
|
||||
storage.styles.removeSheet(true, "silent-mode");
|
||||
},
|
||||
|
||||
/**
|
||||
* XXX: This function is not used!
|
||||
*/
|
||||
runSilently: function (fn, self)
|
||||
{
|
||||
let wasSilent = this.silent;
|
||||
@@ -991,6 +1025,8 @@ function CommandLine() //{{{
|
||||
{
|
||||
try
|
||||
{
|
||||
// The long path is because of complications with the
|
||||
// completion preview.
|
||||
return commandWidget.inputField.editor.rootElement.firstChild.textContent;
|
||||
}
|
||||
catch (e) {}
|
||||
@@ -1001,14 +1037,14 @@ function CommandLine() //{{{
|
||||
get message() messageBox.value,
|
||||
|
||||
/**
|
||||
* Changes the command line to display the following prompt (usually ":")
|
||||
* followed by the command, in the given mode. Valid modes are
|
||||
* attributes of the "modes" variable, and modes.EX is probably
|
||||
* a good choice.
|
||||
* Open the command-line. The main mode is set to
|
||||
* COMMAND_LINE, the extended mode to <b>extendedMode</b>.
|
||||
* Further, callbacks defined for <b>extendedMode</b> are
|
||||
* triggered as appropriate (see {@link Liberator#registerCallback}).
|
||||
*
|
||||
* @param {string} prompt
|
||||
* @param {string} cmd
|
||||
* @param {number} mode
|
||||
* @param {number} extendedMode
|
||||
*/
|
||||
open: function open(prompt, cmd, extendedMode)
|
||||
{
|
||||
@@ -1031,13 +1067,14 @@ function CommandLine() //{{{
|
||||
completions = Completions(commandWidget.inputField);
|
||||
|
||||
// open the completion list automatically if wanted
|
||||
if (cmd.length)
|
||||
liberator.triggerCallback("change", currentExtendedMode, cmd);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes any input from the command line, without executing its
|
||||
* contents. Removes any "More" windows or other such output.
|
||||
* Pressing <ESC> in EX mode normally has this effect.
|
||||
* Closes the command-line. This is ordinarily triggered automatically
|
||||
* by a mode change. Will not hide the command-line immediately if
|
||||
* called directly after a successful command, otherwise it will.
|
||||
*/
|
||||
close: function close()
|
||||
{
|
||||
@@ -1048,7 +1085,7 @@ function CommandLine() //{{{
|
||||
if (history)
|
||||
history.save();
|
||||
|
||||
this.resetCompletions(); // cancels any asynchronous completion still going on, must be before completions = null
|
||||
this.resetCompletions(); // cancels any asynchronous completion still going on, must be before we set completions = null
|
||||
completions = null;
|
||||
history = null;
|
||||
|
||||
@@ -1072,9 +1109,9 @@ function CommandLine() //{{{
|
||||
keepCommand = false;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Hide any auto-completion/More-ing that is happening.
|
||||
* Hides the command-line, and shows any status messages that
|
||||
* are under it.
|
||||
*/
|
||||
hide: function hide()
|
||||
{
|
||||
@@ -1082,23 +1119,28 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Output the given string onto the command line coloured
|
||||
* using the rules according to highlightGroup. If not
|
||||
* given higlightGroup defaults to commandline.HL_NORMAL
|
||||
* and other possibe values are at commandline.HL_[A-Z]*.
|
||||
*
|
||||
* Flags can be any of:
|
||||
* commandline.APPEND_TO_MESSAGES (causes message to be added to the messagesHistory)
|
||||
* commandline.FORCE_SINGLELINE | commandline.DISALLOW_MULTILINE
|
||||
* commandline.FORCE_MULTILINE
|
||||
* Output the given string onto the command-line. With no flags, the
|
||||
* message will be shown in the status line if it's short enough to
|
||||
* fit, and contains no new lines, and isn't XML. Otherwise, it will be
|
||||
* shown in the MOW.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
* @param {number} flags
|
||||
* @param {string} highlightGroup The Highlight group for the
|
||||
* message. @default "Normal"
|
||||
* @param {number} flags Changes the behavior as follows:
|
||||
* commandline.APPEND_TO_MESSAGES - Causes message to be added to the
|
||||
* messages history, and shown by :messages.
|
||||
* commandline.FORCE_SINGLELINE - Forbids the command from being
|
||||
* pushed to the MOW if it's too long or of there are already
|
||||
* status messages being shown.
|
||||
* commandline.DISALLOW_MULTILINE - Cancels the operation if the MOW
|
||||
* is already visible.
|
||||
* commandline.FORCE_MULTILINE - Forces the message to appear in
|
||||
* the MOW.
|
||||
*/
|
||||
echo: function echo(str, highlightGroup, flags)
|
||||
{
|
||||
// liberator.echo uses different order of flags as it omits the highlight group, change v.commandline.echo argument order? --mst
|
||||
// liberator.echo uses different order of flags as it omits the highlight group, change commandline.echo argument order? --mst
|
||||
if (silent)
|
||||
return false;
|
||||
|
||||
@@ -1144,29 +1186,28 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Prompt the user for a string and execute the given
|
||||
* callback with that as the only argument on <CR>
|
||||
* extra can have any of the following attributes:
|
||||
* Prompt the user. Sets modes.main to COMMAND_LINE, which the user may
|
||||
* pop at any time to close the prompt.
|
||||
*
|
||||
* onChange: A function to be called with the current input every time it changes
|
||||
* completer: A function called with a ?context? when the user tries to tabcomplete
|
||||
* promptHighlight: The HighlightGroup to use (default commandline.HL_QUESTION, others
|
||||
* can be found at commandline.HL_[A-Z]*)
|
||||
*
|
||||
* This function sets the mode to modes.COMMAND_LINE, and thus popping the mode will
|
||||
* stop further input from being waited for (useful for stopping onChange)
|
||||
*
|
||||
* @param {string} prompt
|
||||
* @param {string} prompt The input prompt to use.
|
||||
* @param {function(string)} callback
|
||||
* @param {Object} extra
|
||||
* @param {object} extra
|
||||
* @... {function} onChange - A function to be called with the current
|
||||
* input every time it changes.
|
||||
* @... {function(CompletionContext)} completer - A completion function
|
||||
* for the user's input.
|
||||
* @... {string} promptHighlight - The HighlightGroup used for the
|
||||
* prompt. @default "Question"
|
||||
*/
|
||||
input: function input(prompt, callback, extra)
|
||||
input: function _input(prompt, callback, extra)
|
||||
{
|
||||
extra = extra || {};
|
||||
|
||||
promptSubmitCallback = callback;
|
||||
promptChangeCallback = extra.onChange;
|
||||
promptCompleter = extra.completer;
|
||||
input = {
|
||||
submit: callback,
|
||||
change: extra.onChange,
|
||||
complete: extra.completer,
|
||||
};
|
||||
|
||||
modes.push(modes.COMMAND_LINE, modes.PROMPT);
|
||||
currentExtendedMode = modes.PROMPT;
|
||||
@@ -1180,13 +1221,14 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a multiline input from a user, up to but not including
|
||||
* the line which matches the given regular expression. Then
|
||||
* execute the callback with that string as a parameter.
|
||||
* Get a multiline input from a user, up to but not including the line
|
||||
* which matches the given regular expression. Then execute the
|
||||
* callback with that string as a parameter.
|
||||
*
|
||||
* @param {RegExp} untilRegexp
|
||||
* @param {function(string)} callbackFunc
|
||||
*/
|
||||
// FIXME: Buggy, especially when pasting. Shouldn't use a RegExp.
|
||||
inputMultiline: function inputMultiline(untilRegexp, callbackFunc)
|
||||
{
|
||||
// Kludge.
|
||||
@@ -1207,11 +1249,12 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle events, the come from liberator when liberator.mode = modes.COMMAND_LINE
|
||||
* but also takes blur/focus/input events raw from #liberator-commandline-command
|
||||
* in the XUL
|
||||
* Handles all command-line events. All key events are passed here when
|
||||
* COMMAND_LINE mode is active, as well as all input, keyup, focus, and
|
||||
* blur events sent to the command-line XUL element.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @private
|
||||
*/
|
||||
onEvent: function onEvent(event)
|
||||
{
|
||||
@@ -1347,15 +1390,14 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle events when we are in multiline output mode,
|
||||
* these come from liberator when modes.extended & modes.MULTILINE_OUTPUT
|
||||
* and also from #liberator-multiline-output in the XUL
|
||||
*
|
||||
* FIXME: if 'more' is set and the MOW is not scrollable we should still
|
||||
* allow a down motion after an up rather than closing
|
||||
* Handle events when we are in multiline output mode, these come from
|
||||
* liberator when modes.extended & modes.MULTILINE_OUTPUT and also from
|
||||
* #liberator-multiline-output in the XUL.
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
// FIXME: if 'more' is set and the MOW is not scrollable we should still
|
||||
// allow a down motion after an up rather than closing
|
||||
onMultilineOutputEvent: function onMultilineOutputEvent(event)
|
||||
{
|
||||
let win = multilineOutputWidget.contentWindow;
|
||||
@@ -1374,8 +1416,8 @@ function CommandLine() //{{{
|
||||
{
|
||||
event.preventDefault();
|
||||
let target = event.button == 0 ? liberator.CURRENT_TAB : liberator.NEW_TAB;
|
||||
if (event.target.href == "#")
|
||||
liberator.open(String(event.target), target);
|
||||
if (event.target.getAttribute("href") == "#")
|
||||
liberator.open(event.target.textContent, target);
|
||||
else
|
||||
liberator.open(event.target.href, target);
|
||||
}
|
||||
@@ -1565,14 +1607,20 @@ function CommandLine() //{{{
|
||||
}
|
||||
},
|
||||
|
||||
getSpaceNeeded: function getSpaceNeeded()
|
||||
{
|
||||
let rect = commandlineWidget.getBoundingClientRect();
|
||||
let offset = rect.bottom - window.innerHeight;
|
||||
return Math.max(0, offset);
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh or remove the prompt that displays when in multiline mode.
|
||||
* showHelp will cause the possible key-options to be displayed,
|
||||
* force will cause a display of the default message even if it
|
||||
* could be at the end of the output.
|
||||
* Update or remove the multiline output widget's "MORE" prompt.
|
||||
*
|
||||
* @param {boolean} force
|
||||
* @param {boolean} showHelp
|
||||
* @param {boolean} force If true, "-- More --" is shown even if we're
|
||||
* at the end of the output.
|
||||
* @param {boolean} showHelp When true, show the valid key sequences
|
||||
* and what they do.
|
||||
*/
|
||||
updateMorePrompt: function updateMorePrompt(force, showHelp)
|
||||
{
|
||||
@@ -1592,12 +1640,11 @@ function CommandLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the height of the multilineOutputWidget to fit
|
||||
* its contents, if <b>open</b> is true, it will cause the
|
||||
* widget to uncollapse, if not it will leave the widget
|
||||
* closed.
|
||||
* Changes the height of the multilineOutputWidget to fit in the
|
||||
* available space.
|
||||
*
|
||||
* @param {boolean} open
|
||||
* @param {boolean} open If true, the widget will be opened if it's not
|
||||
* already so.
|
||||
*/
|
||||
updateOutputHeight: function updateOutputHeight(open)
|
||||
{
|
||||
@@ -1606,13 +1653,13 @@ function CommandLine() //{{{
|
||||
|
||||
let doc = multilineOutputWidget.contentDocument;
|
||||
|
||||
// The container needs to be collapsed for this calculation to work.
|
||||
outputContainer.collapsed = true;
|
||||
let availableHeight = 250;
|
||||
try
|
||||
{
|
||||
availableHeight = getBrowser().mPanelContainer ?
|
||||
getBrowser().mPanelContainer.boxObject.height : getBrowser().boxObject.height;
|
||||
if (!outputContainer.collapsed)
|
||||
availableHeight += parseFloat(outputContainer.height);
|
||||
}
|
||||
catch (e) {}
|
||||
doc.body.style.minWidth = commandlineWidget.scrollWidth + "px";
|
||||
@@ -1621,15 +1668,8 @@ function CommandLine() //{{{
|
||||
outputContainer.collapsed = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable any active completion functions by calling their cancelFunc's
|
||||
* Will also remove the completions preview window.
|
||||
*/
|
||||
resetCompletions: function resetCompletions()
|
||||
{
|
||||
autocompleteTimer.reset();
|
||||
|
||||
// liberator.dump("Resetting completions...");
|
||||
if (completions)
|
||||
{
|
||||
completions.context.cancelAll();
|
||||
@@ -1644,11 +1684,12 @@ function CommandLine() //{{{
|
||||
}; //}}}
|
||||
|
||||
/**
|
||||
* The list which is used for the completion box (and QuickFix window in future)
|
||||
* The list which is used for the completion box (and QuickFix window in
|
||||
* future).
|
||||
*
|
||||
* @param {string} id The id of the XUL <iframe> which we want to fill it
|
||||
* MUST be inside a <vbox> (or any other html element, because otherwise
|
||||
* setting the height does not work properly
|
||||
* @param {string} id The id of the <iframe> which will display the list. It
|
||||
* must be in its own container element, whose height it will update as
|
||||
* necessary.
|
||||
*/
|
||||
function ItemList(id) //{{{
|
||||
{
|
||||
@@ -1668,8 +1709,11 @@ function ItemList(id) //{{{
|
||||
}
|
||||
|
||||
function dom(xml, map) util.xmlToDom(xml, doc, map);
|
||||
|
||||
// Unused.
|
||||
function elemToString(elem) elem.nodeType == elem.TEXT_NODE ? elem.data :
|
||||
"<" + [elem.localName].concat([a.name + "=" + a.value.quote() for ([i, a] in Iterator(elem.attributes))]).join(" ") + ">";
|
||||
|
||||
var doc = iframe.contentDocument;
|
||||
var container = iframe.parentNode;
|
||||
|
||||
@@ -1697,6 +1741,7 @@ function ItemList(id) //{{{
|
||||
div.style.minWidth = "";
|
||||
// FIXME: Belongs elsewhere.
|
||||
commandline.updateOutputHeight(false);
|
||||
setTimeout(function () { container.height -= commandline.getSpaceNeeded() }, 0)
|
||||
}
|
||||
|
||||
function getCompletion(index) completionElements.snapshotItem(index - startIndex);
|
||||
@@ -1717,6 +1762,7 @@ function ItemList(id) //{{{
|
||||
</div>
|
||||
</div>, divNodes);
|
||||
doc.body.replaceChild(div, doc.body.firstChild);
|
||||
div.scrollIntoView(true);
|
||||
|
||||
items.contextList.forEach(function init_eachContext(context) {
|
||||
delete context.cache.nodes;
|
||||
@@ -1736,13 +1782,15 @@ function ItemList(id) //{{{
|
||||
</div>, context.cache.nodes);
|
||||
divNodes.completions.appendChild(context.cache.nodes.root);
|
||||
});
|
||||
|
||||
setTimeout(function () { autoSize(); }, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the entries in "items" to fill the listbox and
|
||||
* does incremental filling to speed up things.
|
||||
* Uses the entries in "items" to fill the listbox and does incremental
|
||||
* filling to speed up things.
|
||||
*
|
||||
* @param {number} offset Start at this index and show maxItems
|
||||
* @param {number} offset Start at this index and show maxItems.
|
||||
*/
|
||||
function fill(offset)
|
||||
{
|
||||
@@ -1760,7 +1808,7 @@ function ItemList(id) //{{{
|
||||
function getRows(context)
|
||||
{
|
||||
function fix(n) Math.max(0, Math.min(len, n));
|
||||
end -= context.message + context.incomplete;
|
||||
end -= !!context.message + context.incomplete;
|
||||
let len = context.items.length;
|
||||
let start = off;
|
||||
off += len;
|
||||
@@ -1820,7 +1868,6 @@ function ItemList(id) //{{{
|
||||
|
||||
completionElements = buffer.evaluateXPath("//xhtml:div[@liberator:highlight='CompItem']", doc);
|
||||
|
||||
autoSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1896,7 +1943,10 @@ function ItemList(id) //{{{
|
||||
getCompletion(sel).removeAttribute("selected");
|
||||
fill(newOffset);
|
||||
if (index >= 0)
|
||||
{
|
||||
getCompletion(index).setAttribute("selected", "true");
|
||||
getCompletion(index).scrollIntoView(false);
|
||||
}
|
||||
|
||||
//if (index == 0)
|
||||
// this.start = now;
|
||||
@@ -1945,14 +1995,11 @@ function StatusLine() //{{{
|
||||
|
||||
return value;
|
||||
},
|
||||
completer: function completer(filter)
|
||||
{
|
||||
return [
|
||||
completer: function completer(context) [
|
||||
["0", "Never display status line"],
|
||||
["1", "Display status line only if there are multiple windows"],
|
||||
["2", "Always display status line"]
|
||||
];
|
||||
},
|
||||
],
|
||||
validator: Option.validateCompleter
|
||||
});
|
||||
|
||||
@@ -1963,10 +2010,11 @@ function StatusLine() //{{{
|
||||
return {
|
||||
|
||||
/**
|
||||
* Update the status bar to indicate how secure the website is
|
||||
* secure => https:// with valid certificate
|
||||
* broken => https:// with invalid certificate
|
||||
* insecure => http://
|
||||
* Update the status bar to indicate how secure the website is:
|
||||
* secure - Secure connection with valid certificate.
|
||||
* broken - Secure connection with invalid certificate, or
|
||||
* mixed content.
|
||||
* insecure - Insecure connection.
|
||||
*
|
||||
* @param {'secure'|'broken'|'insecure'} type
|
||||
*/
|
||||
@@ -1992,12 +2040,12 @@ function StatusLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Update which URL is displayed on the status line,
|
||||
* if url is omitted then buffer.URL is used instead and
|
||||
* status icons [+-â¤] are updated to match whether one can
|
||||
* go back/forwards in history/have bookmarked the page.
|
||||
* Update the URL displayed in the status line. Also displays status
|
||||
* icons, [+-♥], when there are next and previous pages in the
|
||||
* current tab's history, and when the current URL is bookmarked,
|
||||
* respectively.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {string} url The URL to display. @default buffer.URL
|
||||
*/
|
||||
updateUrl: function updateUrl(url)
|
||||
{
|
||||
@@ -2042,11 +2090,12 @@ function StatusLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the contents of the status line's input buffer
|
||||
* to the given string.
|
||||
* Set the contents of the status line's input buffer to the given
|
||||
* string. Used primarily when a key press requires further input
|
||||
* before being processed, including mapping counts and arguments,
|
||||
* along with multi-key mappings.
|
||||
*
|
||||
* Used for displaying partial key combinations in
|
||||
* normal mode.
|
||||
* @param {string} buffer
|
||||
*/
|
||||
updateInputBuffer: function updateInputBuffer(buffer)
|
||||
{
|
||||
@@ -2057,15 +2106,13 @@ function StatusLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the display of the progress bar.
|
||||
* If the parameter is a string, it will be
|
||||
* displayed literally. Otherwise it must be a number
|
||||
* less than one.
|
||||
* Negative numbers cause a "Loading..." status,
|
||||
* Positive (< 1) numbers cause an arrow ==> of length
|
||||
* proportional to the arrow.
|
||||
* Update the page load progress bar.
|
||||
*
|
||||
* @param {string|number} progress
|
||||
* @param {string|number} progress The current progress, as follows:
|
||||
* A string - Displayed literally.
|
||||
* A ratio 0 < n < 1 - Displayed as a progress bar.
|
||||
* A number n <= 0 - Displayed as a "Loading" message.
|
||||
* Any other number - The progress is cleared.
|
||||
*/
|
||||
updateProgress: function updateProgress(progress)
|
||||
{
|
||||
@@ -2095,11 +2142,11 @@ function StatusLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the correct tabcount (e.g. [1/5]) on the status bar.
|
||||
* If either parameter is omitted, they will be calculated.
|
||||
* Display the correct tabcount (e.g., [1/5]) on the status bar.
|
||||
*
|
||||
* @param {number} currentIndex
|
||||
* @param {number} totalTabs
|
||||
* @param {number} currentIndex The 1-based index of the
|
||||
* currently selected tab. @optional
|
||||
* @param {number} totalTabs The total number of tabs. @optional
|
||||
*/
|
||||
updateTabCount: function updateTabCount(currentIndex, totalTabs)
|
||||
{
|
||||
@@ -2126,14 +2173,10 @@ function StatusLine() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Display the correct position on the status bar, if the
|
||||
* percent parameter is omitted it will be calculated.
|
||||
* Display the main content's vertical scroll position in the status
|
||||
* bar.
|
||||
*
|
||||
* Negative numbers are set to "All", Zero implies "Top"
|
||||
* One or above is "Bot", and anything else is multiplied by
|
||||
* a hundred and displayed as a percentage.
|
||||
*
|
||||
* @param {number} percent
|
||||
* @param {number} percent The position, as a percentage. @optional
|
||||
*/
|
||||
updateBufferPosition: function updateBufferPosition(percent)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -296,8 +296,8 @@ const util = { //{{{
|
||||
/**
|
||||
* Generates an Asciidoc help entry.
|
||||
*
|
||||
* @param {Object} obj A liberator <b>Command</b>, <b>Mapping</b> or
|
||||
* <b>Option</b> object
|
||||
* @param {Command|Mapping|Option} obj A liberator <b>Command</b>,
|
||||
* <b>Mapping</b> or <b>Option</b> object
|
||||
* @param {string} extraHelp Extra help text beyond the description.
|
||||
* @returns {string}
|
||||
*/
|
||||
@@ -359,8 +359,8 @@ const util = { //{{{
|
||||
* argument.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {function} callback
|
||||
* @returns {Object}
|
||||
* @param {function(XMLHttpRequest)} callback
|
||||
* @returns {XMLHttpRequest}
|
||||
*/
|
||||
httpGet: function httpGet(url, callback)
|
||||
{
|
||||
@@ -426,10 +426,10 @@ const util = { //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts a URI string into an URI object.
|
||||
* Converts a URI string into a URI object.
|
||||
*
|
||||
* @param {string} uri
|
||||
* @returns {Object}
|
||||
* @returns {nsIURI}
|
||||
*/
|
||||
// FIXME: createURI needed too?
|
||||
newURI: function (uri)
|
||||
@@ -611,7 +611,7 @@ const util = { //{{{
|
||||
* ['www.google.com/search?q=bla', 'www.osnews.com']
|
||||
*
|
||||
* @param {string} str
|
||||
* @returns {Array}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
stringToURLArray: function stringToURLArray(str)
|
||||
{
|
||||
@@ -623,7 +623,7 @@ const util = { //{{{
|
||||
// Try to find a matching file.
|
||||
let file = io.getFile(url);
|
||||
if (file.exists() && file.isReadable())
|
||||
return file.path;
|
||||
return services.get("io").newFileURI(file).spec;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
@@ -638,14 +638,13 @@ const util = { //{{{
|
||||
|
||||
// Ok, not a valid proto. If it looks like URL-ish (foo.com/bar),
|
||||
// let Gecko figure it out.
|
||||
if (/[.]/.test(url) && !/\s/.test(url) || /^[\w.]+:\d+(?:\/|$)/.test(url))
|
||||
if (/[.]/.test(url) && !/\s/.test(url) || /^[\w-.]+:\d+(?:\/|$)/.test(url))
|
||||
return url;
|
||||
|
||||
// TODO: it would be clearer if the appropriate call to
|
||||
// getSearchURL was made based on whether or not the first word was
|
||||
// indeed an SE alias rather than seeing if getSearchURL can
|
||||
// process the call usefully and trying again if it fails - much
|
||||
// like the comments below ;-)
|
||||
// process the call usefully and trying again if it fails
|
||||
|
||||
// check for a search engine match in the string, then try to
|
||||
// search for the whole string in the default engine
|
||||
@@ -663,7 +662,8 @@ const util = { //{{{
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {Document} doc
|
||||
* @param {Object} nodes
|
||||
* @param {Object} nodes If present, nodes with the "key" attribute are
|
||||
* stored here, keyed to the value thereof.
|
||||
* @returns {Node}
|
||||
*/
|
||||
xmlToDom: function xmlToDom(node, doc, nodes)
|
||||
@@ -686,9 +686,6 @@ const util = { //{{{
|
||||
}
|
||||
}; //}}}
|
||||
|
||||
// Struct is really slow, AT LEAST 5 times slower than using structs or simple Objects
|
||||
// main reason is the function ConStructor(), which i couldn't get faster.
|
||||
// Maybe it's a TraceMonkey problem, for now don't use it for anything which must be fast (like bookmarks or history)
|
||||
function Struct()
|
||||
{
|
||||
let self = this instanceof Struct ? this : new Struct();
|
||||
|
||||
@@ -51,6 +51,6 @@ do
|
||||
)
|
||||
done
|
||||
|
||||
cd $stage; zip -r "$top/$jar" *
|
||||
(cd $stage; zip -r "$top/$jar" *)
|
||||
rm -rf "$stage"
|
||||
|
||||
|
||||
@@ -1,30 +1,9 @@
|
||||
/***** BEGIN LICENSE BLOCK ***** {{{
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
© 2008: Kris Maglione <maglione.k at Gmail>
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
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.
|
||||
Copyright © 2008-2009 by Kris Maglione <maglione.k at Gmail>
|
||||
Distributable under the terms of the MIT license, which allows
|
||||
for sublicensing under any compatible license, including the MPL,
|
||||
GPL, and MPL. Anyone who changes this file is welcome to relicense
|
||||
it under any or all of those licenseses.
|
||||
}}} ***** END LICENSE BLOCK *****/
|
||||
|
||||
var EXPORTED_SYMBOLS = ["storage", "Timer"];
|
||||
@@ -80,10 +59,10 @@ function Timer(minInterval, maxInterval, callback)
|
||||
{
|
||||
timer.cancel();
|
||||
this.doneAt = 0;
|
||||
}
|
||||
};
|
||||
this.flush = function ()
|
||||
{
|
||||
if (this.latest)
|
||||
if (this.doneAt == -1)
|
||||
this.notify();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -10,7 +10,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2008: Christian Dietrich <stettberger@dokucode.de>
|
||||
Copyright (c) 2008 by Christian Dietrich <stettberger@dokucode.de>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -13,7 +13,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -89,9 +89,9 @@ function Mail() //{{{
|
||||
var notifyFlags = nsIFolderListener.intPropertyChanged | nsIFolderListener.event;
|
||||
mailSession.AddFolderListener(folderListener, notifyFlags);
|
||||
|
||||
function getFolderCompletions(filter)
|
||||
function getFolderCompletions(context)
|
||||
{
|
||||
let folders = mail.getFolders(filter);
|
||||
let folders = mail.getFolders(context.filter);
|
||||
context.completions = folders.map(function (folder)
|
||||
[folder.server.prettyName + ": " + folder.name,
|
||||
"Unread: " + folder.getNumUnread(false)]);
|
||||
|
||||
@@ -13,7 +13,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
1
muttator/locale/en-US/Makefile
Symbolic link
1
muttator/locale/en-US/Makefile
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../common/Makefile.doc
|
||||
@@ -1,4 +1,7 @@
|
||||
2009:
|
||||
* InspireFocus
|
||||
* Michael Fremont
|
||||
* Kamil Dworakowski
|
||||
* Jonathan Austin
|
||||
* Steven Romanow
|
||||
|
||||
|
||||
@@ -20,20 +20,19 @@ BUGS:
|
||||
- http://cgiirc.blitzed.org?chan=%23debug is unusable after login in
|
||||
|
||||
(recent CVS regressions):
|
||||
- visual caret mode is broken
|
||||
- the message system is a bit of a debacle at the moment but I'm not sure how
|
||||
it's supposed to work. MST, can you spec it when you have some time?
|
||||
E.g. :ls | :echomsg "Foobar" doesn't add "Foobar" to the already open MOW.
|
||||
Obviously I think it should but I'm not sure if it's a bug or not in your
|
||||
view, thanks. --djk
|
||||
The spec is easy: echomsg() is used for informational purposes, and should therefore
|
||||
never need user interaction. Therefore: If the MOW is open, print the message there,
|
||||
but never open the MOW for an echomsg(). --mst
|
||||
- While the old :open foo<tab> was broken/annoying, so is the one after 02-01-2008, as
|
||||
I am often waiting ~20sec or more after doing :open not-cached-things<tab>.
|
||||
We should probably just abort searching after 5 secs if we already have found some entries.
|
||||
- :set noflashblock seems broken (= :set fb? afterwards says "fb"), let's see if that's a
|
||||
plugin or a vimp issue.
|
||||
- visual caret mode is broken, requires a manual page focus first anyway or
|
||||
else it chucks, I haven't investigated --djk
|
||||
- messages is still broken in several ways - needs testing.
|
||||
=> :ls | :echomsg "Foobar" doesn't add "Foobar" to the already open MOW.
|
||||
=> it often overwrites the open command-line while editing etc.
|
||||
- <tags> and <keyword> autocmd 'keywords' are not available when adding a
|
||||
bookmark - they're being set after the observer triggers the autocmd event.
|
||||
- MOW is broken for multiple commands when open E.g. :ls | ls
|
||||
- completion height is broken, try :a<tab>....<tab>, when it wraps it's totally off.
|
||||
and even if it is not totally off, i had it jump by one pixel when wrapping around.
|
||||
If that's unfixable, i propose reverting the new completion height stuff.
|
||||
|
||||
FEATURES:
|
||||
9 finish :help TODOs
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@@ -792,9 +792,9 @@ function History() //{{{
|
||||
function (args) { history.list(args.join(" "), args.bang, args["-max"] || 1000); },
|
||||
{
|
||||
bang: true,
|
||||
completer: function (context) { context.quote = null, completion.history(context); },
|
||||
options: [[["-max", "-m"], options.OPTION_INT]]
|
||||
completer: function (context) { context.quote = null; completion.history(context); },
|
||||
// completer: function (filter) completion.history(filter)
|
||||
options: [[["-max", "-m"], options.OPTION_INT]]
|
||||
});
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
@@ -962,7 +962,14 @@ function QuickMarks() //{{{
|
||||
else
|
||||
quickmarks.remove(args.string);
|
||||
},
|
||||
{ bang: true });
|
||||
{
|
||||
bang: true,
|
||||
completer: function (context)
|
||||
{
|
||||
context.title = ["QuickMark", "URL"];
|
||||
context.completions = qmarks;
|
||||
}
|
||||
});
|
||||
|
||||
commands.add(["qma[rk]"],
|
||||
"Mark a URL with a letter for quick access",
|
||||
|
||||
@@ -11,7 +11,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
@@ -13,7 +13,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the
|
||||
License.
|
||||
|
||||
(c) 2006-2008: Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
Copyright (c) 2006-2009 by Martin Stubenschrott <stubenschrott@gmx.net>
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
||||
1
vimperator/locale/en-US/Makefile
Symbolic link
1
vimperator/locale/en-US/Makefile
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../common/Makefile.doc
|
||||
@@ -40,19 +40,19 @@ The first URL is opened in the current tab, and all other URLs are
|
||||
opened in new tabs.
|
||||
Each token is analyzed and in this order:
|
||||
|
||||
. Opened as a local file if it is an existing relative or absolute filename.
|
||||
* [c]:open /etc/fstab[c] shows the file system table.
|
||||
* [c]:open ../other/foo.html[c] in your home directory opens
|
||||
1. Opened as a local file if it is an existing relative or absolute filename.
|
||||
- [c]:open /etc/fstab[c] shows the file system table.
|
||||
- [c]:open ../other/foo.html[c] in your home directory opens
|
||||
[a]/home/other/foo.html[a]
|
||||
. Opened with the specified search engine if the token looks like a search
|
||||
2. Opened with the specified search engine if the token looks like a search
|
||||
string and the first word is the name of a search engine ([c]:open wikipedia
|
||||
linus torvalds[c] opens the Wikipedia entry for linus torvalds). The short
|
||||
name of a search engine is automatically guessed from its name. If you want
|
||||
to set a custom name, you can change it with [c]:dialog searchengines[c].
|
||||
. Opened with the default search engine or keyword (specified with the
|
||||
3. Opened with the default search engine or keyword (specified with the
|
||||
'defsearch' option) if the first word is no search engine ([c]:open linus
|
||||
torvalds[c] opens a Google search for linux torvalds).
|
||||
. Passed directly to Firefox in all other cases ([c]:open www.osnews.com,
|
||||
4. Passed directly to Firefox in all other cases ([c]:open www.osnews.com,
|
||||
www.slashdot.org[c] opens OSNews in the current, and Slashdot in a new
|
||||
background tab).
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ ________________________________________________________________________________
|
||||
|F| +
|
||||
||#F#{hint}||
|
||||
________________________________________________________________________________
|
||||
Start QuickHint mode, but open link in a new tab. Like normal QuickHint mode
|
||||
(activated with [m]f[m]) but opens the link in a new tab.
|
||||
Start QuickHint mode, but open link in a new tab. Like normal QuickHint
|
||||
mode (activated with [m]f[m]) but opens the link in a new tab. The new
|
||||
tab will be loaded in background according to the
|
||||
\'browser.tabs.loadInBackground' Firefox preference.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -49,9 +51,9 @@ this hint mode. Then press [a]24[a] to copy the hint location.
|
||||
* |;b| [m]b[m] to open its location in a new background tab
|
||||
* |;w| [m]w[m] to open its destination in a new window
|
||||
* |;F| [m]F[m] to follow a sequence of [m]<CR>[m]-delimited hints in background tabs
|
||||
* |;O| [m]O[m] to preselect its location in an [c]:open[c] query
|
||||
* |;T| [m]T[m] to preselect its location in a [c]:tabopen[c] query
|
||||
* |;W| [m]W[m] to preselect its location in a [c]:winopen[c] query
|
||||
* |;O| [m]O[m] to [c]:open[c] a URL based on hint location
|
||||
* |;T| [m]T[m] to [c]:tabopen[c] a URL based on its location
|
||||
* |;W| [m]W[m] to [c]:winopen[c] a URL based on its location
|
||||
* |;v| [m]v[m] to view its destination source
|
||||
* |;V| [m]V[m] to view its destination source in the external editor
|
||||
* |;y| [m]y[m] to yank its destination location
|
||||
@@ -59,9 +61,6 @@ this hint mode. Then press [a]24[a] to copy the hint location.
|
||||
|
||||
Hintable elements for all extended hint modes can be set in the
|
||||
'extendedhinttags' XPath string.
|
||||
|
||||
Note: The behavior of [m];t[m] and [m];b[m] is inverted if the
|
||||
\'browser.tabs.loadInBackground' Firefox preference is set to false.
|
||||
________________________________________________________________________________
|
||||
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
@@ -330,7 +330,7 @@ properties, describing the completions and where the replacement is to start.
|
||||
|
||||
*start* is the index into the word being completed at which the returned values
|
||||
should be applied and *completions* is a two dimensional array of the form:
|
||||
\[[arg1, description1], [arg2, description2], ...]
|
||||
[[arg1, description1], [arg2, description2], ...]
|
||||
|
||||
// TODO: add examples
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ ________________________________________________________________________________
|
||||
||:qma[rk] {a-zA-Z0-9} [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Mark a URL with a letter for quick access. You can also mark whole groups like this: +
|
||||
[c]:qmark f \http://forum1.com, \http://forum2.com, imdb some artist[c]
|
||||
[c]:qmark f +++http://forum1.com+++, +++http://forum2.com+++, imdb some artist[c]
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|
||||
@@ -7,28 +7,28 @@ section:Initialization[initialization,startup]
|
||||
|
||||
At startup, Vimperator completes the following tasks in order.
|
||||
|
||||
. Vimperator can perform user initialization commands. When
|
||||
1. Vimperator can perform user initialization commands. When
|
||||
one of the following is successfully located, it is executed, and no
|
||||
further locations are tried.
|
||||
|
||||
.. |$VIMPERATOR_INIT| _$VIMPERATOR_INIT_ -- May contain a single ex
|
||||
a. |$VIMPERATOR_INIT| _$VIMPERATOR_INIT_ -- May contain a single ex
|
||||
command (e.g.,
|
||||
"[c]:source {file}[c]").
|
||||
.. [a]\~/_vimperatorrc[a] -- Windows only. If this file exists, its
|
||||
b. [a]\~/_vimperatorrc[a] -- Windows only. If this file exists, its
|
||||
contents are executed and
|
||||
_$MY_VIMPERATORRC_ set to its path.
|
||||
.. [a]\~/.vimperatorrc[a] -- If this file exists, its contents are
|
||||
c. [a]\~/.vimperatorrc[a] -- If this file exists, its contents are
|
||||
executed.
|
||||
|
||||
. If 'exrc' is set, then any RC file in the current directory is also sourced.
|
||||
2. If 'exrc' is set, then any RC file in the current directory is also sourced.
|
||||
|
||||
. All directories in 'runtimepath' are searched for a "plugin"
|
||||
subdirectory and all yet unloaded plugins are loaded. For each
|
||||
plugin directory, all *.\{js,vimp} files (including those in further
|
||||
subdirectories) are sourced alphabetically. No plugins will be sourced
|
||||
if 'noloadplugins' is set. Any particular plugin will not be loaded
|
||||
if it has already been loaded (e.g., by an earlier [c]:loadplugins[c]
|
||||
command).
|
||||
3. All directories in 'runtimepath' are searched for a "plugin"
|
||||
subdirectory and all yet unloaded plugins are loaded. For each
|
||||
plugin directory, all *.\{js,vimp} files (including those in further
|
||||
subdirectories) are sourced alphabetically. No plugins will be sourced
|
||||
if 'noloadplugins' is set. Any particular plugin will not be loaded
|
||||
if it has already been loaded (e.g., by an earlier [c]:loadplugins[c]
|
||||
command).
|
||||
|
||||
The user's ~ (i.e., "home") directory is determined as follows:
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ function getBufferPosition()
|
||||
|
||||
function getLocation() window.content.document.location.href;
|
||||
|
||||
|
||||
function echoLine(str, group)
|
||||
{
|
||||
if (!doc)
|
||||
|
||||
Reference in New Issue
Block a user