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

To redefine the named keys, see the section titled "Mapping Named Keys to functions".
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)		     (function key F1)
...
F20	    (none)		     (function key F20)

nkpTab	    (none)		     (see "keypad" section below)
nkpEnt	    (none)		     (see "keypad" section below)
nkp*	    (none)		     (see "keypad" section below)
nkp+	    (none)		     (see "keypad" section below)
nkp,	    (none)		     (see "keypad" section below)
nkp-	    (none)		     (see "keypad" section below)
nkp.	    (none)		     (see "keypad" section below)
nkp/	    (none)		     (see "keypad" section below)
nkp0	    (none)		     (see "keypad" section below)
...
nkp9	    (none)		     (see "keypad" section below)
nkp=	    (none)		     (see "keypad" section below)

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. Note that some xterms capture shift_insert, shift_pgup, and shift_pgdn by default for their own use, so tf will not receive these sequences. 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 tf author for inclusion in a future release of tf).

Numeric keypad

TF tries to put the keypad in "application mode", which on many terminals will make the keypad keys generate unique character sequences. Application mode can be disabled by setting %keypad to "off". The meaning of your numeric keypad keys depends on your terminal emulator and its settings, the setting of %keypad in tf, and the state of your NumLock key. Two common configurations of the keypad are shown below. A name on a key in the diagram indicates that it is bound in tf to "/key_name".
            configuration A                   configuration B

     +------+------+------+------+     +------+------+------+------+
     |      |      |      |      |     |      |nkp/  |nkp*  |nkp-  |
     +------+------+------+------+     +------+------+------+------+
     |Home  |Up    |PgUp  |      |     |nkp7  |nkp8  |nkp9  |nkp+  |
     +------+------+------+      |     +------+------+------+      |
     |Left  |Center|Right |      |     |nkp4  |nkp5  |nkp6  |      |
     +------+------+------+------+     +------+------+------+------+
     |End   |Down  |PgDn  |      |     |nkp1  |nkp2  |nkp3  |nkpEnt|
     +------+------+------+      |     +------+------+------+      |
     |   Insert    |Delete|      |     |    nkp0     |nkp.  |      |
     +-------------+------+------+     +-------------+------+------+
How this works for some specific terminals:
X Consortium xterm
%keypad=on and NumLock on gives configuration B above; %keypad=off and NumLock on gives normal digit/punctuation keys; and NumLock off gives configuration A.
XFree86/X.Org xterm
Identical to X Consortium xterm if you disable the "Alt/numlock modifiers" option (under the ctrl-leftclick menu); if you do not, then %keypad=on and NumLock on gives normal digit/punctuation keys, and there is no way to get configuration B. There is also a "VT220 keyboard" option; if that is enabled, %keypad=on and NumLock off gives configuration B, and all other combinations of %keypad and NumLock give normal digit/punctuation keys.
linux (Linux console)
%keypad=on gives configuration B, with these changes: "NumLock" calls /key_f1, "/" calls /key_f2, "*" calls /key_f3, and "-" calls /key_f4. With %keypad=off, NumLock chooses between configuration A and normal digit/punctuation keys. (Prior to TF 5.0 beta 7, it was often impossible to set %keypad=on because many (if not all) "linux" termcap entries were missing a necessary code; TF now supplies that code automatically if it is missing and %TERM is "linux".)
konsole and gnome-terminal
As far as I can tell, %keypad has no effect, NumLock chooses between configuration A and normal digit/punctuation keys, and there is no way to get configuration B.
PuTTY
%keypad=on and NumLock on gives configuration B above; %keypad=off and NumLock on gives normal digit/punctuation keys; and NumLock off gives a configuration similar to configuration A.
Mac OSX Terminal
By default, Terminal's keypad always acts like normal digit/punctuation keys. But if you turn on "strict vt100 keypad behavior" under Terminal | Window Settings | Emulation, then %keypad=on will give a configuration similar to configuration B.

In some environments, 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

Named keys have two levels of mapping: first the character sequence generated by the key is bound (with /def -b) to call a macro named key_name; then the macro key_name is defined to execute a command. If you wish to change the functionality of any named key, you should do so by redefining key_name. For example, if you want Insert to invoke your own macro /foo, you should redefine "/def key_insert = /foo". You should only make a direct keybinding if a key on your terminal generates a character sequence not covered by TF's default bindings; and then you should only bind the character sequence to call key_name (but first, see the "keypad" section above). For example, if your Insert key generates "^[Q", you can bind it with "/def -b'^[Q' = /key_insert". You should never redefine any of the predefined /dokey_* or /kb_* commands.

There are several advantages to this two-level mapping: redefining a key's function is independent of the terminal; and adding keybindings for new terminals is independent of the functions invoked by a named key.

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 for Mac OS X Terminal.app users: by default, Terminal.app traps PageUp and PageDown keys itself and does not send them to the application (tf). It does however send Shift-PageUp and Shift-PageDown to the application, so you can use these to scroll in tf running inside Terminal. You can also tell Terminal to send the unshifted keys to tf by redefining them in Terminal | Window Settings | Keyboard.

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, 2005, 2006-2007 Ken Keys