mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 13:52:26 +01:00
Generally niftier :mkv
This commit is contained in:
@@ -857,7 +857,16 @@ function Buffer() //{{{
|
|||||||
bang: true,
|
bang: true,
|
||||||
hereDoc: true,
|
hereDoc: true,
|
||||||
literal: 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]"],
|
commands.add(["dels[tyle]"],
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ function Command(specs, description, action, extraInfo) //{{{
|
|||||||
this.bang = extraInfo.bang || false;
|
this.bang = extraInfo.bang || false;
|
||||||
this.count = extraInfo.count || false;
|
this.count = extraInfo.count || false;
|
||||||
this.literal = extraInfo.literal || false;
|
this.literal = extraInfo.literal || false;
|
||||||
|
this.serial = extraInfo.serial;
|
||||||
|
|
||||||
this.isUserCommand = extraInfo.isUserCommand || false;
|
this.isUserCommand = extraInfo.isUserCommand || false;
|
||||||
this.replacementText = extraInfo.replacementText || null;
|
this.replacementText = extraInfo.replacementText || null;
|
||||||
@@ -166,23 +167,13 @@ function Commands() //{{{
|
|||||||
function getMatchingUserCommands(name, filter)
|
function getMatchingUserCommands(name, filter)
|
||||||
{
|
{
|
||||||
var matches = [];
|
var matches = [];
|
||||||
outer:
|
|
||||||
for (let [,cmd] in Iterator(exCommands))
|
for (let [,cmd] in Iterator(exCommands))
|
||||||
{
|
{
|
||||||
if (cmd.isUserCommand)
|
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))
|
|
||||||
matches.push(cmd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
if (util.map(filter, function (f) f).every(function ([k, v]) v == null || cmd[k] == v))
|
||||||
matches.push(cmd);
|
matches.push(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,6 +190,17 @@ function Commands() //{{{
|
|||||||
return NaN;
|
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 ArgType = new Struct("description", "parse");
|
||||||
const argTypes = [
|
const argTypes = [
|
||||||
null,
|
null,
|
||||||
@@ -291,6 +293,26 @@ function Commands() //{{{
|
|||||||
return true;
|
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)
|
get: function (name)
|
||||||
{
|
{
|
||||||
for (let i = 0; i < exCommands.length; i++)
|
for (let i = 0; i < exCommands.length; i++)
|
||||||
@@ -350,20 +372,6 @@ function Commands() //{{{
|
|||||||
// TODO: should it handle comments?
|
// TODO: should it handle comments?
|
||||||
parseArgs: function (str, options, argCount, allowUnknownOptions, literal, complete)
|
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]
|
// returns [count, parsed_argument]
|
||||||
function getNextArg(str)
|
function getNextArg(str)
|
||||||
{
|
{
|
||||||
@@ -546,8 +554,8 @@ function Commands() //{{{
|
|||||||
let compl = opt[3] || [];
|
let compl = opt[3] || [];
|
||||||
if (typeof compl == "function")
|
if (typeof compl == "function")
|
||||||
compl = compl();
|
compl = compl();
|
||||||
let filter = quoteArg(sub[optname.length + 1])
|
let quote = quoteArg[sub[optname.length + 1]] || quoteArg[""];
|
||||||
return [i + optname.length + 1, completion.filter(compl.map(filter), filter(arg))];
|
return [i + optname.length + 1, completion.filter(compl.map(quote), quote(arg))];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!invalid)
|
if (!invalid)
|
||||||
@@ -668,6 +676,8 @@ function Commands() //{{{
|
|||||||
return matches;
|
return matches;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get quoteArg() quoteArg,
|
||||||
|
|
||||||
removeUserCommand: function (name)
|
removeUserCommand: function (name)
|
||||||
{
|
{
|
||||||
for (let i = 0; i < exCommands.length; i++)
|
for (let i = 0; i < exCommands.length; i++)
|
||||||
@@ -690,7 +700,7 @@ function Commands() //{{{
|
|||||||
if (res == undefined) // Ignore anything undefined
|
if (res == undefined) // Ignore anything undefined
|
||||||
res = "<" + token + ">";
|
res = "<" + token + ">";
|
||||||
if (quote && typeof res != "number")
|
if (quote && typeof res != "number")
|
||||||
return '"' + String.replace(res, '"', '\\"', "g") + '"';
|
return quoteArg['"'](res);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -782,6 +792,20 @@ function Commands() //{{{
|
|||||||
[["-nargs"], commandManager.OPTION_STRING, function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
|
[["-nargs"], commandManager.OPTION_STRING, function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
|
||||||
[["-bang"], commandManager.OPTION_NOARG],
|
[["-bang"], commandManager.OPTION_NOARG],
|
||||||
[["-count"], 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)
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,15 @@ function Editor() //{{{
|
|||||||
{ flags: Mappings.flags.MOTION | Mappings.flags.COUNT });
|
{ 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
|
// mode = "i" -> add :iabbrev, :iabclear and :iunabbrev commands
|
||||||
function addAbbreviationCommands(ch, modeDescription)
|
function addAbbreviationCommands(ch, modeDescription)
|
||||||
{
|
{
|
||||||
@@ -157,20 +166,25 @@ function Editor() //{{{
|
|||||||
"Abbreviate a key sequence" + modeDescription,
|
"Abbreviate a key sequence" + modeDescription,
|
||||||
function (args)
|
function (args)
|
||||||
{
|
{
|
||||||
args = args.string;
|
let lhs = args.arguments[0];
|
||||||
|
let rhs = args.literalArg;
|
||||||
if (!args)
|
|
||||||
{
|
|
||||||
editor.listAbbreviations(mode, "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var matches = args.match(/^(\S+)(?:\s+(.+))?$/);
|
|
||||||
var [lhs, rhs] = [matches[1], matches[2]];
|
|
||||||
if (rhs)
|
if (rhs)
|
||||||
editor.addAbbreviation(mode, lhs, rhs);
|
editor.addAbbreviation(mode, lhs, rhs);
|
||||||
else
|
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]"],
|
commands.add([ch ? ch + "una[bbrev]" : "una[bbreviate]"],
|
||||||
@@ -892,21 +906,6 @@ function Editor() //{{{
|
|||||||
|
|
||||||
// Abbreviations {{{
|
// 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)
|
// filter is i, c or "!" (insert or command abbreviations or both)
|
||||||
listAbbreviations: function (filter, lhs)
|
listAbbreviations: function (filter, lhs)
|
||||||
{
|
{
|
||||||
@@ -914,10 +913,11 @@ function Editor() //{{{
|
|||||||
{
|
{
|
||||||
if (abbrev[lhs])
|
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)
|
if (abbr[0] == filter)
|
||||||
liberator.echo(abbrev[lhs][i][0] + " " + lhs + " " + abbrev[lhs][i][1]);
|
liberator.echo(abbr[0] + " " + lhs + " " + abbr[1]);
|
||||||
|
// Is it me, or is this clearly very wrong? --Kris
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -932,14 +932,13 @@ function Editor() //{{{
|
|||||||
let list =
|
let list =
|
||||||
<table>
|
<table>
|
||||||
{
|
{
|
||||||
template.map(abbrev, function ([lhs, rhs])
|
template.map(abbrevs(), function ([lhs, rhs])
|
||||||
template.map(rhs, function (abbr)
|
searchFilter.indexOf(rhs[0]) < 0 ? undefined :
|
||||||
searchFilter.indexOf(abbr[0]) < 0 ? undefined :
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{abbr[0]}</td>
|
<td>{rhs[0]}</td>
|
||||||
<td>{lhs}</td>
|
<td>{lhs}</td>
|
||||||
<td>{abbr[1]}</td>
|
<td>{rhs[1]}</td>
|
||||||
</tr>))
|
</tr>)
|
||||||
}
|
}
|
||||||
</table>;
|
</table>;
|
||||||
if (list.*.length())
|
if (list.*.length())
|
||||||
|
|||||||
@@ -228,50 +228,31 @@ function IO() //{{{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let line = "\" " + liberator.version + "\n";
|
let lines = [['"' + liberator.version]];
|
||||||
line += "\" Mappings\n";
|
|
||||||
|
|
||||||
[[[modes.NORMAL], ""],
|
// FIXME: Use a set/specifiable list here:
|
||||||
[[modes.COMMAND_LINE], "c"],
|
for (let cmd in commands)
|
||||||
[[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)
|
|
||||||
{
|
{
|
||||||
// TODO: options should be queried for this info
|
if (cmd.serial)
|
||||||
// TODO: string/list options might need escaping in future
|
lines.push(cmd.serial().map(commands.commandToString));
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
lines = util.Array.flatten(lines);
|
||||||
|
|
||||||
// :mkvimrc doesn't save autocommands, so we don't either - remove this code at some point
|
// :mkvimrc doesn't save autocommands, so we don't either - remove this code at some point
|
||||||
// line += "\n\" Auto-Commands\n";
|
// line += "\n\" Auto-Commands\n";
|
||||||
// for (let item in autocommands)
|
// for (let item in autocommands)
|
||||||
// line += "autocmd " + item.event + " " + item.pattern.source + " " + item.command + "\n";
|
// 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() != "\\")
|
// if (mappings.getMapLeader() != "\\")
|
||||||
// line += "\nlet mapleader = \"" + mappings.getMapLeader() + "\"\n";
|
// line += "\nlet mapleader = \"" + mappings.getMapLeader() + "\"\n";
|
||||||
|
|
||||||
// source a user .vimperatorrc file
|
// source a user .vimperatorrc file
|
||||||
line += "\nsource! " + filename + ".local\n";
|
lines.push("\nsource! " + filename + ".local");
|
||||||
line += "\n\" vim: set ft=vimperator:";
|
lines.push("\n\" vim: set ft=vimperator:");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
io.writeFile(file, line);
|
io.writeFile(file, lines.join("\n"));
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -132,30 +132,10 @@ function Mappings() //{{{
|
|||||||
|
|
||||||
function mappingsIterator(modes, stack)
|
function mappingsIterator(modes, stack)
|
||||||
{
|
{
|
||||||
var output;
|
modes = modes.slice();
|
||||||
var maps = stack[modes[0]];
|
return (map for ([i, map] in Iterator(stack[modes.shift()]))
|
||||||
|
if (modes.every(function (mode) stack[mode].some(
|
||||||
for (let i = 0; i < maps.length; i++)
|
function (m) m.rhs == map.rhs && m.names[0] == map.names[0]))))
|
||||||
{
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMapCommands(ch, modes, modeDescription)
|
function addMapCommands(ch, modes, modeDescription)
|
||||||
@@ -203,7 +183,20 @@ function Mappings() //{{{
|
|||||||
[["<silent>", "<Silent>"], commands.OPTION_NOARG]
|
[["<silent>", "<Silent>"], commands.OPTION_NOARG]
|
||||||
],
|
],
|
||||||
argCount: 1,
|
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"],
|
commands.add([ch ? ch + "m[ap]" : "map"],
|
||||||
|
|||||||
@@ -799,7 +799,16 @@ function Options() //{{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [len, completion.filter(completions, filter, true)];
|
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]"],
|
commands.add(["unl[et]"],
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const template = {
|
|||||||
// Vim generally doesn't like /foo*/, because */ looks like a comment terminator.
|
// Vim generally doesn't like /foo*/, because */ looks like a comment terminator.
|
||||||
// Using /foo*(:?)/ instead.
|
// Using /foo*(:?)/ instead.
|
||||||
if (processStrings)
|
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}</>;
|
return <>{arg}</>;
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return <span class="hl-Null">{arg}</span>;
|
return <span class="hl-Null">{arg}</span>;
|
||||||
|
|||||||
@@ -29,6 +29,15 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
|||||||
const util = { //{{{
|
const util = { //{{{
|
||||||
|
|
||||||
Array: {
|
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 an array: [["foo", "bar"], ["baz"]] -> ["foo", "bar", "baz"]
|
||||||
flatten: function (ary)
|
flatten: function (ary)
|
||||||
{
|
{
|
||||||
@@ -165,7 +174,7 @@ const util = { //{{{
|
|||||||
{
|
{
|
||||||
if (delimiter == undefined)
|
if (delimiter == undefined)
|
||||||
delimiter = '"';
|
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)
|
formatBytes: function (num, decimalPlaces, humanReadable)
|
||||||
@@ -254,6 +263,14 @@ const util = { //{{{
|
|||||||
return ret;
|
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
|
// if color = true it uses HTML markup to color certain items
|
||||||
objectToString: function (object, color)
|
objectToString: function (object, color)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user