You can start background processes with start-process, which shouldn't pop up a buffer:
(start-process "process-name" "buffer-name" "program")
Process names are modified to avoid duplication as necessary, so don't worry about that. Just give it a name useful for debugging in the future!
If you give a "buffer-name", a buffer will be created but not shown ...
Remove the corresponding function from the relevant variable :
(setq kill-buffer-query-functions (delq 'process-kill-buffer-query-function kill-buffer-query-functions))
How did I find this ?
kill-this-buffer uses kill-buffer internally, which references the variable kill-buffer-query-functions.
In addition to the other answers, the original poster may wish to consider using the built-in profiling feature: https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html
To begin profiling, type M-x profiler-start. You can choose to profile by processor usage, memory usage, or both. After doing some work, type M-x profiler-report to display ...
Like Tikhon mentioned, (start-process) is the way to go. In case you don't want to create a buffer but would still like to react to the background process status, you can also employ (set-process-sentinel). Here's a modified example I'm taking from my projector package:
(set-process-sentinel (start-process "process-name" nil "command") #'output-message-...
The question was asked in 2016. Now in 2019, there exists M-x proced:
Mode for displaying system processes and sending signals to them.
Proced makes an Emacs buffer containing a listing of the current system processes. You can use the normal Emacs commands to move around in this buffer, and special Proced commands to operate on the processes listed....
As I understand it, this is a non-issue. Emacs is single-threaded, and only processes output from subprocesses when idle. Therefore, there is no time between calling start-file-process and set-process-filter when process output could arrive without being handled.
The info page (elisp) Accepting Output states:
Output from asynchronous subprocesses ...
A live object is one that you can reach by following pointers from other live objects. Functions and variables are live because they are reachable from the global list of definitions. Setting a definition to nil means that it no longer points to the value it once did, potentially creating garbage. The GC will collect that garbage in fairly short order. As ...
You may want to check list-processes:
list-processes is an interactive compiled Lisp function in
(list-processes &optional QUERY-ONLY BUFFER)
Display a list of all processes that are Emacs sub-processes.
If optional argument QUERY-ONLY is non-nil, only processes with
the query-on-exit flag set are listed.
Any process ...
Although it is not clearly documented in its man page, emacsclient doesn't seem to accept a full command (i.e. program + arguments) as the alternate editor, only a program.
You could write a small shell script:
exec emacs -q -nw "$@"
and use it as the alternate editor:
export EDITOR='emacsclient -a PATH_TO_YOUR_SCRIPT'
default-directory has to be a directory, not the filename of a directory. In other words it has to end with a slash. In some places it does not matter whether a directory path ends with a slash or not, here it does.
(let ((default-directory "/some/directory/"))
What about writing a "safe" version of shell-command that would properly escape arguments using shell-quote-argument ?
(defun safe-shell-command (args &optional output-buffer error-buffer)
(apply 'shell-command (mapconcat 'shell-quote-argument args " ")
output-buffer error-buffer nil))
(the same would easily apply to async-...
Running eval "$(direnv hook $0)" defines a function that hooks into $PROMPT_COMMAND, which is never called when bash is run as bash -ic because there is no prompt. You can change the line:
eval "$(direnv hook $0)"
eval "$(direnv hook $0)" && _direnv_hook
to explicitly call the hook function.
Edit: Just realized rekado gave a very similar ...
This doesn't seem to be a problem with Emacs but with bash. shell-command just executes call-process on the shell and passes arguments. I tried this on a regular shell:
bash -ic "cd ~/code/foo && echo $PATH"
~/.bashrc is sourced, but the direnv hook is not run. When direnv hook bash is executed, a function _direnv_hook is output and prepended to ...
I like htop and so I also use it in emacs. However the interactive part doesn't work this way.
(defun htop ()
(if (get-buffer "*htop*")
(ansi-term "/bin/bash" "htop")
(comint-send-string "*htop*" "htop\n")))
For two processes A and B mutually killing each other you can use the following approach:
Start the first process just with start-process and remember its process (as lisp object).
Start the second process B with async-start-process and kill A in its finish-func.
Define a process sentinel for A which kills B at exit of A.
The classic method is to use buffer-local variables in the buffer associated with the process.
(defvar faustine-process-source-buffer nil
"Source buffer from which the current process is generating mdoc.")
(defun faustine-mdoc (&optional build-all)
"Generate mdoc of the current file, display ...
Here's a simple function that gets the pid of the process running in the current buffer and then calls the pstree command to get the process tree of that process:
(defun iproc ()
(let ((pid (process-id (get-buffer-process (current-buffer)))))
(shell-command (format "pstree -p %d" pid))))
If I have a *shell* buffer running bash, run ...
Thanks to Rekado and Erik for pointing out how the direnv hook works by using $PROMPT_COMMAND. Since shell-command doesn't use a prompt, this wasn't getting executed.
While Erik's answer works in my example of calling a shell command with M-! with default-directory set, it wouldn't work in the following example:
(let ((default-directory "~/code/"))
You can achieve this by just adding a GNU timeout invocation to your shell command, which circumvents needing to know any details about Emacs behavior. For example running:
$ timeout 5 sleep 10
Will return in 5 seconds, not 10 (timeout effectively presses Ctrl-C for you).
While call-process is running, emacs will processing events, with-timeout will not work without this:
The timeout is checked whenever Emacs waits for some kind of external
event (such as keyboard input, input from subprocesses, or a certain
time); if the program loops without waiting in any way, the timeout
will not be detected.
You can still use ...
What you are looking for is called comint-mode - the system which underlies most (all?) emacs interaction modes (lisp, scheme, shell, python, &c).
Here are some starting points:
Comint: Writing your own Command Interpreter
The functionality used by comint mode is start-process, so I think you might like to start with that. You send data to the process with process-send-string, and the process's output is "automatically" read by Emacs and passed to the process filter, which is a function you provide via set-process-filter.
The main difficulty is that you don't get to choose ...
Something in this spirit should do the trick. I tried it with espeak under Ubuntu; I guess it would work with say as well.
(defun my-read-words-on-region ()
"Send the region to `espeak'."
(start-process "espeak-process" "espeak-buffer" "espeak" "-v" "en-us")
(process-send-region "espeak-process" (region-beginning) (region-end)))
setenv-internal and setenv change the list stored in process-environment (as local or special variable) by side-effects.
It does not help if you assign the list (pointer) to a local variable process-environment. You still have only a single list for the process-environment which is just bound to two variables -- the global variable process-environment and ...
If your ~/dotfiles/rundo.sh accepts stdin as input, like many other commands
such as grep/wc/bash/python, to run a command with the region as stdin, simply
run M-| ~/dotfiles/rundo.sh (M-| runs shell-command-on-region).
If the command doesn't support stdin, the following should do what you described
(defun rundo (beg end)
"Wrapper of ~/dotfiles/rundo.sh."...
You can suppress display in the minibuffer by setting minibuffer-message-timeout to 0.
For example, I use something like this in a few places where I want to toggle a minor mode while in a minibuffer prompt (like ido find-file) without being interrupted by a 'mode enabled' message:
(let ((minibuffer-message-timeout 0))
I know this is an emacs forum, but maybe the simplest thing to do is to write a simple shell script that filters stderr. For example in file nostderr.sh:
And then run that in your start-process.