How to make Emacs run a program and don't wait for output/respond? I tried to open a pdf in an external program:
(shell-command (concat "start sumatrapdf " (shell-quote-argument path) " -page " search))))
But it won't open another files until the existing sumatrapdf process is closed. I tried async-shell-command, but it opens a new buffer with Async output which I don't need.
What is the right way to open files in external programs?
start-process function can handle that:
(start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)
Start a program in a subprocess. Return the process object for it.
NAME is name for process. It is modified if necessary to make it unique.
BUFFER is the buffer (or buffer name) to associate with the process.
Process output (both standard output and standard error streams) goes
at end of BUFFER, unless you specify an output stream or filter
function to handle the output. BUFFER may also be nil, meaning that
this process is not associated with any buffer.
PROGRAM is the program file name. It is searched for in `exec-path'
(which see). If nil, just associate a pty with the buffer. Remaining
arguments are strings to give program as arguments.
If you want to separate standard output from standard error, invoke
the command through a shell and redirect one of them using the shell
syntax.
If you don't want to associate bufer with open process — pass nil as BUFFER argument
See C-h k M-!
...
If COMMAND ends in ampersand, execute it asynchronously. The output
appears in the buffer `Async Shell Command'. That buffer is in shell
mode.
...
IOW, M-! my_command --opt=foo arg1 arg2 & will start my_command and create a *Async Shell Command* buffer with my_command running in it but emacs will give control back to you right away.
Related
I have an external command line program that I would like to invoke from elisp. This is easy enough with shell-command, but it doesn't work correctly when the command line program is interactive, which in my particular case it is: The invoked script sees EOF when it reads stdin when I call it like this:
;; upload command is a string with the name of
;; a python script and some args
(shell-command upload-command
(get-buffer-create "*upload output*")))))
The python script identified by upload-command may ask some yes/no questions and it may prompt for a password, for which I'd like masked input. Ideally, all of this interaction would occur within the minibuffer.
How can I arrange things so that my external interactive command interacts with the user via minibuffer when called via elisp?
The easiest way is to use either make-comint or make-comint-in-buffer:
(make-comint-in-buffer "upload-script-process" "*upload output*" upload-command)
This will runs the script in a buffer like a shell buffer, so it doesn't fulfill the requirement of having all interaction happen in the minibuffer. It will, however, automatically read passwords in masked form from the minibuffer, provided the password prompt matches comint-password-prompt-regexp.
Note that upload-command in this example here needs to be the name of an executable file on exec-path. Any extra switches or other arguments to the script have to be passed as string arguments to make-comint:
(make-comint-in-buffer "upload-script-process" "*upload output*"
upload-command nil "--verbose" "--other-option")
See the Emacs documentation for more details.
I have an Emacs command like following:
(defun query-lisp (word)
(interactive "sType a word to query:")
(message "%s" (query word)))
The query operation is a time-consuming operation. When this command is running Emacs blocks the whole frame. Is there a way to make Emacs run this command in the background or block only a single window such as the minibuffer?
If you plan to use an external process (which you have indicated in a comment to another question), you can use the following:
(start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)
This will return a process object. You can either send the output to a buffer, or you could attach a filter function to the process. In the latter case, this is a function that is called every time your process emits any output.
In addition, you could attach a sentinel function to your process. This function is called everytime the status of your process changes, this is useful to find out when it has exited.
There are several examples of the above in the source code of Emacs, one such example is compile.el.
Emacs doesn't have threads. For long operations you can split up the task into chunks and execute the chunks in idle timers, so emacs can respond to user input between the chunks.
The other possibility is running it as an external process from which emacs accepts the output.
For example, you can use something like this
(shell-command "sleep 10 && echo 'finished' &")
The result will be displayed in *Async Shell Command* buffer.
In windows shell it's possible to pause the output just by selecting a text in the shell window (a QuickEdit mode must be enabled). The same is possible in the cygwin shell (again with a QuickEdit mode).
How can I pause the output in emacs shell?
I need to pause it because some tasks are very verbose and it's difficult to search the necessary text in a big buffer.
When I execute M-x comint-stop-subjob I get a message "No SIGTSTP support"
As an example try to pause the following:
find . -type f -name "*.txt" -exec cat {} ';'
Not exactly what you asked for, but clone-buffer will get you close to what you want. After binding it to a convenient key and running your find command, calling clone-buffer will copy the contents of the buffer to a new buffer. The find command in the original buffer keeps running, but the cloned buffer contains only the output of find up to the point that you cloned it.
You can invoke this command multiple times in the original window, giving you a series of stop points to examine. I don't know how to actually pause the original window though.
Note that the newly cloned buffers are fully functional shell buffers.
You can stop the job by pressing C-c C-z. Then just enter fg to make it work again.
I don't know about pausing the output, but you can presumably just narrow the buffer?
C-xnn to narrow-to-region
C-xnn to narrow-to-page
C-xnw to widen to full buffer
I would like to write a small script in ELisp that would:
send a command to a given buffer
get its output
parse it
send it to another buffer
I am struggling with point 2: I cant get the output of a command. For example, if I have a shell buffer on, I can use
(process-send-string "shell" "help\n")
to send "help" to my shell buffer. It will then show the list of the commands available. But how can I get this list to use it somewhere else?
Thanks,
S4m
(buffer-string) returns the contents of the current buffer, so (with-current-buffer <buf> (buffer-string)) will return the contents of <buf>.
I don't know the exact emacs commands for this off the top of my head, but one option would be to do the following:
Set the mark in the shell buffer right below the command line
Execute the command.
Move the point to the end of the file and kill the text between there and the mark.
Move to the destination buffer and yank the text into there.
Have you considered using the shell-command or shell-command-to-string functions?
The don't "send a command to a buffer" like you asked, but they do both allow running a command through a process that will be started just for that purpose and either dumping the output into a target buffer or collecting it into a string.
I have a program that can send text to any other program for further analysis (eg sed, grep, etc). I would like it to send the data to Emacs and do analysis there. How would I do that? EmacsClient takes a filename by default, this is a data string not a file and I really don't want to create and delete files just to send data to Emacs.
EmacsClient has an "eval" command-line option that let's you execute lisp code instead of open files. Is there a simple lisp function that will open a new buffer with the given text?
Edit: I'm looking for something like:
emacsclientw.exe -eval (open-new-buffer 'hello world')
And a new buffer would automatically appear with the word "hello world". I'm not sure how the name of the buffer would be set. Hopefully something auto-numbered.
This does what you ask for:
emacsclient -e '(open-buffer-with "some\nstuff\nhere")'
(defun open-buffer-with (txt)
"create a new buffer, insert txt"
(pop-to-buffer (get-buffer-create (generate-new-buffer-name "something")))
(insert txt))
Obviously you can customize open-buffer-with to do what you want.
There's a similar question you might want to look at: How do I get basic App<->Emacs integration?.
How about this approach?
emacsclient -e '
(progn
(pop-to-buffer (generate-new-buffer "Piped"))
(insert (decode-hex-string "
'$(perl -e 'print unpack "H*", qq("Hello, World!")'
)'")))
'
I've inserted newlines to break up this very long line for display purposes.
When I run this from a terminal window, a new buffer named Piped opens in my Emacs window, containing the text "Hello, World!" (complete with quotes). When I run it again, another buffer named Piped<2> opens, with the same text.
The hex-escaping (which can probably be just as easily accomplished with any other high-level language, not just Perl) is for escaping quotes that would otherwise terminate the string constant being fed to (insert).
This approach feeds text to Emacs via Emacsclient on the command line, so very long input text might give it a problem. A more general solution might be able to break up long input data and feed it to Emacs across several Emacsclient invocations.