Gnu Emacs: send commands from other program? - emacs

Is it possible to send commands to Gnu Emacs from another program?
It would e.g. be nice if I could tell emacs go to a certain line in the current text document.

First, M-x server-start in Emacs (or put (server-start) in your init.el file).
Then you should be able to send Emacs commands with emacsclient - for example to go to line #10 in whatever buffer has focus:
emacsclient --eval "(with-current-buffer (window-buffer) (goto-line 10))"
(Thanks to comments below for pointing out errors! Always test 😅)

Related

Set up emacs server so that it dies when the last frame is closed

I have run into issues using the emacs server started when I log in and emacsclient. Specifically, I use the same emacs server for different R projects things get ugly and commands from different projects end up going to the same R session.
My work around is to invoke a second server with /usr/bin/emacs --daemon=Rmd-1 when I log in. I have a bash script written such that the first .Rmd file I work with attaches to this daemon and then the command /usr/bin/emacs --daemon=Rmd-2 is issued. If I end up working with a second .Rmd file, then this server is used and a third server is started with /usr/bin/emacs --daemon=Rmd-3 and ready to work with another .Rmd file if needed.
This works pretty well except for one thing. Because after many years I am hard wired to end my emacs session using C-x C-c by the end of the day I have many emacs servers running. I'm looking for a way to trigger save-buffers-kill-emacs when the C-x C-c command is given in an emacsclient running on a daemon matching "Rmd-[0-9]+". I can't see any emacsclient options that would do that and I'm at a loss as to how to edit my custom.el file.
Can some one help me?
(note I'm running GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.30) on Ubuntu 22.04)
Drawing on McNisse's suggestion, adding the following to my personal.el file seems to give me the desired behavior.
;; Remap C-c C-x if daemon name matches "Rmd-[0-9]+"
;;
(cond
((string-prefix-p "Rmd-" (daemonp))
(global-set-key (kbd "C-x C-c") 'save-buffers-kill-emacs)
)
)

Is there any way to transfer the content of an external editor in postgresql to query buffer without quitting the editor?

My environment:
OS: Linux CentOS 7 (x86_64)
PostgreSQL version: 10.5
Emacs 26.1
I use Emacs as the external editor in postgresql (set in my EDITOR environment variable). So whenever I type in psql shell, \e it opens Emacs where I can write/modify queries, views, functions, etc.
If I understand correctly, once Emacs is open, when I enter C-x C-s, that is, I save and then I quit C-x C-c, the content edited in Emacs is transferred to the query buffer to be parsed and executed (assuming it contains semicolon at the end). So basically each time I have to run \e then edit, then save and quit the editor to get the job done.
Now, given that I use Emacs for multiple programming languages, I've rather a big init file. As a result, it takes several seconds to start Emacs (both in -nw and GUI mode). Obviously this is quite annoying given the number of times that I have to open and quit the editor while I'm using \e in psql.
So my question is: Is there any way to let the external editor remain open and continue working with the same editor for further queries and somehow decide to transfer the result to query buffer without needing to quit the editor?
Run emacsclient instead of emacs. I have a script at ~/bin/editor:
#!/bin/sh
exec emacsclient -c -a '' "$#"
And then I set export EDITOR=$HOME/bin/editor in my ~/.bashrc.
The upshot is you only start Emacs once, and every time you run $EDITOR, it just attaches to the same Emacs session.
Also, I do
(global-set-key (kbd "C-x C-c") #'delete-frame)
(global-set-key (kbd "C-x C-S-c") #'save-buffers-kill-emacs)
so C-x C-c just deletes the frame instead of killing Emacs.
Just save the query to a temporary file, for example /tmp/q.sql and run \i /tmp/q.sql from psql multiple times from a second terminal.

How to invoke Emacs from an Erlang escript?

Inspired by Git as when you type "git commit", it opens an Emacs or Vim session for you. I'm writing an Erlang escript, and I want it to open an Emacs session at the end of the execution of the escript. I've tried
os:cmd("emacs -nw file.txt")
but it doesn't seem to work. Evaluating the above command within the Erlang shell yields
"emacs: standard input is not a tty\n"
One way to do this is to keep an Emacs running with server mode (put (server-mode) in your ~/.emacs), and call emacsclient instead of emacs from Erlang. That will open the file in the existing Emacs session. emacsclient exits and returns control to your Erlang program once you hit C-x # in Emacs.

Emacs compilation mode won't see bash alias

Emacs M-x compile does not see any aliases set in .bashrc. If I use M-x shell then type the alias, it is fine. I tried sourcing .bashrc from /etc/profile, from ~/.profile, ~/bash_env, anything I can think of to no avail.
I am on Emacs 23 and Ubuntu 11. I start emacs using /usr/bin/emacs %F, from a desktop button.
Emacs inherits its environment from the parent process. How are you invoking Emacs - from the command line, or some other way?
What happens if you:
M-x compile RET C-a C-k bash -i -c your_alias RET
Invoking bash as an interactive shell (-i option) should read your .bashrc aliases.
Edit: I think both M-x shell-command and M-x compile execute commands in an inferior shell via call-process. Try the following in your .emacs (or just evaluate):
(setq shell-file-name "bash")
(setq shell-command-switch "-ic")
I notice that after evaluation of the above, .bashrc aliases are picked up for use by both M-x shell-command and M-x compile, i.e
M-x compile RET your_alias RET
should then work.
My environment: Emacs 24.1 (pretest rc1), OSX 10.7.3
Keith Flower's answer works but can result in some slowdowns due to .bashrc being unnecessarily loaded in other places (presumably many many times, my computer is not exactly under-powered but emacs was almost unusable when trying to use autocomplete.el).
An alternative way is to locally modify shell-command-switch only for the functions where it is needed. This can be done using emacs' "advice" feature to create a wrapper around those functions. Here's an example that modifies compile:
;; Define + active modification to compile that locally sets
;; shell-command-switch to "-ic".
(defadvice compile (around use-bashrc activate)
"Load .bashrc in any calls to bash (e.g. so we can use aliases)"
(let ((shell-command-switch "-ic"))
ad-do-it))
You need to write similar "advice" for each function that you want to use .bashrc (e.g. I also needed to define the same advice for recompile), just copy the above and replace compile in the above with another function name.
You may like emac's bash-completion :
https://github.com/szermatt/emacs-bash-completion
You'll be able to use tab completion of your aliases in the compilation minibuffer and in shell-mode.
Enjoy !
(they speak about it here Bash autocompletion in Emacs shell-mode )
I think compilation commands are not interpreted through a shell: they are juste exec'ed by emacs (which means aliases, shell functions and other shell-specific things are not taken into account).
Try to wrap you compilation command into a shell-script which would source the correct environment.
You can do this either with a full-fledged shell-script in the form
#!/bin/bash
source "~/.bashrc"
my_command
or directly in emacs with a compilation command of the form
bash -c "source ~/.bashrc; my_command"
See Is there a way to get my emacs to recognize my bash aliases and custom functions when I run a shell command? for a fix which doesn't run all your .bashrc and doesn't create these error messages:
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell

I want to run the cygwin bash shell from native windows emacs app

I have followed instructions from How can I run Cygwin Bash Shell from within Emacs? this question and I have gone further and added the (setq explicit-bash-args '("--login" "-i")) command, however emacs continues to only display the dos prompt when I type M-x shell. In summery my .emacs file looks like this:
(defun cygwin-shell ()
"Run cygwin bash in shell mode."
(interactive)
(let ((explicit-shell-file-name "C:/cygwin/bin/bash"))
(call-interactively 'shell)))
(setq explicit-bash-args '("--login" "-i"))`
Please be gentle with the answers as I am right at the bottom of the famous vertical emacs learning curve!
If you implemented the answer from that question, note that you have to do M-x cygwin-shell to start bash. If you want to use it for every M-x shell you need to call
(setq explicit-shell-file-name "C:/cygwin/bin/bash")
Since you stated that you are learning, here's a few tips when trying this out.
type C-x C-f ~/.emacs to open your .emacs file in your user path.
Enter your function above at the end
M-x load-file [RET] .emacs: loads the buffer (no need to restart emacs)
C-h a: If you are interested in some specific action, you can look it up
C-h v [RET] variable: can inspect the variable, check the value of explicit-bash-args for instance
And, btw, I'm not sure what the "--login -i" does, but someone stated in a comment that you should have that so "ls" would work. If you have your cygwin bin path in your PATH environment variable, bash will find ls anyway. No need to escape the path variable either, this is handled by bash (do an echo $PATH in bash when you get it working and you'll see).