XTerm Notes

These are simply some notes I have saved concerning XTerm. I read through the manual in detail. I then explain the important bits of it to my future self who forgets what I have read before and needs another explanation.

Understanding XTerm and Backspace/DEL

Upstream XTerm source defaults to erase being the BS character. But IMNHO it should always be the DEL character. Debian patches XTerm in order to change BS to DEL.

That patch is picked up from all of the usual Debian derivatives so in Debian, Devuan, Ubuntu, Mint, Devuan, Trisquel, others, the default is good. Also in Void therefore I assume they use the same patch too. (I will look when I understand how Void builds packages.) However in other systems such as FreeBSD this patching is not done. When I launched an XTerm in FreeBSD with no configuration the default was BS. Therefore FreeBSD required me to set a configuration to make erase DEL.

This override works. Initially when this override seemed the way I found this worked. Note that the order of definition matters. Defining this override in the opposite order does not work. Therefore the code for matching keys must be priority order specific. (Or maybe I needed to say something like ~Alt to force indicate that Alt is not pressed? I came upon that later and have not tested it.)

XTerm*VT100.Translations: #override \n\
    Alt <Key>BackSpace: string(0x1b) string(0x7f)\n\
    <Key>BackSpace: string(0x7f)

But then discovered backarrowKey:false and that seemed simpler and better and possibly more correct. Therefore my current solution was arrived at using this following research path.

Here is the upstream documentation.

Let me replicate snippets from the above here. This is the upstream documentation for XTerm.

Application Resources

   backarrowKeyIsErase (class BackarrowKeyIsErase)
           Tie the VTxxx backarrowKey and ptyInitialErase resources
           together by setting the DECBKM state according to whether the
           initial erase character is a backspace (8) or delete (127)
           character.  A "false" value disables this feature.  The default
           is "False".

           Here are tables showing how the initial settings for

           o   backarrowKeyIsErase (BKIE),

           o   backarrowKey (BK), and

           o   ptyInitialErase (PIE), along with the

           o   stty erase character (^H for backspace, ^? for delete)

           will affect DECBKM.  First, xterm obtains the initial erase
           character:

           o   xterm''s internal value is ^H

           o   xterm asks the operating system for the value which stty
               shows

           o   the ttyModes resource may override erase

           o   if ptyInitialErase is false, xterm will look in the
               terminal database

           Summarizing that as a table:

           PIE     stty   termcap   erase

           -------------------------------
           false    ^H      ^H       ^H
           false    ^H      ^?       ^?
           false    ^?      ^H       ^H
           false    ^?      ^?       ^?
           true     ^H      ^H       ^H
           true     ^H      ^?       ^H
           true     ^?      ^H       ^?
           true     ^?      ^?       ^?

           Using that erase character, xterm allows further choices:

           o   if backarrowKeyIsErase is true, xterm uses the erase
               character for the initial state of DECBKM

           o   if backarrowKeyIsErase is false, xterm sets DECBKM to 2
               (internal).  This ties together backarrowKey and the
               control sequence for DECBKM.

           o   applications can send a control sequence to set/reset
               DECBKM control set

           o   the "Backarrow Key (BS/DEL)" menu entry toggles DECBKM

           Summarizing the initialization details:

           erase   BKIE    BK      DECBKM   result
           ----------------------------------------
            ^?     false   false     2        ^H
            ^?     false   true      2        ^?
            ^?     true    false     0        ^?
            ^?     true    true      1        ^?
            ^H     false   false     2        ^H
            ^H     false   true      2        ^?
            ^H     true    false     0        ^H
            ^H     true    true      1        ^H

