#pragma section-numbers on <> Conkeror has the ability to launch, and even interact with, external programs. {{{#!wiki caution To call external programs from Conkeror, in most cases, you will need to have ConkerorSpawnHelper set up. }}} = Spawn Functions = The high level api to launch shell commands consists of four functions, well, actually two functions and two coroutines. They all accept the two keyword arguments `$cwd` and `$fds`, which we will get back to. The ones named with the word "blind" are non-blocking. That is, they launch the process and don't wait for it to return. == shell_command == Coroutine shell command launcher, waits for process to finish, and yields its exit status. One positional argument, "command", is a full command line. Must be properly shell-escaped. == shell_command_with_argument == Variant of shell_command which takes a second position parameter, "arg", which will be substituted into the command wherever there is a "{}". == shell_command_blind == Normal function shell command launcher. Launches command and returns without waiting for process to complete. One positional argument, command line to run. If neither of the keyword arguments $cwd or $fds is given, then the call is made without using conkeror-spawn-helper. == shell_command_with_argument_blind == Variant of shell_command_blind which takes a second positional parameter, "arg", which will be substituted into the command wherever there is a "{}". = Keyword Arguments = == $cwd == $cwd is an nsIFile giving the working directory for the shell command. == $fds == $fds is structure giving file descriptor readers and writers. This is the tricky bit. The fds structure is an object whose keys are the numbered file descriptors. FD 0 will be attached to the program's stdin, FD 1 to its stdout, and FD 2 to its stderr. In the typical case $fds will be an array of two or three elements. What those elements are, we will come to presently. Each element of $fds is a javascript object that contains one or both of the properties `input` and `output`. If you are sending something ''to'' the program, that's an output. If you're reading something ''from'' the program, that's an input. The values of these `input` and `output` properties are readers and writers, respectively. So let's have some pseudocode of what we know so far: {{{ $fds = [{output: a_writer_for_the_programs_stdin}, {input: a_reader_for_the_programs_stdout}, {input: a_reader_for_the_programs_stderr}] }}} You can have more numbered FDs if needed, even bidirectional ones with both input and output. But let's keep this simple. = Examples = == Generate and Display an Image == In this example, we use the !ImageMagick program `convert` to generate a picture of a rose, which we display in a new buffer. Output of `convert` is processed directly, with no temp files involved. {{{ interactive("rose", "Show the ImageMagick rose in a new buffer. "+ "Requires ImageMagick convert.", function (I) { var data = "", error = ""; var result = yield shell_command( "convert rose: png:", $fds = [{ output: async_binary_string_writer("") }, { input: async_binary_reader(function (s) data+=s||"") }, { input: async_binary_reader(function (s) error+=s||"") }]); if (result != 0 || error != "") throw new interactive_error("status "+result+", "+error); var uri = "data:image/png;base64,"+btoa(data); browser_object_follow(I.buffer, OPEN_NEW_BUFFER, load_spec({ uri: uri })); }); }}}