Keymaps

Iron Resources Files

Iron keymap resource files are text files that are compiled and used by Iron to define key bindings, menus, macros, scopes (colors, sizes, etc) and other settings.

You, the user, can customize any of Iron’s text resource files and tailor the user-interface and look of Iron to meet your needs and preferences. Iron resource files are written using Iron’s internal language called Zinc.

The Zinc file format is simple and straightforward, designed to be customized easily and be tolerant of software changes that will occur between releases. Zinc is composed of declarations and statements that make references to built-in actions and settings.

The following sections describes Iron’s Keymap file format, it’s content and information that is useful for working with other Iron resource files.

Refer to the Iron Resource Files: Customizing documentation on how to compile (press F7) and debug (press F4) Zinc files in more detail.

 

You might not think that programmers are artists, but programming is an extremely creative profession. It’s logic-based creativity. 

John Romero

Director, designer, programmer, and developer, co-founder of id Software and designer for many of their games, including Wolfenstein 3D, Dangerous Dave, Hexen, Doom and Quake.

Keymaps: Loading and Compiling

Iron Keymap resource files are text files that are compiled and used by Iron to define key bindings otherwise known as hotkeys or shortcuts.

The iron.keymap file can be loaded using the Tools|Keymaps|Load Keymap File menu option or via the Command Palette (press F8) and type iron.keymap and Enter.

This document will describe the Zinc keymap file format, it’s grammar, content and uses.

Key Bindings & Combos

All of Iron’s user input is processed via the key bindings defined in the iron.keymap file.

Different combinations of pressed keys on the keyboard (and mouse) define a key combo. A key combo can be a single character like the key for letter “A”, a function key, a keypad key, arrow keys, a mouse button. Or a key combo can be combination of any number of keys or buttons.

Key combos can also be combined with modifiers, that is, the left and right Control, Alt and Shift keys.

Ideally the combinations are simple, easy to remember, few in number, easy and comfortable to type one or two-handed. However, editing source code is an intensely interactive process so keeping combos limited and organized is rather challenging. Iron uses two or three keys per combo and reserves four keys for special or rare use circumstances.

Note:  Combo sequences such as typing Ctrl+K and then Ctrl+U to define one action like a special fighting move or casting of a spell in a video game is not yet supported.

Warning:  Some keyboards will not support more than four keys per combo and some combos simply cannot be accommodated by the keyboard hardware or are used exclusively by the operating system.

In addition to keys, Iron provides modifiers that allow combinations to be valid only as a result of releasing a key as opposed to pressing a key to form the combo. These are the release and press modifiers. Thus it’s possible to perform one action when a key is pressed (to form the combo) and different action when it’s released (that breaks the combo).

Iron also has  repeat and no_repeat modifiers which means that input generated by holding down a key long enough to repeat can be handled differently than if the key is pressed and quickly released. For example, deleting text to the end of the line and continuing to hold down the key combo Ctrl+K, though harmless, doesn’t make sense to do repeatedly (hint…once the text is deleted to the end of the line, there’s no text to delete multiple times).

Another example, using home+repeat allows the Home key to be used both to jump to the beginning of the line (first key press, no repeat) and going to the beginning of the file (hold until Home repeats).

Other than Alt+F4 (which is hardcoded to Quit Iron), all input to Iron is mapped with the iron.keymap file including the alphabet, digits and punctuation. This allows international keyboards and non-QWERTY keyboards to be easily re-mapped for use with  Iron.

Note:  More international keyboard and font support is coming in the future.

Note:  Use of var modifier statements is experimental though they are required in a few of the keymap_set() declarations in the iron.keymap file at this time. Distinguishing between left and right Control, Alt and Shift keys is not supported at this time.

Key Bindings: First Match Wins

One of the first things you’ll notice in the iron.keymap file is that there are a lot of key bindings. And you’ll notice that some key bindings show up many times. How does Iron determine which macro or set of built-in actions to execute when you press a certain combo of keys on the keyboard?

At the top of the file you’ll see how the Escape key (ESC) in the key_combo() statements is bound to many different actions. Which action gets executed depends on the current context. Most often the context is determined by where the caret is in the file, where it is on the line or simply by what type of file is current.

The context can also be determined by what is happening within Iron. For example, if an audio clip is playing, pressing the ESC key will stop playing it using the audio.cancel() built-in action.

Often, which pane is current is used to determine the context. For example, the Enter key when used in the Command Palette instructs Iron to execute the one-line command the caret is on. In a text file pane, the Enter key starts a new line. When pressed while the iron.results Find-in-Files file is current, the Enter key will load a source file and jump to the line the caret is referencing.