Wow! That's quite the logic flow that someone created in there. I might even go so far as to say this feels like a spaghetti monster. Feels like if one carefully worked through it that there might be a path that would result in DEL be selected for erase.

   ptyInitialErase (class PtyInitialErase)
           If "true", xterm will use the pseudo-terminal''s sense of the
           stty erase value.  If "false", xterm will set the stty erase
           value to match its own configuration, using the kb string from
           the termcap entry as a reference, if available.

           In either case, the result is applied to the TERMCAP variable
           which xterm sets, if the system uses TERMCAP.

           See also the ttyModes resource, which may override this.  The
           default is "False".

The ptyInitialErase seems ineffective. Need to write a C program to create a pty pair and inspect the initial pty state to verify. But setting ptyInitialErase:true had no effect in my testing. Perhaps the erase character is being set to '#' which was the early default?

   backarrowKey (class BackarrowKey)
           Specifies whether the backarrow key transmits a backspace (8)
           or delete (127) character.  This corresponds to the DECBKM
           control sequence.  A "true" value specifies backspace.  The
           default is "True".  Pressing the control key toggles this
           behavior.

Setting backarrowKey false correctly sets erase to DEL but does not set stty erase to DEL. This simple setting seems to anticlimactic after reading through the documentation for backarrowKeyIsErase. Simplest is usually best. Therefore this is best. It does require also using ttyModes because though XTerm now sends the desired character it does not set up the tty to match.

   ttyModes (class TtyModes)
           Specifies a string containing terminal setting keywords.
           Except where noted, they may be bound to characters.  Other
           keywords set modes.  Not all keywords are supported on a given
           system.  Allowable keywords include:

           Keyword   POSIX?   Notes
           ----------------------------------------------------------------
           brk       no       CHAR may send an "interrupt" signal, as well
                              as ending the input-line.
           dsusp     no       CHAR will send a terminal "stop" signal
                              after input is flushed.
           eof       yes      CHAR will terminate input (i.e., an end of
                              file).
           eol       yes      CHAR will end the line.
           eol2      no       alternate CHAR for ending the line.
           erase     yes      CHAR will erase the last character typed.
           erase2    no       alternate CHAR for erasing the last input-
                              character.
           flush     no       CHAR will cause output to be discarded until
                              another flush character is typed.
           intr      yes      CHAR will send an "interrupt" signal.
           kill      yes      CHAR will erase the current line.
           lnext     no       CHAR will enter the next character quoted.
           quit      yes      CHAR will send a "quit" signal.
           rprnt     no       CHAR will redraw the current line.
           start     yes      CHAR will restart the output after stopping
                              it.
           status    no       CHAR will cause a system-generated status
                              line to be printed.
           stop      yes      CHAR will stop the output.
           susp      yes      CHAR will send a terminal "stop" signal
           swtch     no       CHAR will switch to a different shell layer.
           tabs      yes      Mode disables tab-expansion.
           -tabs     yes      Mode enables tab-expansion.
           weras     no       CHAR will erase the last word typed.

           Control characters may be specified as ^char (e.g., ^c or ^u)
           and ^? may be used to indicate delete (127).  Use ^- to denote
           undef.  Use \034 to represent ^\, since a literal backslash in
           an X resource escapes the next character.

           This is very useful for overriding the default terminal
           settings without having to run stty every time an xterm is
           started.  Note, however, that the stty program on a given host
           may use different keywords; xterm''s table is built in.  The
           POSIX column in the table indicates which keywords are
           supported by a standard stty program.

           If the ttyModes resource specifies a value for erase, that
           overrides the ptyInitialErase resource setting, i.e., xterm
           initializes the terminal to match that value.

And therefore we reach the simple configuration solution for Xresources.

!! Setting backarrowKey false correctly sets erase to DEL but does not
!! set stty erase to DEL.  Still needs ttyModes: erase ^? too.
XTerm*backarrowKey:false
XTerm*ttyModes: erase ^?

Whew! That gets the basic keyboard setup done. Just a little more configuration to finish things off.

