# keybindings

## Default keybindings

TF's default command line editing keys are similar to those in emacs and bash. In addition, several features may be invoked by more than one keybinding, and TF has keybindings for unique features like switching the foreground socket.

Here, and throughout the TF documentation, the notation "^X" means the character generated by typing the X key while holding the CTRL key. Also, "^[" can be more easily typed just by pressing the ESC key. /Def -b and /bind accept the ^X notation as well as "\number" notation, where number is the octal, hexadecimal, or decimal number of the character's ascii value. For example, the escape character can be given in any of these forms: ^[, \033, \0x1B, or \27.

In the tables below, keys with "*" in the "Meaning" column make use of kbnum (see below).

### Named keys

    Key	    Command		    Meaning
    ---	    -------		    -------
    Up	    /kb_up_or_recallb	    *cursor up or recall bkwd input history
    Down	    /kb_down_or_recallf	    *cursor down or recall fwd input history
    Right	    /dokey RIGHT	    *cursor right
    Left	    /dokey LEFT		    *cursor left
    Center	    (none)

    Esc_Left    /fg -<		    *foreground previous socket
    Esc_Right   /fg ->		    *foreground next socket

    Ctrl_Up     /dokey_recallb	    *recall backward input
    Ctrl_Down   /dokey_recallf	    *recall forward input
    Ctrl_Right  /dokey_wright	    *word right
    Ctrl_Left   /dokey_wleft	    *word left

    Insert	    /test insert:=!insert    toggle insert mode
    Delete	    /dokey dch		    *delete character
    Home	    /dokey_home		     cursor to beginning of line
    End	    /dokey_end		     cursor to end of line
    PgDn	    /dokey_pgdn		    *scroll forward a screenful
    PgUp	    /dokey_pgup		    *scroll back a screenful
    Tab	    /dokey page		    *scroll forward a screenful

    Ctrl_Home   /dokey_recallbeg	     recall first line of input
    Ctrl_End    /dokey_recallend	     recall last line of input
    Ctrl_PgDn   /dokey_flush	     scroll forward to last screenful
    Ctrl_PgUp   (reserved for future use)

    F1	    /help		     help
    F2	    (none)		     (see text below)
    ...
    F12	    (none)

    nkp1	    (none)		     (see text below)
    ...
    nkp9	    (none)