So, almost every key binding will have a context expression. In other words, Iron is designed (and can be further personalized as needed) to perform the appropriate and expected action based on the editing task you are doing at any given time.

When you press (or release) a keyboard key or mouse button, Iron scans through the active key_combo() statements defined in the iron.keymap file from top-to-bottom looking for a matching combination of pressed keys or buttons. When it finds a key binding match, Iron then evaluates the context expression to determine if the context is true. If it is, the key_combo()’s command expression is executed. The command expression is the set of macros or actions that tells Iron what to do.

If the context expression evaluates to false (for example no audio clip is playing), the key_combo()’s command expression is not executed and Iron continues to seek out a matching key binding and valid context. Once Iron finds a matching key binding, a valid context and executes the command expression, that completes the processing of the keyboard or mouse stroke (press or release).

So, whenever pressing or releasing a key, Iron searches the file from top-to-bottom and the first match (and valid context) wins.

Note: On Iron’s roadmap, multiple keymap files with a precedence order will be supported. This will allow different key bindings to take precedence based on system-wide contexts such as which operating system is in use, which computer or international language is current, which computer or keyboard is present. The same logic will apply, there will be layers of keymap files and bindings and the first match still wins.

Context and Command Expressions

The key_combo() function has two formats:

key_combo( <key_combo>, <context_expression>, <command_expression> );
key_combo( <key_combo>, <command_expression> );

The <key_combo> is an arithmetic-like expression composed of keys, buttons or modifiers separated by the addition operator “+” (no quotes) that define a pattern of pressed keys. The order of keys and whitespace do not matter.

The <context_expression> and <command_expression> are simplified boolean expressions composed of AND’ed operands of function calls (action or macro calls). The simplified grammar (to be expanded in the future) allows built-in actions and user-defined macros to be evaluated from left-to-right.

Note:  Evaluation stops short-circuit-wise when an action or macro returns false.

In the formats above, if there’s no <context_expression>, the <command_expression> will be executed any time the <key_combo> is matched (the context is assumed to be true). Should the <command_expression> return false, Iron will continue to seek another matching key combo. This is how the audio.cancel() action will consume an ESC key press and cancel all currently playing audio clips -or- not consume the ESC key if there are no clips playing and return false allowing other things to be cancelled further down in the keymap file.

Zinc expressions support AND and NOT’ed function calls. The OR operator and parenthetical grouping are not yet supported. The expression production rules are as follows:

expression := <funct_call> [ and <funct_call> | and not( <funct_call> ) ]*
funct_call := <action_call> | <macro_call> | true | false
action_call := action_name( <param_list> )
macro_call := macro_name()
param_list := void | <named_param> [, <named_param> ]*
named_param := <param_name> = <param_value>
param_value := integer | real | true | false | string | enum

Action calls have a list of comma separated named parameters. Named parameters consist of the <parameter_name>, the equals sign (=) assignment operator and a simple constant value (no expressions). Constant values can be integers, real numbers, double-quoted strings, enumerations or boolean constants. Being named, parameters can be listed in any order.

Each action’s named parameters have a default value that will be used should the action call not include that parameter. The default values Iron employs is generally setup to accommodate the Traditional Mode key bindings. Iron Professional Mode key bindings often specify parameters that inform the built-in action to perform somewhat differently than you might be accustomed to.

Note:  Documentation for each action and the default values for named parameters will be provided internally by Iron in a future release.

Named parameters that are not recognized by Iron or of the wrong type will generate a warning message, syntax highlight in an alternate color and be ignored by the compiler. The Zinc debug key (F4) will take you to the specific problem and echo the warning in the Status pane.

The intent of using defaulted named parameters is that the keymap file (and other Zinc files) that you customize will stay valid with new releases of Iron which may add or change parameter names, types or default values.

Though it is not necessarily good form, context expressions can perform actions that have an effect on a file, change an internal state or what have you. This means, in the course of evaluating the context expression, actions are executed every time the key and button state matches the defined combo. Short-circuit evaluation still applies.

Note:  Context and command expressions use short-circuit-like evaluation but is opposite to how most short-circuit evaluation works in most computer languages. Evaluation/execution of context and command expressions halts whenever a macro or action returns false.

Key Bindings and Macros (and Menus)

Key binding context and command expressions can reference either built-in actions or user-defined macros. User-defined macros are all located in the iron.macro file by default. They can, however, be defined in any of Iron’s resource files and referenced anywhere.

Note: For the timing being, macros and other Zinc declarations all have global scope and visibility between all the Zinc files. The namespace statements, though required, are ignored.

Macros have pairs of context and command expressions. When a macro is referenced by a key binding’s context expression, the key binding is using the macro’s context expression. When the key binding’s command expression references a macro, the key binding is using the macro’s command expression.

