When emacs is not already running, emacsclient always starts as a console application, but I'd like it to start as a gui application.
This is the command I use:
emacsclient -a "" file
The -a "" is there to start an emacs instance, if none is running already.
What about specifying -a /usr/bin/emacs or whatever your emacs is?
To create a new Emacs frame:
emacsclient -c -a "" file
The advantage of -a "" compared to #choroba's answer is that it starts emacs in a daemon mode so the next time you'll try to open a file it will open it almost instantly without requiring you to start Emacs with a server either manually or via .emacs with (server-start) or (server-mode 1).
Related
I want to use capistrano for a custom sets of tasks on a remote server not directly related to deployment, it would be useful for me if I can start vim using capistrano, I've tried with this:
set :pty, true
execute "vim #{shared_path}/my_file.txt"
But I receive this (for obvious reasons)
01 stdin: is not a tty
01 Vim: Warning: Output is not to a terminal
01 Vim: Warning: Input is not from a terminal
It's there anyway to make it work?
As far as I know you can't start vim without a terminal. You could start a terminal with vim in it, here are a few ways to do this:
Start a terminal like st, xterm or similar. Examples:
x-terminal-emulator -e vim
st -e vim
xterm -e vim
This solution is not the best, as terminal-emulators can have different switches for executing commands on call. -e is working for st and xterm.
A better solution is to start a shell like zsh, bash or similar, because almost every shell works with the same switch, which is -c to start a program directly in it. Example:
zsh -c vim
bash -c vim
I am trying to use Emacs Client. I am on OSX. so:
alias ec="/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n -c -a -nw /Applications/Emacs.app/Contents/MacOS/Emacs"
Then I put (start-server) on my init.el file. A\and:
e --daemon
So when I run ec. And a clean Emacs instance is fired up.
Whats is wrong here?
Thanks in advance
It is so confusing that emacsclient said it can't find socket just after executing emacs --daemon in bash:
$ ps aux | grep emacs
shiangro 1744 0.0 0.0 2432784 604 s000 S+ 1:03下午 0:00.00 grep emacs
$ /usr/local/bin/emacs --daemon
("emacs")
Starting Emacs daemon.
Restarting server
$ /usr/local/bin/emacsclient -t
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 have this settings in my .emacs:
(server-start)
(setq server-socket-dir "~/.emacs.d/server")
and it works,the server file ~/.emacs.d/server/server was just there,but emacsclient say it can't find socket,so annoying that I have to tell him the socket file using the -s option.
I find this thorny problem while I want let emacs runing as a daemon after everytime rebooting(start) systerm by using crontab's ◎reboot special strings.
In this case ,cron successfully started the emacs server and the server file ~/.emacs.d/server/server was also there, but later when I started a terminal and tried to emacsclient -t ,it failed and complained can't find socket file!
Although I can bypass this problem by using -s ~/.emacs.d/server/server everytime I excute emacsclient,or alias emacsclient as emacsclient -s ~/.emacs.d/server/server ,but is ther a better way to comfort my heart?
Backgroud:
system: Mac OS X 10.9.2
emacs: GNU Emacs 24.3.1 installed by homebrew
Finding the server socket file is the tricky bit, you can use lsof to find it, and then a bit of grep-ing to extract the socket path/filename.
lsof -c emacs | grep server | grep -E -o '[^[:blank:]]*$'
Or on OSX when you expect to be running /Application/Emacs you'd change the command name lsof is looking for with -c Emacs. ie.
lsof -c Emacs | grep server | grep -E -o '[^[:blank:]]*$'
You could use cut instead of the messy filtering grep (searching for non-blanks until the line end [^[:blank:]]*$)
lsof -c Emacs | grep server | cut -c70-
Better yet, squish the interspacing and use cut's field chopping.
lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8
Now that you have the socket (or it's empty) you can do a conditional start on emacsclient, ie.
#!/bin/bash
socket_file=$(lsof -c Emacs | grep server | tr -s " " | cut -d' ' -f8)
if [[ $socket_file == "" ]]; then
# Just run Emacs (with any arguments passed to the script)
# It would be a good idea to parse the arguments and clean/remove
# anything emacsclient specific.
# (ie. -e should be --eval for emacs)
# note that emacsclient doesn't fix these args for you either
# when using -a / --alternate-editor
emacs $# &
# or on OSX
/Application/Emacs.app/Contents/MacOS/Emacs $# &
else
emacsclient $# -n -s $socket_file
fi
Since you've done:
/usr/local/bin/emacs --daemon
the server is already started. So, you don't actually need the:
(server-start)
(setq server-socket-dir "~/.emacs.d/server")
in your .emacs. When you follow that approach, the server is placed in /tmp/emacs502 (or maybe some other number). On linux, emacsclient doesn't seem to have trouble finding it there (in that case I'm seeing /tmp/emacs1920), and so "emacsclient -nw" works. I'm trying it on OSX using HomeBrew, as you are, and I find I have to connect using:
emacsclient -nw -s /tmp/emacs502/server
(If you used --deamon=name, then you would use "name" instead of "server" in that last line.)
emacsclient only finds the emacs server if I run emacs from the command line. If I run emacs from the Ubuntu launcher then emacsclient fails to connect to the server.
If you want to use the Emacs daemon instead of the server, define the two environment variables
export ALTERNATE_EDITOR=""
export EDITOR=emacsclient
You can add these environment variables in either ~/.bashrc or ~/.profile.
If the ALTERNATE_EDITOR environment variable is empty, then Emacs will run its daemon and connect to it.
I think emacsclient can look for special file server in standard path only, e.g. in /tmp/emacs1000. If you change this parameter server-socket-dir, then you should tell about it to emacsclient by key -s.
I start emacsclient using:
emacsclient -a "" -c
This opens a frame connected to the emacs daemon, and starts the daemon if it's not already started. Great, this works fine.
However, I like opening my emacs frames maximized. With emacs, I would use -mm. However, that doesn't work with emacsclient. How do I make this work?
(It seems I could make something work by adding a shell file like so: emacsclient -a "myshell.sh" -c, where the shell file is: emacs -mm, but I haven't been able to make that work - the server doesn't stay up.)
You can add the following line to .emacs, so that Emacs can be started with the window maximized. See http://www.gnu.org/software/emacs/manual/html_node/elisp/Size-Parameters.html#Size-Parameters for details.
(add-to-list 'default-frame-alist '(fullscreen . maximized))
Emacs client accepts -F option, where you can specify frame parameters, so the above example would be:
emacsclient -c -a "" -F "((fullscreen . maximized))"
Let's say you want to run emacsclient fullscreen, which was my case.
man emacsclient shows emacsclient has -F option:
-F, --frame-parameters=ALIST
set the parameters of a newly-created frame.
In Emacs Manual, which is an info file, section (emacs) emacsclient Options has more information. Specifically for this question (elisp) Size Parameters mentions fullscreen parameter. To run emacsclient fullscreen, you need to supply an alist, with one element being (fullscreen . fullboth) like that:
emacsclient -c -F "((fullscreen . fullboth))"
emacsclient provides the --eval (-e for short) command line option for executing arbitrary Emacs Lisp code, so you can visit a file and call suspend-frame from the command line like so:
emacsclient -a "" -c --eval "(progn (find-file \"/tmp/my-file\") (suspend-frame))"
You could put this in a script, e.g:
#!/bin/bash
emacsclient -a "" -c --eval "(progn (find-file \"$1\") (suspend-frame))"
If I have emacs running as a daemon on my system, I can connect to it easily using emacsclient. This I know. However, what I would like to know is, is there a way to tell emacs (not emacsclient) to behave like emacsclient if a daemon is already running?
e.g.
# emacs daemon is not running
emacs # should start a new frame
# ...
# emacs daemon IS running
emacs # should actually behave like emacsclient, i.e. connect to my daemon
Is there anything I can do to my init.el to replicate this kind of behaviour?
I don't think so, but can you achieve a similar effect by using emacsclient with an empty string as the the --alternate-editor option? From http://www.gnu.org/s/libtool/manual/emacs/emacsclient-Options.html#emacsclient-Options:
-a command
--alternate-editor=command
.
.
.
As a special exception, if command is the empty string, then emacsclient starts Emacs in daemon mode and then tries connecting again.
You can do the -a '' thing with emacsclient but what I do and a lot of people do is to have some kind of script that basically does what emacsclient '' does in multiple steps.
My version is something like this BASH script: The part you are interested in is the ensure-server-is-running function. This is the "main function" of the script, what follows is the ensure-server-is-running function and the rest is there after that for your curiosity but does not contribute to answering the question.
#!/bin/bash
# ec.sh
#
# [function definitions]
#
ensure-server-is-running
ensure-frame-exists
focus-current-frame
Ensuring that the server is running
# ec.sh function definition
# From https://emacs.stackexchange.com/a/12896/19972
function server-is-running() {
emacsclient -e '(+ 1 0)' > /dev/null 2>&1
}
function ensure-server-is-running(){
if ! server-is-running ; then
echo "Need to start daemon, press enter to continue, C-c to abort"
read
emacs --daemon
fi
}
And the other two function:
# ec.sh function definition
# From https://superuser.com/a/862809
function frame-exists() {
emacsclient -n -e "(if (> (length (frame-list)) 1) 't)" 2>/dev/null | grep -v nil >/dev/null 2>&1
}
function ensure-frame-exists() {
if ! frame-exists ; then
emacsclient -c --no-wait
fi
}
# From https://emacs.stackexchange.com/a/54139/19972
function focus-current-frame() {
# Doesn't work a frame exists and is in a terminal
emacsclient --eval "(progn (select-frame-set-input-focus (selected-frame)))"
}
focus-current-frame is something that will make the OS put you in the current Emacs Frame. This is the most important feature. For me I insert an adapted version of this into a MacOS Automator app. When there is an emacs GUI frame, doing Spotlight Search "EmacsC" (usually just typing the "e" is enough), puts me in my emacs window. It's a super fast way of switching to an emacs window.
Here's what I do. It's like the solution by #philippe-carpin, in the sense that it's a script that does multiple steps:
If emacs daemon is not running: start it, create a frame
If daemon but no frame: create a frame
If daemon with frame: focus that frame
In all cases you can pass filename(s) that will be opened.
In addition, my script only tries to run a piece of elisp just once and if there's no daemon it will not start an emacs process to run that elisp. So it should be slightly faster.
get_emacs_daemon_state () {
emacs_get_state_script='(if (> (length (frame-list)) 1) "daemon-with-frame" "daemon-no-frame")'
emacsclient -e "$emacs_get_state_script" -a "echo no-daemon" 2>/dev/null |
tr -d \" | cut -d' ' -f1
}
state=$(get_emacs_daemon_state)
create_frame_arg=""
if [[ $state = no-daemon ]]; then
emacs --daemon
fi
if [[ $state != daemon-with-frame ]]; then
create_frame_arg="--create-frame"
fi
client="emacsclient --no-wait $create_frame_arg"
if [[ $# -gt 0 ]]; then
# open files passed as arguments
$client "$#"
else
# if no file passed, we just focus the frame
$client --eval "(select-frame-set-input-focus (selected-frame))" >/dev/null
fi