Hidden powers of screen and xterm: multiple windows inside of a terminal
LVEE 2016
XTerm
Default xterm looks unpleasantly in most distributions: small, barely readable fonts, no multiple tabs or CJK1 support. Thus many users disregard it, though it is one of the most powerful applications if tuned properly.
All numerous features of XTerm can be tuned via X Resources. Ways of providing them depend on WM and distribution, but portable way is to run (file name may be arbitrary):
xrdb ~/.Xresources
Fonts
Arbitrary TTF font of your liking may be set using following resources:
xterm*faceName: DejaVu Sans Mono:style=Bold
xterm*faceSize: 15
On some fonts and sizes symbols like “_” may be unreadable, to correct this use:
xterm*scaleHeight: 1.01
Let’s add some CJK love (double size glyphs CJK font and 4-byte width symbols):
XTerm*combiningChars: 4
XTerm*faceNameDoublesize: mikachan
Of course, CJK must be properly configured, e.g.:
export GTK_IM_MODULE=uim
export QT_IM_MODULE=uim
export XMODIFIERS=\@im=uim
uim-xim --engine=anthy-utf8 &
Colors
256-color palette can be enabled:
xterm*termName: xterm-256color
Custom RGB colors configuration:
xterm*color1: rgb:b2/18/18
xterm*color2: rgb:18/b2/18
...
It is possible to replace bold and underline attributes by color:
xterm*colorBDMode: True
xterm*colorBD: magenta3
xterm*colorULMode: True
xterm*colorUL: cyan3
Limitation: if locale is not UTF-8 and wide chars (CJK) are used, 256 colors are not available due to limited number of XResources.
Solution: use UTF-8!
Dynamic colors change (for already printed text) can be done using escape sequence:
\033]<target>;#RRGGBB\007
E.g. to set background to #1818B2 (marine blue):
echo -ne "\033]10;#1818B2\007"
For details about possible targets see 2, example scripts are at 3.
Screen
GNU screen is a terminal manager, you may think of it like a window manager for terminals.
Why do you need that? There are so many terminals with multiple tabs and various features available… Because of its client–server architecture! It is possible to continue your work remotely, to survive broken ssh link like it was nothing and so on.
Screen server is started and stopped automatically and manages terminal sessions which can be attached and detached arbitrary by the user. This allows to connect both locally and via ssh from different hosts or interrupted connections.
Just start screen, you’ll have an ordinary terminal (in some distributions you may see information info). It works like an ordinary terminal. All screen controls can be accessed via C-a-* (^A) sequence, e.g. C-a-c will create new terminal, C-a-n will switch to next one, C-a-p will switch to previous terminal, C-a-" shows list of terminal windows available.
Screens can be detached from underlying terminal via screen -d or C-a-d and reattached using screen -r or screen -RD (with forced reattach first).
Configuration
Tired of repeating C-a-* here and there? Let’s configure it to something else. Screen’s configuration lies in ~/.screenrc (though any file may be provided using -c option). The following option will bind C-a (command sequence) to menu key (on most common keyboards):
bindkey ^[[29~ command
But how to get that ^[[29~ escape sequence? This little trick will help:
cat > /dev/null
Now press any hotkeys you like and if they are not intercepted by other software (e.g. VM or DE), you will see their escape sequences.
This way 256 colors and bce (background color erase) can be enabled in screen:
term screen-256color-bce-s
defbce on
In screen each terminal window has its own history. It can be access via copy mode (C-a-ESC or C-a-). It is possible to search within it (C-S for forward search, C-R for backward direction), select and copy using space, paste using C-a-]. But default history depth is just 100 lines per windown. This can be fixed via:
defscrollback 3000
Status line
It is possible to configure status line showing date, time, list of windows, names of current directories per window and highlight an active one (and more information available for screen, see its man page for details).
This will create a simple status line with green on black [date(blue) time] in the right corner:
hardstatus string '%{= kG}%= [%{B}%d/%m %{G}%0c:%s]'
and always enable it an the bottom line:
hardstatus alwayslastline
Here things became more complicated:
hardstatus string '%{= kG}[%= %{= kw}%?%-Lw%?%{m}(%{W}%n*%f%t%?(%u)%?%{m})%{w}%?%+Lw%?%?%= %{G}][%{B}%d/%m %{G}%0c]'
To the right of date/time from previous example list of windows is added, active window is highlighted and window title is being shown.
PS1 variable can be modified to truncate window name to 8 chars (or whatever you like) and collapse $HOME to ~, so put something alike in bashrc:
case ${TERM} in
...
screen*)
PROMPT_COMMAND='tmp="${PWD/$HOME/\~}"; tmp=${tmp##*/}; [[ -z $tmp ]] && tmp=/; echo -ne "\033k${tmp:0:8}\033\\"; unset tmp'
;;
esac
Now we have something yummy like shown on fig.1.
Moving around windows using menu-p, menu-n and menu-" is still tiring. How about using arrows (S-right and S-left) for moving between windows and C-S-right, C-S-left to move windows themselves? The following lines does this:
bindkey ^[[1;2D prev
bindkey ^[[1;2C next
bindkey ^[[1;6D bumpleft
bindkey ^[[1;6C bumpright
Troubleshooting
Sometimes after su, sudo or ssh 256 color depth or bce are lost. This happens because $TERM and $TERMCAP environment variables are not passed. To fix this either reconfigure your software to pass and accept these variables (look for ssh_config SendEnv, sshd_config AcceptEnv and so on) or set $TERM properly and set bce on in screen session.
1 CJK is a collective term for the Chinese, Japanese, and Korean languages.
fn2. http://rtfm.etla.org/xterm/ctlseq.html
fп3. http://rcr.io/words/dynamic-xterm-colors.html
Abstract licensed under Creative Commons Attribution-ShareAlike 3.0 license
Back