Tuesday, March 25, 2008

Screen Tips

I use screen quite a bit for a number of reasons. I plan to periodically edit this blog entry as a notepad for GNU screen features I use frequently. If you're not familiar with screen, at the most basic functionality, it lets you do things like run multiple processes inside of one terminal. These processes are typically shells, but I frequently run a split session between Vim and a shell (see screenshot below). It also allows you to detach from your current session and later return. This is great for things like long-running compiles, keeping tabs on a process, or logging out of an ssh session without killing the foregrounded process. Read below for a summary of all these features (and more).


At the basic level, you want to fire up screen and give it a session name. This is useful for coming back and re-attaching to the session later. Start screen like this:

screen -S dailyvim

You'll be presented with an identical looking shell that you were in prior to the command, but don't be fooled. Type in a command like "ls -l" and then hit ctrl-a c (create screen). You'll be presented with a new shell with an empty command line. What's happened is you're actually running two shells now within a single terminal. Type in a new command like "date" then hit ctrl-a n (next screen). You should be taken back to the directory listing you saw before. Now hit ctrl-a d (detach). The entire session is pushed to the background, and you can resume it whenever you would like. If you want, you can close the current term, open a new one, or even do a remote login and still resume the session. Re-attach to your screen session by issuing the following command, screen -R dailyvim.

Scrollback, Copy & Paste:

Another nice feature of screen is that it allows you to scrollback through your shell session as needed to look at information that may have scrolled by too quickly to read. The length of the scrollback buffer is managed through your .screenrc file, but for most purposes the default is probably ok. Anytime you're inside of screen, scrollback can be invoked via Ctrl-a ESC. Once in scrollback mode, Vi navigation keys conveniently allow you to scroll around; although, you can also use the arrow keys if desired. From inside scrollback, you can yank text into a copy buffer if you so desire. Press the space bar once to initiate a copy and press it again to complete the copy. To paste the copied text press Ctrl-a ]. The following Vi commands work in this mode (from TFM):

h, j, k, l move the cursor line by line or column by column.
0,^ and $ move to the leftmost column, to the first or last non-whitespace character on the line.
H, M and L move the cursor to the leftmost column of the top, center or bottom line of the window.
+ and - positions one line up and down.
G moves to the specified absolute line (default: end of buffer).
| moves to the specified absolute column.
w, b, e move the cursor word by word.
B, E move the cursor WORD by WORD (as in vi).
C-u and C-d scroll the display up/down by the specified amount of lines while preserving the cursor position. C-b and C-f scroll the display up/down a full screen.
g moves to the beginning of the buffer.
% jumps to the specified percentage of the buffer.

Split Window:

Sometimes I like to run a shell underneath my Vim session. Screen makes this possible by allowing me to do a horizontal split on the current screen session. From inside screen, hit Ctrl-a S (capital). You should now have two windows. Hop between them by pressing Ctrl-a tab. The second window is probably blank. Give it focus and hit Ctrl-a c (create) to create a session inside of it. You can do Ctrl-a n (next) as usual to cycle through sessions.

Command Mode:

Screen provides a slew of commands that can manipulate behavior of your current session. To give a command, you need to initially enter command mode. To do this, type Ctrl-a :. From there you can type in any command screen recognizes. I use command mode to resize a split window to my desired height as follows (Ctrl-a :resize N) where N is the number of rows high you want to current window. It also supports plus and minus arguments on N for relative adjustment.

Other tricks:

hardcopy command: From inside screen, type Ctrl-a h (hardcopy), and screen will dump whatever is displayed in the current buffer to a file "hardcopy.n". This is handy if you don't want to (or can't) use the mouse to copy and paste.

digraph mode: Ctrl-a Ctrl-v allows you to enter digraphs on the command line. Try :digraph in Vim for a listing of available digraphs.

list sessions: screen -ls lists all sessions currently associated with your UID.

re-attach: screen -d will attach to a given session (even if currently attached). This is useful if you forgot to detach before you left the office, etc...

list windows: Ctrl-a " will give you a selectable list of windows in the current session.

name window: Ctrl-a A will let you name the current window for the window list.

currently attached: Ctrl-a * will show currently attached displays.


Anonymous said...

Another handy movement command that I use constantly is:

For instance, fq in normal mode would jump to the next lower-case q on the current line. Typing ; will jump to the next one.

Similarly, F<char> jumps to the specified character, but in a leftward direction.

Pair these commands with delete or change action, and you've gotten something really helpful, especially for developers:
df" (deletes up to and including next quote char)
dt" (deletes up to but NOT including next quote char)


romanofski said...

I'm actually wondering if it's possible to reorganise the screen buffers. If I have something running on two and would like to move it two 3 or 4 ... like moving the tabs in Firefox ...

Avi said...

It is possible to "move around" the buffers using the :number command.
for example if you are now on buffer number 5 and you type command :number 2,
than buffers 2 and 5 will switch places