### Unnamed key sequences

    String	Command			Meaning
    ------	-------			-------
    "^A"	/dokey_home		 cursor to beginning of line
    "^B"	/dokey LEFT		*cursor left
    "^D"	/dokey_dch		*delete character to the right
    "^E"	/dokey_end		 cursor to end of line
    "^F"	/dokey RIGHT		*cursor right
    "^G"	/beep 1			 beep
    "^H"	(internal)		*backspace
    "^I"	/key_tab		 perform the function assigned to the TAB key
    "^J"	(internal)		 execute current line
    "^K"	/dokey_deol		 delete to end of line
    "^L"	/dokey redraw		 redraw (not clear) screen
    "^M"	(internal)		 execute current line
    "^N"	/dokey recallf		*recall forward input history
    "^P"	/dokey recallb		*recall backward input history
    "^Q"	/dokey LNEXT		 input next key literally (may be overridden
    				 by terminal)
    "^R"	/dokey REFRESH		 refresh line
    "^S"	/dokey PAUSE		 pause screen
    "^T"	/kb_transpose_chars	*transpose characters
    "^U"	/kb_backward_kill_line	 delete to beginning of line
    "^V"	/dokey LNEXT		 input next key literally
    "^W"	/dokey BWORD		*delete backward word (space-delimited)
    "^?"	(internal)		*backspace
    "^X^R"	/load ~/.tfrc		 reload personal config file
    "^X^V"	/version		 display version information
    "^X^?"	/kb_backward_kill_word	*delete backward word (punctuation-delimited)
    "^X["	/dokey_hpageback	*scroll back a half screenful
    "^X]"	/dokey_hpage		*scroll forward a half screenful
    "^X{"	/dokey_pageback		*scroll back a screenful
    "^X}"	/dokey_page		*scroll forward a screenful
    "^[^E"	/kb_expand_line		 expand current input line in place
    "^[^H"	/kb_backward_kill_word	*delete backward word (punctuation-delimited)
    "^[^I"	/complete		 complete current word, depending on context
    "^[^L"	/dokey clear		 clear screen (can be refilled with scrollback)
    "^[^N"	/dokey line		*scroll forward one line
    "^[^P"	/dokey lineback		*scroll back one line
    "^[^W"	/complete worldname	 complete TF world name
    "^[$"	/complete macroname	 complete TF macro name
    "^[%"	/complete variable	 complete TF variable name
    "^[/"	/complete filename	 complete file name (unix only)
    "^[ "	/kb_collapse_space	 change multiple spaces to a single space
    "^[-"	/set kbnum=-		 start kbnum entry with -
    "^[0"	/set kbnum=+0		 start kbnum entry with 0
    ...
    "^[9"	/set kbnum=+9		 start kbnum entry with 9
    "^[;"	/complete user_defined	 complete from %{completion_list}
    "^[="	/kb_goto_match		 move cursor to matching parenthesis/bracket
    "^[."	/kb_last_argument	 input last word of previous line
    "^[<"	/dokey recallbeg	 go to beginning of input history
    "^[>"	/dokey recallend	 go to end of input history
    "^[J"	/dokey selflush		 selective flush (similar to "/dokey flush"
    				 followed by "/limit -a")
    "^[L"	/kb_toggle_limit	 toggle between /unlimit and /relimit
    "^[_"	/kb_last_argument	 input last word of previous line
    "^[b"	/dokey_wleft		*cursor to beginning of word
    "^[c"	/kb_capitalize_word	*capitalize word
    "^[d"	/kb_kill_word		*delete forward word
    "^[f"	/dokey_wright		*cursor to end of word
    "^[h"	/dokey_hpage		*scroll forward a half screenful
    "^[i"	/complete input_history	 complete from previously typed words
    "^[j"	/dokey flush		 jump to last screenful of text
    "^[l"	/kb_downcase_word	*convert word to lower case
    "^[n"	/dokey searchf		*search forward input history
    "^[p"	/dokey searchb		*search backward input history
    "^[u"	/kb_upcase_word		*convert word to upper case
    "^[v"	/@test insert:=!insert	 toggle insert mode
    "^[w"	/to_active_or_prev_world /fg next active world, or previous world
    "^[{"	/fg -<			*foreground previous socket
    "^[}"	/fg ->			*foreground next socket
    "^[^?"	/kb_backward_kill_word	*delete backward word (punctuation-delimited)
    "^]"	/bg			 put all sockets in background

### Other useful commands not bound by default

    Command			Meaning
    -------			-------
    /dokey_bspc		*delete character
    /dokey UP		*cursor up
    /dokey DOWN		*cursor down
    /dokey RECALLB		*recall input backward
    /dokey RECALLF		*recall input forward
    /dokey NEWLINE		 execute input line

### Terminal keys

Some keys are interpeted by the terminal, not TF, so if you want to change them, you must do so outside of TF (e.g. with `stty` in unix). Typical unix terminal keys include:

        Key   Name   Meaning
        ---   ----   -------
        ^C    int    generates a SIGINT signal.
        ^\    quit   generates a SIGQUIT signal.
        ^Z    susp   suspends the TF process

When TF starts, it disables the terminal driver's "stop" and "start" keys (typically ^S and ^Q), so they are available for binding within TF.

## Using keys

Keys F1...F12 are the function keys, located across the top of most keyboards.

Keys with names of the form "esc_name" correspond to the ESC key followed by the name key. There is an "esc_name" for every single key in the Named Key table above, but only the ones with default meanings are listed in the table; the rest are available for custom definitions.

On recent versions of xterm with the modifyCursorKeys resource, tf can recognize when the CTRL, SHIFT, or META modifier is held down while pressing the editor keys (insert, delete, home, end, pgdn, pgup), arrow keys, or numbered function keys, and calls `/key_ctrl_name`, `/key_shift_name`, or `/key_meta_name`, respectively. Additionally, by default, each `/key_meta_name` calls the corresponding `/key_esc_name`, so, for example, pressing META-Left has the same effect as ESC Left. If you use another terminal emulator that generates unique character sequences for ctrl-, shift-, and meta-modified keys, you can bind those sequences to call the corresponding `/key_mod_name` (and send them to the author for inclusion in a future release of tf).

