Back from a hiatus, today I share some suggestions on how to get UTF8-aware $TERM descriptions on NetBSD, as well as my personal vi(1) and tmux configurations
Unicode $TERM
the TERM environmental variable defines a set of capabilities and behavioral procedures for all CLI programs, by looking up the system’s terminfo(5) database for term descriptions; this is essential for programs drawing pipes to stdout, including vi(1), and naturally all programs relying on curses/s-lang libraries. A broken or null(dumb) TERM easily screws up all those TUI applications
rxvt-unicode terminal emulator includes nice TERM descriptions for modern displays, with support for 256color and built-in UTF-8 compliance;
Unfortunately the x11/rxvt-unicode pkgsrc package neither installs, nor compiles those descriptions into the system’s database. Here’s a quick fix:
build/install urxvt with unicode term descriptions
% echo "PKG_OPTIONS.rxvt-unicode=perl unicode3 rxvt-term xft2" >> /etc/mk.conf
% cd /usr/pkgsrc/x11/rxvt-unicode && make install clean clean-depends; cd -
append the installed descriptions to the system terminfo repo and compile them into a new database
% UTF8TERM="/usr/pkg/share/examples/rxvt-unicode/rxvt-unicode.terminfo"
% if [ -f "$UTF8TERM" ]; then
\ > cat $UTF8TERM >> /usr/share/misc/terminfo
\ > fi
% tic /usr/share/misc/terminfo
Copy the term descriptions repo to $USER’s home dir and create a local databse
% cp /usr/share/misc/terminfo ~/.terminfo
% tic ~/.terminfo -o ~/.terminfo.cdb
Verify that the unicode descriptions have been properly installed
% infocmp -1 rxvt-unicode-256color | head -n 2
# Reconstructed from /home/sehnsucht/.terminfo.cdb
rxvt-unicode-256color|rxvt-unicode terminal with 256 colors (X Window System
Now you can finally set the new TERM definition:
% TERM="rxvt-unicode-256color"; export TERM
nvi(1) editor [1]
Unlike nvi, all other vi clones (elvis, vile, but especially vim and neovim) come with a lot of new functionalities compared to the original BSD Unix vi, often making it more complex by order of magnitudes. I’ve seen heavily customized vim builds using 50+ plugins, endless configs, complex themes and a lot of startup scripts. While some people, especially developers, may like to turn vi into a complex yet slow IDE, and still effectively make a productive use of it, this is not the case of the casual end-user like me, who just needs a simple editor for personal notes, config files, scripts and a bit of casual coding.
So why nvi? It’s the only maintained vi re-implementation which remained true to its original Unix philosophy , by just keeping ‘fixing’ and ‘polishing’, rather than ‘adding’; ridiculously simple and lightweight; has an acceptably easy learning curve (as opposite a huge pile of books awaits the one attempting to master vim), provides concise documentation; it’s included in base so:
- it’s the only thing you have on a live BSD session
_ it’s the only thing you have left if you manage to break either pkgsrc or ncurses
- doesn’t require additional software to be installed
Upon startup, nvi, looks by default for a ~/.nexrc
configuration file to source, here's mine:
"""^[2]^[3] ABBREVIATIONS """
ab #d #define
ab #i #include
ab Attr Attributes
ab Appl Application
ab Vari Variables
ab Req Request
ab UNI Sapienza Universita' di Roma
ab mail sehnsucht@fastmail.com
ab xmpp sehnsucht@xmpp.jp
""" MACROS (KEYBINDINGS) """
"" Show help ^[4]
map ^H :!$PAGER ~/.vi_help^M
"" Write out file
map ^Q :wq!^M
"" Read and append <cmd> stdout to next line, first white space
" previous/current file diff
map rd +:r!diff -u # %^M
" tmux buffer
map rb +:r!tmux show-buffer^M
" today date
map rt +:r{!}date +\%Y-\%m-\%d^M
" XA_CLIPBOARD
map rc +:r!xclip -o -sel clip^M
" sysinfo
map rs +:r!uname -rs^M
"" Formatting
" indent lines
map gi :%!indent -i4^M
" format paragraph
map gf :"{,"}!fmt -p -w 78^M
" sort lines alphabetically
map gs :%!sort -u %^M
" process file with hunspell
map gh :!hunspell -d en_US %^M
" substitute patterns up to current position
map gr :^,.s///g^M
" double space, whole file
map gd :%!sed G^M
" uncomment lines
map gu :k/\/\#/^M
"" Manipulating Buffers ^[5]
" display vi buffers
map K :display buffers
" cut current line to buffer '1'
map C "1Y$dd
" paste '1' after current position
map V a"1p
" mark current position as begin of new buffer
map # ma
" mark current position as end of new buffer
map * mb
" append new buffer to next line
map bi :'a,'b co .
" delete marked buffer
map be :'a,'b del .
" move marked buffer to 'n' line
map bm :'a,'b mo .
""" TUNABLE OPTIONS """
" Autoindentation
set ai
" Discard control characters
set bf
" Char to edit command-line history.
set cedit=\^[
" Store buffer on tmpfs
set dir=/tmp
" Encoding
set fileencoding=UTF-8
" Case insensitive searches
set ignorecase
" Hide whitespace and EOL characters
set nolist
" show line numbers
set nu
" Display a row/column ruler
set ruler
" Additional section boundaries
set sections=SeAhBhChDh
" Shell env for ! commands
set shell=/usr/pkg/bin/mksh
" Show matching brackets
set showmatch
" Display current editor mode
set showmode
" Shift width in spaces
set sw=8
" TAB width in spaces
set tabstop=8
" TERM type
set term=rxvt-unicode-256color
" Verbose error messages
set verbose
" 78-N chars wrapmargin
set wm=2
set wl=78
and here's my ~/.vi_help
file (largely stolen online)
Editing Commands Deleting Commands
---------------- -----------------
i insert x delete current character
I insert (head of line) 3x delete 3 characters
o open a new line (below) X delete character to left
O open a new line (above) dw delete current word
a append d3w delete 3 words from current word
A append at end of line db delete one word to left
u undo d0 delete to beginning of line
. repeat last command d$ delete to end of line
dd delete current line
5dd delete 5 lines
------------------- -----------------
Cutting and Pasting Movement Commands
------------------- -----------------
yy yank (copy) current line H move to top of screen (high)
5yy yank 5 lines M move to middle
p paste L move to low
P paste above current position 10G go to line 10
G go to end of lines
gg go to first line
w go to next word
b go back to previous word
0 beginning of line
$ end of line
------------------
Searching Commands
------------------
/foo search for "foo"
?foo search backwards for "foo"
n find next match
N find previous match
---------------------
Run External Commands
---------------------
:!ls -al list current directory (long list)
:!pwd print working directory
----------------------
Substitute Commands
----------------------
:s/F.*E/BA/ swap first (longest) F.*E with BA (current line only)
:s/FOO/BAR/g swap FOO with BAR (current line only)
:1,$s/FOO/BAR/g swap every occurrence of FOO with BAR (entire file)
:%s/FOO/BAR/g swap FOO with BAR (find in all lines)
%s = 1,$s
:/co/s/FOO/BAR/g in lines that contain "co",
swap FOO with BAR (current line only)
:.+3s/FOO/BAR/g swap FOO with BAR on current+3 line
not work with %s directly
:+3s/FOO/BAR/g same as .+3s
:10,20s/FOO/BAR/g swap FOO with BAR on lines 10 through 20
----------------------
Miscellaneous Commands
----------------------
:w save current file
:w /path/to/file save current file to a different path
:r /path/to/file read contents of a file into the current file
:10,20d delete lines 10 through 20
:10,20y yank (copy) lines 10 through 20 to the buffer
Notes:
[1]. The /bin/vi(1) binary you can find on BSDs is more specifically an actively developed implementation of the nvi() editor first appeared in 1994 on 4.4BSD-Lite, as a written-from-scratch, improved and refined clone of the original (and proprietary) Bill’s Joy vi(1) editor (written in turn as replacement for traditional Unix ed(1) and first appeared in 1978 as part of, and in conjunction with, the first release of BSD UNIX). As Bill Joy was later on employed by Sun Microsystems, Solaris historically adopted his vi as /bin/vi. With the advent of OpenSolaris in 2006, original vi was open-sourced under CDDL along with the rest (e.g. the Bourne Shell, see heirloom-sh), so if you want a taste of pure UNIX, go install illumos... but I warn you: it’s even more barebones than what I going to show you below.
Now, you may have noticed Linux distributions usually provide a vi(1) binary too. In most cases this a symlink to vim
; Slackware and its derivatives, use elvis
as default vi replacement; the only exception that I’m aware of is Void Linux, which uses nvi
.
[2] Press SPACEBAR to expand pinned abbreviations
[3] Any line beginning with a double quote is marked as comment, and as such ignored
[4] "^M" (CTRL-V+Return) escapes Enter
[5] A buffer is an area where commands can save changed or deleted text for later use. nvi buffers are named with a single character preceded by a double quote
Further reading
All you need is found inside vi(1); a cheat sheet like the one shown above can help =P