Emacsclient called by applescript can't find emacs server socket - emacs

The shell command
emacsclient -n -e '(make-remember-frame)'
works.
But the applescript
do shell script "emacsclient -n -e '(make-remember-frame)'"
just returns
emacsclient: can't find socket; have you started the server?
To start the server in Emacs, type \"M-x server-start\".
emacsclient: No socket or alternate editor. Please use:
--socket-name
--server-file (or environment variable EMACS_SERVER_FILE)
--alternate-editor (or environment variable ALTERNATE_EDITOR)

I rarely use this, but it has worked successfully in the past for various purposes. Perhaps you can modify it to suit your needs. The init.el or .emacs file must have (server-start) inside in order to make everything work. I have lots of stuff that loads when Emacs is activated for the first time, so I need a 5 second delay before emacsclient is called -- you can adjust the delay downward if your Emacs loads faster. If Emacs is already running, there is no need for a delay. You can comment out the verbal messages generated by say -- I used them this morning to test the conditions and make a minor adjustment to the script. The script contains a command-line example on line 4, which calls two Emacs functions. Of course, the path to your Emacs and emacsclient will need to be adjusted to wherever you have installed them on your computer.
# `(server-start)` must be inside `init.el` or `.emacs` file.
# This script can be used in the terimal: osascript path-to-script arguments
# Terminal Example:
# osascript /Users/HOME/.0.data/.0.emacs/.emacsclient.applescript "-e '(progn (dired \"/Applications\") (message \"Hello-World\!\"))'"
on run argv
set arg to item 1 of argv
set emacs to application "Emacs"
set appIsRunning to emacs is running
if appIsRunning then
say "Emacs is already running."
do shell script "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/bin/emacsclient " & arg
else
tell application "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/Emacs" to activate
say "Please wait five seconds for Emacs to load."
delay 5
do shell script "/Users/HOME/.0.data/.0.emacs/Emacs_06_01_2014.app/Contents/MacOS/bin/emacsclient " & arg
end if
end run

Related

emacs --daemon with --batch and input file

I would like to create a script that simply cleans up the whitespace and tabs on several files in a folder for me. I have created a bash file with among other things:
emacsclient -t -e '(progn (prelude-cleanup-buffer-or-region) (save-buffer-kill-terminal))' $FILE
Now this doesn't seem to work as it interprets ALL the file arguments as functions to be run (so $FILE is executed as a function). (P.S. prelude-cleanup-buffer-or-region is from here)
Now what I really want appears to be --batch described here (since I don't actually want to display anything on the screen) but this isn't one of the options of emacsclient. The reason I want to use emacsclient rather than just using emacs --batch is that I have a lot of startup files so want all of this to stay loaded otherwise my script would take too long.
Does anyone have any advice on how to go about this?
Thanks in advance.
emacsclient -e means evaluate lisp forms, do not edit files
from the man page
-e, --eval
do not visit files but instead evaluate the arguments as Emacs
Lisp expressions.
I guess you could add a (find-file "file") to your list of forms to execute
I just tried this snippet -
/opt/local/bin/emacsclient -e '(progn (find-file "./tmpfoo")
(end-of-buffer) (insert "ffff") (save-buffer))'
and it edits the file silently like you'd expect.
you could use shell globbing and a script to expand an argument filename into the list of forms.
do not run with the -t switch either, -e doesn't expect to have a persistent editor window, and you don't need the kill-terminal. The client will just run your elisp and exit.
I think I would probably write a lisp function that took a filename argument, that I loaded into emacs at startup time, and then just call that with a filename via emacsclient,
e.g. FILENAME="somefile"; emacsclient -e "(now-do-my-thing $FILENAME)"

Closing emacs in emacs

Occasionally when using emacs in term mode I will mistakenly run emacs file instead of just opening the file. This will create a nested emacs client inside the current client. My problem is how to close the inner client only?
Answer
You should be able to C-z out of it, then kill it with
kill %1
Explanation
C-z will suspend the current process, assigning it a job number and returning you to the shell.
The jobs command will show you the current jobs and their numbers. kill allows you to kill a process by its job number using the %n syntax.
Just use the command M-x kill-emacs inside the inner emacs. Backgrounding and killing it works fine but it is a little bit more hackish.
You should use the top Emacs. Starts emacs with:
emacs --daemon
Starts all frame with:
emacsclient -c
From your term:
emacsclient -n
Or you should use eshell instead.