TF tries to put the keypad in "application mode", which on many terminals will make the keypad keys generate unique character sequences if Num Lock is on. Application mode can be disabled by setting %keypad to "off". The meaning of your numeric keypad keys depends on your terminal emulator, setting of %keypad, and the state of NumLock. For example, in some versions of xterm, the numbered keys of the numeric keypad act like this:

              NumLock off                       %keypad on
                                              and NumLock on

         +------+------+------+            +------+------+------+
         |Home  |Up    |PgUp  |            |nkp7  |nkp8  |nkp9  |
         +------+------+------+            +------+------+------+
         |Left  |Center|Right |            |nkp4  |nkp5  |nkp6  |
         +------+------+------+            +------+------+------+
         |End   |Down  |PgDn  |            |nkp1  |nkp2  |nkp3  |
         +------+------+------+            +------+------+------+

And in an xterm with %keypad off and NumLock on, they act like normal digit keys.

In some configurations, unnamed key sequences consisting of "^[" (ESC) followed by one other character may also be typed by holding the META key while typing the other character instead of typing ESC before the other character. See %meta_esc.

The one-time warning about certain new keybindings in 5.0 can be disabled by setting the variable warn_5keys=off.

## Mapping Named Keys to functions

Each key in the Named Key table above is implemented by a macro named key_name; the standard definition of key_name is shown in the "Command" column. If you wish to change the functionality of any named key, you should do so by redefining key_name, not by redefining the binding for the character sequence generated by the key, nor by redefining the /dokey_* or /kb_* command that key_name calls. There are several advantages to this method: you do not need to know what characters are generated by the special keys on your keyboard, and they will work on multiple terminals. For example, if you want Insert to invoke your own macro /foo, you should redefine "`/def key_insert = /foo`".

Examples of popular alternatives to the standard key definitions:

Make PgUp and PgDn to scroll a half screen instead of a full screen:

        /def key_pgdn = /dokey_hpage
        /def key_pgup = /dokey_hpageback

Make up and down arrow keys perform movement only:

        /def key_up = /dokey_up
        /def key_down = /dokey_down

Make up and down arrow keys perform input recall only:

        /def key_up = /dokey_recallb
        /def key_down = /dokey_recallf

Before version 5.0, /def -B was the only way to bind a named key to a macro. This, however, has been superceded by the use of "key_name" macros. Whereas /def -B depends strictly on termcap entries, the bindings to "key_name" macros are automatically generated from TF's own list of standard keybindings in addition to termcap entries. Termcap entries are often incomplete or not well matched to your terminal emulator; TF's additional keybindings fill in the gaps. So, to redefine the meaning of a named key, you should redefine "`/def key_name` = ...", not "`/def -Bname` = ...". The names recognized by /def -B are different than the names in the Named Key table. For reference, they are: the function keys "F0", "F1",... "F19"; the keypad keys "KP1" (upper left), "KP2" (center), "KP3" (upper right), "KP4" (lower left), "KP5" (lower right); the arrow keys "Up", "Down", "Right", "Left"; and the other keys, "Backspace", "Clear EOL", "Clear EOS", "Clear Screen", "Delete", "Delete Line", "Home", "Home Down", "Insert", "Insert Line", "PgDn", "PgUp", "Scroll Down", "Scroll Up". They must be spelled as shown, but capitalization is ignored. The function keycode() can be used to find the string generated by a key (as defined in the termcap entry for %TERM).

## Mapping character sequences to functions

/Def -b (or /bind) allows you to bind a character sequence to a macro body. Typing that sequence at the keyboard (which may mean pressing a single key that generates the sequence) will then execute the macro body.

TF's input handler recognizes ^H and ^? as backspace and ^J and ^M as newline, even when they are not bound to anything. However, if a keybinding is defined for any of these keys, it will override the internal handling of that key.

At startup, TF also examines the terminal driver settings for character sequences corresponding to the /dokey functions BWORD, DLINE, REFRESH, and LNEXT, and binds them accordingly in addition to the default bindings listed above.