Why use macros?

  • Like in other programming languages, macros are used to descriptively name functionality and can be referenced multiple places throughout the Iron resource file set.
  • Macros have up to four pairs of context and command expressions. This allows Iron to match a key binding and then attempt to validate up to four different contexts. This is equivalent to using a boolean OR operator i.e. allows for more complex context validation.
  • When the same macro is referenced by a key binding and a menu item, the menu item will render the key combo (shortcut) on the right side of the menu item.

Note: To display a key combo on a menu item, Iron will seek out the first key binding in the iron.keymap file that references the same macro. This mechanism works well enough but may be replaced in the future with a stronger coupling scheme, i.e. use of some kind of name tagging. To be determined.

Note: Macros are described in detail in the Iron Resource Files: Macros documentation. Built-in actions and their parameters are quite in flux at this early stage of Iron’s development. More documentation on actions will be forthcoming.

Function Call Subsystems & Parameters

Iron’s built-in actions are grouped into a number of subsystems. The subsystems use many of the same enumerated parameter types. The subsystems and some of the enumerated parameters are described here.

Action names are composed of one or two parts separated by a dot (period) and followed by a comma-separated named parameter list enclosed in parenthesis. If there is a two-part name, the first part is the Iron subsystem, the second part is descriptive of the action to be performed.

The subsystems are:

audio                     —  used to play & control audio warnings and prompts
bookmark          —  used to work with regions (bookmarks) and logbooks
caret                      —  used to manipulate the caret(s), part of fine editing
cpi                           —  Command Palette Interpreter used to change/inspect internal settings
command           —  used to execute commands as if typed into the Command Palette
edit                         —  fine editing functions for inserting & deleting text, etc.
fif                             —  Find-in-File(s) actions for searching
file                           —  to manipulate and inspect files (e.g. close, open, create, exist, lock)
file_tabs               —  used to interact with the file tab system
fling                        —  used to issue 3D notifications that animate in various ways
font                        —  used to change font settings
lexer                      —  used to inspect the lexer/parser associated with a file
liquid                     —  a 3D graphics effect
menu                     —  used to interact with the 3D menu system
mouse                   —  used for picking with the mouse
notice                    —  simplified version of flings used to issue warnings, errors and info
pane                       —  used to manipulate & inspect pane settings, layouts and components
scrap                      —  clipboard interaction for copying, cutting and pasting text
select                     —  used for defining & manipulation of single and multiple selections
zinc                         —  used to compile and debug Iron resource files

Some of the common enumeration types used as parameters include:

Bookmark type (bookmark_type):

any                                          —  refers to any type of bookmark
bookmark                           —  generic bookmark, normally user-created
error                                       —  error location, created by the Zinc compiler
first                                         —  first bookmark in a logbook
info                                         —  informational
last                                          —  last bookmark in a logbook
warning                               —  warning location, created by the Zinc compiler

Fling transitions (transition):

blast                                      —  pops on screen, blasts outward and falls by gravity
blast_fade_out                —  blasts out, falls by gravity then fades out
fade_in_out                       —  fades in, remains briefly, then fades out
fade_out                             —  pops on screen, then fades out
fade_slide_fall                 —  fades in, slides right, falls by gravity
fall_fade_in_out              —  fades in, falls by gravity and fades out
slide_fade_in_out          —  fades in, slides right, then fades out

Caret shapes (caret_shape):

box                                          —  box that outlines a character
box_arrow                          —  box with sides augmented to indicate selection direction
bar_horz                              —  horizontal bar below the character
bar_vert                               —  typical vertical bar preceding current character

Pane usage (pane_usage):

current                                 —  the currently active pane (which is of the following pane types)
text                                         —  where source code is edited
command                            —  the Command Palette pane for searching and loading files
status                                     —  the Status pane is a log of action responses or warnings
directories                          —  list of directory path names, defines the Directory Search Path
extensions                          —  list of file name extensions used in Seek and Loading of files

Selection styles (select_style):

none                                       —  no selection, just a bare caret
column                                 —  a column (block) selection
line                                          —  a line selection (another type of block)
stream                                  —  a stream selection (traditional, prose style)
same                                      —  continue using the current selection style
same_or_column            —  if no selection, switch to column
same_or_line                     —  if no selection, switch to line
same_or_stream             —  if no selection, switch to stream
xxx_padded                        —  appended to same/column/line so whitespaces is added cut/paste
xxx_not_padded              —  appended to same/column/line so no whitespace is added

Selection type (select_type):

single                     —  apply or consider only a single selection (aka the primary caret/selection)
multi                      —  apply or consider all selections aka Multi-Selection action