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

Generally niftier :mkv

This commit is contained in:
Kris Maglione
2008-10-30 03:31:19 +00:00
parent bfe0530209
commit a53b702200
8 changed files with 155 additions and 123 deletions

View File

@@ -857,7 +857,16 @@ function Buffer() //{{{
bang: true,
hereDoc: true,
literal: true,
options: [[["-name", "-n"], commands.OPTION_STRING]]
options: [[["-name", "-n"], commands.OPTION_STRING]],
serial: function () [
{
command: this.name,
bang: true,
options: sty.name ? {"-name": sty.name} : {},
arguments: [sty.sites.join(",")],
literalArg: sty.css
} for ([k, sty] in styles.userSheets)
]
});
commands.add(["dels[tyle]"],

View File

@@ -81,6 +81,7 @@ function Command(specs, description, action, extraInfo) //{{{
this.bang = extraInfo.bang || false;
this.count = extraInfo.count || false;
this.literal = extraInfo.literal || false;
this.serial = extraInfo.serial;
this.isUserCommand = extraInfo.isUserCommand || false;
this.replacementText = extraInfo.replacementText || null;
@@ -166,25 +167,15 @@ function Commands() //{{{
function getMatchingUserCommands(name, filter)
{
var matches = [];
outer:
for (let [,cmd] in Iterator(exCommands))
{
if (cmd.isUserCommand)
{
for (let [k, v] in Iterator(filter))
if (!name || cmd.name.match("^" + name))
{
if (v != null && cmd[k] != v)
continue outer;
}
if (name)
{
if (cmd.name.match("^" + name))
if (util.map(filter, function (f) f).every(function ([k, v]) v == null || cmd[k] == v))
matches.push(cmd);
}
else
{
matches.push(cmd);
}
}
}
return matches;
@@ -199,6 +190,17 @@ function Commands() //{{{
return NaN;
}
function quote(q, list) list.reduce(function (acc, [k,v])
{
v = "\\" + (v || k);
return function (str) acc(String.replace(str, k, v, "g"))
}, function (val) q + val + q);
const quoteArg = {
'"': quote('"', [["\n", "n"], ["\t", "t"], ['"'], ["\\"]]),
"'": quote("'", [["\\"], ["'"]]),
"": quote("", [["\\"], [" "]])
}
const ArgType = new Struct("description", "parse");
const argTypes = [
null,
@@ -291,6 +293,26 @@ function Commands() //{{{
return true;
},
commandToString: function (args)
{
let res = [args.command + (args.bang ? "!" : "")];
function quote(str) quoteArg[/\s/.test(str) ? '"' : ""](str);
for (let [opt, val] in Iterator(args.options || {}))
{
res.push(opt);
if (val != null)
res.push(quote(val));
}
for (let [,arg] in Iterator(args.arguments || []))
res.push(quote(arg));
let str = args.literalArg;
if (str)
res.push(/\n/.test(str) ? "<<EOF\n" + str + "EOF" : str);
return res.join(" ");
},
get: function (name)
{
for (let i = 0; i < exCommands.length; i++)
@@ -350,20 +372,6 @@ function Commands() //{{{
// TODO: should it handle comments?
parseArgs: function (str, options, argCount, allowUnknownOptions, literal, complete)
{
function quoteArg(quote)
{
switch (quote)
{
case "'":
return function (str) "'" + str.replace(/[\\']/g, "\\$&") + "'";
case '"':
return function (str) '"' + str.replace(/[\\"\t\n]/g,
function (c) (c == "\n" ? "\\n" : c == "\t" ? "\\t" : "\\" + c));
default:
return function (str) str.replace(/[\\ ]/g, "\\$&");
}
}
// returns [count, parsed_argument]
function getNextArg(str)
{
@@ -546,8 +554,8 @@ function Commands() //{{{
let compl = opt[3] || [];
if (typeof compl == "function")
compl = compl();
let filter = quoteArg(sub[optname.length + 1])
return [i + optname.length + 1, completion.filter(compl.map(filter), filter(arg))];
let quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
return [i + optname.length + 1, completion.filter(compl.map(quote), quote(arg))];
}
if (!invalid)
@@ -668,6 +676,8 @@ function Commands() //{{{
return matches;
},
get quoteArg() quoteArg,
removeUserCommand: function (name)
{
for (let i = 0; i < exCommands.length; i++)
@@ -690,7 +700,7 @@ function Commands() //{{{
if (res == undefined) // Ignore anything undefined
res = "<" + token + ">";
if (quote && typeof res != "number")
return '"' + String.replace(res, '"', '\\"', "g") + '"';
return quoteArg['"'](res);
return res;
});
}
@@ -782,6 +792,20 @@ function Commands() //{{{
[["-nargs"], commandManager.OPTION_STRING, function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
[["-bang"], commandManager.OPTION_NOARG],
[["-count"], commandManager.OPTION_NOARG],
],
serial: function () [
{
command: this.name,
// Yeah, this is a bit scary. Perhaps I'll fix it when I'm
// awake.
options: util.Array.assocToObj(util.map({argCount: "-nargs", bang: "-bang", count: "-count"},
function ([k, v]) k in cmd && cmd[k] != "0" && [v, typeof cmd[k] == "boolean" ? null : cmd[k]])
.filter(function(k) k)),
arguments: [cmd.name],
literalArg: cmd.replacementText
}
for ([k,cmd] in Iterator(exCommands))
if (cmd.isUserCommand && cmd.replacementText)
]
});

View File

@@ -147,6 +147,15 @@ function Editor() //{{{
{ flags: Mappings.flags.MOTION | Mappings.flags.COUNT });
}
// For the record, some of this code I've just finished throwing
// away makes me want to pull someone else's hair out. --Kris
function abbrevs()
{
for (let [lhs, abbr] in Iterator(abbrev))
for (let [,rhs] in Iterator(abbr))
yield [lhs, rhs];
}
// mode = "i" -> add :iabbrev, :iabclear and :iunabbrev commands
function addAbbreviationCommands(ch, modeDescription)
{
@@ -157,20 +166,25 @@ function Editor() //{{{
"Abbreviate a key sequence" + modeDescription,
function (args)
{
args = args.string;
if (!args)
{
editor.listAbbreviations(mode, "");
return;
}
var matches = args.match(/^(\S+)(?:\s+(.+))?$/);
var [lhs, rhs] = [matches[1], matches[2]];
let lhs = args.arguments[0];
let rhs = args.literalArg;
if (rhs)
editor.addAbbreviation(mode, lhs, rhs);
else
editor.listAbbreviations(mode, lhs);
editor.listAbbreviations(mode, lhs || "");
},
{
argCount: 1,
literal: true,
serial: function () [
{
command: this.name,
arguments: [lhs],
literalArg: abbr[1]
}
for ([lhs, abbr] in abbrevs())
if (abbr[0] == mode)
]
});
commands.add([ch ? ch + "una[bbrev]" : "una[bbreviate]"],
@@ -892,21 +906,6 @@ function Editor() //{{{
// Abbreviations {{{
abbreviations: {
__iterator__: function ()
{
var tmpCmd;
for (let lhs in abbrev)
{
for (let i = 0; i < abbrev[lhs].length; i++)
{
tmpCmd = (abbrev[lhs][i][0] == "!") ? "abbreviate" : abbrev[lhs][i][0] + "abbrev";
yield (tmpCmd + " " + lhs + " " + abbrev[lhs][i][1] + "\n");
}
}
}
},
// filter is i, c or "!" (insert or command abbreviations or both)
listAbbreviations: function (filter, lhs)
{
@@ -914,10 +913,11 @@ function Editor() //{{{
{
if (abbrev[lhs])
{
for (let i = 0; i < abbrev[lhs].length; i++)
for (let [,abbr] in Iterator(abbrev[lhs]))
{
if (abbrev[lhs][i][0] == filter)
liberator.echo(abbrev[lhs][i][0] + " " + lhs + " " + abbrev[lhs][i][1]);
if (abbr[0] == filter)
liberator.echo(abbr[0] + " " + lhs + " " + abbr[1]);
// Is it me, or is this clearly very wrong? --Kris
return true;
}
}
@@ -932,14 +932,13 @@ function Editor() //{{{
let list =
<table>
{
template.map(abbrev, function ([lhs, rhs])
template.map(rhs, function (abbr)
searchFilter.indexOf(abbr[0]) < 0 ? undefined :
<tr>
<td>{abbr[0]}</td>
<td>{lhs}</td>
<td>{abbr[1]}</td>
</tr>))
template.map(abbrevs(), function ([lhs, rhs])
searchFilter.indexOf(rhs[0]) < 0 ? undefined :
<tr>
<td>{rhs[0]}</td>
<td>{lhs}</td>
<td>{rhs[1]}</td>
</tr>)
}
</table>;
if (list.*.length())

View File

@@ -228,50 +228,31 @@ function IO() //{{{
return;
}
let line = "\" " + liberator.version + "\n";
line += "\" Mappings\n";
let lines = [['"' + liberator.version]];
[[[modes.NORMAL], ""],
[[modes.COMMAND_LINE], "c"],
[[modes.INSERT, modes.TEXTAREA], "i"]].forEach(function ([modes, modechar]) {
// NOTE: names.length is always 1 on user maps. If that changes, also fix getUserIterator and v.m.list
for (let map in mappings.getUserIterator(modes))
line += modechar + (map.noremap ? "noremap" : "map") + " " + map.names[0] + " " + map.rhs + "\n";
});
line += "\n\" Options\n";
for (let option in options)
// FIXME: Use a set/specifiable list here:
for (let cmd in commands)
{
// TODO: options should be queried for this info
// TODO: string/list options might need escaping in future
if (!/fullscreen|usermode/.test(option.name) && option.value != option.defaultValue)
{
if (option.type == "boolean")
line += "set " + (option.value ? option.name : "no" + option.name) + "\n";
else
line += "set " + option.name + "=" + option.value + "\n";
}
if (cmd.serial)
lines.push(cmd.serial().map(commands.commandToString));
}
lines = util.Array.flatten(lines);
// :mkvimrc doesn't save autocommands, so we don't either - remove this code at some point
// line += "\n\" Auto-Commands\n";
// for (let item in autocommands)
// line += "autocmd " + item.event + " " + item.pattern.source + " " + item.command + "\n";
line += "\n\" Abbreviations\n";
for (let abbrCmd in editor.abbreviations)
line += abbrCmd;
// if (mappings.getMapLeader() != "\\")
// line += "\nlet mapleader = \"" + mappings.getMapLeader() + "\"\n";
// source a user .vimperatorrc file
line += "\nsource! " + filename + ".local\n";
line += "\n\" vim: set ft=vimperator:";
lines.push("\nsource! " + filename + ".local");
lines.push("\n\" vim: set ft=vimperator:");
try
{
io.writeFile(file, line);
io.writeFile(file, lines.join("\n"));
}
catch (e)
{

View File

@@ -132,30 +132,10 @@ function Mappings() //{{{
function mappingsIterator(modes, stack)
{
var output;
var maps = stack[modes[0]];
for (let i = 0; i < maps.length; i++)
{
output = true;
for (let index = 1; index < modes.length; index++) // check other modes
{
output = false; // toggle false, only true whan also found in this mode
for (let j = 0; j < user[modes[index]].length; j++) // maps
{
// NOTE: when other than user maps, there might be more than only one names[x].
// since only user mappings gets queried here, only names[0] gets checked for equality.
if (maps[i].rhs == user[modes[index]][j].rhs && maps[i].names[0] == user[modes[index]][j].names[0])
{
output = true;
break; // found on this mode - check next mode, if there is one, where it could still fail...
}
}
break; // not found in this mode -> map wont' match all modes...
}
if (output)
yield maps[i];
}
modes = modes.slice();
return (map for ([i, map] in Iterator(stack[modes.shift()]))
if (modes.every(function (mode) stack[mode].some(
function (m) m.rhs == map.rhs && m.names[0] == map.names[0]))))
}
function addMapCommands(ch, modes, modeDescription)
@@ -203,7 +183,20 @@ function Mappings() //{{{
[["<silent>", "<Silent>"], commands.OPTION_NOARG]
],
argCount: 1,
literal: true
literal: true,
serial: function () {
let noremap = this.name.indexOf("noremap") > -1;
return [
{
command: this.name,
options: map.silent ? {"<silent>": null} : {},
arguments: [map.names[0]],
literalArg: map.rhs
}
for (map in mappingsIterator(modes, user))
if (map.rhs && map.noremap == noremap)
]
}
};
commands.add([ch ? ch + "m[ap]" : "map"],

View File

@@ -799,7 +799,16 @@ function Options() //{{{
}
}
return [len, completion.filter(completions, filter, true)];
}
},
serial: function () [
{
command: this.name,
literalArg: opt.type == "boolean" ? (opt.value ? "" : "no") + opt.name
: opt.name + "=" + opt.value
}
for (opt in options)
if (!opt.getter && opt.value != opt.defaultValue && (opt.scope & options.OPTION_SCOPE_GLOBAL))
]
});
commands.add(["unl[et]"],

View File

@@ -53,7 +53,7 @@ const template = {
// Vim generally doesn't like /foo*/, because */ looks like a comment terminator.
// Using /foo*(:?)/ instead.
if (processStrings)
return <span class="hl-Function">{String(arg).replace(/\{(.|\n)*(?:)/, "{ ... }")}</span>;
return <span class="hl-Function">{String(arg).replace(/\{(.|\n)*(?:)/g, "{ ... }")}</span>;
return <>{arg}</>;
case "undefined":
return <span class="hl-Null">{arg}</span>;

View File

@@ -29,6 +29,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
const util = { //{{{
Array: {
// [["a", "b"], ["c", "d"]] -> {a: "b", c: "d"}
// From Common Lisp, more or less
assocToObj: function (assoc)
{
let obj = {};
assoc.forEach(function ([k, v]) { obj[k] = v });
return obj;
},
// flatten an array: [["foo", "bar"], ["baz"]] -> ["foo", "bar", "baz"]
flatten: function (ary)
{
@@ -165,7 +174,7 @@ const util = { //{{{
{
if (delimiter == undefined)
delimiter = '"';
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n").replace("\t", "\\t") + delimiter;
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n", "g").replace("\t", "\\t", "g") + delimiter;
},
formatBytes: function (num, decimalPlaces, humanReadable)
@@ -254,6 +263,14 @@ const util = { //{{{
return ret;
},
map: function (obj, fn)
{
let ary = [];
for (let i in Iterator(obj))
ary.push(fn(i));
return ary;
},
// if color = true it uses HTML markup to color certain items
objectToString: function (object, color)
{