From 03ed0502c8614df008018aef91cbce0c3b9f99f3 Mon Sep 17 00:00:00 2001 From: Doug Kearns Date: Mon, 20 Oct 2008 14:38:22 +0000 Subject: [PATCH] add shell command completion for :! --- NEWS | 1 + content/completion.js | 30 +++++++++++++++++++++++++++++- content/io.js | 13 ++++++++----- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 6b7a0b83..bb6c843b 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ special versions for the old behavior * IMPORTANT: renamed Startup and Quit autocmd events to VimperatorEnter and VimperatorLeave respectively + * add shell command completion for :! * add :map to prevent a mapping from being echoed * add guioptions=nN to number tabs * add :loadplugins command diff --git a/content/completion.js b/content/completion.js index f44fc856..3d91ab91 100644 --- a/content/completion.js +++ b/content/completion.js @@ -886,7 +886,7 @@ function Completion() //{{{ var command = commands.get(cmd); if (command && command.completer) { - matches = str.match(/^:*\d*\w+[\s!]\s*/); + matches = str.match(/^:*\d*(?:\w+[\s!]|!)\s*/); exLength = matches ? matches[0].length : 0; [start, completions] = command.completer.call(this, args, special); } @@ -1073,6 +1073,34 @@ function Completion() //{{{ return [0, completions]; }, + shellCommand: function shellCommand(filter) + { + let generate = function () + { + const environmentService = Components.classes["@mozilla.org/process/environment;1"] + .getService(Components.interfaces.nsIEnvironment); + + let dirNames = environmentService.get("PATH").split(RegExp(WINDOWS ? ";" : ":")); + let commands = []; + + for (let [,dirName] in Iterator(dirNames)) + { + let dir = io.getFile(dirName); + if (dir.exists() && dir.isDirectory()) + { + io.readDirectory(dir).forEach(function (file) { + if (file.isFile() && file.isExecutable()) + commands.push([file.leafName, dir.path]); + }); + } + } + + return commands; + } + + return [0, this.cached("shell-command", filter, generate, "filter")]; + }, + sidebar: function sidebar(filter) { let menu = document.getElementById("viewSidebarMenu"); diff --git a/content/io.js b/content/io.js index 45e6b0a6..7c90c4af 100644 --- a/content/io.js +++ b/content/io.js @@ -363,18 +363,21 @@ function IO() //{{{ if (special) args = "!" + (args || ""); - // TODO: better escaping of ! to also substitute \\! correctly - args = args.replace(/(^|[^\\])!/g, "$1" + lastRunCommand); + // TODO: Hmmm, actually Vim doesn't handle multiple backslashes and documents it - desirable? + args = args.replace(/((?:^|[^\\])(?:\\\\)*)!/g, function(m, n) n != null ? n + lastRunCommand : m) lastRunCommand = args; - var output = io.system(args); - var command = ":" + util.escapeHTML(commandline.getCommand()) + "
"; + let output = io.system(args); + let command = ":" + util.escapeHTML(commandline.getCommand()) + "
"; liberator.echo(command + util.escapeHTML(output)); autocommands.trigger("ShellCmdPost", {}); }, - { bang: true }); + { + bang: true, + completer: function (filter) completion.shellCommand(filter) + }); /////////////////////////////////////////////////////////////////////////////}}} ////////////////////// PUBLIC SECTION //////////////////////////////////////////