emacsen's journal - Emacs and Screen
[Recent Entries][Archive][Friends][User Info]
06:58 am
[Link] |
Emacs and Screen A coworker challenged me that if I loved Emacs so much, why was I always using nano. I realized why, solved it, and present my solution to you.
I hate articles that make you dig around for the answers to problems, so here it is:
Add this to your ~/.emacs:
(server-start) (add-hook 'after-init-hook 'server-start) (add-hook 'server-done-hook (lambda () (shell-command "screen -r -X select `cat ~/tmp/emacsclient-caller`")))
Add this to your ~/.screenrc:
screen -t Shell 0 bash screen -t Emacs 1 emacs -nw select 0
Make a script called ~/bin/emacs:
#!/bin/sh echo $WINDOW >~/tmp/emacsclient-caller screen -r -X select 1 emacsclient "$1"
And this to your ~/.bashrc:
export PATH=~/bin:$PATH # Auto-screen invocation. see: http://taint.org/wk/RemoteLoginAutoScreen # if we're coming from a remote SSH connection, in an interactive session # then automatically put us into a screen(1) session. Only try once # -- if $STARTED_SCREEN is set, don't try it again, to avoid looping # if screen fails for some reason. if [ "$PS1" != "" -a "${STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" != x ] then STARTED_SCREEN=1 ; export STARTED_SCREEN [ -d $HOME/lib/screen-logs ] || mkdir -p $HOME/lib/screen-logs sleep 1 screen -RR && exit 0 # normally, execution of this rc script ends here... echo "Screen failed! continuing with normal bash startup" fi # [end of auto-screen snippet]
Now the explanation
The problem with running emacs directly on the servers I work on is the startup time. I find that starting Emacs takes between a half-second and two seconds. This delay is just high enough to be frustrating. The nano editor has a far shorter delay, so I use that.
If I could eliminate the delay, I would use Emacs. So I began to investigate a way to do that.
Emacs users probably already use and are familiar with emacs-server, a special emacs setting which allows a single Emacs session to be started up. When an editor is needed, the existing Emacs can come up and take control without having to start up or use any extra memory.
Emacs-server can be started with a simple:
(server-start)
in your ~/.emacs file.
Then you can set your $EDITOR variable to "emacsclient".
The problem with this for me is that emacs-server seems to work best in a graphical environment, where Emacs can pop up when necessary. It doesn't work on a console. Or does it.
GNU Screen provides a sort of virtual window system for shell environments. I already use GNU Screen.
After doing a web search for gnu screen and emacs, I found this page on EmacsWiki.
I stole most of my work from there.
The main problem I had with the screen session presented there is that Emacs starts on window 1. Even if you have defined another window, such as:
screen -t Shell 0 bash
Unless you have the select 0 line, Emacs will place you on the last window, and you'll be waiting for Emacs to start. By selecting window 0, you're brought to the shell and Emacs is free to initialize on window 1. By the time you've figured out which file you'll want to edit, it'll have finished initializing.
Now if you want to edit a file, simply type:
emacs FILENAME
And screen will bring you back to window 1, with your running Emacs, with the file open. Once you release the file C-x-#, you'll be brought back to your originating screen window.
Extra Screen Settings
As a bonus, here are my other screen settings:
Getting Rid of the Splash Screen
Screen has a helpful splash screen. It's only useful the first hundred times you see it, so I turn it off:
startup_message off
Turning off the Beep
Beeping is annoying. Screen let's us turn on a visual beep. Unfortunately the default visual beep message is "Wuff Wuff", so I replace it with "BEEP":
vbell on vbell_msg "BEEP"
The Hardstatus Line
The main feature of Screen is that it can act much like a window manager. Using the hardstatus line makes this feature useful. This hardstatus line came from elsewhere, but I don't know where:
hardstatus on hardstatus alwayslastline hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a "
Logging the Shell Window
At work, I find it particularly helpful to keep a log of work done in my shell window. Since I define my shell window as window 0, I can simply add -L to the shell window definition, making it: screen -L -t Shell 0
The log filename template I find most useful is
logfile screenlogs/%H_%Y-%m-%d-%n.log
Setting the Window Title Automatically
While I explicitly set the window titles, I also like when the commands I run set the window titles automatically. This page describes title setting for various shells, but since I use bash, there's a bit of a hoop that I have to jump through. First, I set my title to look for the command after the bash prompt. In my .screenrc:
shelltitle "$ |bash"
and then in my bash initialization file ~/.bashrc, I export a magic string which is used by screen:
export PS1='\[\033k\033\\\]\u@\h:\w\$ '
And that's it! A powerful text environment.
Tags: computer
|
|
| |
| From: | (Anonymous) |
| Date: | July 11th, 2007 01:20 pm (UTC) |
|---|
| | screen select command | (Link) |
|
Hi, the screen "select" command works with windows numbers AND with windows titles. So if you have your emacs window called "emacs" you can "screen -X select emacs".
There is also a patch (http://lists.gnu.org/archive/html/screen-devel/2006-03/msg00003.html) for searching window titles, so you can have your shell set the title for the currently running command, and later search for it or bind the "search emacs" to some key..
![[User Picture]](http://l-userpic.livejournal.com/11319391/2205946) | | From: | emacsen |
| Date: | July 12th, 2007 10:18 am (UTC) |
|---|
| | Re: screen select command | (Link) |
|
That's a good point.
I'm less likely to use the patch because at work we use stock software where possible. I'd hope that if it's good, it'll trickle down into the mainline source and into the distributions.
My greatest trouble with emacs and screen is that by default screen uses Ctrl-a as the escape key. In emacs and bash I use Ctrl-A a lot go go to beginning of line. My first configuration in a new machine is to add this to ~/.screenrc:
escape ^pp
Now Ctrl-p is the escape key and screen and emacs live happly for ever.
There's a small typo in your text: "Emacs-server can be started with a simple:
(start-server)" it should be (server-start) as in the code snippet above.
![[User Picture]](http://l-userpic.livejournal.com/11319391/2205946) | | From: | emacsen |
| Date: | July 12th, 2007 10:19 am (UTC) |
|---|
| | Re: Another tip | (Link) |
|
Thanks for the tip. I'm going to do that (re the keybinding).
I also fixed the typo.
![[User Picture]](http://l-userpic.livejournal.com/20424721/947940) | | From: | zenspider |
| Date: | July 16th, 2007 03:24 pm (UTC) |
|---|
| | Re: Another tip | (Link) |
|
I use 'escape ^]^]' because it is telnet's escape and used in pretty much the same context. Since I use ssh exclusively, there is no conflict.
| From: | (Anonymous) |
| Date: | June 12th, 2009 05:47 pm (UTC) |
|---|
| | Re: Another tip | (Link) |
|
'C-a a' in screen will send Ctrl-a to the shell, so you don't need to remap any keys if you can tolerate the extra keystroke.
![[User Picture]](http://l-userpic.livejournal.com/3905419/624907) | | From: | phil_g |
| Date: | July 11th, 2007 03:41 pm (UTC) |
|---|
| | | (Link) |
|
I do basically the same thing, but I use the escape sequence screen provides to execute commands. This gets closer to guaranteeing that the correct display changes back to the original window. (I use multiattach all the time, so a mere 'screen -r -X select' doesn't always target the right display.)
In my .screenrc, I have:
multiuser on
aclchg :window: +x select
And my .emacs contains:
(add-hook 'server-done-hook
(lambda ()
(set-buffer (get-buffer-create "*screen*"))
(insert-file-contents "~/tmp/emacsclient-caller")
(send-string-to-terminal
(concat "\e]83;select " (thing-at-point 'word) "\a"))
(kill-buffer "*screen*")))
I'm really looking forward to multi-tty support in the main tree. (Tentatively slated for Emacs 23.)
![[User Picture]](http://l-userpic.livejournal.com/11319391/2205946) | | From: | emacsen |
| Date: | July 12th, 2007 01:45 pm (UTC) |
|---|
| | | (Link) |
|
Wow your solution seems clean. I'll have to play with it later.
As for multi-tty support in the main tree... it's really amazing how many nice things are in 23... The font support is the most obvious, but so is the character support.
On my laptop, I'm already running a CVS checkout of 23 with minimal issues.
| From: | (Anonymous) |
| Date: | July 11th, 2007 06:39 pm (UTC) |
|---|
| | and... | (Link) |
|
don't forget, in .bashrc or wherever you like
alias e='emacs' alias se='sudo emacs'
mmmm, yummy!
thanks for the tips!
| | Why? I mean, really... | (Link) |
|
I know this is a bit dangerous to ask.
Why?!
I know one can love an environment and most of the world is DIY, but why isn't this easier? since just about everyone i know that uses emacs recommends to use the server component, why is it so hard to use it?
I know that there is always work being done on solving this issue, but the issue has been around for quite a while. So why isn't there a real solution?
Issues like these will drive people away from using emacs, since it's too hard to create a sane working environment.
![[User Picture]](http://l-userpic.livejournal.com/11319391/2205946) | | From: | emacsen |
| Date: | July 12th, 2007 10:23 am (UTC) |
|---|
| | Re: Why? I mean, really... | (Link) |
|
I know one can love an environment and most of the world is DIY, but why isn't this easier?
Because each component of this only sees part of the picture.
screen knows about session management, not about what applications are running.
emacs knows about the emacsclient sessions and servers, and everything works fine in X, but in this case, there's no X, so we have to help it along.
| From: | (Anonymous) |
| Date: | December 12th, 2007 03:31 pm (UTC) |
|---|
| | Need some help = ) | (Link) |
|
Hi, as i could understand you are not bad in Emacs. I have some work to do and can't find the way. The problem is that I want to send commands to the Emacs server from bash, such as save(it's C-x C-s,if I'm not mistaken). For myself i'm using the vim editor and it allows to send commands to it's server via "vim --remote-send ':w'" command(which saves the file and closes it, if you are not familiar to vim/gvim). Is there a similar command for the emacsclient, or is there another way?
Thanks
![[User Picture]](http://l-userpic.livejournal.com/11319391/2205946) | | From: | emacsen |
| Date: | December 12th, 2007 04:01 pm (UTC) |
|---|
| | Re: Need some help = ) | (Link) |
|
If you're not editing the file, why would you run the command remotely?
| From: | (Anonymous) |
| Date: | August 14th, 2008 08:44 pm (UTC) |
|---|
| | Thank you! Plus a question ... | (Link) |
|
Thank you for writing all this out, it saved me a ton of time and it's coming up on the top of google searches for obvious keywords!
As I'm re-introducing myself to emacs through screen, having done it last about 10 years ago, my current issue is that now the delete key (in a bare emacs it's (delete-backward-char)) when I use screen it becomes (delete-char). Which is the wrong thing. So far, I'm lost as to what the problem is. A (global-set-key) fixes it for the session but isn't a general solution. Any ideas? Thanks!
| From: | (Anonymous) |
| Date: | August 15th, 2008 11:03 am (UTC) |
|---|
| | Re: Thank you! Plus a question ... | (Link) |
|
What terminal are you running?
(xterm, rvxt, gnome-terminal, etc?) |
|