mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 16:27:59 +01:00
ex parser for use with .vimperatorrc, the command line and other sourced files. sourced files are no longer javascript code, but can use the new :javascript ex command to execute javascript. :javascript also supports multiline with heredocs (:js <<EOF). File completion for the :source command.
This commit is contained in:
@@ -131,16 +131,11 @@ var g_commands = [/*{{{*/
|
||||
],
|
||||
[
|
||||
["execute", "exe"],
|
||||
"Run any javascript command through eval()",
|
||||
"Acts as a javascript interpreter by passing the argument to <code>eval()</code>.<br>"+
|
||||
"<code>:exec alert('Hello world')</code> would show a dialog box with the text \"Hello world\".<br>"+
|
||||
"The special version <code>:execute!</code> will open the javascript console of Firefox.",
|
||||
function(args, special) {
|
||||
if (special) // open javascript console
|
||||
openURLsInNewTab("chrome://global/content/console.xul", true);
|
||||
else
|
||||
eval(args);
|
||||
},
|
||||
"Executes a string as an Ex command",
|
||||
"Usage: <code>:execute {expr1} [ ... ]</code><br>" +
|
||||
"Executes the string that results from the evaluation of {expr1} as an Ex command.<br>"+
|
||||
"<code>:execute "echo test"</code> would show a message with the text "test".<br>",
|
||||
execute,
|
||||
null
|
||||
],
|
||||
[
|
||||
@@ -174,6 +169,21 @@ var g_commands = [/*{{{*/
|
||||
hsshow,
|
||||
function(filter) { return get_history_completions(filter); }
|
||||
],
|
||||
[
|
||||
["javascript", "js"],
|
||||
"Run any javascript command through eval()",
|
||||
"Acts as a javascript interpreter by passing the argument to <code>eval()</code>.<br>" +
|
||||
"<code>:javascript alert('Hello world')</code> would show a dialog box with the text \"Hello world\".<br>" +
|
||||
"<code>:javascript <<EOF</code> would read all the lines until a line starting with 'EOF' is found, and will <code>eval()</code> them.<br>" +
|
||||
"The special version <code>:javascript!</code> will open the javascript console of Firefox.",
|
||||
function(args, special) {
|
||||
if (special) // open javascript console
|
||||
openURLsInNewTab("chrome://global/content/console.xul", true);
|
||||
else
|
||||
eval(args);
|
||||
},
|
||||
null
|
||||
],
|
||||
[
|
||||
["mark"],
|
||||
"Mark current location within the webpage",
|
||||
@@ -286,7 +296,7 @@ var g_commands = [/*{{{*/
|
||||
"The .vimperatorrc file in your home directory is always sourced at start up.<br>"+
|
||||
"~ is supported as a shortcut for the $HOME directory.",
|
||||
source,
|
||||
null
|
||||
function (filter) { return get_file_completions(filter); }
|
||||
],
|
||||
[
|
||||
["tabnext", "tn", "tnext"],
|
||||
@@ -910,6 +920,7 @@ function get_command(cmd) // {{{
|
||||
|
||||
function execute_command(count, cmd, special, args) // {{{
|
||||
{
|
||||
if (!cmd) return;
|
||||
var command = get_command(cmd);
|
||||
if (command == null)
|
||||
{
|
||||
@@ -929,6 +940,86 @@ function execute_command(count, cmd, special, args) // {{{
|
||||
|
||||
} // }}}
|
||||
|
||||
function tokenize_ex(string, tag)
|
||||
{
|
||||
// removing commends
|
||||
string.replace(/\s*".*$/, '');
|
||||
if (tag)
|
||||
{
|
||||
if (string == tag)
|
||||
return [null, null, null, null, false];
|
||||
else
|
||||
return [null, null, null, string, tag];
|
||||
}
|
||||
|
||||
// 0 - count, 1 - cmd, 2 - special, 3 - args, 4 - heredoc tag
|
||||
var matches = string.match(/^:*(\d+)?([a-zA-Z]+)(!)?(?:\s+(.*?))?$/);
|
||||
if (!matches) return [null, null, null, null, null];
|
||||
matches.shift();
|
||||
|
||||
if (matches[0])
|
||||
{
|
||||
matches[0] = parseInt(matches[0]);
|
||||
if (isNaN(matches[0])) matches[0] = 0;
|
||||
}
|
||||
else matches[0] = 0;
|
||||
matches[2] = !!matches[2];
|
||||
matches.push(null);
|
||||
if (matches[3])
|
||||
{
|
||||
tag = matches[3].match(/<<\s*(\w+)/);
|
||||
if (tag && tag[1])
|
||||
matches[4] = tag[1];
|
||||
}
|
||||
else matches[3] = '';
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
function multiliner(line, prev_match, heredoc)
|
||||
{
|
||||
var end = true;
|
||||
var match = tokenize_ex(line, prev_match[4]);
|
||||
if (prev_match[3] === undefined) prev_match[3] = '';
|
||||
if (match[4] === null)
|
||||
{
|
||||
focusContent(false, true); // also sets comp_tab_index to -1
|
||||
execute_command.apply(this, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (match[4] === false)
|
||||
{
|
||||
prev_match[3] = prev_match[3].replace(new RegExp('<<\s*' + prev_match[4]), heredoc.replace(/\n$/, ''));
|
||||
execute_command.apply(this, prev_match);
|
||||
prev_match = new Array(5);
|
||||
prev_match[3] = '';
|
||||
heredoc = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
end = false;
|
||||
if (!prev_match[3])
|
||||
{
|
||||
prev_match[0] = match[0];
|
||||
prev_match[1] = match[1];
|
||||
prev_match[2] = match[2];
|
||||
prev_match[3] = match[3];
|
||||
prev_match[4] = match[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
heredoc += match[3] + '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
return [prev_match, heredoc, end];
|
||||
}
|
||||
|
||||
function execute(string)
|
||||
{
|
||||
return execute_command.apply(this, tokenize_ex(string.replace(/^'(.*)'$/, '$1')));
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// statusbar/commandbar handling ////////////////////////////////// {{{1
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1628,7 +1719,12 @@ function source(filename, silent)
|
||||
var s = fd.read();
|
||||
fd.close();
|
||||
|
||||
eval(s);
|
||||
var prev_match = new Array(5);
|
||||
var heredoc = '';
|
||||
var end = false;
|
||||
s.split('\n').forEach(function (line) {
|
||||
[prev_match, heredoc, end] = multiliner(line, prev_match, heredoc);
|
||||
});
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
@@ -1637,7 +1733,6 @@ function source(filename, silent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function help(section, easter)
|
||||
{
|
||||
if (easter)
|
||||
|
||||
@@ -180,6 +180,27 @@ function completion_select_previous_item()/*{{{*/
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
function get_file_completions(filter)/*{{{*/
|
||||
{
|
||||
g_completions = [];
|
||||
|
||||
var match = filter.match(/^(.*[\/\\])(.*?)$/);
|
||||
var dir;
|
||||
if (!match || !(dir = match[1])) return [];
|
||||
var compl = match[2] || '';
|
||||
var fd = fopen(dir, "<");
|
||||
if (!fd) return [];
|
||||
var entries = fd.read();
|
||||
var delim = (fd.path.search(/\\/) != -1) ? "\\" : "/";
|
||||
var reg = new RegExp("^" + fd.path + delim + compl);
|
||||
entries.forEach(function(file) {
|
||||
if (file.path.search(reg) != -1)
|
||||
g_completions.push([file.path]);
|
||||
});
|
||||
|
||||
return g_completions;
|
||||
}/*}}}*/
|
||||
|
||||
|
||||
/*
|
||||
* filter a list of urls
|
||||
|
||||
@@ -129,6 +129,19 @@ function fo_write(buf)
|
||||
LocalFile.prototype.read =
|
||||
function fo_read(max)
|
||||
{
|
||||
if (this.localFile.isDirectory())
|
||||
{
|
||||
var entries = this.localFile.directoryEntries;
|
||||
var array = [];
|
||||
while(entries.hasMoreElements())
|
||||
{
|
||||
var entry = entries.getNext();
|
||||
entry.QueryInterface(Components.interfaces.nsIFile);
|
||||
array.push(entry);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
if (!("inputStream" in this))
|
||||
throw "file not open for reading.";
|
||||
|
||||
|
||||
@@ -63,17 +63,6 @@ var g_settings = [/*{{{*/
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
["completeopt", "cot"],
|
||||
"Define how command line completion works",
|
||||
"Not implemented yet.",
|
||||
function(value) { set_pref("completeopt", value); },
|
||||
function() { return get_pref("completeopt"); },
|
||||
"stringlist",
|
||||
"menu",
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
["extendedhinttags", "eht"],
|
||||
"XPath string of hintable elements activated by ';'",
|
||||
@@ -221,6 +210,17 @@ var g_settings = [/*{{{*/
|
||||
false,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
["wildmode", "wim"],
|
||||
"Define how command line completion works",
|
||||
"Not implemented yet.",
|
||||
function(value) { set_pref("wildmode", value); },
|
||||
function() { return get_pref("wildmode"); },
|
||||
"stringlist",
|
||||
"menu",
|
||||
null,
|
||||
null
|
||||
]
|
||||
]/*}}}*/
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ var g_inputbuffer = ""; // here we store partial commands (e.g. 'g' if you want
|
||||
var g_count = -1; // the parsed integer of g_inputbuffer, or -1 if no count was given
|
||||
var g_bufshow = false; // keeps track if the preview window shows current buffers ('B')
|
||||
|
||||
// handles multi-line commands
|
||||
var prev_match = new Array(5);
|
||||
var heredoc = '';
|
||||
|
||||
// handles to our gui elements
|
||||
var preview_window = null;
|
||||
var status_line = null;
|
||||
@@ -83,7 +87,7 @@ nsBrowserStatusHandler.prototype =
|
||||
|
||||
setOverLink : function(link, b)
|
||||
{
|
||||
echo(link);
|
||||
updateStatusbar(link);
|
||||
|
||||
if (link == "")
|
||||
showMode();
|
||||
@@ -518,45 +522,24 @@ function onVimperatorKeypress(event)/*{{{*/
|
||||
updateStatusbar();
|
||||
return false;
|
||||
}/*}}}*/
|
||||
|
||||
function onCommandBarKeypress(evt)/*{{{*/
|
||||
{
|
||||
var end = false;
|
||||
try
|
||||
{
|
||||
/* parse our command string into tokens */
|
||||
var command = command_line.value;
|
||||
|
||||
var matches1 = command.match(/^:(\d+)/);
|
||||
var matches2 = command.match(/^:(\d+)?([a-zA-Z!]+)/);
|
||||
var matches3 = command.match(/^:(\d+)?([a-zA-Z!]+)\s*(.*?)\s*$/);
|
||||
var count = 0;
|
||||
var cmd = "";
|
||||
var args= "";
|
||||
var special = false;
|
||||
|
||||
if (matches1 != null && matches1.length == 2)
|
||||
count = parseInt(matches1[1], 10);
|
||||
if (matches2 != null && matches2.length >= 3)
|
||||
cmd = matches2[2];
|
||||
if (matches3 != null && matches3.length >= 4)
|
||||
args = matches3[3];
|
||||
|
||||
/* if the user executes a command with ! at the end */
|
||||
if (cmd.length - 1 == cmd.lastIndexOf("!"))
|
||||
{
|
||||
special = true;
|
||||
cmd = cmd.replace(/!$/, "");
|
||||
}
|
||||
else
|
||||
special = false;
|
||||
|
||||
/* user pressed ENTER to carry out a command */
|
||||
if (evt.keyCode == KeyEvent.DOM_VK_RETURN)
|
||||
{
|
||||
// unfocus command line first
|
||||
focusContent(false, true); // also sets comp_tab_index to -1
|
||||
add_to_command_history(command);
|
||||
|
||||
execute_command(count, cmd, special, args);
|
||||
[prev_match, heredoc, end] = multiliner(command, prev_match, heredoc);
|
||||
if (!end)
|
||||
command_line.value = "";
|
||||
}
|
||||
|
||||
else if ((evt.keyCode == KeyEvent.DOM_VK_ESCAPE) ||
|
||||
@@ -606,6 +589,8 @@ function onCommandBarKeypress(evt)/*{{{*/
|
||||
/* user pressed TAB to get completions of a command */
|
||||
else if (evt.keyCode == KeyEvent.DOM_VK_TAB)
|
||||
{
|
||||
var match = tokenize_ex(command);
|
||||
var [count, cmd, special, args] = match;
|
||||
//always reset our completion history so up/down keys will start with new values
|
||||
comp_history_index = -1;
|
||||
|
||||
@@ -714,6 +699,17 @@ function onCommandBarInput(event)
|
||||
command_line.value = ":";
|
||||
}
|
||||
|
||||
function onCommandBarMouseDown(event)
|
||||
{
|
||||
if (command_line.value.indexOf(':') != 0)
|
||||
{
|
||||
command_line.blur();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// focus and mode handling //////////////////////////////////////// {{{1
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -802,12 +798,12 @@ function setStatusbarColor(color)
|
||||
bar.setAttribute("style", "background-color: " + color);
|
||||
}
|
||||
|
||||
function updateStatusbar()
|
||||
function updateStatusbar(message)
|
||||
{
|
||||
var buffers = "[" + (gBrowser.tabContainer.selectedIndex + 1).toString() + "/" +
|
||||
gBrowser.tabContainer.childNodes.length.toString() + "]";
|
||||
|
||||
showStatusbarMessage(getCurrentLocation(), STATUSFIELD_URL);
|
||||
showStatusbarMessage(message || getCurrentLocation(), STATUSFIELD_URL);
|
||||
showStatusbarMessage(" " + g_inputbuffer + " ", STATUSFIELD_INPUTBUFFER);
|
||||
showStatusbarMessage("", STATUSFIELD_PROGRESS);
|
||||
showStatusbarMessage(buffers, STATUSFIELD_BUFFERS);
|
||||
|
||||
@@ -79,7 +79,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
<textbox class="plain" id="vim-commandbar" flex="1" hidden="false" type="timed" timeout="100"
|
||||
onkeypress="onCommandBarKeypress(event);" oninput="onCommandBarInput(event);"
|
||||
style="font-family: monospace"/>
|
||||
onmousedown="onCommandBarMouseDown(event);" style="font-family: monospace"/>
|
||||
</vbox>
|
||||
</toolbar>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user