diff --git a/content/commands.js b/content/commands.js index 35ebeb41..9b5bc1e0 100644 --- a/content/commands.js +++ b/content/commands.js @@ -129,6 +129,7 @@ function Commands() //{{{ /////////////////////////////////////////////////////////////////////////////{{{ var ex_commands = []; + var last_run_command = ""; // updated whenever the users runs a command with :! function addDefaultCommand(command) { @@ -177,7 +178,6 @@ function Commands() //{{{ return null; } - // FIXME: doesn't really belong here... // return [null, null, null, null, heredoc_tag || false]; // [count, cmd, special, args] = match; @@ -1762,19 +1762,25 @@ function Commands() //{{{ addDefaultCommand(new Command(["!", "run"], function(args, special) { - // TODO: if special, run the last command + // :!! 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" + last_run_command); + last_run_command = args; + var output = vimperator.system(args) - if (typeof output === "string") + if (output) vimperator.echo(vimperator.util.escapeHTML(output)); - else - // FIXME: why are we accepting only a string return value from v.system()? -- djk - vimperator.echoerr("Invalid system command: " + args); }, { - usage: ["!{command}"], + usage: ["!{cmd}"], short_help: "Run a command", - help: "Runs {command} through system() and displays its output. " + - "Input redirection (< foo) not done, do not run commands which require stdin or it will hang Firefox!" + help: "Runs {cmd} through system() and displays its output. " + + "Any '!' in {cmd} is replaced with the previous external command. " + + "But not when there is a backslash before the '!', then that backslash is removed.
" + + "Input redirection (< foo) not done, also do not run commands which require stdin or it will hang Firefox!" } )); //}}} diff --git a/content/vimperator.js b/content/vimperator.js index f33931cb..4ee726fd 100644 --- a/content/vimperator.js +++ b/content/vimperator.js @@ -631,10 +631,15 @@ const vimperator = (function() //{{{ run: function(program, args, blocking) { + var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); const WINDOWS = navigator.platform == "Win32"; - var file = Components.classes["@mozilla.org/file/local;1"]. - createInstance(Components.interfaces.nsILocalFile); + if (!args) + args = []; + + if (typeof(blocking) != "boolean") + blocking = false; + try { file.initWithPath(program); @@ -654,14 +659,14 @@ const vimperator = (function() //{{{ catch (e) { } } } + if (!file.exists()) { vimperator.echoerr("command not found: " + program); return -1; } - var process = Components.classes["@mozilla.org/process/util;1"]. - createInstance(Components.interfaces.nsIProcess); + var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file); var ec = process.run(blocking, args, args.length); @@ -670,7 +675,6 @@ const vimperator = (function() //{{{ // when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is fixed // is fixed, should use that instead of a tmpfile - // TODO: pass "input" as stdin // TODO: add shell/shellcmdflag options to replace "sh" and "-c" system: function (str, input) { @@ -695,14 +699,15 @@ const vimperator = (function() //{{{ command += " < \"" + filein.path.replace('"', '\\"') + "\""; } + var res; if (WINDOWS) - this.run("cmd.exe", ["/C", command], true); + res = this.run("cmd.exe", ["/C", command], true); else - this.run("sh", ["-c", command], true); + res = this.run("sh", ["-c", command], true); var fd = vimperator.fopen(fileout, "<"); if (!fd) - return null; + return ""; var s = fd.read(); fd.close(); @@ -710,6 +715,10 @@ const vimperator = (function() //{{{ if (filein) filein.remove(false); + // if there is only one \n at the end, chop it off + if (s && s.indexOf("\n") == s.length-1) + s = s.substr(0, s.length-1); + return s; },