mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 05:57:58 +01:00
made :dialogs generic, moved more commands to vim.js
This commit is contained in:
@@ -588,7 +588,6 @@ vimperator.Commands = function () //{{{
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
@@ -596,198 +595,7 @@ vimperator.Commands = function () //{{{
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
// move to vim.js:
|
||||
commandManager.addUserCommand(new vimperator.Command(["addo[ns]"],
|
||||
function () { vimperator.open("chrome://mozapps/content/extensions/extensions.xul", vimperator.NEW_TAB); },
|
||||
{
|
||||
shortHelp: "Show available Browser Extensions and Themes"
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["beep"],
|
||||
function () { vimperator.beep(); },
|
||||
{
|
||||
shortHelp: "Play a system beep"
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["dia[log]"],
|
||||
function (args, special)
|
||||
{
|
||||
function viewPartialSource()
|
||||
{
|
||||
// copied (and tuned somebit) from browser.jar -> nsContextMenu.js
|
||||
var focusedWindow = document.commandDispatcher.focusedWindow;
|
||||
if (focusedWindow == window)
|
||||
focusedWindow = content;
|
||||
|
||||
var docCharset = null;
|
||||
if (focusedWindow)
|
||||
docCharset = "charset=" + focusedWindow.document.characterSet;
|
||||
|
||||
var reference = null;
|
||||
reference = focusedWindow.getSelection();
|
||||
|
||||
var docUrl = null;
|
||||
window.openDialog("chrome://global/content/viewPartialSource.xul",
|
||||
"_blank", "scrollbars,resizable,chrome,dialog=no",
|
||||
docUrl, docCharset, reference, "selection");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (args)
|
||||
{
|
||||
case "about": openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); break;
|
||||
case "addbookmark": PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksRootId); break;
|
||||
case "addons": BrowserOpenAddonsMgr(); break;
|
||||
case "bookmarks": openDialog("chrome://browser/content/bookmarks/bookmarksPanel.xul", "Bookmarks", "dialog,centerscreen,width=600,height=600"); break;
|
||||
case "checkupdates": checkForUpdates(); break;
|
||||
case "cleardata": Cc[GLUE_CID].getService(Ci.nsIBrowserGlue).sanitize(window || null); break;
|
||||
case "console": toJavaScriptConsole(); break;
|
||||
case "customizetoolbar": BrowserCustomizeToolbar(); break;
|
||||
case "dominspector": inspectDOMDocument(content.document); break;
|
||||
case "downloads": toOpenWindowByType('Download:Manager', 'chrome://mozapps/content/downloads/downloads.xul', 'chrome,dialog=no,resizable'); break;
|
||||
case "history": openDialog("chrome://browser/content/history/history-panel.xul", "History", "dialog,centerscreen,width=600,height=600"); break;
|
||||
case "import": BrowserImport(); break;
|
||||
case "openfile": BrowserOpenFileWindow(); break;
|
||||
case "pageinfo": BrowserPageInfo(); break;
|
||||
case "pagesource": BrowserViewSourceOfDocument(content.document); break;
|
||||
case "places": PlacesCommandHook.showPlacesOrganizer(ORGANIZER_ROOT_BOOKMARKS); break;
|
||||
case "preferences": openPreferences(); break;
|
||||
case "printpreview": PrintUtils.printPreview(onEnterPrintPreview, onExitPrintPreview); break;
|
||||
case "print": PrintUtils.print(); break;
|
||||
case "printsetup": PrintUtils.showPageSetup(); break;
|
||||
case "saveframe": saveFrameDocument(); break;
|
||||
case "savepage": saveDocument(window.content.document); break;
|
||||
case "searchengines": openDialog("chrome://browser/content/search/engineManager.xul", "_blank", "chrome,dialog,modal,centerscreen"); break;
|
||||
case "selectionsource": viewPartialSource(); break;
|
||||
case "": vimperator.echoerr("E474: Invalid argument"); break;
|
||||
default: vimperator.echoerr("Dialog '" + args + "' not available");
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
vimperator.echoerr("Error opening '" + args + "': " + e);
|
||||
}
|
||||
},
|
||||
{
|
||||
shortHelp: "Open a Firefox dialog",
|
||||
completer: function (filter) { return vimperator.completion.dialog(filter); }
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["exe[cute]"],
|
||||
function (args)
|
||||
{
|
||||
vimperator.execute(args);
|
||||
},
|
||||
{
|
||||
shortHelp: "Execute the string that results from the evaluation of {expr1} as an Ex command."
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["exu[sage]"],
|
||||
function (args, special, count, modifiers)
|
||||
{
|
||||
var usage = "<table>";
|
||||
for (let command in vimperator.commands)
|
||||
{
|
||||
usage += "<tr><td style='color: magenta; padding-right: 20px'> :" +
|
||||
vimperator.util.escapeHTML(command.name) + "</td><td>" +
|
||||
vimperator.util.escapeHTML(command.shortHelp) + "</td></tr>";
|
||||
}
|
||||
usage += "</table>";
|
||||
|
||||
vimperator.echo(usage, vimperator.commandline.FORCE_MULTILINE);
|
||||
},
|
||||
{
|
||||
shortHelp: "Show help for Ex commands"
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["h[elp]"],
|
||||
function (args, special, count, modifiers)
|
||||
{
|
||||
function jumpToTag(file, tag)
|
||||
{
|
||||
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/" + file);
|
||||
setTimeout(function() {
|
||||
var elem = vimperator.buffer.getElement('@class="tag" and text()="' + tag + '"');
|
||||
if (elem)
|
||||
window.content.scrollTo(0, elem.getBoundingClientRect().top - 10); // 10px context
|
||||
else
|
||||
dump('no element: ' + '@class="tag" and text()="' + tag + '"\n' );
|
||||
}, 200);
|
||||
}
|
||||
|
||||
if (!args)
|
||||
{
|
||||
vimperator.open("chrome://" + vimperator.config.name.toLowerCase() + "/locale/intro.html");
|
||||
return;
|
||||
}
|
||||
|
||||
var [, items] = vimperator.completion.help(args);
|
||||
var partialMatch = -1;
|
||||
for (var i = 0; i < items.length; i++)
|
||||
{
|
||||
if (items[i][0] == args)
|
||||
{
|
||||
jumpToTag(items[i][1], items[i][0]);
|
||||
return;
|
||||
}
|
||||
else if (partialMatch == -1 && items[i][0].indexOf(args) > -1)
|
||||
{
|
||||
partialMatch = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (partialMatch > -1)
|
||||
jumpToTag(items[partialMatch][1], items[partialMatch][0]);
|
||||
else
|
||||
vimperator.echoerr("E149: Sorry, no help for " + args);
|
||||
},
|
||||
{
|
||||
shortHelp: "Display help",
|
||||
completer: function (filter) { return vimperator.completion.help(filter); }
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["javas[cript]", "js"],
|
||||
function (args, special)
|
||||
{
|
||||
if (special) // open javascript console
|
||||
vimperator.open("chrome://global/content/console.xul", vimperator.NEW_TAB);
|
||||
else
|
||||
{
|
||||
// check for a heredoc
|
||||
var matches = args.match(/(.*)<<\s*([^\s]+)$/);
|
||||
if (matches && matches[2])
|
||||
{
|
||||
vimperator.commandline.inputMultiline(new RegExp("^" + matches[2] + "$", "m"),
|
||||
function (code)
|
||||
{
|
||||
try
|
||||
{
|
||||
eval(matches[1] + "\n" + code);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
vimperator.echoerr(e.name + ": " + e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
else // single line javascript code
|
||||
{
|
||||
try
|
||||
{
|
||||
eval("with(vimperator){" + args + "}");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
vimperator.echoerr(e.name + ": " + e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
shortHelp: "Run any JavaScript command through eval()",
|
||||
completer: function (filter) { return vimperator.completion.javascript(filter); }
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["let"],
|
||||
function (args)
|
||||
{
|
||||
@@ -1041,133 +849,6 @@ vimperator.Commands = function () //{{{
|
||||
));
|
||||
|
||||
// move to io.js:
|
||||
commandManager.addUserCommand(new vimperator.Command(["cd", "chd[ir]"],
|
||||
function (args)
|
||||
{
|
||||
if (!args)
|
||||
args = "~";
|
||||
|
||||
if (vimperator.io.setCurrentDirectory(args))
|
||||
vimperator.echo(vimperator.io.getCurrentDirectory());
|
||||
},
|
||||
{
|
||||
shortHelp: "Change the current directory",
|
||||
completer: function (filter) { return vimperator.completion.file(filter, true); }
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["pw[d]"],
|
||||
function (args)
|
||||
{
|
||||
if (args)
|
||||
vimperator.echoerr("E488: Trailing characters");
|
||||
else
|
||||
vimperator.echo(vimperator.io.getCurrentDirectory());
|
||||
},
|
||||
{
|
||||
shortHelp: "Print the current directory name"
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["mkv[imperatorrc]"],
|
||||
function (args, special)
|
||||
{
|
||||
// TODO: "E172: Only one file name allowed"
|
||||
var filename;
|
||||
if (args)
|
||||
filename = args;
|
||||
else
|
||||
filename = (navigator.platform == "Win32") ? "~/_vimperatorrc" : "~/.vimperatorrc";
|
||||
|
||||
var file = vimperator.io.getFile(filename);
|
||||
if (file.exists() && !special)
|
||||
{
|
||||
vimperator.echoerr("E189: \".vimperatorrc\" exists (add ! to override)");
|
||||
return;
|
||||
}
|
||||
|
||||
var line = "\" " + vimperator.version + "\n";
|
||||
line += "\" Mappings\n";
|
||||
|
||||
var mode = [[[vimperator.modes.NORMAL], ""], [[vimperator.modes.COMMAND_LINE], "c"],
|
||||
[[vimperator.modes.INSERT, vimperator.modes.TEXTAREA], "i"]];
|
||||
for (var y = 0; y < mode.length; y++)
|
||||
{
|
||||
// NOTE: names.length is always 1 on user maps. If that changes, also fix getUserIterator and v.m.list
|
||||
for (var map in vimperator.mappings.getUserIterator(mode[y][0]))
|
||||
line += mode[y][1] + (map.noremap ? "nore" : "") + "map " + map.names[0] + " " + map.rhs + "\n";
|
||||
}
|
||||
|
||||
line += "\n\" Options\n";
|
||||
for (var option in vimperator.options)
|
||||
{
|
||||
// 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";
|
||||
}
|
||||
}
|
||||
|
||||
// :mkvimrc doesn't save autocommands, so we don't either - remove this code at some point
|
||||
// line += "\n\" Auto-Commands\n";
|
||||
// for (var item in vimperator.autocommands)
|
||||
// line += "autocmd " + item + "\n";
|
||||
|
||||
line += "\n\" Abbreviations\n";
|
||||
for (var abbrCmd in vimperator.editor.abbreviations)
|
||||
line += abbrCmd;
|
||||
|
||||
// if (vimperator.events.getMapLeader() != "\\")
|
||||
// line += "\nlet mapleader = \"" + vimperator.events.getMapLeader() + "\"\n";
|
||||
|
||||
// source a user .vimperatorrc file
|
||||
line += "\nsource! " + filename + ".local\n";
|
||||
line += "\n\" vim: set ft=vimperator:";
|
||||
|
||||
vimperator.io.writeFile(file, line);
|
||||
},
|
||||
{
|
||||
shortHelp: "Write current key mappings and changed options to [file]"
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["so[urce]"],
|
||||
function (args, special)
|
||||
{
|
||||
// FIXME: implement proper filename quoting
|
||||
//if (/[^\\]\s/.test(args))
|
||||
//{
|
||||
// vimperator.echoerr("E172: Only one file name allowed");
|
||||
// return;
|
||||
//}
|
||||
|
||||
vimperator.io.source(args, special);
|
||||
},
|
||||
{
|
||||
shortHelp: "Read Ex commands from {file}",
|
||||
completer: function (filter) { return vimperator.completion.file(filter, true); }
|
||||
}
|
||||
));
|
||||
commandManager.addUserCommand(new vimperator.Command(["!", "run"],
|
||||
function (args, special)
|
||||
{
|
||||
// :!! needs to be treated specially as the command parser sets the special flag but removes the ! from args
|
||||
if (special)
|
||||
args = "!" + (args || "");
|
||||
|
||||
// TODO: better escaping of ! to also substitute \\! correctly
|
||||
args = args.replace(/(^|[^\\])!/g, "$1" + lastRunCommand);
|
||||
lastRunCommand = args;
|
||||
|
||||
var output = vimperator.io.system(args);
|
||||
if (output)
|
||||
vimperator.echo(vimperator.util.escapeHTML(output));
|
||||
},
|
||||
{
|
||||
shortHelp: "Run a command"
|
||||
}
|
||||
));
|
||||
|
||||
// TODO: move where? (commands.js would be fine, but timing issue)
|
||||
commandManager.addUserCommand(new vimperator.Command(["com[mand]"],
|
||||
@@ -1615,293 +1296,12 @@ vimperator.Commands = function () //{{{
|
||||
{ shortHelp: "Close preview window on bottom of screen" }
|
||||
));
|
||||
|
||||
// move where?
|
||||
commandManager.addUserCommand(new vimperator.Command(["pref[erences]", "prefs"],
|
||||
function (args, special, count, modifiers)
|
||||
{
|
||||
if (!args)
|
||||
{
|
||||
// TODO: copy these snippets to more function which should work with :tab xxx
|
||||
if (modifiers && modifiers.inTab)
|
||||
{
|
||||
vimperator.open(special ? "about:config" :
|
||||
"chrome://browser/content/preferences/preferences.xul", vimperator.NEW_TAB);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (special) // open firefox settings gui dialog
|
||||
vimperator.open("about:config", vimperator.CURRENT_TAB);
|
||||
else
|
||||
openPreferences();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vimperator.echoerr("E488: Trailing characters");
|
||||
}
|
||||
},
|
||||
{
|
||||
shortHelp: "Show Browser Preferences"
|
||||
}
|
||||
));
|
||||
|
||||
// move to tabs.js
|
||||
commandManager.addUserCommand(new vimperator.Command(["reloada[ll]"],
|
||||
function (args, special) { vimperator.tabs.reloadAll(special); },
|
||||
{ shortHelp: "Reload all pages" }
|
||||
));
|
||||
|
||||
// move where?
|
||||
commandManager.addUserCommand(new vimperator.Command(["se[t]"],
|
||||
// TODO: support setting multiple options at once
|
||||
function (args, special, count, modifiers)
|
||||
{
|
||||
if (special)
|
||||
{
|
||||
var onlyNonDefault = false;
|
||||
if (!args)
|
||||
{
|
||||
args = "all";
|
||||
onlyNonDefault = true;
|
||||
}
|
||||
// 1 2 3 4 5
|
||||
var matches = args.match(/^\s*?([a-zA-Z0-9\.\-_{}]+)([?&!])?\s*(([+-^]?)=(.*))?\s*$/);
|
||||
var name = matches[1];
|
||||
var reset = false;
|
||||
var invertBoolean = false;
|
||||
|
||||
if (matches[2] == "&")
|
||||
reset = true;
|
||||
else if (matches[2] == "!")
|
||||
invertBoolean = true;
|
||||
|
||||
if (name == "all" && reset)
|
||||
vimperator.echoerr("You can't reset all the firefox options, it could make your browser unusable.");
|
||||
else if (name == "all")
|
||||
vimperator.options.listPrefs(onlyNonDefault, "");
|
||||
else if (reset)
|
||||
vimperator.options.resetPref(name);
|
||||
else if (invertBoolean)
|
||||
vimperator.options.invertPref(name);
|
||||
else if (matches[3])
|
||||
{
|
||||
var value = matches[5];
|
||||
switch (value)
|
||||
{
|
||||
case undefined:
|
||||
value = "";
|
||||
break;
|
||||
case "true":
|
||||
value = true;
|
||||
break;
|
||||
case "false":
|
||||
value = false;
|
||||
break;
|
||||
default:
|
||||
var valueInt = parseInt(value, 10);
|
||||
if (!isNaN(valueInt))
|
||||
value = valueInt;
|
||||
}
|
||||
vimperator.options.setPref(name, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
vimperator.options.listPrefs(onlyNonDefault, name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var onlyNonDefault = false; // used for :set to print non-default options
|
||||
if (!args)
|
||||
{
|
||||
args = "all";
|
||||
onlyNonDefault = true;
|
||||
}
|
||||
|
||||
// 1 2 3 4 5 6
|
||||
var matches = args.match(/^\s*(no|inv)?([a-z]+)([?&!])?\s*(([+-^]?)=(.*))?\s*$/);
|
||||
if (!matches)
|
||||
{
|
||||
vimperator.echoerr("E518: Unknown option: " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
var unsetBoolean = false;
|
||||
if (matches[1] == "no")
|
||||
unsetBoolean = true;
|
||||
|
||||
var name = matches[2];
|
||||
var all = false;
|
||||
if (name == "all")
|
||||
all = true;
|
||||
|
||||
var option = vimperator.options.get(name);
|
||||
if (!option && !all)
|
||||
{
|
||||
vimperator.echoerr("E518: Unknown option: " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
var valueGiven = !!matches[4];
|
||||
|
||||
var get = false;
|
||||
if (all || matches[3] == "?" || (option.type != "boolean" && !valueGiven))
|
||||
get = true;
|
||||
|
||||
var reset = false;
|
||||
if (matches[3] == "&")
|
||||
reset = true;
|
||||
|
||||
var invertBoolean = false;
|
||||
if (matches[1] == "inv" || matches[3] == "!")
|
||||
invertBoolean = true;
|
||||
|
||||
var operator = matches[5];
|
||||
|
||||
var value = matches[6];
|
||||
if (value === undefined)
|
||||
value = "";
|
||||
|
||||
// reset a variable to its default value
|
||||
if (reset)
|
||||
{
|
||||
if (all)
|
||||
{
|
||||
for (let option in vimperator.options)
|
||||
option.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
option.reset();
|
||||
}
|
||||
}
|
||||
// read access
|
||||
else if (get)
|
||||
{
|
||||
if (all)
|
||||
{
|
||||
vimperator.options.list(onlyNonDefault);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (option.type == "boolean")
|
||||
vimperator.echo((option.value ? " " : "no") + option.name);
|
||||
else
|
||||
vimperator.echo(" " + option.name + "=" + option.value);
|
||||
}
|
||||
}
|
||||
// write access
|
||||
// NOTE: the behaviour is generally Vim compatible but could be
|
||||
// improved. i.e. Vim's behaviour is pretty sloppy to no real
|
||||
// benefit
|
||||
else
|
||||
{
|
||||
var currentValue = option.value;
|
||||
var newValue;
|
||||
|
||||
switch (option.type)
|
||||
{
|
||||
case "boolean":
|
||||
if (valueGiven)
|
||||
{
|
||||
vimperator.echoerr("E474: Invalid argument: " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (invertBoolean)
|
||||
newValue = !option.value;
|
||||
else
|
||||
newValue = !unsetBoolean;
|
||||
|
||||
break;
|
||||
|
||||
case "number":
|
||||
value = parseInt(value);
|
||||
|
||||
if (isNaN(value))
|
||||
{
|
||||
vimperator.echoerr("E521: Number required after =: " + args);
|
||||
return;
|
||||
}
|
||||
|
||||
if (operator == "+")
|
||||
newValue = currentValue + value;
|
||||
else if (operator == "-")
|
||||
newValue = currentValue - value;
|
||||
else if (operator == "^")
|
||||
newValue = currentValue * value;
|
||||
else
|
||||
newValue = value;
|
||||
|
||||
break;
|
||||
|
||||
case "charlist":
|
||||
if (operator == "+")
|
||||
newValue = currentValue.replace(new RegExp("[" + value + "]", "g"), "") + value;
|
||||
else if (operator == "-")
|
||||
newValue = currentValue.replace(value, "");
|
||||
else if (operator == "^")
|
||||
// NOTE: Vim doesn't prepend if there's a match in the current value
|
||||
newValue = value + currentValue.replace(new RegExp("[" + value + "]", "g"), "");
|
||||
else
|
||||
newValue = value;
|
||||
|
||||
break;
|
||||
|
||||
case "stringlist":
|
||||
if (operator == "+")
|
||||
{
|
||||
if (!currentValue.match(value))
|
||||
newValue = (currentValue ? currentValue + "," : "") + value;
|
||||
else
|
||||
newValue = currentValue;
|
||||
}
|
||||
else if (operator == "-")
|
||||
{
|
||||
newValue = currentValue.replace(new RegExp("^" + value + ",?|," + value), "");
|
||||
}
|
||||
else if (operator == "^")
|
||||
{
|
||||
if (!currentValue.match(value))
|
||||
newValue = value + (currentValue ? "," : "") + currentValue;
|
||||
else
|
||||
newValue = currentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
newValue = value;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "string":
|
||||
if (operator == "+")
|
||||
newValue = currentValue + value;
|
||||
else if (operator == "-")
|
||||
newValue = currentValue.replace(value, "");
|
||||
else if (operator == "^")
|
||||
newValue = value + currentValue;
|
||||
else
|
||||
newValue = value;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
vimperator.echoerr("E685: Internal error: option type `" + option.type + "' not supported");
|
||||
}
|
||||
|
||||
if (option.isValidValue(newValue))
|
||||
option.value = newValue;
|
||||
else
|
||||
// FIXME: need to be able to specify more specific errors
|
||||
vimperator.echoerr("E474: Invalid argument: " + args);
|
||||
}
|
||||
},
|
||||
{
|
||||
shortHelp: "Set an option",
|
||||
completer: function (filter, special) { return vimperator.completion.option(filter, special); }
|
||||
}
|
||||
));
|
||||
// TODO: check for v.has("windows")
|
||||
commandManager.addUserCommand(new vimperator.Command(["winc[lose]", "wc[lose]"],
|
||||
function (args) { window.close(); },
|
||||
|
||||
Reference in New Issue
Block a user