Keyboard Setup

   metaSendsEscape (class MetaSendsEscape)
           Tells xterm what to do with input-characters modified by Meta:

           o   If "true", Meta characters (a character combined with the
               Meta modifier key) are converted into a two-character
               sequence with the character itself preceded by ESC.  This
               applies as well to function key control sequences, unless
               xterm sees that Meta is used in your key translations.

           o   If "false", Meta characters input from the keyboard are
               handled according to the eightBitInput resource.

           The default is "False".

Normally I use metaSendsEscape:true in order to use Meta for both bash command line and for emacs. This works everywhere and I have been using it for a couple of decades. I think I went this route due to bash (and possibly ksh first) not supporting the 8th bit modifier.

   eightBitInput (class EightBitInput)
           If "true", Meta characters (a single-byte character combined
           with the Meta modifier key) input from the keyboard are
           presented as a single character, modified according to the
           eightBitMeta resource.  If "false", Meta characters are
           converted into a two-character sequence with the character
           itself preceded by ESC.  The default is "true".

           The metaSendsEscape and altSendsEscape resources may override
           this feature.  Generally keyboards do not have a key labeled
           "Meta", but "Alt" keys are common, and they are conventionally
           used for "Meta".  If they were synonymous, it would have been
           reasonable to name this resource "altSendsEscape", reversing
           its sense.  For more background on this, see the meta(3X)
           function in curses.

           Note that the Alt key is not necessarily the same as the Meta
           modifier.  The xmodmap utility lists your key modifiers.  X
           defines modifiers for shift, (caps) lock and control, as well
           as 5 additional modifiers which are generally used to configure
           key modifiers.  Xterm inspects the same information to find the
           modifier associated with either Meta key (left or right), and
           uses that key as the Meta modifier.  It also looks for the
           NumLock key, to recognize the modifier which is associated with
           that.

           If your xmodmap configuration uses the same keycodes for Alt-
           and Meta-keys, xterm will only see the Alt-key definitions,
           since those are tested before Meta-keys.  NumLock is tested
           first.  It is important to keep these keys distinct; otherwise
           some of xterm's functionality is not available.

           The eightBitInput resource is tested at startup time.  If
           "true", the xterm tries to put the terminal into 8-bit mode.
           If "false", on startup, xterm tries to put the terminal into
           7-bit mode.  For some configurations this is unsuccessful;
           failure is ignored.  After startup, xterm does not change the
           terminal between 8-bit and 7-bit mode.

           As originally implemented in X11, the resource value did not
           change after startup.  However (since patch #216 in 2006) xterm
           can modify eightBitInput after startup via a control sequence.
           The corresponding terminfo capabilities smm (set meta mode) and
           rmm (reset meta mode) have been recognized by bash for some
           time.  Interestingly enough, bash's notion of "meta mode"
           differs from the standard definition (in the terminfo manual),
           which describes the change to the eighth bit of a character.
           It happens that bash views "meta mode" as the ESC character
           that xterm puts before a character when a special meta key is
           pressed.  bash's early documentation talks about the ESC
           character and ignores the eighth bit.

Another long bit of documentation describing these deep details. The note about bash not handling 8th bit meta, at least in the earlier days, I think is why metaSendsEscape:true has been the desired choice.

!! Configure Alt as the Meta key to send ESC prefix.
XTerm*metaSendsEscape:true

I settled on metaSendsEscape:true for some definition of a very long time now.

Mouse Interaction

This is definitely going to be something that other people won't like. But I always want to have the mouse available for copy and paste operations. Some programs such as htop take over the mouse and use it for other purposes. That's great, for other people. Not for me. I disable this so that the mouse on a terminal always behaves like a mouse on a terminal.

   allowMouseOps (class AllowMouseOps)
           Specifies whether control sequences that enable xterm to send
           escape sequences to the host on mouse-clicks and movement.  The
           default is "true".

I like to be able to use the mouse to copy and paste text from one place to another place. But allowMouseOps:true breaks that ability in applications that enable it. Because then instead of the terminal performing the copy it sends mouse events expecting the application to handle it approprirately. Which fails miserably! For example htop uses mouse events and clicking will not copy but will only select the entry. Very frustrating!

!! Mouse for copy and paste not for selecting.
XTerm*allowMouseOps:false

I never have a use for selecting the entry with the mouse but I do want to copy text often. When those became enabled by default this just about killed me until I turned it off.

Where is focus?

Originally with X Windows the "I" always showed where input would go when typing. This appears to annoy people because they turn it off. Not knowing where focus is located annoys me. I turn off hiding of the pointer so that I can always see where input is going.

   pointerMode (class PointerMode)
           Specifies when the pointer may be hidden as the user types.  It
           will be redisplayed if the user moves the mouse, or clicks one
           of its buttons.

           0  never

           1  the application running in xterm has not activated mouse
              mode.  This is the default.

           2  always.

That results in this X resource setting.

! Restore previous default of never hiding the pointer.
XTerm*pointerMode:0

Hiding the pointer is useful for people using Click-To-Focus in the window manager which both raises the window and focuses input. In that case the window with focus is always the one on top. But I use Focus-Follows-Mouse which is the original X Windows default behavior and want to see which window has the mouse and therefore which window has focus. This is not necessarily the window on top and might be the input window under a graphics one.

UTF-8, Unicode, Locales

The upstream documentation says this. I start there. I analyze what it says afterward.

   locale (class Locale)
           Specifies how to use luit, an encoding converter between UTF-8
           and locale encodings.  The resource value (ignoring case) may
           be:

           true
               Xterm will use the encoding specified by the users'
               LC_CTYPE locale (i.e., LC_ALL, LC_CTYPE, or LANG variables)
               as far as possible.  This is realized by always enabling
               UTF-8 mode and invoking luit in non-UTF-8 locales.

           medium
               Xterm will follow users' LC_CTYPE locale only for UTF-8,
               east Asian, and Thai locales, where the encodings were not
               supported by conventional 8bit mode with changing fonts.
               For other locales, xterm will use conventional 8bit mode.

           checkfont
               If mini-luit is compiled-in, xterm will check if a Unicode
               font has been specified.  If so, it checks if the character
               encoding for the current locale is POSIX, Latin-1 or
               Latin-9, uses the appropriate mapping to support those with
               the Unicode font.  For other encodings, xterm assumes that
               UTF-8 encoding is required.

           false
               Xterm will use conventional 8bit mode or UTF-8 mode
               according to utf8 resource or -u8 option.

           Any other value, e.g., "UTF-8" or "ISO8859-2", is assumed to be
           an encoding name; luit will be invoked to support the encoding.
           The actual list of supported encodings depends on luit.  The
           default is "medium".

           Regardless of your locale and encoding, you need an ISO-10646-1
           font to display the result.  Your configuration may not include
           this font, or locale-support by xterm may not be needed.

           At startup, xterm uses a mechanism equivalent to the
           load-vt-fonts(utf8Fonts, Utf8Fonts) action to load font name
           subresources of the VT100 widget.  That is, resource patterns
           such as "*vt100.utf8Fonts.font" will be loaded, and (if this
           resource is enabled), override the normal fonts.  If no
           subresources are found, the normal fonts such as "*vt100.font",
           etc., are used.

           For instance, you could have this in your resource file:

               *VT100.font: 12x24
               *VT100.utf8Fonts.font:9x15

           When started with a UTF-8 locale, xterm would use 9x15, but
           allow you to switch to the 12x24 font using the menu entry
           "UTF-8 Fonts".

           The resource files distributed with xterm use ISO-10646-1
           fonts, but do not rely on them unless you are using the locale
           mechanism.

   utf8 (class Utf8)
           This specifies whether xterm will run in UTF-8 mode.  If you
           set this resource, xterm also sets the wideChars resource as a
           side-effect.  The resource can be set via the menu entry "UTF-8
           Encoding".  The default is "default".

           Xterm accepts either a keyword (ignoring case) or the number
           shown in parentheses:

           false (0)
              UTF-8 mode is initially off.  The command-line option +u8
              sets the resource to this value.  Escape sequences for
              turning UTF-8 mode on/off are allowed.

           true (1)
              UTF-8 mode is initially on.  Escape sequences for turning
              UTF-8 mode on/off are allowed.

           always (2)
              The command-line option -u8 sets the resource to this value.
              Escape sequences for turning UTF-8 mode on/off are ignored.

           default (3)
              This is the default value of the resource.  It is changed
              during initialization depending on whether the locale
              resource was set, to false (0) or always (2).  See the
              locale resource for additional discussion of non-UTF-8
              locales.

           If you want to set the value of utf8, it should be in this
           range.  Other nonzero values are treated the same as "1", i.e.,
           UTF-8 mode is initially on, and escape sequences for turning
           UTF-8 mode on/off are allowed.

   utf8Fonts (class Utf8Fonts)
           See the discussion of the locale resource.  This specifies
           whether xterm will use UTF-8 fonts specified via resource
           patterns such as "*vt100.utf8Fonts.font" or normal (ISO-8859-1)
           fonts via patterns such as "*vt100.font".  The resource can be
           set via the menu entry "UTF-8 Fonts".  The default is
           "default".

           Xterm accepts either a keyword (ignoring case) or the number
           shown in parentheses:

           false (0)
                  Use the ISO-8859-1 fonts.  The menu entry is enabled,
                  allowing the choice of fonts to be changed at runtime.

           true (1)
                  Use the UTF-8 fonts.  The menu entry is enabled,
                  allowing the choice of fonts to be changed at runtime.

           always (2)
                  Always use the UTF-8 fonts.  This also disables the menu
                  entry.

           default (3)
                  At startup, the resource is set to true or false,
                  according to the effective value of the utf8 resource.

It used to be that I would set locale:true because I thought that was needed in order to get UTF-8 fonts. But reading the documentation carefully shows that locale:false with utf8:always produces the desired result without involving the LC_CTYPE environment variable and therefore seems more reliable.

XTerm*locale:false
XTerm*utf8:always

I don't disable the utf8Fonts menu checkbox with utf8Fonts:true because I never change it. But that could be the same.

Tektronics Graphical

The Tektronix 4010 is a combined text and graphics terminal from the 1970's. I have never seen one in real life. But they were an influential terminal and many other terminals implemented the same thing or something similar.

The Arch wiki page provides for a demonstration. I have not ever needed to use the graphics mode. Therefore I disable it as a simplification. I can't get switched into graphics mode if I have disabled the mode.

   tekInhibit (class TekInhibit)
           Specifies whether or not the escape sequence to enter Tektronix
           mode should be ignored.  The default is "false".

Results in this X resource configuration.

XTerm*TekInhibit:on

Scroll Bars

I like having scrollbars. Once again other people disable them.

          Enable Scrollbar (resource scrollbar)
                 Enable (or disable) the scrollbar.  This corresponds to
                 the -sb option and the scrollBar resource.

Results in this X resource configuration.

XTerm*ScrollBar:on

If not set the default is to not have a scrollbar. I like the scrollbar.

Jump Scrolling

   -j      This option indicates that xterm should do jump scrolling.  It
           corresponds to the jumpScroll resource.  Normally, text is
           scrolled one line at a time; this option allows xterm to move
           multiple lines at a time so that it does not fall as far
           behind.  Its use is strongly recommended since it makes xterm
           much faster when scanning through large amounts of text.  The
           VT100 escape sequences for enabling and disabling smooth scroll
           as well as the VT Options menu can be used to turn this feature
           on or off.

Results in this X resource configuration.

XTerm*JumpScroll:true

Avoids some of the problem of becoming trapped waiting for a large amount of text to spew forth by allowing XTerm to jump ahead. It does not avoid the I/O buffering of it. But keeps the terminal out of the bottleneck of it.

Other Miscellany

Completely just personal preference choices.

XTerm*Foreground:White
XTerm*Background:Black
XTerm*cursorColor:Yellow
XTerm*pointerColor:Yellow

Following are simply historical snippets I have tried over the years and am not currently using but might want to investigate again.

! XTerm*VT100*font2:5x7
! XTerm*VT100*font3:6x10
! XTerm*VT100*font4:7x13
! XTerm*VT100*font5:9x15

!!XTerm*fontMenu*fontdefault*Label:Default 16
!!XTerm*fontMenu*font1*Label:Unreadable 2
!!XTerm*fontMenu*font2*Label:Tiny 12
!!XTerm*fontMenu*font3*Label:Small 14
!!XTerm*fontMenu*font4*Label:Medium 16
!!XTerm*fontMenu*font5*Label:Large 18
!!XTerm*fontMenu*font6*Label:Huge 24
!!
!!scalable*faceName:Inconsolata
!!scalable*faceSize:12
!!scalable*faceSize1:3
!!scalable*faceSize2:5
!!scalable*faceSize3:7
!!scalable*faceSize4:12
!!scalable*faceSize5:18
!!scalable*faceSize6:25
!!
!!! XTerm*Font:-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-iso10646-1
!!XTerm*Font:-efont-fixed-medium-r-normal-*-16-*-*-*-*-*-iso10646-1
!!XTerm*Font2:-efont-fixed-medium-r-normal-*-12-*-*-*-*-*-iso10646-1
!!XTerm*Font3:-efont-fixed-medium-r-normal-*-14-*-*-*-*-*-iso10646-1
!!XTerm*Font4:-efont-fixed-medium-r-normal-*-16-*-*-*-*-*-iso10646-1
!!XTerm*Font5:-misc-fixed-medium-r-normal--18-*-*-*-*-*-iso10646-1
!!XTerm*Font6:-efont-fixed-medium-r-normal-*-24-*-*-*-*-*-iso10646-1

Because of the fonts issue I will sneak some graphical emacs in too.

Emacs*Foreground:White
Emacs*Background:Black
Emacs*cursorColor:Yellow
! Emacs*font:-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-iso10646-1
!!Emacs*font:-efont-fixed-medium-r-normal-*-16-*-*-*-*-*-iso10646-1
! Emacs*Geometry:80x50

An example here at Stack Overflow is the only reference I see anywhere that shows how to combine characters such as ESC DEL into a string. This produced "Alt BackSpace: string(0x1b) string(0x7f)" for me which initially worked as an override.

That Stack Overflow entry suggests this following.

xterm -xrm 'XTerm.VT100.translations: \n\
    #override \n\
Ctrl<Key>Left: string(0x1b) string("b") \n\
Ctrl<Key>Right: string(0x1b) string("f")'

A Stack Exchange posting just not quite there.

Here is another valiant attempt to document this problem.

Worth saving at least this blog about xterm.

It includes this field map cheat sheet.

-bitstream-charter-medium-r-normal-xxx-0-0-0-0-p-0-iso8859-1
     |        |      |    |   |     |  | | | | | |    \    \
     |        |      |    |   |     \  \ \ \ \ \ \     +----+- character set
     |        |      |    |   \      \  \ \ \ \ \ +- average width
     |        |      |    |    \      \  \ \ \ \ +- spacing
     |        |      |    \     \      \  \ \ \ +- vertical res.
     |        |      |     \     \      \  \ \ +- horizontal res.
     |        |      |      \     \      \  \ +- points
     |        |      |       \     \      \  +- pixels
     |        |      |        \     \      \
  foundry  family  weight   slant  width  additional style

Another example of mapping override.

Includes this one.

<Key>KP_Enter: string(0x1b) string("OM") \n\

License

Copyright (C) 2022, 2023 Bob Proulx

Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.