#+TITLE: Zutty user guide
#+OPTIONS: author:nil timestamp:nil num:nil val:nil html-style:nil H:3 ^:{}
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="org.css"/>

* Installation

You will probably need to install Zutty from source. This is not as
scary as it might seem, because Zutty has very few dependencies and is
a relatively small program.

** 1. Install build dependencies

On a current (stable or testing) Debian, or a Debian-derivative such
as Ubuntu, the following command will make sure everything you need to
build Zutty is in place. It also gives you an idea of what you need to
install Zutty on other flavours of Linux.

: sudo apt-get install \
:    build-essential pkg-config python3 \
:    libegl-dev libfreetype-dev libgles-dev libxmu-dev

Hint: You might need to substitute =libfreetype6-dev= for
=libfreetype-dev= and =libgles2-mesa-dev= for =libgles-dev=.
When in doubt, use your distribution's package manager along with your
favourite Internet search engine.

** 2. Obtain the source

Clone the source from git:
: git clone https://github.com/tomszilagyi/zutty.git
: cd zutty

Alternatively, to download a compressed tarball of a certain release
version, go to https://github.com/tomszilagyi/zutty/releases, download
the tarball you want (we recommend the latest one), and uncompress it.
Further steps assume that your working directory is within the
uncompressed directory, so =cd= into it!

** 3. Configure the source

You are supposed to be inside the repository (or release) directory
structure, i.e., the =zutty= directory created above should be your
working directory. Issue this command:

: ./waf configure

You should see some output with a confirmation of the Zutty version
you are going to build, and whether you are creating a Debug build (it
should say "no" at this point; read the [[./HACKING.org][Developer guide]] if you are
interested in debugging Zutty).

By default, g++ (the gcc compiler for C++) will be used to compile
Zutty. To use clang instead, pass =--check-cxx-compiler=clang++= to
the above script.

In the configure output, you will see checks for the presence of the
build dependencies. If anything is missing, the configure script will
terminate with an error. Otherwise, the configure output will finish
with a line like this:

: 'configure' finished successfully (0.373s)

In case you will want to install the =zutty= executable to somewhere
other than =/usr/local/bin=, use the =--prefix= option to specify the
installation prefix (the default is =/usr/local=). For example, I
often install stuff for my user account only, in which case I would
issue =./waf configure --prefix=/home/tom/root= so that later on,
=zutty= would end up installed as =/home/tom/root/bin/zutty=.

If you would like to learn more, =./waf --help= lists a reference of
every option you can use.

** 4. Compile the source

Just type:

: ./waf

Alternatively, if you want to specify the number of jobs to run in
parallel, issue =./waf -j 4= (substitute your number of CPU cores in
place of 4).

The compilation messages should be self-explanatory (assuming you do
not run into C++ error messages -- decoding those is an art form in its
own right). A successful compile ends with a line like this:

: 'build' finished successfully (23.524s)

At this point, the =zutty= executable is complete and ready to be run
at =build/src/zutty= and you might want to launch it just to see if it
works. You can run it without arguments to start it up with defaults,
or add =-h= (or =-help=) to learn about available options.

** 5. Install Zutty

For regular use, it is best to copy the =zutty= executable to a
system-wide directory for binaries where it will be found as part of
the default executable search path. This makes it easier to launch and
also decouples it from any local changes. You can manually copy the
executable built in the previous step, but it might be easier to use
the built-in install step in the =waf= script. Running it with =sudo=
will ensure that it is able to write to protected system-wide
locations:

: sudo ./waf install

Note that your ability to run the above command (with =sudo=) is
contingent on the presence of =sudo=, the setup of your user account
with respect to sudo, etc. If it does not work, please search the web
or ask your friendly local guru. Also, if you have specified an
install location that is actually yours (like the one I showed above)
then of course there is no point in using =sudo=.

At the end, you should see something like this:

: 'install' finished successfully (0.135s)

Congratulations, you are now ready to start using Zutty as your
terminal!

* Usage reference

** User interface actions

The following list summarizes user-triggered actions. Note that these
are hooks handled by the terminal itself, and will not reach the
program running in the terminal. For the specification of how the
terminal encodes keypresses to the program running inside it, see the
[[./KEYS.org][Key mapping sequences]] reference.

