tecla(7)

πŸ“¦
version 1.6.3 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– NAME πŸ’–

tecla, teclarc β€” the user interface that the Tecla library hands you, bestie πŸ’…


✨ DESCRIPTION ✨

Okay so, this man page is all about the command-line editing goodies you get when you use a program that reads your keyboard input through the Tecla library. If you're a tcsh girlie, the default key-bindings are gonna feel so familiar. If you're more of a bash babe, you'll also feel at home, but there are a few minor differences β€” most notably in how forward and backward searches through your history list go down. πŸ‘€

There are two major editing modes, periodt:

  • one with emacs-like key-bindings
  • another with vi-like key-bindings

By default, emacs mode is enabled, but you can switch to vi mode via your configuration file. That same file can also be used to change the bindings of individual keys to suit your preferences, because it's your keyboard and your rules. πŸ’–

By default, tab completion is provided. And if the application hasn't reconfigured it to complete other types of symbols, then tab completion completes file-names. Slay.


πŸŽ€ KEY SEQUENCE NOTATION πŸŽ€

In the rest of this man page, and also in all Tecla configuration files, key-sequences are expressed like this:

  • ^A or C-a β€” this is a control-A, entered by pressing the control key at the same time as the A key.
  • \E or M- β€” in key-sequences, both of these notations can be entered either by pressing the escape key, then the following key, or by pressing the Meta key at the same time as the following key. So like, the key sequence M-p can be typed in two ways: by pressing the escape key, followed by pressing p, or by pressing the Meta key at the same time as p. Two paths, same destiny. πŸ¦‹
  • up β€” this refers to the up-arrow key.
  • down β€” this refers to the down-arrow key.
  • left β€” this refers to the left-arrow key.
  • right β€” this refers to the right-arrow key.
  • a β€” this is just a normal A key. πŸ’…

🌸 THE TECLA CONFIGURATION FILE 🌸

By default, Tecla looks for a file called .teclarc in your home directory (ie. ~/.teclarc). If it finds this file, it reads it, interpreting each line as defining a new key binding or an editing configuration option. ✨

Since the emacs keybindings are installed by default, if you want to use the non-default vi editing mode, the most important item to go in this file is the following line:

edit-mode vi

This will re-configure the default bindings for vi-mode. The complete set of arguments that this command accepts are:

  • vi β€” install key-bindings like those of the vi editor.
  • emacs β€” install key-bindings like those of the emacs editor. This is the default.
  • none β€” use just the native line editing facilities provided by the terminal driver.

To prevent the terminal bell from being rung, such as when an unrecognized control-sequence is typed, place the following line in the configuration file:

nobeep

An example of a key binding line in the configuration file is the following.