## Mapping character sequences to Named Keys

Because TF runs in a terminal and not in a windowing system, it does not see actual keystrokes, but only the characters generated by a keystroke. For example, the up arrow key on many terminals generates "^[[A", and that is what TF receives. Thus, TF uses a set of definitions like "`/def -b'charsequence' = /key_name`" to map chracter sequences to the keys that generate them. If two different keys generate the same sequence of characters, there is no way for TF to tell them apart.

At startup, TF automatically binds character sequences to the named key macros according to vt100, vt220, ANSI, and xterm definitions, plus OS/2 definitions if running on OS/2, as well as the termcap entry corresponding to your %TERM variable. If the named keys on your terminal generate character sequences that are not recognized by TF, you will need to bind them yourself with "`/def -b'charsequence' = /key_name`". For example, if your terminal's PgUp key generates "^[[3~", TF will think you pressed Delete, since that is the character sequence generated by Delete on most terminals. To tell TF about PgUp on your terminal, you should do "`/def -b'^[[3~' = /key_pgup`".

Note: some broken terminal emulators (TeraTerm, NiftyTelnet) send incorrect character sequences for the editor keypad (insert, delete, home, end, pgup, pgdn). For TeraTerm users, the preferred fix is to copy %TFLIBDIR/teraterm.keyboard.cnf to KEYBOARD.CNF in their TeraTerm directory; this will help all applications you run within TeraTerm, not just TF. Users of either terminal emulator may work around the problem with "`/load kb_badterm.tf`".

Note that before version 3.5 alpha 21 or beta 1, it was usually harmless to "/set TERM=vt100" on terminals that accepted a superset of vt100 display codes. However, the termcap key definitions are often different for terminals that are otherwise similar (e.g., vt100 and xterm share many display codes, but the key definitions are different), so setting %TERM incorrectly may interfere with the operation of named keys. Xterm users should also note that since 5.0, TF has its own scrollback, and xterm's scrollback will not work properly even if you try to trick TF with TERM=vt100.

## "Kbnum" argument

With the default keybindings, ESC followed by an optional "-" and any number of digits sets the global variable %kbnum. By default, the current %kbnum value is displayed near the right end of the status line. Then, when any other keybinding is typed, that keybinding may use the value of %kbnum. Whether the keybinding uses the value or not, %kbnum is cleared after the keybinding has run. Most keybindings that use %kbnum use it as a repeat count. For example, typing "`ESC 1 2 x`" is the same as typing "`x`" 12 times. For keybindings that have a sense of direction, negative values of %kbnum reverse that direction: for example, typing "`ESC - 4 PgDn`" is like typing "`PgUp`" 4 times. The "`^G`" (/beep) keybinding does not honor %kbnum, so it can be used to cancel %kbnum with no effect. The variable %max_kbnum sets an upper limit on the value of %kbnum that can be entered by the ESC and digit keys, to prevent typos from sending TF into very long loops.

The interpretation of %kbnum must be done by the command called from the keybinding; it is not done automatically by TF. So, for %kbnum to be meaningful in a macro you write, you must implement those semantics yourself. Additionally, most of the standard "/kb_*" and "/dokey" commands that use %kbnum are optimized to not simply repeat the command a number of times, but instead calculate only the end result. For example, ESC 300 TAB does not laboriously scroll 300 screenfuls of text onto the screen, but figures out what the 300th screenful looks like and draws that immediately. It does this because /dokey_page calls "`/test morescroll( winlines() * (kbnum?:1))`".

To set %kbnum by means other than the default keybindings above, simply /set it as you would any other variable. Once it is set, all typed digits are appended to it. When any non-digit key is typed, that key will be executed, and %kbnum will be cleared.

## Other key bindings

Some additional keyboard operations can be defined by /loading these library files:

kb-old.tf
  keybindings like those in TF 4.0 and earlier
kb-emacs.tf
  additional emacs-like keybindings
kbregion.tf
  cut-and-paste operations
kbstack.tf
  save the current input line with ESC DOWN and restore it later with ESC UP.

See the comments at the top of each file for further documentation.

See also: /dokey, /bind, /complete, %wordpunct, signals.

Back to index
Back to tf home page

Copyright © 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004 Ken Keys