| Trigger                                               | Action                                                                                                                                                                                                                    |
|-------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Shift+PageUp, Shift+PageDown                          | Page screen upwards (into earlier scrollback history) or downwards by half the page height. If on the alternate screen with =-altScroll= enabled, emit synthetic arrow key events to move up/down half the screen height. |
| Scroll wheel up/down                                  | Page screen up/down by 5 lines; if on the alternate screen with =-altScroll= enabled, emit a single synthetic up/down arrow key event.                                                                                    |
| Left mouse button press (and hold)                    | Start a new selection. Adjust by moving the mouse with the button held down.                                                                                                                                              |
| Right mouse button press (and hold)                   | Adjust current selection (will grab the edge closest to the pointer); adjust by moving the mouse with the button held down.                                                                                               |
| Quickly release and re-engage left/right mouse button | While a selection is in progress, this will cycle between snap-to-char, snap-to-word and snap-to-line. (In rectangular selection mode, only snap-to-char exists.)                                                         |
| Space key while left/right mouse button is held       | Toggle between /regular/ and /rectangular/ selection mode.                                                                                                                                                                |
| Middle mouse button, Shift+Insert                     | Paste the current content of the primary selection into the terminal.                                                                                                                                                     |
| Control+Shift+C                                       | Copy the current content of the primary selection into the clipboard selection. (With =-autoCopy= enabled, this happens automatically whenever the primary selection is set.)                                             |
| Control+Shift+V                                       | Paste the current content of the clipboard selection into the terminal.                                                                                                                                                   |
|-------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

** Environment variables

Zutty sets or alters the below environment variables in the process
spawned to run the shell. All other environment variables accessible
to Zutty will be passed unaltered to the shell program.

| Environment variable | Treatment                                                                                                                   |
|----------------------+-----------------------------------------------------------------------------------------------------------------------------|
| =DISPLAY=            | Set to the current X display.                                                                                               |
| =SHELL=              | Set to the full (resolved) pathname of the shell being run; unset if the program is not a valid shell as per =/etc/shells=. |
| =TERM=               | Set to =xterm-256color=.                                                                                                    |
| =WINDOWID=           | Set to the current X window id of the Zutty window.                                                                         |
| =ZUTTY_VERSION=      | Set to the build version of Zutty.                                                                                          |
* Configuration

Zutty has a set of configuration options, all of which have:
- a command line option;
- an X resource database (Xrdb) key;
- a sensible hard default.

For each option, the above list defines the order of preference.  That
is, the command line can be used to define or override a setting in a
transient way; Xrdb entries may be used to persistently alter the
default value for an option; and lastly, without any option or
configuration, Zutty will still have a workable default.

There is also a set of [[Extra resources]] available for persistent
configuration, but not settable via command line options.

To view the list of options, issue =zutty -h= (short for =-help=):

