# keys

Manages key bindings in Textadept.

## Overview

Key bindings are defined in the global table `keys`. Each key-value pair in
`keys` consists of either a string key sequence and its associated command,
a string lexer language (from the *lexers/* directory) with a table of key
sequences and commands, a string key mode with a table of key sequences and
commands, or a key sequence with a table of more sequences and commands. The
latter is part of what is called a "key chain", to be discussed below. When
searching for a command to run based on a key sequence, key bindings in the
current key mode have priority. If no key mode is active, key bindings in the
current lexer have priority, followed by the ones in the global table. This
means if there are two commands with the same key sequence, the one specific
to the current lexer is run. However, if the command returns the boolean
value `false`, the lower-priority command is also run. (This is useful for
language-specific modules to override commands like Adeptsense
autocompletion, but fall back to word autocompletion if the first command
fails.)

## Key Sequences

Key sequences are strings built from a combination of modifier keys and the
key itself. Modifier keys are "Control", "Shift", and "Alt" on Windows,
Linux, BSD, and in curses. On Mac OSX they are "Command" (`⌘`), "Alt/Option"
(`⌥`), "Control" (`^`), and "Shift" (`⇧`). These modifiers have the following
string representations:

Modifier | Linux / Win32 | Mac OSX | Terminal |
---------|---------------|---------|----------|
Control  | `'c'`         | `'m'`   | `'c'`    |
Alt      | `'a'`         | `'a'`   | `'m'`    |
Shift    | `'s'`         | `'s'`   | `'s'`    |
Command  | N/A           | `'c'`   | N/A      |

For key values less than 255, their string representation is the character
that would normally be inserted if the "Control", "Alt", and "Command"
modifiers were not held down. Therefore, a combination of `Ctrl+Alt+Shift+A`
has the key sequence `caA` on Windows and Linux, but a combination of
`Ctrl+Shift+Tab` has the key sequence `cs\t`. On a United States English
keyboard, since the combination of `Ctrl+Shift+,` has the key sequence `c<`
(`Shift+,` inserts a `<`), the key binding is referred to as `Ctrl+<`. This
allows key bindings to be language and layout agnostic. For key values
greater than 255, the [`KEYSYMS`](#KEYSYMS) lookup table is used. Therefore,
`Ctrl+Right Arrow` has the key sequence `cright`. Uncommenting the `print()`
statements in *core/keys.lua* will print key sequences to standard out
(stdout) for inspection.

## Commands

Commands bound to key sequences can be either Lua functions, or tables
containing Lua functions with a set of arguments to call the function with.
Examples are:

    keys['cn'] = buffer.new
    keys['cs'] = buffer.save
    keys['a('] = {_M.textadept.editing.enclose, '(', ')'}
    keys['cu'] = function() io.snapopen(_USERHOME) end

(The function and function table syntax are functionally equivalent. You can
use either.)

[`buffer`][] references are handled properly in static contexts.

[`buffer`]: buffer.html

## Modes

Sets of key bindings can be grouped together into modes. When a key
[mode](#MODE) is active, all key bindings defined outside the mode are
ignored until the mode is unset. Here is a simple vi mode example:

    keys.command_mode = {
      ['h'] = buffer.char_left,
      ['j'] = buffer.line_up,
      ['k'] = buffer.line_down,
      ['l'] = buffer.char_right,
      ['i'] = function()
        keys.MODE = nil
        gui.statusbar_text = 'INSERT MODE'
      end
    }
    keys['esc'] = function() keys.MODE = 'command_mode' end
    events.connect(events.UPDATE_UI, function()
      if keys.MODE == 'command_mode' then return end
      gui.statusbar_text = 'INSERT MODE'
    end)
    keys.MODE = 'command_mode' -- default mode

## Key Chains

Key chains are a powerful concept. They allow multiple key bindings to be
assigned to one key sequence. Language-specific modules
[use key chains](#LANGUAGE_MODULE_PREFIX) for their functions. By default,
the `Esc` (`⎋` on Mac OSX | `Esc` in curses) key cancels a key chain, but it
can be redefined via [`CLEAR`](#CLEAR). An example key chain looks like:

    keys['aa'] = {
      a = function1,
      b = function2,
      c = {function3, arg1, arg2}
    }

- - -

## Fields

- - -

<a id="CLEAR"></a>
### `CLEAR` (string)

The string representing the key sequence that clears the current key chain.
  It cannot be part of a key chain.
  The default value is `'esc'` for the `Esc` (`⎋` on Mac OSX | `Esc` in
  curses) key.

- - -

<a id="LANGUAGE_MODULE_PREFIX"></a>
### `LANGUAGE_MODULE_PREFIX` (string)

The starting key of the key chain reserved for language-specific modules.
  The default value is `'cl'` on platforms other than Mac OSX, `'ml'`
  otherwise. Equivalent to `Ctrl+L` (`⌘L` on Mac OSX | `M-L` in curses).

- - -

<a id="MODE"></a>
### `MODE` (string)

The current key mode.
  When non-`nil`, all key bindings defined outside of `keys[MODE]` are
  ignored.
  The default value is `nil`.

- - -


## Tables

- - -

<a id="KEYSYMS"></a>
### `KEYSYMS`

Lookup table for string representations of key codes higher than 255.
Key codes can be identified by temporarily uncommenting the `print()`
statements in *core/keys.lua*.

- - -

<a id="_G.keys"></a>
### `_G.keys`

Map of key bindings to commands, with language-specific key tables assigned
to a lexer name key.

- - -