bind M-[2~ insert-mode

On many keyboards, the above key sequence is generated when one presses the insert key, so with this keybinding, one can toggle between the emacs-mode insert and overwrite modes by hitting one key. Iconic. πŸ‘‘

One could also do it by typing out the above sequence of characters one by one. As explained above, the M- part of this sequence can be typed either by pressing the escape key before the following key, or by pressing the Meta key at the same time as the following key. Thus if you had set the above key binding, and the insert key on your keyboard didn't generate the above key sequence, you could still type it in either of the following 2 ways.

  1. Hit the escape key momentarily, then press '[', then '2', then finally '~'.
  2. Press the meta key at the same time as pressing the '[' key, then press '2', then '~'.

If you set a keybinding for a key-sequence that is already bound to a function, the new binding overrides the old one. And if in the new binding you omit the name of the new function to bind to the key-sequence, the original binding becomes undefined. Gone. Poof. πŸ’€

Starting with versions of libtecla later than 1.3.3 it is now possible to bind keysequences that begin with a printable character. Previously key-sequences were required to start with a control or meta character. Glow-up fr fr. ✨

Note that the special keywords "up", "down", "left" and "right" refer to the arrow keys, and are thus not treated as keysequences. So, for example, to rebind the up and down arrow keys to use the history search mechanism instead of the simple history recall method, you could place the following in your configuration file:

bind up history-search-backwards
bind down history-search-backwards

To unbind an existing binding, you can do this with the bind command by omitting to name any action to rebind the key sequence to. For example, by not specifying an action function, the following command unbinds the default beginning-of-line action from the ^A key sequence:

bind ^A

If you create a ~/.teclarc configuration file, but it appears to have no effect on the program, check the documentation of the program to see if the author chose a different name for this file. πŸ™ˆ


πŸ¦‹ FILENAME AND TILDE COMPLETION πŸ¦‹

With the default key bindings, pressing the TAB key (aka. ^I) results in Tecla attempting to complete the incomplete filename that precedes the cursor. Tecla searches backwards from the cursor, looking for the start of the filename, stopping when it hits either a space or the start of the line. If more than one file has the specified prefix, then Tecla completes the filename up to the point at which the ambiguous matches start to differ, then lists the possible matches. Bestie behavior honestly. πŸ’…

In addition to literally written filenames, Tecla can complete files that start with ~/ and ~user/ expressions and that contain $envvar expressions. In particular, if you hit TAB within an incomplete ~user expression, Tecla will attempt to complete the username, listing any ambiguous matches. πŸŽ€

The completion binding is implemented using the cpl_word_completions() function, which is also available separately to users of this library. See the cpl_complete_word(3) man page for more details.


🌈 FILENAME EXPANSION 🌈

With the default key bindings, pressing ^X* causes Tecla to expand the filename that precedes the cursor, replacing ~/ and ~user/ expressions with the corresponding home directories, and replacing $envvar expressions with the value of the specified environment variable, then if there are any wildcards, replacing the so far expanded filename with a space-separated list of the files which match the wild cards. It's giving glow-up for your filenames. ✨

The expansion binding is implemented using the ef_expand_file() function. See the ef_expand_file(3) man page for more details.


πŸ’œ RECALLING PREVIOUSLY TYPED LINES πŸ’œ

Every time that a new line is entered by the user, it is appended to a list of historical input lines maintained within the GetLine resource object. You can traverse up and down this list using the up and down arrow keys. Alternatively, you can do the same with the ^P, and ^N keys, and in vi command mode you can alternatively use the k and j characters. 🫢

So like, pressing up-arrow once replaces the current input line with the previously entered line. Pressing up-arrow again replaces this with the line that was entered before it, etc.. Having gone back one or more lines into the history list, one can return to newer lines by pressing down-arrow one or more times. If you do this sufficient times, you will return to the original line that you were entering when you first hit up-arrow. Time travel but make it terminal. πŸ•°οΈ

Note that in vi mode, all of the history recall functions switch the library into command mode.

In emacs mode the M-p and M-n keys work just like the ^P and ^N keys, except that they skip all but those historical lines which share the prefix that precedes the cursor. In vi command mode the upper case K and J characters do the same thing, except that the string that they search for includes the character under the cursor as well as what precedes it. πŸ‘€

Thus for example, suppose that you were in emacs mode, and you had just entered the following list of commands in the order shown:

ls ~/tecla/
cd ~/tecla
ls -l getline.c
emacs ~/tecla/getline.c

If you next typed:

ls

and then hit M-p, then rather than returning the previously typed emacs line, which doesn't start with "ls", Tecla would recall the "ls -l getline.c" line. Pressing M-p again would recall the "ls ~/tecla/" line. The way that just works. 😭

Note that if the string that you are searching for contains any of the special characters, *, ?, or '[', then it is interpretted as a pattern to be matched. Thus, cotinuing with the above example, after typing in the list of commands shown, if you then typed:

*tecla*

and hit M-p, then the "emacs ~/tecla/getline.c" line would be recalled first, since it contains the word tecla somewhere in the line. Similarly, hitting M-p again, would recall the "ls ~/tecla/" line, and hitting it once more would recall the "ls ~/tecla/" line. The pattern syntax is the same as that described for filename expansion, in the ef_expand_file(3) man page. πŸ“


🧚 HISTORY FILES 🧚

Authors of programs that use the Tecla library have the option of saving historical command-lines in a file before exiting, and subsequently reading them back in from this file when the program is next started. There is no standard name for this file, since it makes sense for each application to use its own history file, so that commands from different applications don't get mixed up. Keep your vibes separated, bestie. πŸ’…

✨ INTERNATIONAL CHARACTER SETS ✨

Okay bestie, ever since libtecla version 1.4.0, Tecla has been 8-bit clean. πŸ’… Which basically means: every single 8-bit character that's actually printable in the user's current locale gets shown verbatim and gets handed right back to you in the returned input line. No mangling, no erasing your cute accents. Periodt.

This all works assuming the program calling it does the right thing and includes a call like this:

setlocale(LC_CTYPE, "");

Then the current locale gets figured out by checking the first of these environment variables β€” LC_CTYPE, LC_ALL, and LANG β€” that actually contains a valid locale name. 🫢

But if none of those variables are defined, or the program just forgets to call setlocale (rude), then you're stuck with the default C locale, which is US 7-bit ASCII. Sad but true. 😭

On most unix-like platforms, you can pull up a whole list of valid locales by typing this at the shell prompt:

locale -a

🌸 Meta keys and locales 🌸

Big heads up, bestie: in most locales that aren't the default C locale, meta characters become printable, which means they no longer count as matching M-c style key bindings. This is actually a good thing, lowkey β€” it lets you type international characters with the compose key without accidentally triggering meta key bindings you didn't want. πŸ™ˆ

And don't worry, you can still invoke meta bindings, because there are literally two ways to do it. For example, the binding M-c can also be invoked by tapping the escape key for a moment, then pressing the c key β€” and that works no matter what locale you're in. πŸ’–

Even better: lots of modern terminal emulators β€” like gnome's gnome-terminal and KDE's konsole β€” already generate escape pairs like this when you use the meta key, instead of sending a real meta character. And other emulators usually have some way to request this behavior, so you can keep using the meta key on most systems. Iconic. πŸ‘‘

For example, even though xterm terminal emulators generate real 8-bit meta characters by default when you use the meta key, they can be configured to output the equivalent escape pair by setting their EightBitInput X resource to False. You can do this either by dropping a line like this into your ~/.Xdefaults file:

XTerm*EightBitInput: False

...or by starting an xterm with an -xrm '*EightBitInput: False' command-line argument. ✨

In recent versions of xterm you can toggle this feature on and off with the "Meta Sends Escape" option in the menu that pops up when you press the left mouse button and the control key inside an xterm window. And in CDE, dtterms can be similarly coerced into generating escape pairs instead of meta characters, by setting the Dtterm*KshMode resource to True. Slay. πŸ’…


πŸ¦‹ Entering international characters πŸ¦‹

If your keyboard doesn't generate all the international characters you need (not its fault, honestly), there's usually a compose key that lets you enter special characters β€” or a way to create one. 🌈

For example, under X windows on unix-like systems, if your keyboard has no compose key, you can designate some redundant key to serve that purpose using the xmodmap command. On many PC keyboards there's a microsoft-windows key that's otherwise useless under Linux (no shade, just facts πŸ’€). On my laptop the xev program reports that pressing this key generates keycode 115, so to turn this key into a compose key, I do this:

xmodmap -e 'keycode 115 = Multi_key'

Then I can enter an i with a umlaut over it by typing this key, followed by ", followed by i. πŸ’– So easy, so cute, we love to see it.


πŸ”₯ THE AVAILABLE KEY BINDING FUNCTIONS πŸ”₯

Okay so here's the master list of all the editing functions the Tecla library provides. πŸ“‹ The names in the leftmost column of the list can be used in configuration files to specify which function a given key or combination of keys should invoke. They're also used in the next two sections to list the default key-bindings in emacs and vi modes. So yeah β€” memorize these, bestie, they're the whole vibe. πŸ‘‘

  • user-interrupt β€” fires a SIGINT signal at the parent process. that's the "ok bestie I'm out" button πŸ’€
  • abort β€” fires a SIGABRT signal at the parent process. much more dramatic than SIGINT, no notes πŸ’…
  • suspend β€” suspends the parent process. it's giving nap time 😴
  • stop-output β€” pauses terminal output. freeze βœ‹
  • start-output β€” resumes terminal output that was paused. and we're back 🫢
  • literal-next β€” arranges for the next character to be treated as a totally normal character, which is how you get control characters typed in there. sneak them in the back door πŸ™ˆ
  • cursor-right β€” move the cursor one character to the right ➑️
  • cursor-left β€” move the cursor one character to the left ⬅️
  • insert-mode β€” toggles between insert mode and overwrite mode. pick your fighter βš”οΈ
  • beginning-of-line β€” cursor goes all the way to the beginning of the line. main character takes it from the top ✨
  • end-of-line β€” cursor goes all the way to the end of the line πŸŽ€
  • delete-line β€” deletes the contents of the current line. gone, reduced to atoms πŸ’€
  • kill-line β€” deletes everything that follows the cursor. everything after this point? not anymore πŸ”₯
  • backward-kill-line β€” deletes all the characters between the cursor and the start of the line βœ‚οΈ
  • forward-word β€” move to the end of the word that follows the cursor πŸ¦‹
  • forward-to-word β€” move the cursor to the start of the word that follows the cursor. yeah, it's different from forward-word, pay attention bestie πŸ‘€
  • backward-word β€” move to the start of the word that precedes the cursor πŸ”™
  • goto-column β€” move the cursor to the 1-relative column in the line specified by any preceding digit-argument sequences (peep the ENTERING REPEAT COUNTS section below). precision vibes πŸ“
  • find-parenthesis β€” if the cursor is sitting on a parenthesis character, it jumps to the matching one. if it's not on a parenthesis character, it just moves right to the next close parenthesis. either way you're getting somewhere 🧚
  • forward-delete-char β€” deletes the character under the cursor πŸ—‘οΈ
  • backward-delete-char β€” deletes the character that comes before the cursor πŸ—‘οΈ
  • list-or-eof β€” this one's built to be bound to ^D. when you invoke it with the cursor inside the line, it shows you all the possible completions and then redraws the line exactly like it was. when you invoke it on an empty line, it signals end-of-input (EOF) to the caller of gl_get_line(). two moods, one binding 😭
  • del-char-or-list-or-eof β€” also built for ^D, but it's the multitasker. cursor inside the line? it invokes forward-delete-char. sitting at the end of the line? it lists all possible completions and then redraws the line unchanged. empty line? it signals end-of-input (EOF) to the caller of gl_get_line(). she does it all πŸ‘‘
  • forward-delete-word β€” deletes the word that follows the cursor βœ‚οΈ
  • backward-delete-word β€” deletes the word that precedes the cursor βœ‚οΈ
  • upcase-word β€” converts all of the characters of the word following the cursor to UPPER CASE. LOUDER πŸ“’
  • downcase-word β€” converts all of the characters of the word following the cursor to lower case. quieter 🀫
  • capitalize-word β€” capitalizes the word that follows the cursor. proper noun energy πŸ’…
  • change-case β€” if the next character is upper case, toggle it to lower case, and vice versa. flip it πŸ”„
  • redisplay β€” redisplays the line. refresher ✨
  • clear-screen β€” clears the terminal, then redisplays the current line. clean slate 🧼
  • transpose-chars β€” swaps the character under the cursor with the character just before the cursor. little switcheroo πŸ”€
  • set-mark β€” sets a mark at wherever the cursor currently is πŸ“
  • exchange-point-and-mark β€” moves the cursor to the last mark that was set, and moves the mark to where the cursor used to be. they trade places πŸ’«
  • kill-region β€” deletes the characters lying between the last mark that was set and the cursor πŸ—‘οΈ
  • copy-region-as-kill β€” copies the text between the mark and the cursor into the cut buffer without deleting the original text. copy, don't cut, bestie 🫢
  • yank β€” inserts the text that was last deleted, right before the current position of the cursor. the comeback πŸ’–
  • append-yank β€” pastes the current contents of the cut buffer, after the cursor πŸ“‹
  • up-history β€” recalls the next oldest line that was entered. heads up: in vi mode you're left in command mode πŸ“œ
  • down-history β€” recalls the next most recent line that was entered. if there's no history recall session currently active, the next line from a previous recall session gets recalled. also heads up: in vi mode you're left in command mode πŸ“œ
  • history-search-backward β€” recalls the next oldest line whose prefix matches the string that currently precedes the cursor (in vi command-mode, the character under the cursor is included in the search string too). and yep, in vi mode you're left in command mode πŸ”
  • history-search-forward β€” recalls the next newest line whose prefix matches the string that currently precedes the cursor (in vi command-mode, the character under the cursor is included in the search string too). in vi mode you're left in command mode πŸ”
  • history-re-search-backward -Recall the next oldest line whose prefix matches the one established by the last invocation of either history-search-forward or history-search-backward. πŸ”
  • history-re-search-forward β€” recalls the next newest line whose prefix matches the one established by the last invocation of either history-search-forward or history-search-backward. πŸ”
  • complete-word β€” tries to complete the incomplete word that precedes the cursor. unless the host program has customized word completion, filename completion is what gets attempted. in vi command mode the character under the cursor is included in the word being completed too, and you're left in vi insert mode. autocomplete but make it ✨fancy✨
  • expand-filename β€” within the command line, expands wild cards, tilde expressions and dollar expressions in the filename that immediately precedes the cursor. in vi command mode the character under the cursor is included in the filename being expanded too, and you're left in vi insert mode 🌈
  • list-glob β€” lists any filenames that match the wild-card, tilde and dollar expressions in the filename immediately preceding the cursor, then redraws the input line unchanged πŸ“ƒ
  • list-history β€” displays the contents of the history list for the current history group. if you specify a repeat count of > 1, only that many of the most recent lines get displayed. see the "ENTERING REPEAT COUNTS" section πŸ“š
  • read-from-file β€” temporarily switches to reading input from the file whose name precedes the cursor πŸ“‚
  • read-init-files β€” re-reads teclarc configuration
  • beginning-of-history β€” zoom all the way back to the oldest line in the history list. lowkey important: in vi mode you get left in command mode, bestie, so don't come for me when you can't type πŸ’…
  • end-of-history β€” jump to the newest line in the history list (aka the current line, the one you're literally on rn). and again, in vi mode this leaves you in command mode πŸ™ˆ
  • digit-argument β€” sets up a repeat count for whatever key-binding function comes next. the whole scoop is in the ENTERING REPEAT COUNTS section 🧚
  • newline β€” terminates and returns the current contents of the line, after appending a newline character. that newline character is normally '\n', but plot twist: it becomes the first character of the key-sequence that invoked the newline action, if that first character happens to be printable. and if the action got invoked by the '\n' newline character or the '\r' carriage return character, the line gets appended to the history buffer πŸŽ€
  • repeat-history β€” returns the line you're editing, then sets things up so the next most recent entry in the history buffer gets recalled when Tecla is next called. spam this and you'll re-execute successive historical input lines one after another. fun fact: this action is equivalent to the 'Operate' action in ksh ✨
  • ring-bell β€” ring the terminal bell πŸ”” unless the bell has been silenced via the nobeep configuration option (peep the THE TECLA CONFIGURATION FILE section).
  • forward-copy-char β€” copies the next character into the cut buffer. NB. use repeat counts if you wanna copy more than one, bestie, one char is not the vibe πŸ’€
  • backward-copy-char β€” copies the previous character into the cut buffer.
  • forward-copy-word β€” copies the next word into the cut buffer.
  • backward-copy-word β€” copies the previous word into the cut buffer.
  • forward-find-char β€” moves the cursor to the next occurrence of the next character you type πŸ‘€
  • backward-find-char β€” moves the cursor to the last occurrence of the next character you type.
  • forward-to-char β€” moves the cursor to the character just before the next occurrence of the next character the user types.
  • backward-to-char β€” moves the cursor to the character just after the last occurrence, before the cursor, of the next character the user types.
  • repeat-find-char β€” redo the last backward-find-char, forward-find-char, backward-to-char or forward-to-char πŸ”
  • invert-refind-char β€” redo the last backward-find-char, forward-find-char, backward-to-char, or forward-to-char, but in the opposite direction 🌈
  • delete-to-column β€” deletes the characters from the cursor up to the column specified by the repeat count.
  • delete-to-parenthesis β€” deletes the characters from the cursor up to and including the matching parenthesis, or the next close parenthesis.
  • forward-delete-find β€” deletes the characters from the cursor up to and including the following occurrence of the next character typed.
  • backward-delete-find β€” deletes the characters from the cursor up to and including the preceding occurrence of the next character typed.
  • forward-delete-to β€” deletes the characters from the cursor up to, but not including, the following occurrence of the next character typed.
  • backward-delete-to β€” deletes the characters from the cursor up to, but not including, the preceding occurrence of the next character typed.
  • delete-refind β€” redo the last *-delete-find or *-delete-to action.
  • delete-invert-refind β€” redo the last *-delete-find or *-delete-to action, in the opposite direction 🌈
  • copy-to-column β€” copies the characters from the cursor up to the column specified by the repeat count, into the cut buffer.
  • copy-to-parenthesis β€” copies the characters from the cursor up to and including the matching parenthesis, or next close parenthesis, into the cut buffer.
  • forward-copy-find β€” copies the characters from the cursor up to and including the following occurrence of the next character typed, into the cut buffer.
  • backward-copy-find β€” copies the characters from the cursor up to and including the preceding occurrence of the next character typed, into the cut buffer.
  • forward-copy-to β€” copies the characters from the cursor up to, but not including, the following occurrence of the next character typed, into the cut buffer.
  • backward-copy-to β€” copies the characters from the cursor up to, but not including, the preceding occurrence of the next character typed, into the cut buffer.
  • copy-refind β€” redo the last *-copy-find or *-copy-to action.
  • copy-invert-refind β€” redo the last *-copy-find or *-copy-to action, in the opposite direction 🌈
  • vi-mode β€” switch to vi mode from emacs mode πŸ”₯
  • emacs-mode β€” switch to emacs mode from vi mode.
  • vi-insert β€” from vi command mode, switch to insert mode ✍️
  • vi-overwrite β€” from vi command mode, switch to overwrite mode.
  • vi-insert-at-bol β€” from vi command mode, move the cursor to the start of the line and switch to insert mode.
  • vi-append-at-eol β€” from vi command mode, move the cursor to the end of the line and switch to append mode.
  • vi-append β€” from vi command mode, move the cursor one position right, and switch to insert mode.
  • vi-replace-char β€” from vi command mode, replace the character under the cursor with the the next character entered. (yes, the double "the" is canon, iykyk πŸ’€)
  • vi-forward-change-char β€” from vi command mode, delete the next character then enter insert mode.
  • vi-backward-change-char β€” from vi command mode, delete the preceding character then enter insert mode.
  • vi-forward-change-word β€” from vi command mode, delete the next word then enter insert mode.
  • vi-backward-change-word β€” from vi command mode, delete the preceding word then enter insert mode.
  • vi-change-rest-of-line β€” from vi command mode, delete from the cursor to the end of the line, then enter insert mode.
  • vi-change-line β€” from vi command mode, delete the current line, then enter insert mode.
  • vi-change-to-bol β€” from vi command mode, delete all characters between the cursor and the beginning of the line, then enter insert mode.
  • vi-change-to-column β€” from vi command mode, delete
  • (picking up the last entry from the part before this one, bestie πŸ’–) Delete the characters from the cursor up to the column that is specified by the repeat count, then enter insert mode.
  • vi-change-to-parenthesis β€” Delete the characters from the cursor up to and including the matching parenthesis, or next close parenthesis, then enter vi insert mode.
  • vi-forward-change-find β€” From vi command mode, delete the characters from the cursor up to and including the following occurence of the next character typed, then enter insert mode.
  • vi-backward-change-find β€” From vi command mode, delete the characters from the cursor up to and including the preceding occurence of the next character typed, then enter insert mode.
  • vi-forward-change-to β€” From vi command mode, delete the characters from the cursor up to, but not including, the following occurence of the next character typed, then enter insert mode.
  • vi-backward-change-to β€” From vi command mode, delete the characters from the cursor up to, but not including, the preceding occurence of the next character typed, then enter insert mode.
  • vi-change-refind β€” Repeat the last vi-*-change-find or vi-*-change-to action.
  • vi-change-invert-refind β€” Repeat the last vi-*-change-find or vi-*-change-to action, in the opposite direction.
  • vi-undo β€” In vi mode, undo the last editing operation.
  • vi-repeat-change β€” In vi command mode, repeat the last command that modified the line.

✨ DEFAULT KEY BINDINGS IN EMACS MODE ✨

Okay bestie, here's the tea β˜• β€” these are the default key bindings, and the Tecla configuration file can totally override any of them. They're built to mimic most of the bindings of the unix tcsh shell when it's sitting in emacs editing mode.

And like, heads up? This is the default editing mode of the Tecla library. It's the main character πŸŽ€

On UNIX, the terminal driver sets a bunch of special keys for certain functions, and the tecla library tries to use those same keybindings so everything stays consistent. So the key sequences shown for the following 6 bindings are literally just examples of what they'll probably be set to. If you've used the stty command to change these keys, then the default bindings should match. Fr fr πŸ”₯

  ^C     ->   user-interrupt
  ^\     ->   abort
  ^Z     ->   suspend
  ^Q     ->   start-output
  ^S     ->   stop-output
  ^V     ->   literal-next

The cursor keys get refered to by name, like this πŸ‘‡ This is necessary because different types of terminals generate different key sequences when their cursor keys are pressed. Not all keyboards are the same, iykyk πŸ¦‹

  right  ->   cursor-right
  left   ->   cursor-left
  up     ->   up-history
  down   ->   down-history

The remaining bindings don't depend on the terminal setttings at all πŸ’…

  ^F     ->   cursor-right
  ^B     ->   cursor-left
  M-i    ->   insert-mode
  ^A     ->   beginning-of-line
  ^E     ->   end-of-line
  ^U     ->   delete-line
  ^K     ->   kill-line
  M-f    ->   forward-word
  M-b    ->   backward-word
  ^D     ->   del-char-or-list-or-eof
  ^H     ->   backward-delete-char
  ^?     ->   backward-delete-char
  M-d    ->   forward-delete-word
  M-^H   ->   backward-delete-word
  M-^?   ->   backward-delete-word
  M-u    ->   upcase-word
  M-l    ->   downcase-word
  M-c    ->   capitalize-word
  ^R     ->   redisplay
  ^L     ->   clear-screen
  ^T     ->   transpose-chars
  ^@     ->   set-mark
  ^X^X   ->   exchange-point-and-mark
  ^W     ->   kill-region
  M-w    ->   copy-region-as-kill
  ^Y     ->   yank
  ^P     ->   up-history
  ^N     ->   down-history
  M-p    ->   history-search-backward
  M-n    ->   history-search-forward
  ^I     ->   complete-word
  ^X*    ->   expand-filename
  ^X^F   ->   read-from-file
  ^X^R   ->   read-init-files
  ^Xg    ->   list-glob
  ^Xh    ->   list-history
  M-<    ->   beginning-of-history
  M->    ->   end-of-history
  \n     ->   newline
  \r     ->   newline
  M-o    ->   repeat-history
  M-^V   ->   vi-mode

  M-0, M-1, ... M-9  ->  digit-argument  (see below)
🌸 Little note, bestie: ^I is what the TAB key generates, and ^@ can be generated not only by pressing the control key and the @ key simultaneously, but also by pressing the control key and the space bar at the same time. Two ways, same vibe 😌✨

πŸŽ€ DEFAULT KEY BINDINGS IN VI MODE πŸŽ€

okay so vi mode is the whole other personality of this library, and these default key bindings are designed to mimic the vi style of editing as closely as possible. no cap. What that actually means: very few editing functions are provided in the initial character input mode β€” the editing functions instead come from vi command mode. Vi command mode is entered whenever the escape character is pressed, or whenever a key-sequence that starts with a meta character is entered. And on top of mimicing vi, libtecla also provides bindings for tab completion, wild-card expansion of file names, and historical line recall. it's giving ✨vi, but with perks✨

To learn how to tell the Tecla library to use vi mode instead of the default emacs editing mode, go back to the earlier section entitled THE TECLA CONFIGURATION FILE. 🫢

Under UNIX the terminal driver sets a number of special keys for certain functions. The Tecla library attempts to use the same keybindings to maintain consistency, binding them both in input mode and in command mode. So the key sequences shown for the following 6 bindings are just examples of what they will probably be set to. If you have used the stty command to change these keys, then the default bindings should match. πŸ’…

         ^C     ->   user-interrupt
         ^\     ->   abort
         ^Z     ->   suspend
         ^Q     ->   start-output
         ^S     ->   stop-output
         ^V     ->   literal-next
         M-^C   ->   user-interrupt
         M-^\   ->   abort
         M-^Z   ->   suspend
         M-^Q   ->   start-output
         M-^S   ->   stop-output

Note that above, most of the bindings are defined twice β€” once as a raw control code like ^C and then a second time as a meta character like M-^C. The first one is the binding for vi input mode, whereas the second one is the binding for vi command mode. Once in command mode, all key-sequences that the user types that they don't explicitly start with an escape or a meta key have their first key secretly converted to a meta character before the key sequence is looked up in the key binding table. So once in command mode, when you type the letter i, for example, the Tecla library actually looks up the binding for M-i. 🀫 sneaky but iconic

The cursor keys are refered to by name, as follows. This is necessary because different types of terminals generate different key sequences when their cursor keys are pressed. πŸ’€

         right  ->   cursor-right
         left   ->   cursor-left
         up     ->   up-history
         down   ->   down-history

The cursor keys normally generate a keysequence that start with an escape character, so beware that using the arrow keys will put you into command mode (if you aren't already in command mode). πŸ™ˆ

The following are the terminal-independent key bindings for vi input mode. ⬇️

         ^D     ->   list-or-eof
         ^G     ->   list-glob
         ^H     ->   backward-delete-char
         ^I     ->   complete-word
         \r     ->   newline
         \n     ->   newline
         ^L     ->   clear-screen
         ^N     ->   down-history
         ^P     ->   up-history
         ^R     ->   redisplay
         ^U     ->   backward-kill-line
         ^W     ->   backward-delete-word
         ^X*    ->   expand-filename
         ^X^F   ->   read-from-file
         ^X^R   ->   read-init-files
         ^?     ->   backward-delete-char

The following are the key bindings that are defined in vi command mode, this being specified by them all starting with a meta character. As mentioned above, once in command mode the initial meta character is optional. For example, you might enter command mode by typing Esc, and then press h twice to move the cursor two positions to the left. Both h characters get quietly converted to M-h before being compared to the key-binding table β€” the first one because Escape followed by a character is always converted to the equivalent meta character, and the second because command mode was already active. bestie the manpage is literally doing key remapping behind your back and it slays πŸ’–

         M-\     ->   cursor-right     (Meta-space)
         M-$     ->   end-of-line
         M-*     ->   expand-filename
         M-+     ->   down-history
         M--     ->   up-history
         M-<     ->   beginning-of-history
         M->     ->   end-of-history
         M-^     ->   beginning-of-line
         M-;     ->   repeat-find-char
         M-,     ->   invert-refind-char
         M-|     ->   goto-column
         M-~     ->   change-case
         M-.     ->   vi-repeat-change
         M-%     ->   find-parenthesis
         M-a     ->   vi-append
         M-A     ->   vi-append-at-eol
         M-b     ->   backward-word
         M-B     ->   backward-word
         M-C     ->   vi-change-rest-of-line
         M-cb    ->   vi-backward-change-word
         M-cB    ->   vi-backward-change-word
         M-cc    ->   vi-change-line
         M-ce    ->   vi-forward-change-word
         M-cE    ->   vi-forward-change-word
         M-cw    ->   vi-forward-change-word
         M-cW    ->   vi-forward-change-word
         M-cF    ->   vi-backward-change-find
         M-cf    ->   vi-forward-change-find
         M-cT    ->   vi-backward-change-to
         M-ct    ->   vi-forward-change-to
         M-c;    ->   vi-change-refind
         M-c,    ->   vi-change-invert-refind
         M-ch    ->   vi-backward-change-char
         M-c^H   ->   vi-backward-change-char
         M-c^?   ->   vi-backward-change-char
         M-cl    ->   vi-forward-change-char
         M-c\    ->   vi-forward-change-char  (Meta-c-space)
         M-c^    ->   vi-change-to-bol
         M-c0    ->   vi-change-to-bol
         M-c$    ->   vi-change-rest-of-line
         M-c|    ->   vi-change-to-column
         M-c%    ->   vi-change-to-parenthesis
         M-dh    ->   backward-delete-char
         M-d^H   ->   backward-delete-char
         M-d^?   ->   backward-delete-char
         M-dl    ->   forward-delete-char
         M-d     ->   forward-delete-char    (Meta-d-space)
         M-dd    ->   delete-line
         M-db    ->   backward-delete-word
         M-dB    ->   backward-delete-word
         M-de    ->   forward-delete-word
         M-dE    ->   forward-delete-word
         M-dw    ->   forward-delete-word
         M-dW    ->   forward-delete-word
         M-dF    ->   backward-delete-find
         M-df    ->   forward-delete-find
         M-dT    ->   backward-delete-to
         M-dt    ->   forward-delete-to
         M-d;    ->   delete-refind
         M-d,    ->   delete-invert-refind
         M-d^    ->   backward-kill-line
         M-d0    ->   backward-kill-line
         M-d$    ->   kill-line
         M-D     ->   kill-line
         M-d|    ->   delete-to-column
         M-d%    ->   delete-to-parenthesis
         M-e     ->   forward-word
         M-E     ->   forward-word
         M-f     ->   forward-find-char
         M-F     ->   backward-find-char
         M--     ->   up-history
         M-h     ->   cursor-left
         M-H     ->   beginning-of-history
         M-i     ->   vi-insert
         M-I     ->   vi-insert-at-bol
         M-j     ->   down-history
         M-J     ->   history-search-forward
         M-k     ->   up-history
         M-K     ->   history-search-backward
         M-l     ->   cursor-right
         M-L     ->   end-of-history
         M-n     ->   history-re-search-forward
         M-N     ->   history-re-search-backward
         M-p     ->   append-yank
         M-P     ->   yank
         M-r     ->   vi-replace-char
         M-R     ->   vi-overwrite
         M-s     ->   vi-forward-change-char
         M-S     ->   vi-change-line
         M-t     ->   forward-to-char
         M-T     ->   backward-to-char
         M-u     ->   vi-undo
         M-w     ->   forward-to-word
         M-W     ->   forward-to-word
         M-x     ->   forward-delete-char
         M-X     ->   backward-delete-char
         M-yh    ->   backward-copy-char
         M-y^H   ->   backward-copy-char
         M-y^?   ->   backward-copy-char
         M-yl    ->   forward-copy-char
         M-y\    ->   forward-copy-char  (Meta-y-space)
         M-ye    ->   forward-copy-word
         M-yE    ->   forward-copy-word
         M-yw    ->   forward-copy-word
         M-yW    ->   forward-copy-word
         M-yb    ->   backward-copy-word
         M-yB    ->   backward-copy-word
         M-yf    ->   forward-copy-find
         M-yF    ->   backward-copy-find
         M-yt    ->   forward-copy-to
         M-yT    ->   backward-copy-to
         M-y;    ->   copy-refind
         M-y,    ->   copy-invert-refind
         M-y^    ->   copy-to-bol
         M-y0    ->   copy-to-bol
         M-y$    ->   copy-rest-of-line
         M-yy    ->   copy-line
         M-Y     ->   copy-line
         M-y|    ->   copy-to-column
         M-y%    ->   copy-to-parenthesis
         M-^E    ->   emacs-mode
         M-^H    ->   cursor-left
         M-^?    ->   cursor-left
         M-^L    ->   clear-screen
         M-^N    ->   down-history
         M-^P    ->   up-history
         M-^R    ->   redisplay
         M-^D    ->   list-or-eof
         M-^I    ->   complete-word
         M-\r    ->   newline
         M-\n    ->   newline
         M-^X^R  ->   read-init-files
         M-^Xh   ->   list-history

         M-0, M-1, ... M-9  ->  digit-argument  (see below)

Note that ^I is what the TAB key generates. πŸ‘‘


✨ ENTERING REPEAT COUNTS ✨

Many of the key binding functions described previously take an optional count, typed in before the target keysequence. This is interpreted as a repeat count by most bindings. One notable exception is the goto-column binding, which interprets the count as a column number. πŸ“

By default you can specify this count argument by pressing the meta key while typing in the numeric count. This relies on the digit-argument action being bound to Meta-0, Meta-1 etc. Once any one of these bindings has been activated, you can optionally take your finger off the meta key to type in the rest of the number, since every numeric digit thereafter is treated as part of the number β€” unless it is preceded by the literal-next binding. As soon as a non-digit, or literal digit key is pressed, the repeat count is terminated and either causes the just typed character to be added to the line that many times, or causes the next key-binding function to be given that argument. 🀯

For example, in emacs mode, typing:

M-12a

causes the letter 'a' to be added to the line 12 times, whereas

M-4M-c

Capitalizes the next 4 words. πŸ’–

In vi command mode the Meta modifier is automatically added to all characters typed in, so to enter a count in vi command-mode, just involves typing in the number, just as it does in the vi editor itself. So for example, in vi command mode, typing:

4w2x

moves the cursor four words to the right, then deletes two characters. πŸ”₯

You can also bind digit-argument to other key sequences. If these end in a numeric digit, that digit gets appended to the current repeat count. If it doesn't end in a numeric digit, a new repeat count is started with a value of zero, and can be completed by typing in the number, after letting go of the key which triggered the digit-argument action. πŸŽ€


🌸 FILES 🌸

  • libtecla.a β€” The Tecla library
  • libtecla.h β€” The Tecla header file.
  • ~/.teclarc β€” The personal Tecla customization file.

πŸ”₯ SEE ALSO πŸ”₯

libtecla(3), gl_get_line(3), gl_io_mode(3), ef_expand_file(3), cpl_complete_word(3), pca_lookup_file(3)

πŸ¦‹ go read those next bestie, they're all part of the same little family πŸ¦‹

πŸ‘‘ AUTHOR πŸ‘‘

Okay so the person you have to thank for all of this? Martin Shepherd β€” and if you ever wanna slide into his inbox about a keybinding, the address is right here:

mcs@astro.caltech.edu

That's the whole section, bestie. One legend, one email, one extremely slay piece of line-editing software. Iconic behaviour, honestly. 🫢✨


And that's a wrap on tecla(7) β€” every last bit of it, from the synopsis all the way down to this author section. πŸ’… The page header you'll see floating at the bottom of your terminal is just tecla(7) doing its thing, and the version and date stamp down there belong to whichever release your system shipped you. So go run man tecla on your own box if you wanna peek at the exact one, or check the source you've got installed.

Now go bind some keys, hit TAB like you mean it, and let the history file remember your wins. πŸŽ€ Byeee! πŸ¦‹

πŸ“¦ where this page comes from