: Usage:
:   zutty [-option ...] [shell]
:
: Options:
:   -altScroll    Alternate scroll mode
:   -autoCopy     Sync primary to clipboard
:   -bg           Background color (default: #000)
:   -boldColors   Enable bright for bold
:   -border       Border width in pixels (default: 2)
:   -cr           Cursor color
:   -display      Display to connect to
:   -dwfont       Double-width font to use (default: 18x18ja)
:   -fg           Foreground color (default: #fff)
:   -font         Font to use (default: 9x18)
:   -fontsize     Font size (default: 16)
:   -fontpath     Font search path (default: /usr/share/fonts)
:   -geometry     Terminal size in chars (default: 80x24)
:   -glinfo       Print OpenGL information
:   -help         Print usage listing and quit
:   -listres      Print resource listing and quit
:   -login        Start shell as a login shell
:   -name         Instance name for Xrdb and WM_CLASS
:   -rv           Reverse video
:   -saveLines    Lines of scrollback history (default: 500)
:   -shell        Shell program to run
:   -showWraps    Show wrap marks at right margin
:   -title        Window title (default: Zutty)
:   -quiet        Silence logging output
:   -verbose      Output info messages
:   -e            Command line to run

All options can be abbreviated as long as they are non-ambiguous, so
it's fine to write =-di= short for =-display=, =-gl= for =-glinfo=,
=-fontp= for =-fontpath=, =-t= for =-title=, =-q= for =-quiet=, etc.

Boolean options (=-altScroll=, =-autoCopy=, =-boldColors=, =-glinfo=,
=-login=, =-rv=, =-showWraps=, =-quiet=, =-verbose=) do not expect an
argument; the mere presence of these options amounts to a setting of
"true". To set them to "false", change the leading dash to a plus
sign. For example, =+boldColors= will /disable/ the "boldColors"
option (which is enabled by default). This might also be useful to
override an option that is by default false, but has been set to true
in the X resource database (see [[Persistent configuration]]).

All other options expect exactly one argument, with the exception of
=-e=, which must be the last option, to be followed by the command
line to run.

The options are further documented below, grouped into sections by
topic. To set up a persistent configuration (altered defaults), see
the next section [[Persistent configuration]].

** Basic configuration and mode switches

:   -altScroll    Alternate scroll mode [boolean]

If enabled, mouse scroll up and down events while on the alternate
screen buffer are translated into synthetic up- and down-arrow key
events. This might prove to be a convenient way of moving up/down
one-by-one in programs usually navigated with the keyboard arrows.

Another, similar effect (also on the alternate screen) is that the
keys normally used to page through the screen buffer (Shift+PageUp,
Shift+PageDown) will generate the same synthetic up- and down-arrow
key events as above, but in multiples, to scroll half the amount of
scrollable lines. This might be convenient in the same situations,
only for larger jumps.

:   -autoCopy     Sync primary to clipboard [boolean]

By enabling this option, Zutty will automatically propagate the
primary selection to the clipboard each time a selection is completed,
acting as if you pressed Control+Shift+C immediately after each
selection. This might be convenient if you do not wish to use the dual
selection capability (primary plus clipboard), and expect to be able
to paste into other programs that source the data from the clipboard.

:   -display      Display to connect to

The X display to connect to. By default, the value of the environment
variable DISPLAY is used. This option is exceptional in that (for
obvious reasons) it cannot be configured via the X resource database,
only the command line.

:   -glinfo       Print OpenGL information

If enabled, Zutty will query and log some GL variables on program
startup. These include EGL_VERSION, EGL_VENDOR, EGL_EXTENSIONS, as
well as GL_RENDERER, GL_VERSION, GL_VENDOR, GL_EXTENSIONS, and numeric
limits on the Compute Shader implementation. This is mostly a
debugging aid. The output is not affected by any verbosity changes
made via =-v= or =-q=.

:   -help         Print usage listing and quit

Print the help message containing the list of options documented here,
and quit.

:   -listres      Print resource listing and quit

Print a listing of configurable [[Extra resources]] and quit.

:   -name         Instance name for Xrdb and WM_CLASS

This option specifies the application instance name, which will be
used to look up resources in the X resource database, and reported to
the window manager as part of the =WM_CLASS= property (the other part
being the application class name, hardcoded as =Zutty=).  The
specified name should not contain "." (dot) or "*" (asterisk), as
those characters have special meanings within Xrdb entries.

If this option is not present, but the environment variable
=RESOURCE_NAME= is set, that will be used instead. If none of these
are available, the hard default value of =Zutty= will be used.

This option is exceptional in that (for obvious reasons) it cannot be
configured via the X resource database, only the command line.

:   -saveLines    Lines of scrollback history (default: 500)

Set the number of lines to keep in off-screen page history, viewable
via paging the terminal up/down by Shift+PageUp and Shift+PageDown
(jumping half a page-height at once), or the mouse scrollwheel (moving
in units of 5 lines). The set amount of saved lines is in addition to
the lines visible in the terminal window.

The default value is 500 lines, which should be enough for everyday
use (the occasional peek at the output of a command that rolled off
the screen). The minimum setting is 0 (no scrollback), the maximum
allowed value is 50,000. Note that while the performance of scrolling
itself (and Zutty in general) will /not/ degrade with a larger
setting, the screen buffer /will/ consume proportional amounts of
memory.  With very large settings, this will dominate the total memory
usage of Zutty! For example, 1024 buffered lines (24 lines on-screen
and 1000 lines of scrollback) with 80 columns will consume 960 KiB;
this will balloon to 10 MiB with 10,000 lines of scrollback.
Adjusting the column width will have a similar (proportional) effect;
50,000 lines at a width of 120 columns will consume a whopping 70 MiB!

Note that the alternate screen buffer does not have scrollback; this
is by design and in conformance with the relevant specs (but see
=-altScroll= for enabling synthetic up- and down-arrow key events).

:   -quiet        Silence logging output [boolean]
:   -verbose      Output info messages [boolean]

These options control the verbosity of log output emitted by
Zutty. You will only observe the effects of these if you run Zutty
itself from another terminal (as opposed to some launcher that
discards the program's output). In that case, you will notice output
that looks like this:

: I [font.cc: 54] Loading /usr/share/fonts/X11/misc/9x18.pcf.gz as primary
: I [font.cc:198] Glyph size 9x18
: ...
: I [main.cc:118] Window ID: 48234498 / 0x2e00002
: I [charvdev.cc:377] Resize to 935 x 771 pixels, 103 x 42 chars

The first letter is an indication of the log level or "severity"; =E=
means Error, =W= stands for Warning, =I= is Info and =T= is Trace.
Trace will only be output if you compile Zutty into a debug build; see
the [[./HACKING.org][Developer guide]] for details. Next, the origin of the log message
is shown in square brackets, indicating the source code location
(filename and line number) where the message was printed. Then comes
the actual message.

By default (if neither =-quiet= nor =-verbose= is given), Zutty will
print errors and warnings, but not info messages. If =-verbose= is
given, info messages are also printed. On the other hand, if =-quiet=
is given, nothing is printed. If both options are given, =-quiet=
wins.

** General appearance

:   -geometry     Terminal size in chars (default: 80x24)

This option defines the desired initial size of the terminal as
measured in characters. (The pixel size of the window will be a
function of this plus the font geometry, and cannot be specified
directly.)

This is just a request to the window manager; Zutty will accept and
work with whatever final window size it gets. Setting this will in no
way interfere with your ability to resize Zutty once it is up and
running.

:   -bg           Background color (default: #000)
:   -fg           Foreground color (default: #fff)
:   -cr           Cursor color

These options accept a hexadecimal RGB or RRGGBB color specification,
similar to how you can define a color in many other places, e.g., CSS.
The leading =#= is optional (supported mainly to provide compatibility
with established conventions); take care to protect it from the shell
when passing it on the command line. Both lower- and uppercase
hexadecimal digits (a-f, A-F) are accepted, but note that names (e.g.,
=red= instead of =#f00=) are /not/ supported.

If not explicitly set, the cursor color defaults to the foreground
color. In case the cursor is placed on a cell with a background color
set to the cursor color, the cursor color is automatically inverted to
ensure it stays visible.

:   -rv           Reverse video [boolean]

Using this option will swap the effective foreground and background
color, regardless of whether their values originate from =-fg= and
=-bg=, or the corresponding resources, or the defaults. It will /not/
swap the meaning of color codes and such; if a program explicitly
specifies the color green, it will be rendered green with and without
=-rv=.

:   -boldColors   Enable bright for bold [boolean]

This option enables combining the bold attribute with a brightening of
base colors. That is, when printing bold text, colors 0 through 7 will
be mapped to colors 8 through 15 by adding 8 to the color number.
These normally correspond to the brighter variants of the same colors.
This is enabled by default; supply =+boldColors= on the command line
to turn it off.

:   -border       Border width in pixels (default: 2)

Specify the border width; specifically, the border that is part of the
client area of the Zutty window and not part of any window decoration
outside of the program's direct control. (This is equivalent to what
Xterm calls internal border width.)

:   -showWraps    Show wrap marks at right margin [boolean]

Specify whether to draw a vertical mark on the right edge of cells
having the =wrap= bit set. This bit is set in case an auto-wrap occurs
just after the given position, so it only gets set on the right
margin.  However, following an increase of the window size, cells with
a set =wrap= bit might reside inside the right margin.

When selecting text, line breaks are suppressed depending on the
=wrap= bit (wrapped text is copied without the breaks introduced by
the wraps), so a visual indicator of this status bit might be useful
to better understand (or predict) behaviour. It might also be useful
to see this when debugging Zutty or an application writing text at the
right margin.

:   -title        Window title (default: Zutty)

Set the title of the Zutty window. This might be overridden by usage
of the =-e= option (setting the title to the basename of the program
to be run), or at any later time by escape sequences output by the
shell (or any program executed by it).

** Shell/command specification

:   -login        Start shell as a login shell [boolean]

When this option is enabled, the shell started by Zutty will be a
login shell. This will be signalled to the shell process by setting
its =argv [0]= to begin with a dash (=-=). Shells evaluate different
sets of startup files depending on this (e.g., =bash= sources
=/etc/profile= and =~/.bash_profile= if started as a login shell, but
sources =~/.bashrc= otherwise). Please consult the documentation of
your shell for accurate details.

When using the =-e= option, this option will be ignored, because =-e=
is supposed to be used to launch non-shell text-mode programs in a
terminal window, and manipulating the =argv [0]= of such programs
might interfere with their operation.

:   -shell        Shell program to run

Specify the shell program to run in the terminal. As a bit of special
syntax, this option can be passed both as a regular option (=-shell
bash= anywhere among a list of other options), or just the shell
itself (=bash=) as the last item on the command line. Either way, this
option is mutually exclusive with using the =-e= option. If both forms
are present, the last item on the command line will take precedence
over the value supplied after =-shell=.

The algorithm to resolve the executable to spawn resembles the
behaviour of =xterm=, and follows these steps:

0. Start with the value of =shell= (the last argument given after all
   valid options, if present, or the value supplied after =-shell=).
   In case no =shell= argument is given, the =Zutty.shell= resource is
   consulted; if that is not set, the value of the =SHELL= environment
   variable is used; if that is not set, the built-in default of
   =bash= is assumed.
1. If not already an absolute path, resolve this to an absolute path
   taking =PATH= into account, trying elements of the list of =PATH=
   entries until the given shell resolves to an existing file at that
   path.
2. Fall back on the =SHELL= environment variable, then the user's
   =/etc/passwd= shell entry, if the above did not result in any
   candidate.
3. Use =/bin/sh= as a last resort.
4. Validate the outcome of the above steps against the permitted shell
   entries found in =/etc/shells=. Proceed, but clear =SHELL= from the
   environment if the program is not listed as a valid shell.  Else,
   set =SHELL= to the resolved full program path.

:   -e            Command line to run

This option specifies the command line (program and arguments) to be
run in the Zutty terminal window. It also sets the window title to the
basename of the program to be executed.

Note that this must be the last option on the command line, as
everything after it will be passed verbatim to the spawned child
process.

Using this option is mutually exclusive with the =-shell= option, and
will silently override it, as well as discarding the =-login= option,
if any of those are also present.

** Font selection

Zutty employs a simple but powerful model of font selection. Font
files are located under a search path and loaded by Zutty itself
(bypassing any infrastructure such as a font server, etc). In
principle, any font that is supported by the Freetype font library can
be used; in practice, only monospace fonts make sense. Both fixed size
(bitmap) fonts and scaled (vectorized) fonts are supported.

You specify the font to use by its name, which will be part of the
actual filename(s) that store the font. Multiple variants of the font
will be sought after: Zutty will try to find a Regular, a Bold, an
Italic and a Bold Italic variant of the font you specify. It is not an
error if these do not exist, as long as the primary variant (Regular)
is found.

:   -font        Font to use (default: 9x18)

This option specifies the font name to use. The name supplied will
form the basis of a case-insensitive search under the font search
path. The search will try to locate a set of files under the same
subdirectory, starting with the supplied name and ending with the same
extension that is one of the recognized font file extensions. If such
a set of files is found, the full filenames (the parts after the
specified font name) will be used to assign the files to each variant
sought after.

For example, the default font is =9x18=. This is one of the "misc
fixed" fonts. After seeing that the font name is =9x18=, Zutty will
search under the font path =/usr/share/fonts= for files starting with
=9x18=. It will find =9x18.pcf.gz= and =9x18B.pcf.gz=, both under
=/usr/share/fonts/X11/misc=. Based on the filenames, Zutty will
recognize the first file as the regular variant, and the second file
as the bold variant. Other variants are absent; use of text attributes
that depend on them will result in sensible fallbacks.

As a second example, we will load a scaled font called Liberation Mono
by supplying =-font LiberationMono= (or =-font liberationmono=) to
Zutty. This will result in several files found, all under
=/usr/share/fonts/truetype/liberation=: =LiberationMono-Regular.ttf=,
=LiberationMono-Bold.ttf=, =LiberationMono-Italic.ttf= and
=LiberationMono-BoldItalic.ttf=. These files will be loaded as the
respective variants of the chosen font.

:   -dwfont      Double-width font to use (default: 18x18ja)

This option specifies the font name to use for rendering double-width
characters (CJK ideographs). Everything written above for =-font=
applies here as well. The double-width font is located in a separate
search, so it may reside in a different location (the set of search
paths is the same; see =-fontpath=). It may also be of a different
type (e.g., it is possible to use a scaled font for CJK characters
even if the main font is of a fixed type). No variants (bold, italic)
are considered.

The default setting is a fixed width bitmap font chosen to work well
with the default main font (see =-font=). See [[Recommended fonts]] below
for tips on using a scalable CJK font.

The font size to use will be defined by the main font (governed by the
=-fontsize= option). For the double-width font to load, its geometry
must match this predetermined cell size (times two horizontally). It
is not an error if no suitable font is found. A warning will be logged
on startup, and the program will draw empty boxes in place of any
double-width characters. In such case, as only the ability to render
these characters is missing, it is still possible to select them in
Zutty and paste into a different program that is able to display them.

:   -fontsize    Font size (default: 16)

For scaled fonts, such as Liberation Mono above, this setting controls
the height, measured in integer pixels, to rasterize the glyphs to.
The actual character grid size will almost always be more, due to the
fact that typefaces have some spacing around the glyphs themselves.

The specified size, if within one pixel of the size of a bitmap
strike, will result in picking that strike (pre-rasterized version)
from a scaled font with strikes. If there are no strikes, or the
specified size is too far from any pre-rasterized sizes, Zutty falls
back to rendering the outline at the requested size.

In case of a fixed size font with multiple bitmap sizes, the size
closest to the configured size will be selected.

:   -fontpath    Font search path (default: /usr/share/fonts)

This option specifies the root of the directory structure where font
files will be searched. It is seldom necessary to change this, but
might be useful to try some new font you downloaded from the Internet
(and have not yet installed to a system-wide location).

Hint: you can specify more than one root, separated by colons. These
will be searched in order (left to right) until the specified font is
found.

*** Recommended fonts

The author of Zutty prefers the so-called [[https://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html][misc-fixed]] fonts. These are
upgraded, extended versions of the bitmap fonts originally designed
for the X Window System, created in the '80s in an era of much
inferior computer displays. Their availability is universal; you
probably have them installed already. These fonts are highly optimized
for readability at low resolutions. There is a convenient range of
sizes, several fonts have bold variants and support thousands of
international characters and symbols outside ASCII. Zutty will work
best with any of misc-fixed 6x13, 7x13, 7x14, 8x13, 9x15 and 9x18
(there are more, but the ones listed have a bold-face variant as
well).

If you prefer scalable fonts (e.g., because you have a high-resolution
HiDPI display or prefer LARGE glyphs with a more modern look), Zutty
works well with freely available scaled terminal fonts such as
Anonymous Pro, Deja Vu Sans Mono, Free Mono, Hack, Inconsolata,
Liberation Mono, Source Code Pro, and possibly many more.

The rest of this section gives Debian-specific recommendations; use it
as a source of inspiration if you use a different distribution. The
following list of package names might serve as a useful starting point
to obtain some usable fonts. For each package, install it and pass the
specified name(s) to =-font= to check them out:

- =xfonts-base=: 6x13, 7x13, 7x14, 8x13, 9x15, 9x18
- =fonts-dejavu-core=: DejaVuSansMono
- =fonts-liberation=: LiberationMono
- =fonts-freefont-ttf=: FreeMono
- =fonts-hack-otf=: Hack
- =fonts-inconsolata=: Inconsolata
- =ttf-anonymous-pro=: "Anonymous Pro"

Note that the quotation marks are required when passing an argument
value with a space, e.g.: =zutty -font "Anonymous Pro"=

The default CJK font =18x18ja= belongs to the =xfonts-base= package,
along with all other misc-fixed fonts recommended above. There is a
similar font =18x18ko= with the same fixed geometry providing more,
and slightly differently drawn, glyphs (try with =-dwfont 18x18ko=).

For scaled CJK fonts, the following packages are recommended:

- =fonts-wqy-microhei=: wqy-microhei
- =fonts-wqy-zenhei=: wqy-zenhei

For example, after installing the package =fonts-wqy-zenhei=, try
something like this to get a fully scalable font system:
=zutty -font dejavusansmono -dwfont wqy-zenhei -fontsize 32=\\
Experiment with the size; do not expect good results at small font
sizes.

In the above setup, the =-fontsize= setting guides the rasterized cell
size of the main font, the result of which guides the rasterized cell
size of the double-width font. The order is interesting mainly because
the rasterized size might be subtly different than the requested size.

A discussion of the subtle (language-specific) differences of CJK
glyphs provided by different fonts for the same code point is beyond
the scope of this document. [[https://en.wikipedia.org/wiki/Han_unification#Examples_of_language-dependent_glyphs][This table]] might be useful to identify
variants; copy-paste any glyph in a given row into Zutty and see which
variant the current font gives you!

*** Making fonts discoverable

Zutty has a simple heuristic to identify the font files to load for
each variant of a given size of a requested font face. This will work
for lots of fonts (see above), but inevitably, certain fonts will have
naming schemes that evade this mechanism. In such a case, manually
renaming the files on your system will help. An even better method is
to create symlinks (symbolic links) to the font files with alternative
names that Zutty will be able to correctly identify. This has the
advantage of preserving the original files.

For example, [[https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/][UW ttyp0]] is a family of freely available monospace bitmap
fonts that works well with Zutty. You might want to consider it as an
alternative to the "misc fixed" family. However, installing these
fonts will yield names such as (for the 18-point, Unicode encoded
variant): =t0-18-uni.pcf.gz= (regular), =t0-18b-uni.pcf.gz= (bold),
=t0-18i-uni.pcf.gz= (italic). The solution is to add symlinks such as:

- =t0-18.pcf.gz -> t0-18-uni.pcf.gz=
- =t0-18b.pcf.gz -> t0-18b-uni.pcf.gz=
- =t0-18i.pcf.gz -> t0-18i-uni.pcf.gz=

These symlinks will allow you to use this font in Zutty by starting it
via =-font t0-18=. Add a similar set of symlinks for each point size
you want to be able to use.

* Persistent configuration

The configuration options documented in the previous chapter
[[Configuration]] can be assigned altered defaults by adding entries to
the X resource database. Refer to the previous chapter for the list
and semantics of all options; here we show how to add entries for them
to your X resource database (Xrdb).

Open the file =.Xresources= in your home directory, or create it if
you do not have one. Use the following snippet merely as a starting
point; its purpose is to help you with enough examples to get what you
want, with the right syntax. Hint: you will /not/ want to set exactly
these options.

: Zutty.title:                   The Big Zutty
: Zutty.geometry:                120x45
: Zutty.altScroll:               true
: Zutty.boldColors:              false
: Zutty.font:                    Inconsolata
: Zutty.fontsize:                18
: Zutty.fontpath:                /home/tom/root/share/fonts:/usr/share/fonts
: Zutty.fg:                      #00ff80
: Zutty.bg:                      #234
: Zutty.cr:                      #0f0

As you can see, the general pattern is simple: one setting per line,
starting with a key that looks like =Zutty.<option>=, a colon, and the
desired value in a second column. The option names are exactly as
documented in the previous chapter.

Note that no quoting is necessary around string values containing a
space, and that boolean values are explicit, unlike on the command
line.

The program's resource lookup key =Zutty= is configurable via the
=-name= option and the =RESOURCE_NAME= environment variable (with the
former taking precedence over the latter), making it possible to have
various configuration sets activated by different instance names.  For
example, copy the above example snippet to something like this:

: MyCustomZutty.title:           The Custom Zutty
: MyCustomZutty.geometry:        135x54
: ...

Then, this custom configuration can be activated by starting Zutty via
=zutty -name MyCustomZutty= or =RESOURCE_NAME=MyCustomZutty zutty=.
Also, the WM_CLASS window property will be set to contain the
configured instance name, which might be useful for window management
(identification). Note: there is no fallback to the default instance
name =Zutty=; for each custom instance name, you need to duplicate all
the settings you care about.

After saving your =~/.Xresources=, run the command =xrdb -merge
~/.Xresources= to merge the new settings from your file to the
in-memory resource database. Alternatively, just restart your X
session (log out and back in to your graphical desktop).

The configured values will show up in the output of =zutty -h= to
confirm that your settings have taken effect. For example, if you were
following along, you should now see

:   -title        Window title (configured: The Big Zutty)

instead of the original version that read

:   -title        Window title (default: Zutty)

** Extra resources

Zutty can be configured via some extra resources not available as
command line options. To get a printout of all these extra resources
available for configuration, pass the =-listres= option to Zutty. The
result will look like this:

: Resources:
:   altSendsEscape    Encode Alt key as ESC prefix (default: true)
:   modifyOtherKeys   Key modifier encoding level; 0..2 (default: 1)
:   color0            Palette color 0 (default: #000000)
:   color1            Palette color 1 (default: #cd0000)
:   ...
:   color15           Palette color 15 (default: #ffffff)

To customize =<resource>=, put an entry into =~/.Xresources= under the
key =Zutty.<resource>=. For example:

: Zutty.altSendsEscape:          false
: Zutty.modifyOtherKeys:         0

After merging into Xrdb, the above output will reflect the configured
values, similar to the output of =zutty -h= for options as shown
above.

*** altSendsEscape

The resource setting =altSendsEscape= controls how key combinations
containing the Alt modifier are encoded. The setting can be toggled
dynamically at runtime via DEC set/reset 1036/1039 (both numbers are
equivalent).  This is an xterm extension. The default value is true
(enabled).

When enabled, hitting any ordinary key (letters, punctuation symbols,
etc.) while holding Alt will result in the key being prefixed by the
ESC character. This is also applied to some special keys, e.g.,
Alt-Tab sends =ESC TAB= and Alt-Backspace sends =ESC DEL= or =ESC \b=
depending on the current DECBKM mode setting.  This allows programs
such as terminal-mode Emacs to recognize keyboard bindings containing
Alt (or Meta).

If =altSendsEscape= is disabled (set to false), Alt will cause the
characters to be shifted by adding 128 (setting the 8-th bit). This is
then sent UTF-8 encoded to the shell.

Notes:
- Unlike XTerm, Zutty does not distinguish between Alt and
  Meta.
- In case =modifyOtherKeys= is non-zero (see below), the effects of
  that will take precedence over this setting and produce a uniform
  encoding for selected (if set to 1) or all (if set to 2) modified
  key combinations.

*** modifyOtherKeys

Zutty supports the =modifyOtherKeys= setting, which further affects
how special keys (modifier combinations) are encoded into control
sequences. It corresponds to xterm's identically named option (another
xterm extension; see its [[https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys][documentation]] and [[https://dickey.his.com/xterm/xterm.faq.html#xterm_modother][this FAQ entry]]).

This setting can be altered dynamically at runtime via the control
sequence =CSI > 4 ; P m= where =P= can be 0, 1 or 2 (or omitted, which
is equivalent to 0). This is typically done by programs such as Vim to
be able to distinguish between e.g., =TAB= and =^I=.

The default value of modifyOtherKeys can be configured via the Xrdb
resource with the same name. In the absence of any configuration, it
defaults to 1 when Zutty is started. This enables e.g., terminal-mode
Emacs to correctly recognize most key combinations, while preserving
the ability to generate raw control characters (such as =NUL= via
Control-2, =ESC= via Control-3, etc).  See the relevant table in the
[[./KEYS.html#Special key
 combinations][key mapping reference]] for several examples.

*** Base palette colors

The default 256-color palette of Zutty is identical to =xterm='s
default colors. You may override the base 16 colors via the resources
=color0= to =color15=.  Feel free to configure none, a couple, or all
of them.  Here is an example configuration for installing the colors
of the [[https://srcery-colors.github.io][Srcery]] palette:

: Zutty.color0:                  #1c1b19
: Zutty.color1:                  #ef2f27
: Zutty.color2:                  #519f50
: Zutty.color3:                  #fbb829
: Zutty.color4:                  #2c78bf
: Zutty.color5:                  #e02c6d
: Zutty.color6:                  #0aaeb3
: Zutty.color7:                  #d0bfa1
: Zutty.color8:                  #918175
: Zutty.color9:                  #f75341
: Zutty.color10:                 #98bc37
: Zutty.color11:                 #fed06e
: Zutty.color12:                 #68a8e4
: Zutty.color13:                 #ff5c8f
: Zutty.color14:                 #53fde9
: Zutty.color15:                 #fce8c3

Note that the default foreground and background colors are separate
from the palette: resetting the text color (via SGR 39) will set it to
the default foreground color (configurable via =fg=), which might or
might not be identical to =color15=. The same is true when resetting
the background color (via SGR 49): the default background color (via
=bg=) will be used, which might or might not be identical to =color0=.

** Removing and overriding persistent configuration

Removing a piece of configuration is a bit tricky. If you remove a
setting from =~/.Xresources= and merge that into Xrdb, it will have no
immediate effect, since the existing setting will still persist
in-memory until you restart your X session.

To get around this, you might issue =xrdb -remove= to drop all your
customizations (and then reload them from file). Another solution is
to use =xrdb ~/.Xresources= (without the =-merge=) to load exactly
what is in that file (as opposed to merging). Useful if you have no
other sources of configuration!

Now that you have a tailored baseline of how you expect Zutty to start
up without any explicit options, remember that you can still override
all options on the command line! For example, if you have
=Zutty.altScroll: true= in your config, you might start Zutty with the
=+altScroll= option to turn it off only in that instance.