Using emacsclient instead of emacs - translating arguments

I am at the moment using a separate instance for guns, which I start as follow:
emacs --name Mail --title Mail --no-desktop --no-splash --funcall gnus
As gnus is nicely responsive, and all my other emacs stuff is running as emacsclient from a different emacs instance, I would like to try to run gnus also from as emacsclient. But I am struggling to translate the commnd line options I use. I have to set the windos name and title, as I am using awesome windows manager and the window should be sortet according the window name. Also, I would like to start gnus automatically.
So how can I translate the above command, that gnus is started as emacsclient with the windows name and title set to Mail?
emacsclient ...???
You can also use the -F parameter that sets the frame alist and combine it with the -e parameter for executing what you like, so there's no need to define any function. The invocation would then look like this:
emacsclient -F '((name . "Mail"))' -e '(gnus)'
For information about the parameters, see (info "(elisp)Frame parameters").
I'm not sure you can do this using only command-line switches. However, it is possible to define an elisp function to set-up a gnus frame, and call this function from emacsclient.
Try putting this in your emacs initialization file:
(defun my/create-gnus-frame ()
"Create a new frame running `gnus'."
(select-frame
(make-frame '((name . "Mail"))))
(gnus))
and run gnus like this from the command-line:
emacsclient -e '(my/create-gnus-frame)'
And the X properties (as obtained with xprop) of the newly created frame seem to be correct:
WM_CLASS(STRING) = "Mail", "Emacs"
WM_ICON_NAME(STRING) = "Mail"
WM_NAME(STRING) = "Mail"

Automatically saving shell history in Emacs

Is there an easy way to automatically save every command I execute in shell-mode buffer? I'm running things like python and lua from Emacs' shell buffer and want to save those in addition to regular bash commands.
Default behavior saves history in in .history or .bash_history, but it does not save input to subprocesses. As an example, if I do the following
ls /export/hda3/tmp
python
a=2+3
import sys
sys.exit()
ls /export/hda3/tmp
the following gets saved
#1328903075
ls /export/hda3/tmp
#1328903081
python
#1328903087
ls /export/hda3/tmp
Commands are saved automatically, only you need to make sure to actually exit the shell. If you simply kill the shell buffer then no commands will be saved.
I added a check to emacs exit to warn me if I have an open shell buffer, so that I can exit it manually:
(defun my-check-if-no-shell-buffer-exists ()
(if (not (get-buffer "*shell*"))
t
(message "you have a shell buffer, make sure you exit it manually")
nil))
(add-hook 'kill-emacs-query-functions 'my-check-if-no-shell-buffer-exists)
It would even be better if the shell buffer would do it automatically when killing the buffer. I think it's a bug in emacs that it fails to do that.
Edit: I noticed I have a setting which prevented running process warnings when emacs exits and that's why I needed the above function. If you get a warning about a running shell already when exiting, then you don't need it, you only need to exit the shell manually to save history.

How can I make emacsclient just open a window for an existing emacs daemon without opening a new file

I use an emacs daemon to preserve my emacs session even if I have to reboot the machine that I run my X server on or if I want to access the same session from a different machine. This works very well but when restoring a session I'd quite like to just run "emacsclient --create-frame --no-wait" to connect to the daemon without opening a new file. It won't let me get away without specifying a filename.
I've tried using --eval to execute a function rather than open a file but the window just goes away when the evaluation is complete.
(Emacs 23.1 via backports on Debian GNU/Linux 5.0.)
From the help provided by emacsclient, you have a few options. First, is the one mentioned already which is emacsclient -c. That will try to create a frame associated with the emacs daemon. The advantage to this is that if DISPLAY is not set, then it will open emacs in the terminal.
Which brings us to the next best option (especially if you are logging in remotely): emacsclient -t which forces emacs to open up in terminal mode even if DISPLAY is set.
Also keep in mind that you can set the display from the command-line as well. I use this often when logging in remotely from VNC. The full command would be emacsclient -d DISPLAY -c
emacsclient -c works for me.
emacsclient -n -e "(make-frame)"
The -n flag means that the emacsclient doesn't wait, and the emacs instance doesn't destroy the frame.
If you are using emacs from the command line, you might also want to consider emacsclient -t