mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2026-01-27 20:35:47 +01:00
Add :list* commands, linkify help tags in certain output, and augment :yank to accept JavaScript directly.
This commit is contained in:
@@ -940,14 +940,18 @@ const CommandLine = Module("commandline", {
|
||||
dactyl.open(event.target.href, where);
|
||||
}
|
||||
|
||||
let command = event.originalTarget.getAttributeNS(NS.uri, "command");
|
||||
if (command && dactyl.commands[command]) {
|
||||
return dactyl.withSavedValues(["forceNewTab"], function () {
|
||||
dactyl.forceNewTab = event.ctrlKey || event.shiftKey || event.button == 1;
|
||||
dactyl.commands[command](event);
|
||||
});
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case "<LeftMouse>":
|
||||
event.preventDefault();
|
||||
let command = event.originalTarget.getAttributeNS(NS.uri, "command");
|
||||
if (command && dactyl.commands[command])
|
||||
return dactyl.commands[command](event);
|
||||
else
|
||||
openLink(dactyl.CURRENT_TAB);
|
||||
openLink(dactyl.CURRENT_TAB);
|
||||
return false;
|
||||
case "<MiddleMouse>":
|
||||
case "<C-LeftMouse>":
|
||||
@@ -1708,7 +1712,7 @@ const CommandLine = Module("commandline", {
|
||||
{ validator: function (value) value >= 1 });
|
||||
|
||||
options.add(["messages", "msgs"],
|
||||
"Number of messages to store in the :message history",
|
||||
"Number of messages to store in the :messages history",
|
||||
"number", 100,
|
||||
{ validator: function (value) value >= 0 });
|
||||
|
||||
|
||||
@@ -1395,6 +1395,15 @@ const Commands = Module("commands", {
|
||||
completer: function (context) completion.userCommand(context)
|
||||
});
|
||||
|
||||
dactyl.addUsageCommand({
|
||||
name: ["listc[ommands]", "lc"],
|
||||
description: "List all Ex commands along with their short descriptions",
|
||||
iterate: function (args) commands,
|
||||
format: {
|
||||
description: function (cmd) template.linkifyHelp(cmd.description + (cmd.replacementText ? ": " + cmd.action : ""))
|
||||
}
|
||||
});
|
||||
|
||||
function checkStack(cmd) {
|
||||
util.assert(io.sourcing && io.sourcing.stack &&
|
||||
io.sourcing.stack[cmd] && io.sourcing.stack[cmd].length,
|
||||
@@ -1454,13 +1463,14 @@ const Commands = Module("commands", {
|
||||
commands.add(["y[ank]"],
|
||||
"Yanks the output of the given command to the clipboard",
|
||||
function (args) {
|
||||
let res = commandline.withOutputToString(commands.execute, commands, args[0]);
|
||||
let cmd = /^:/.test(args[0]) ? args[0] : ":echo " + args[0];
|
||||
let res = commandline.withOutputToString(commands.execute, commands, cmd);
|
||||
dactyl.clipboardWrite(res);
|
||||
let lines = res.split("\n").length;
|
||||
dactyl.echomsg("Yanked " + lines + " line" + (lines == 1 ? "" : "s"));
|
||||
},
|
||||
{
|
||||
completer: function (context) completion.ex(context),
|
||||
completer: function (context) completion[/^:/.test(context.filter) ? "ex" : "javascript"](context),
|
||||
literal: 0
|
||||
});
|
||||
},
|
||||
|
||||
@@ -48,6 +48,10 @@ const Dactyl = Module("dactyl", {
|
||||
this.commands = {};
|
||||
this.modules = modules;
|
||||
this.observers = {};
|
||||
|
||||
this.commands["dactyl.help"] = function (event) {
|
||||
dactyl.help(event.originalTarget.textContent);
|
||||
};
|
||||
},
|
||||
|
||||
/** @property {string} The name of the current user profile. */
|
||||
@@ -139,6 +143,35 @@ const Dactyl = Module("dactyl", {
|
||||
});
|
||||
},
|
||||
|
||||
addUsageCommand: function (params) {
|
||||
commands.add(params.name, params.description,
|
||||
function (args) {
|
||||
let results = array(params.iterate(args))
|
||||
.sort(function (a, b) String.localeCompare(a.name, b.name));
|
||||
if (args.length)
|
||||
results = results.filter(function (item) args.map(String.toLowerCase)
|
||||
.every(function (arg) (item.name + item.description).toLowerCase().indexOf(arg) >= 0));
|
||||
commandline.commandOutput(
|
||||
template.usage(results, params.format));
|
||||
},
|
||||
{
|
||||
argCount: "*",
|
||||
completer: function (context, args) {
|
||||
context.keys.text = util.identity;
|
||||
context.keys.description = function () seen[this.text] + " matching items";
|
||||
let seen = {};
|
||||
context.completions = array(item.description.toLowerCase().split(/[()\s]+/)
|
||||
for (item in params.iterate(args)))
|
||||
.flatten().filter(function (w) /^\w[\w-_']+$/.test(w))
|
||||
.map(function (k) {
|
||||
seen[k] = (seen[k] || 0) + 1;
|
||||
return k;
|
||||
}).uniq()
|
||||
},
|
||||
options: params.options || []
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the application bell to notify the user of an error. The
|
||||
* bell may be either audible or visual depending on the value of the
|
||||
@@ -257,8 +290,7 @@ const Dactyl = Module("dactyl", {
|
||||
if (typeof str == "object" && "echoerr" in str)
|
||||
str = str.echoerr;
|
||||
else if (isinstance(str, ["Error"]))
|
||||
str = str.fileName.replace(/^.*? -> /, "")
|
||||
+ ":" + str.lineNumber + ": " + str;
|
||||
str = <>{str.fileName.replace(/^.*? -> /, "")}: {str.lineNumber}: {str}</>;
|
||||
|
||||
if (options["errorbells"])
|
||||
dactyl.beep();
|
||||
@@ -1044,7 +1076,7 @@ const Dactyl = Module("dactyl", {
|
||||
reportError: function reportError(error, echo) {
|
||||
if (error instanceof FailedAssertion || error.message === "Interrupted") {
|
||||
if (error.message)
|
||||
dactyl.echoerr(error.message);
|
||||
dactyl.echoerr(template.linkifyHelp(error.message));
|
||||
else
|
||||
dactyl.beep();
|
||||
return;
|
||||
@@ -1935,7 +1967,6 @@ const Dactyl = Module("dactyl", {
|
||||
argCount: "0",
|
||||
bang: true
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
completion: function () {
|
||||
|
||||
@@ -185,16 +185,17 @@ const Mappings = Module("mappings", {
|
||||
some(function (m) m.rhs && m.rhs === map.rhs && m.name === map.name))))
|
||||
},
|
||||
|
||||
// NOTE: just normal mode for now
|
||||
/** @property {Iterator(Map)} @private */
|
||||
__iterator__: function () {
|
||||
let mode = modes.NORMAL;
|
||||
iterate: function (mode) {
|
||||
let seen = {};
|
||||
for (let map in iterAll(values(this._user[mode]), values(this._main[mode])))
|
||||
if (!set.add(seen, map.name))
|
||||
yield map;
|
||||
},
|
||||
|
||||
// NOTE: just normal mode for now
|
||||
/** @property {Iterator(Map)} */
|
||||
__iterator__: function () this.iterate(modes.NORMAL),
|
||||
|
||||
// used by :mkpentadactylrc to save mappings
|
||||
/**
|
||||
* Returns a user-defined mappings iterator for the specified *mode*.
|
||||
@@ -381,19 +382,6 @@ const Mappings = Module("mappings", {
|
||||
}
|
||||
}
|
||||
|
||||
function findMode(name) {
|
||||
for (let mode in modes.mainModes)
|
||||
if (name == mode || name == mode.char || String.toLowerCase(name).replace(/-/g, "_") == mode.name.toLowerCase())
|
||||
return mode.mask;
|
||||
return null;
|
||||
}
|
||||
function uniqueModes(modes) {
|
||||
modes = modes.map(modules.modes.closure.getMode);
|
||||
let chars = [k for ([k, v] in Iterator(modules.modes.modeChars))
|
||||
if (v.every(function (mode) modes.indexOf(mode) >= 0))];
|
||||
return array.uniq(modes.filter(function (m) chars.indexOf(m.char) < 0).concat(chars));
|
||||
}
|
||||
|
||||
const opts = {
|
||||
completer: function (context, args) {
|
||||
if (args.length == 1)
|
||||
@@ -511,8 +499,66 @@ const Mappings = Module("mappings", {
|
||||
});
|
||||
}
|
||||
|
||||
function findMode(name) {
|
||||
for (let mode in modes.mainModes)
|
||||
if (name == mode || name == mode.char || String.toLowerCase(name).replace(/-/g, "_") == mode.name.toLowerCase())
|
||||
return mode.mask;
|
||||
return null;
|
||||
}
|
||||
function uniqueModes(modes) {
|
||||
modes = modes.map(modules.modes.closure.getMode);
|
||||
let chars = [k for ([k, v] in Iterator(modules.modes.modeChars))
|
||||
if (v.every(function (mode) modes.indexOf(mode) >= 0))];
|
||||
return array.uniq(modes.filter(function (m) chars.indexOf(m.char) < 0).concat(chars));
|
||||
}
|
||||
|
||||
addMapCommands("", [modes.NORMAL, modes.VISUAL], "");
|
||||
|
||||
let args = {
|
||||
getMode: function (args) findMode(args["-mode"]),
|
||||
iterate: function (args) {
|
||||
for (let map in mappings.iterate(this.getMode(args)))
|
||||
for (let name in values(map.names))
|
||||
yield { name: name, __proto__: map };
|
||||
},
|
||||
format: {
|
||||
description: function (map) (XML.ignoreWhitespace = false, XML.prettyPrinting = false, <>
|
||||
{options.get("passkeys").has(map.name)
|
||||
? <span highlight="URLExtra">(passed by {template.helpLink("'passkeys'")})</span>
|
||||
: <></>}
|
||||
{template.linkifyHelp(map.description + (map.rhs ? ": " + map.rhs : ""))}
|
||||
</>)
|
||||
}
|
||||
}
|
||||
|
||||
dactyl.addUsageCommand({
|
||||
__proto__: args,
|
||||
name: ["listk[eys]", "lk"],
|
||||
description: "List all mappings along with their short descriptions",
|
||||
options: [
|
||||
{
|
||||
names: ["-mode", "-m"],
|
||||
type: CommandOption.STRING,
|
||||
description: "The mode for which to list mappings",
|
||||
default: "n",
|
||||
completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.disp]
|
||||
for (mode in modes.mainModes)],
|
||||
validator: function (m) findMode(m)
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
forEach(modes.mainModes, function (mode) {
|
||||
if (mode.char && !commands.get(mode.char + "listkeys", true))
|
||||
dactyl.addUsageCommand({
|
||||
__proto__: args,
|
||||
name: [mode.char + "listk[eys]", mode.char + "lk"],
|
||||
description: "List all " + mode.name + " mode mappings along with their short descriptions",
|
||||
getMode: function (args) mode,
|
||||
options: []
|
||||
});
|
||||
});
|
||||
|
||||
for (let mode in modes.mainModes)
|
||||
if (mode.char && !commands.get(mode.char + "map", true))
|
||||
addMapCommands(mode.char,
|
||||
|
||||
@@ -817,6 +817,36 @@ const Options = Module("options", {
|
||||
}, {
|
||||
}, {
|
||||
commands: function () {
|
||||
let args = {
|
||||
getMode: function (args) findMode(args["-mode"]),
|
||||
iterate: function (args) {
|
||||
for (let map in mappings.iterate(this.getMode(args)))
|
||||
for (let name in values(map.names))
|
||||
yield { name: name, __proto__: map };
|
||||
},
|
||||
format: {
|
||||
description: function (map) (XML.ignoreWhitespace = false, XML.prettyPrinting = false, <>
|
||||
{options.get("passkeys").has(map.name)
|
||||
? <span highlight="URLExtra">(passed by {template.helpLink("'passkeys'")})</span>
|
||||
: <></>}
|
||||
{template.linkifyHelp(map.description)}
|
||||
</>)
|
||||
}
|
||||
}
|
||||
|
||||
dactyl.addUsageCommand({
|
||||
name: ["listo[ptions]", "lo"],
|
||||
description: "List all options along with their short descriptions",
|
||||
iterate: function (args) options,
|
||||
format: {
|
||||
description: function (opt) (XML.ignoreWhitespace = false, XML.prettyPrinting = false, <>
|
||||
{opt.scope == Option.SCOPE_LOCAL
|
||||
? <span highlight="URLExtra">(buffer local)</span> : ""}
|
||||
{template.linkifyHelp(opt.description)}
|
||||
</>)
|
||||
}
|
||||
});
|
||||
|
||||
function setAction(args, modifiers) {
|
||||
let bang = args.bang;
|
||||
if (!args.length)
|
||||
|
||||
Reference in New Issue
Block a user