2 require("interactive.js");
4 const WINDOWS = (get_os() == "WINNT");
5 const POSIX = !WINDOWS;
6 const PATH = getenv("PATH").split(POSIX ? ":" : ";");
7 const path_component_regexp = POSIX ? /^[^/]+$/ : /^[^/\\]+$/;
9 function get_file_in_path(name) {
10 var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
11 if (!path_component_regexp.test(name)) {
14 file.initWithPath(name);
21 for (var i = 0; i < PATH.length; ++i) {
23 file.initWithPath(PATH[i]);
24 file.appendRelativePath(name);
33 function spawn_process_sync(program, args, blocking) {
34 var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
35 var file = get_file_in_path(program);
37 throw new Error("invalid executable: " + program);
39 return process.run(!!blocking, args, args.length);
42 function spawn_process(program, args) {
43 var result = yield in_new_thread(spawn_process_sync, program, args, true);
44 yield co_return(result);
47 function shell_command_sync(cwd, cmd, blocking) {
49 var full_cmd = "cd \"" + shell_quote(cwd) + "\"; " + cmd;
50 return spawn_process_sync(getenv("SHELL") || "/bin/sh",
56 if (cwd.match(/[a-z]:/i)) {
57 full_cmd += cwd.substring(0,2) + " && ";
59 full_cmd += "cd \"" + shell_quote(cwd) + "\" && " + cmd;
61 /* Need to convert the single command-line into a list of
62 * arguments that will then get converted back into a
63 * command-line by Mozilla. */
67 for (var i = 0; i < full_cmd.length; ++i) {
84 if (cur_arg.length > 0)
86 return spawn_process_sync("cmd.exe", out, blocking);
90 function shell_command(cwd, cmd) {
91 var result = yield in_new_thread(shell_command_sync, cwd, cmd, true);
92 yield co_return(result);
95 var PATH_programs = null;
96 function get_shell_command_completer() {
97 if (PATH_programs == null) {
99 var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
100 for (var i = 0; i < PATH.length; ++i) {
102 file.initWithPath(PATH[i]);
103 var entries = file.directoryEntries;
104 while (entries.hasMoreElements()) {
105 var entry = entries.getNext().QueryInterface(Ci.nsIFile);
106 PATH_programs.push(entry.leafName);
110 PATH_programs.sort();
113 return prefix_completer($completions = PATH_programs,
114 $get_string = function (x) { return x; });
118 minibuffer_auto_complete_preferences["shell-command"] = null;
120 /* FIXME: support a relative or full path as well as PATH commands */
121 define_keywords("$cwd");
122 minibuffer.prototype.read_shell_command = function () {
123 keywords(arguments, $history = "shell-command");
124 var prompt = arguments.$prompt || "Shell command [" + arguments.$cwd + "]:";
125 var result = yield this.read(
127 $history = "shell-command",
128 $auto_complete = "shell-command",
130 $validator = function (x, m) {
131 var s = x.replace(/^\s+|\s+$/g, '');
133 m.message("A blank shell command is not allowed.");
138 forward_keywords(arguments),
139 $completer = get_shell_command_completer());
140 yield co_return(result);
143 function shell_command_with_argument_sync(cwd, cmdline, argument, blocking) {
144 if (!cmdline.match("{}")) {
145 cmdline = cmdline + " \"" + shell_quote(argument) + "\"";
147 cmdline = cmdline.replace("{}", "\"" + shell_quote(argument) + "\"");
149 return shell_command_sync(cwd, cmdline, blocking);
152 function shell_command_with_argument(cwd, cmdline, argument) {
153 var result = yield in_new_thread(shell_command_with_argument_sync, cwd, cmdline, argument, true);
154 yield co_return(result);