| Clink v1.3.15 https://github.com/chrisant996/clink Christopher Antos (renovater) Martin Ridgers (creator)

# What is Clink?

Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities. Readline is best known for its use in the Unix shell Bash, the standard shell for Mac OS X and many Linux distributions.

### Features

Here are some highlights of what Clink provides:

- The same line editing as Bash (from the GNU Readline library version 8.1).
- History persistence between sessions.
- Context sensitive completion;
  - Executables (and aliases).
  - Directory commands.
  - Environment variables.
- Context sensitive colored input text.
- Automatic suggestions from history and completions.
- New keyboard shortcuts;
  - Interactive completion list (`Ctrl`+`Space`).
  - Incremental history search (`Ctrl`+`R` and `Ctrl`+`S`).
  - Powerful completion (`Tab`).
  - Undo (`Ctrl`+`Z`).
  - Environment variable expansion (`Ctrl`+`Alt`+`E`).
  - Doskey alias expansion (`Ctrl`+`Alt`+`F`).
  - Scroll the screen buffer (`Alt`+`Up`, etc).
  - `Shift`+Arrow keys to select text, typing replaces selected text, etc.
  - (press `Alt`+`H` for many more...)
- Directory shortcuts;
  - Typing a directory name followed by a path separator is a shortcut for `cd /d` to that directory.
  - Typing `..` or `...` is a shortcut for `cd ..` or `cd ..\..` (each additional `.` adds another `\..`).
  - Typing `-` or `cd -` changes to the previous current working directory.
- Scriptable autosuggest with Lua.
- Scriptable completion with Lua.
- Scriptable key bindings with Lua.
- Colored and scriptable prompt.
- Auto-answering of the "Terminate batch job?" prompt.

By default Clink binds `Alt`+`H` to display the current key bindings. More features can also be found in GNU's Readline.

# Usage

There are several ways to start Clink.

1. If you installed the auto-run, just start `cmd.exe`. Run `clink autorun --help` for more info.
2. To manually start, run the Clink shortcut from the Start menu (or the clink.bat located in the install directory).
3. To establish Clink to an existing `cmd.exe` process, use `<install_dir>\clink inject`.

Starting Clink injects it into a `cmd.exe` process, where it intercepts a handful of Windows API functions so that it can replace the prompt and input line editing with its own Readline-powered enhancements.

# Getting Started

You can use Clink right away without configuring anything:

- Searchable command history will be saved between sessions.
- `Tab` and `Ctrl`+`Space` will do match completion two different ways.
- Press `Alt`+`H` to see a list of the current key bindings.
- Press `Ctrl`+`Shift`+`/` followed by another key to see what command is bound to the key.

There are three main ways of customizing Clink to your preferences: the Readline init file (the `.inputrc` file), the Clink settings (the `clink set` command), and Lua scripts.

## Common Configuration

The following sections describe some ways to begin customizing Clink to your taste.

Enhanced default settings | Optionally use enhanced default settings.
Create a .inputrc file | Create a .inputrc file where config variables and key bindings can be set.
Bash vs Windows | Make `Ctrl`+`F` and `Ctrl`+`M` work like usual on Windows.
Auto-suggest | How to enable and use automatic suggestions.
Colors | Configure the colors.
Key Bindings | Customize your key bindings.
Mouse Input | Optionally enable mouse clicks in the input line, etc.
Startup Cmd Script | Optional automatic `clink_start.cmd` script.
Custom Prompt | Customizing the command line prompt.
Upgrading from Clink v0.4.9 | Notes on upgrading from a very old version of Clink.

### Enhanced default settings

Clink can be installed with plain defaults, or it can be installed with enhanced default settings that enable more of Clink's enhancements by default.

If you install Clink with the setup program and "Use enhanced default settings" is checked, then the enhanced defaults are activated, and then in some places where this documentation refers to default settings the stated default may have been overridden.

If you install Clink from the .zip file then enhanced default settings are activated when the `default_settings` and `default_inputrc` files are present in the binaries directory or in the profile directory. The .zip file comes with the files, but their names have a `_` prefix so that enhanced defaults won't automatically take effect. You can activate the enhanced default settings by renaming the files to remove the `_` prefix.

Here are some of the enhanced defaults. Review the `default_settings` and `default_inputrc` files for the full list.

- Automatic suggestions are enabled.
- Many color settings have colorful defaults.
- Uses Windows key bindings by default.
- The command history's default limit is increased to 25,000 entries.
- Completion expands environment variables (the `match.expand_envvars` setting).
- If no completions are found with a prefix search, then a substring search is used (the `match.substring` setting).
- `Ctrl`+`D` does not exit CMD (the `cmd.ctrld_exits` setting).

### Create a .inputrc file

First you'll want to create a `.inputrc` file, and a good place is in your Windows user profile directory.

This file is used for some configuration, such as key bindings and colored completions.

Create the file by running this command at a CMD prompt:

    notepad %userprofile%\.inputrc

You may want to copy/paste the following sample text into the file as a starting point, and then press `Ctrl`+`S` to save the file.

    # Some common Readline config settings.

    set colored-stats                 on   # Turn on completion colors.
    set colored-completion-prefix     on   # Color the typed completion prefix.

    # Some config settings that only work in Clink.

    $if clink
    set search-ignore-case            on   # Case insensitive history searches.
    set completion-auto-query-items   on   # Prompt before showing completions if they'll exceed half the screen.
    $endif

    # Add your keybindings here...

### Bash vs Windows

The default Clink key bindings are the same as in the "bash" shell for Unix/Linux. That makes some keys like `Ctrl`+`A`, `Ctrl`+`F`, and `Ctrl`+`M` behave differently than you might be used to in CMD.

To instead use the familiar Windows default key bindings you can run `clink set clink.default_bindings windows`.

Or, if you use the setup program with "Use enhanced default settings" checked then "windows" key bindings are the default, and you can run `clink set clink.default_bindings bash` to use the bash default key bindings.

Clink comes with many default key bindings. Use `Alt`+`H` to see all of the active key bindings, or use `Alt`+`Shift`+`?` to check what is bound to a specific key. See Key Bindings to get started configuring your own key bindings.

Here are the differences between the Windows defaults and the bash defaults:

Key | Windows | Bash
--- | --- | ---
`Ctrl`+`A` | Select All. | Go to beginning of line.
`Ctrl`+`B` | (not bound) | Move backward one character.
`Ctrl`+`E` | Expands doskey aliases, environment variables, and history expansions in the current line. | Go to end of line.
`Ctrl`+`F` | Find text (in plain Conhost console windows). | Move forward one character.
`Ctrl`+`M` | Mark text (in plain Conhost console windows). | Same as `Enter`.
`Tab` | Cycle forward through available completions. | Bash style completion.
`Shift`+`Tab` | Cycle backward through available completions. | (not bound)
`Right` | Move forward one character, or at the end of the line insert the next character from the previous input line. | Move forward one character.

### Auto-suggest

Clink can suggest commands as you type, based on command history and completions.

To turn on automatic suggestions, run `clink set autosuggest.enable true`. When the cursor is at the end of the input line, a suggestion may appear in a muted color. If the suggestion isn't what you want, just ignore it. Or accept the whole suggestion with the `Right` arrow or `End` key, accept the next word of the suggestion with `Ctrl`+`Right`, or accept the next full word of the suggestion up to a space with `Shift`+`Right`.

The `autosuggest.strategy` setting determines how a suggestion is chosen.

Or, if you use the setup program with "Use enhanced default settings" checked then automatic suggestions are enabled by default.

### Colors

Clink has many configurable colors for match completions, input line coloring, popup lists, and more.

If you use the setup program with "Use enhanced default settings" checked then many of the color settings have more colorful default values.

#### For completion

When performing completion (e.g. `Tab` or `Ctrl`+`Space`) Clink can add color to the possible completions.

To turn on colored completions, put a line `set colored-stats on` in the .inputrc file (if you copy/pasted the sample text, it's already there).

See the Completion Colors section for how to configure the colors for match completions.

#### Other colors

Clink adds color to the input line by highlighting arguments, flags, doskey macros, and more. If you don't want input line colors, you can turn it off by running `clink set clink.colorize_input false`.

There are also colors for popup lists, and some other things.

To configure a color, run `clink set colorname colorvalue`.

Match completions make it easy to change Clink settings: type `clink set color.` and then use completion (e.g. `Tab` or `Ctrl`+`Space`) to see the available color settings, and to fill in a color value.

Here are some colors you may want to set up right away:

Color | Description | Recommended
--- | --- | ---
`color.executable` | Apply color when the command is an executable file. | `clink set color.executable sgr 38;5;32`
`color.unrecognized` | Apply color when the command is not recognized. | `clink set color.unrecognized sgr 38;5;203`

See the Clink Settings and Color Settings sections for more information on Clink settings.

### Key Bindings

You can customize your key bindings (keyboard shortcuts) by assigning key bindings in the .inputrc file. See Customizing Key Bindings for more information.

Clink comes with many pre-configured key bindings that invoke named commands. Here are a few that you might find especially handy:

`Alt`+`H` | This is `clink-show-help`, which lists the key bindings and commands. Learn more by visiting Customizing Key Bindings.
`Tab` | This is `complete` or `old-menu-complete`, depending on the [`clink.default_bindings`](#default_bindings) Clink setting. `complete` swhich performs completion by selecting from an interactive list of possible completions; if there is only one match, the match is inserted immediately.
`Ctrl`+`Space` | This is `clink-select-complete`, which performs completion by selecting from an interactive list of possible completions; if there is only one match, the match is inserted immediately.
`Alt`+`=` | This is `possible-completions`, which lists the available completions for the current word in the input line.
`Alt`+`.` | This is `yank-last-arg`, which inserts the last argument from the previous line. You can use it repeatedly to cycle backwards through the history, inserting the last argument from each line. Learn more by reading up on the "yank" features in the [Readline manual](https://tiswww.cwru.edu/php/chet/readline/rluserman.html).
`Ctrl`+`R` | This is `reverse-search-history`, which incrementally searches the history. Press it, then type, and it does a reverse incremental search while you type. Press `Ctrl`+`R` again (and again, etc) to search for other matches of the search text. Learn more by reading up on the "search" and "history" features in the [Readline manual](https://tiswww.cwru.edu/php/chet/readline/rluserman.html).
`Ctrl`+`Alt`+`D` | This is `remove-history`, which deletes the currently selected history line after using any of the history search or navigation commands.
`Ctrl`+`Alt`+`K` | This is `add-history`, which adds the current line to the history without executing it, and then clears the input line.
`Ctrl`+`Alt`+`N` | This is `clink-menu-complete-numbers`, which grabs numbers with 3 or more digits from the current console screen and cycles through inserting them as completions (binary, octal, decimal, hexadecimal). Super handy for quickly inserting a commit hash that was printed as output from a preceding command.
`Alt`+`0` to `Alt`+`9` | These are `digit-argument`, which let you enter a numeric value used by many commands. For example `Ctrl`+`Alt`+`W` copies the current word to the clipboard, but if you first type `Alt`+`2` followed by `Ctrl`+`Alt`+`W` then it copies the 3rd word to the clipboard (the first word is 0, the second is 1, etc). Learn more by reading up on "Readline Arguments" in the [Readline manual](https://tiswww.cwru.edu/php/chet/readline/rluserman.html).

For a full list of commands available for key bindings, see New Commands and "Bindable Readline Commands" in the Readline manual.

### Mouse Input

Clink can optionally respond to mouse input, instead of letting the terminal respond to mouse input (e.g. to select text on the screen). When mouse input is enabled in Clink, you can click in the input line or in popup lists, and the mouse wheel scrolls popup lists.

Use `clink set terminal.mouse_input mode` with one of the following modes to control whether Clink responds to mouse input:

Mode | Description
--- | ---
`off` | Lets the terminal host handle mouse input.
`on` | Lets Clink handle mouse input.
`auto` | Lets Clink handle mouse input in ConEmu and in the default Conhost terminal when Quick Edit mode is unchecked in the console Properties dialog.

Use `clink set terminal.mouse_modifier modifiers` or `set CLINK_MOUSE_MODIFIER=modifiers` to control which modifier keys must be held for Clink to respond to mouse input.

These select which modifier keys (`Alt`, `Ctrl`, `Shift`) must be held in order for Clink to respond to mouse input when mouse input is enabled by the `terminal.mouse_input` setting. modifiers is a text string that can list one or more modifier keys: 'alt', 'ctrl', and 'shift'. For example, setting it to "alt shift" causes Clink to only respond to mouse input when both `Alt` and `Shift` are held (and not `Ctrl`). If the `%CLINK_MOUSE_MODIFIER%` environment variable is set then its value supersedes the `terminal.mouse_modifier` setting. In Windows Terminal many modifier keys do special things with mouse clicks, so the modifier key combination that interferes least with built in Windows Terminal behaviors is `Ctrl`+`Alt`.

When mouse input is enabled in Clink, then mouse input works a little differently:

- You can bypass Clink mouse input and use the normal terminal mouse input by holding a different combination of modifier keys than listed in `terminal.mouse_modifier` or `%CLINK_MOUSE_MODIFIER%`.
- Windows Terminal treats `Shift`+`RightClick` specially and turns off line ending detection when copying the selected text to the clipboard. Hold `Ctrl` or `Alt` when right clicking to do the normal copy with line ending detection.
- In ConEmu, the mouse wheel always scrolls the terminal; Clink cannot use it to scroll popup lists.
- In the default Conhost terminal when Quick Edit mode is turned off then Clink will also respond to mouse input when no modifier keys are held.

### Startup Cmd Script

When Clink is injected, it looks for a `clink_start.cmd` script in the binaries directory and profile directory. Clink automatically runs the script(s), if present, when the first CMD prompt is shown after Clink is injected. You can set the `clink.autostart` setting to run a different command, or set it to "nul" to run no command at all.

### Custom Prompt

If you want a customizable prompt with a bunch of styles and an easy-to-use configuration wizard, check out clink-flex-prompt. Also, if you've been disappointed by git making the prompt slow in other shells, try this prompt -- it makes the prompt appear instantly by running git commands in the background and refreshing the prompt once the background commands complete.

Other popular configurable prompts are oh-my-posh and starship.

See Customizing the Prompt for information on how to use Lua to customize the prompt.

## Upgrading from Clink v0.4.9

The new Clink tries to be as backward compatible with Clink v0.4.9 as possible. However, in some cases upgrading may require a little bit of configuration work.

- Some key binding sequences have changed; see Customizing Key Bindings for more information.
- Match coloring works differently now and can do much more; see Completion Colors for more information.
- Old settings and history migrate automatically if the new `clink_settings` and `clink_history` files don't exist (deleting them will cause migration to happen again). To find the directory that contains these files, run `clink info` and look for the "state" line.
- Script compatibility should be very good, but some scripts may still encounter problems. If you do encounter a compatibility problem you can look for an updated version of the script, update the script yourself, or visit the clink repo and open an issue describing details about the compatibility problem.
- Some match generator scripts might need adjustments to become fully compatible with the `autosuggest.enable` setting.
- Some match generator scripts might need adjustments to become fully compatible with the `autosuggest.enable` setting.
- Some settings have changed slightly, and there are many new settings. See Configuring Clink for more information.

# Configuring Clink

Clink has two configuration systems, which is a result of using the Readline library to provide command history and key bindings.

The following sections describe how to configure Clink itself. To learn about the Readline configuration and key bindings, instead see Configuring Readline.

Clink Settings | How to customize Clink's settings.
Color Settings | Describes the syntax used by color settings.
File Locations | Where Clink stores its history and settings files.
Command Line Options | Describes the command line options for the Clink program.
Portable Configuration | How to set up a "portable" installation of Clink, e.g. on a USB drive or network location.

## Clink Settings

The easiest way to configure Clink is to use the `clink set` command. This can list, query, and set Clink's settings. Run `clink set --help` from a Clink-installed cmd.exe process to learn more both about how to use it and to get descriptions for Clink's various options.

The following table describes the available Clink settings:

Name | Default * | Description
--- | --- | ---
`autosuggest.async` | True | When this is `true` matches are generated asynchronously for suggestions. This helps to keep typing responsive.
`autosuggest.enable` | False * | When this is `true` a suggested command may appear in `color.suggestion` color after the cursor. If the suggestion isn't what you want, just ignore it. Or accept the whole suggestion with the `Right` arrow or `End` key, accept the next word of the suggestion with `Ctrl`+`Right`, or accept the next full word of the suggestion up to a space with `Shift`+`Right`. The `autosuggest.strategy` setting determines how a suggestion is chosen.
`autosuggest.original_case` | True | When this is enabled (the default), accepting a suggestion uses the original capitalization from the suggestion.
`autosuggest.strategy` | `match_prev_cmd history completion` | This determines how suggestions are chosen. The suggestion generators are tried in the order listed, until one provides a suggestion. There are three built-in suggestion generators, and scripts can provide new ones. `history` chooses the most recent matching command from the history. `completion` chooses the first of the matching completions. `match_prev_cmd` chooses the most recent matching command whose preceding history entry matches the most recently invoked command, but only when the `history.dupe_mode` setting is `add`.
`clink.autostart` |  | This command is automatically run when the first CMD prompt is shown after Clink is injected. If this is blank (the default), then Clink instead looks for `clink_start.cmd` in the binaries directory and profile directory and runs them. Set it to "nul" to not run any autostart command.
`clink.colorize_input` | True | Enables context sensitive coloring for the input text (see Coloring the Input Text).
`clink.default_bindings` | `bash` * | Clink uses bash key bindings when this is set to `bash` (the default). When this is set to `windows` Clink overrides some of the bash defaults with familiar Windows key bindings for `Tab`, `Ctrl`+`A`, `Ctrl`+`F`, `Ctrl`+`M`, and `Right`.
`clink.gui_popups` | False | When set, Clink uses GUI popup windows instead console text popups. The `color.popup` settings have no effect on GUI popup windows.
`clink.logo` | `full` | Controls what startup logo to show when Clink is injected. `full` = show full copyright logo, `short` = show abbreviated version info, `none` = omit the logo.
`clink.paste_crlf` | `crlf` | What to do with CR and LF characters on paste. Setting this to `delete` deletes them, `space` replaces them with spaces, `ampersand` replaces them with ampersands, and `crlf` pastes them as-is (executing commands that end with a newline).
`clink.path` |  | A list of paths from which to load Lua scripts. Multiple paths can be delimited semicolons.
`clink.promptfilter` | True | Enable prompt filtering by Lua scripts.
`cmd.admin_title_prefix` |  | When set, this replaces the "Administrator: " console title prefix.
`cmd.auto_answer` | `off` | Automatically answers cmd.exe's "Terminate batch job (Y/N)?" prompts. `off` = disabled, `answer_yes` = answer Y, `answer_no` = answer N.
`cmd.ctrld_exits` | True | `Ctrl`+`D` exits the process when it is pressed on an empty line.
`cmd.get_errorlevel` | True | When this is enabled, Clink runs a hidden `echo %errorlevel%` command before each interactive input prompt to retrieve the last exit code for use by Lua scripts. If you experience problems, try turning this off. This is on by default.
`color.arg` |  | The color for arguments in the input line when `clink.colorize_input` is enabled.
`color.arginfo` | `yellow` * | Argument info color. Some argmatchers may show that some flags or arguments accept additional arguments, when listing possible completions. This color is used for those additional arguments. (E.g. the "dir" in a "-x dir" listed completion.)
`color.argmatcher` | * | The color for the command name in the input line when `clink.colorize_input` is enabled, if the command name has an argmatcher available.
`color.cmd` | `bold` * | Used when displaying shell (CMD.EXE) command completions, and in the input line when `clink.colorize_input` is enabled.
`color.cmdredir` | `bold` * | The color for redirection symbols (`<`, `>`, `>&`) in the input line when `clink.colorize_input` is enabled.
`color.cmdsep` | `bold` * | The color for command separaors (`&`, `
`color.comment_row` | `bright white on cyan` * | The color for the comment row in the `clink-select-complete` command. The comment row shows the "and N more matches" or "rows X to Y of Z" messages.
`color.description` | `bright cyan` * | Used when displaying descriptions for match completions.
`color.doskey` | `bright cyan` * | Used when displaying doskey alias completions, and in the input line when `clink.colorize_input` is enabled.
`color.executable` | * | When set, this is the color in the input line for a command word that is recognized as an executable file.
`color.filtered` | `bold` * | The default color for filtered completions (see Filtering the Match Display).
`color.flag` | `default` * | The color for flags in the input line when `clink.colorize_input` is enabled.
`color.hidden` | * | Used when displaying file completions with the "hidden" attribute.
`color.horizscroll` | * | The color for the `<` or `>` horizontal scroll indicators when Readline's `horizontal-scroll-mode` variable is set.
`color.input` | * | The color for input line text. Note that when `clink.colorize_input` is disabled, the entire input line is displayed using `color.input`.
`color.interact` | `bold` | The color for prompts such as a pager's `--More?--` prompt.
`color.message` | `default` | The color for the message area (e.g. the search prompt message, digit argument prompt message, etc).
`color.popup` |  | When set, this is used as the color for popup lists and messages. If no color is set, then the console's popup colors are used (see the Properties dialog box for the console window).
`color.popup_desc` |  | When set, this is used as the color for description column(s) in popup lists. If no color is set, then a color is chosen to complement the console's popup colors (see the Properties dialog box for the console window).
`color.prompt` |  | When set, this is used as the default color for the prompt. But it's overridden by any colors set by Customizing The Prompt.
`color.readonly` | * | Used when displaying file completions with the "readonly" attribute.
`color.selected_completion` | * | The color for the selected completion with the `clink-select-complete` command. If no color is set, then bright reverse video is used.
`color.selection` | * | The color for selected text in the input line. If no color is set, then reverse video is used.
`color.suggestion` | `bright black` * | The color for automatic suggestions when `autosuggest.enable` is enabled.
`color.unexpected` | `default` | The color for unexpected arguments in the input line when `clink.colorize_input` is enabled.
`color.unrecognized` | * | When set, this is the color in the input line for a command word that is not recognized as a command, doskey macro, directory, argmatcher, or executable file.
`debug.log_terminal` | False | Logs all terminal input and output to the clink.log file. This is intended for diagnostic purposes only, and can make the log file grow significantly.
`doskey.enhanced` | True | Enhanced Doskey adds the expansion of macros that follow `|` and `&` command separators and respects quotes around words when parsing `$1`...`$9` tags. Note that these features do not apply to Doskey use in Batch files.
`exec.aliases` | True | When matching executables as the first word (`exec.enable`), include doskey aliases.
`exec.commands` | True | When matching executables as the first word (`exec.enable`), include CMD commands (such as `cd`, `copy`, `exit`, `for`, `if`, etc).
`exec.cwd` | True | When matching executables as the first word (`exec.enable`), include executables in the current directory. (This is implicit if the word being completed is a relative path, or if `exec.files` is true.)
`exec.dirs` | True | When matching executables as the first word (`exec.enable`), also include directories relative to the current working directory as matches.
`exec.enable` | True | Match executables when completing the first word of a line. Executables are determined by the extensions listed in the `%PATHEXT%` environment variable.
`exec.files` | False | When matching executables as the first word (`exec.enable`), include files in the current directory.
`exec.path` | True | When matching executables as the first word (`exec.enable`), include executables found in the directories specified in the `%PATH%` environment variable.
`exec.space_prefix` | True | If the line begins with whitespace then Clink bypasses executable matching (`exec.path`) and will do normal files matching instead.
`files.hidden` | True | Includes or excludes files with the "hidden" attribute set when generating file lists.
`files.system` | False | Includes or excludes files with the "system" attribute set when generating file lists.
`history.dont_add_to_history_cmds` | `exit history` | List of commands that aren't automatically added to the history. Commands are separated by spaces, commas, or semicolons. Default is `exit history`, to exclude both of those commands.
`history.dupe_mode` | `erase_prev` | If a line is a duplicate of an existing history entry Clink will erase the duplicate when this is set to `erase_prev`. Setting it to `ignore` will not add duplicates to the history, and setting it to `add` will always add lines (except when overridden by `history.sticky_search`).
`history.expand_mode` | `not_quoted` | The `!` character in an entered line can be interpreted to introduce words from the history. This can be enabled and disable by setting this value to `on` or `off`. Values of `not_squoted`, `not_dquoted`, or `not_quoted` will skip any `!` character quoted in single, double, or both quotes respectively.
`history.ignore_space` | True | Ignore lines that begin with whitespace when adding lines in to the history.
`history.max_lines` | 10000 * | The number of history lines to save if `history.save` is enabled (1 to 50000).
`history.save` | True | Saves history between sessions. When disabled, history is neither read from nor written to a master history list; history for each session exists only in memory until the session ends.
`history.shared` | False | When history is shared, all instances of Clink update the master history list after each command and reload the master history list on each prompt. When history is not shared, each instance updates the master history list on exit.
`history.sticky_search` | False | When enabled, reusing a history line does not add the reused line to the end of the history, and it leaves the history search position on the reused line so next/prev history can continue from there (e.g. replaying commands via `Up` several times then `Enter`, `Down`, `Enter`, etc).
`lua.break_on_error` | False | Breaks into Lua debugger on Lua errors.
`lua.break_on_traceback` | False | Breaks into Lua debugger on `traceback()`.
`lua.debug` | False | Loads a simple embedded command line debugger when enabled. Breakpoints can be added by calling pause().
`lua.path` |  | Value to append to `package.path`. Used to search for Lua scripts specified in `require()` statements.
`lua.reload_scripts` | False | When false, Lua scripts are loaded once and are only reloaded if forced (see The Location of Lua Scripts for details). When true, Lua scripts are loaded each time the edit prompt is activated.
`lua.strict` | True | When enabled, argument errors cause Lua scripts to fail. This may expose bugs in some older scripts, causing them to fail where they used to succeed. In that case you can try turning this off, but please alert the script owner about the issue so they can fix the script.
`lua.traceback_on_error` | False | Prints stack trace on Lua errors.
`match.expand_envvars` | False * | Expands environment variables in a word before performing completion.
`match.fit_columns` | True | When displaying match completions, this calculates column widths to fit as many as possible on the screen.
`match.ignore_accent` | True | Controls accent sensitivity when completing matches. For example, `ä` and `a` are considered equivalent with this enabled.
`match.ignore_case` | `relaxed` | Controls case sensitivity when completing matches. `off` = case sensitive, `on` = case insensitive, `relaxed` = case insensitive plus `-` and `_` are considered equal.
`match.limit_fitted_columns` | `0` | When the `match.fit_columns` setting is enabled, this disables calculating column widths when the number of matches exceeds this value. The default is 0 (unlimited). Depending on the screen width and CPU speed, setting a limit may avoid delays.
`match.max_rows` | `0` | The maximum number of rows that `clink-select-complete` can use. When this is 0, the limit is the terminal height.
`match.preview_rows` | `0` | The number of rows to show as a preview when using the `clink-select-complete` command (bound by default to `Ctrl`+`Shift`+`Space`). When this is 0, all rows are shown and if there are too many matches it instead prompts first like the `complete` command does. Otherwise it shows the specified number of rows as a preview without prompting, and it expands to show the full set of matches when the selection is moved past the preview rows.
`match.sort_dirs` | `with` | How to sort matching directory names. `before` = before files, `with` = with files, `after` = after files.
`match.substring` | False * | When set, if no completions are found with a prefix search, then a substring search is used.
`match.translate_slashes` | `system` | File and directory completions can be translated to use consistent slashes. The default is `system` to use the appropriate path separator for the OS host (backslashes on Windows). Use `slash` to use forward slashes, or `backslash` to use backslashes. Use `off` to turn off translating slashes from custom match generators.
`match.wild` | True | Matches `?` and `*` wildcards and leading `.` when using any of the completion commands. Turn this off to behave how bash does, and not match wildcards or leading dots (but `glob-complete-word` always matches wildcards).
`prompt.async` | True | Enables asynchronous prompt refresh. Turn this off if prompt filter refreshes are annoying or cause problems.
`prompt.transient` | `off` | Controls when past prompts are collapsed (transient prompts). `off` = never collapse past prompts, `always` = always collapse past prompts, `same_dir` = only collapse past prompts when the current working directory hasn't changed since the last prompt.
`readline.hide_stderr` | False | Suppresses stderr from the Readline library. Enable this if Readline error messages are getting in the way.
`terminal.adjust_cursor_style` | True | When enabled, Clink adjusts the cursor shape and visibility to show Insert Mode, produce the visible bell effect, avoid disorienting cursor flicker, and to support ANSI escape codes that adjust the cursor shape and visibility. But it interferes with the Windows 10 Cursor Shape console setting. You can make the Cursor Shape setting work by disabling this Clink setting (and the features this provides).
`terminal.differentiate_keys` | False | When enabled, pressing `Ctrl` + `H` or `I` or `M` or `[` generate special key sequences to enable binding them separately from `Backspace` or `Tab` or `Enter` or `Esc`.
`terminal.east_asian_ambiguous` | `auto` | There is a group of East Asian characters whose widths are ambiguous in the Unicode standard. This setting controls how to resolve the ambiguous widths. By default this is set to `auto`, but some terminal hosts may require setting this to a different value to work around limitations in the terminal hosts. Setting this to `font` measures the East Asian Ambiguous character widths using the current font. Setting it to `one` uses 1 as the width, or `two` uses 2 as the width. When this is `auto` (the default) and the current code page is 932, 936, 949, or 950 then the current font is used to measure the widths, or for any other code pages (including UTF8) the East Asian Ambiguous character widths are assumed to be 1.
`terminal.emulation` | `auto` | Clink can either emulate a virtual terminal and handle ANSI escape codes itself, or let the console host natively handle ANSI escape codes. `native` = pass output directly to the console host process, `emulate` = clink handles ANSI escape codes itself, `auto` = emulate except when running in ConEmu, Windows Terminal, or Windows 10 new console.
`terminal.mouse_input` | `auto` | Clink can optionally respond to mouse input, instead of letting the terminal respond to mouse input (e.g. to select text on the screen). When mouse input is enabled in Clink, clicking in the input line sets the cursor position, and clicking in popup lists selects an item, etc. Setting this to `off` lets the terminal host handle mouse input, `on` lets Clink handle mouse input, and `auto` lets Clink handle mouse input in ConEmu and in the default Conhost terminal when Quick Edit mode is unchecked in the console Properties dialog. For more information see Mouse Input.
`terminal.mouse_modifier` |  | This selects which modifier keys (`Alt`, `Ctrl`, `Shift`) must be held in order for Clink to respond to mouse input when mouse input is enabled by the `terminal.mouse_input` setting. This is a text string that can list one or more modifier keys: 'alt', 'ctrl', and 'shift'. For example, setting it to "alt shift" causes Clink to only respond to mouse input when both `Alt` and `Shift` are held (and not `Ctrl`). If the `%CLINK_MOUSE_MODIFIER%` environment variable is set then its value supersedes this setting. For more information see Mouse Input.
`terminal.raw_esc` | False | When enabled, pressing Esc sends a literal escape character like in Unix/etc terminals. This setting is disabled by default to provide a more predictable, reliable, and configurable input experience on Windows. Changing this only affects future Clink sessions, not the current session.
`terminal.use_altgr_substitute` | False | Support Windows' `Ctrl`-`Alt` substitute for `AltGr`. Turning this off may resolve collisions with Readline's key bindings.

* Some settings have alternative default values when Clink is installed with "Use enhanced default settings" checked in the setup program. This enables more of Clink's enhancements by default.

> Compatibility Notes:

> - The `esc_clears_line` setting has been replaced by a `clink-reset-line` command that is by default bound to the `Escape` key. See Customizing Key Bindings and Readline for more information.
> - The `match_colour` setting has been removed, and Clink now supports Readline's completion coloring. See Completion Colors for more information.

## Color Settings

### Friendly Color Names

The Clink color settings use the following syntax:

`[attributes] [foreground_color] [on [background_color]]`

Optional attributes (can be abbreviated to 3 letters):

- `bold` or `nobold` adds or removes boldface (usually represented by forcing the color to use high intensity if it doesn't already).
- `underline` or `nounderline` adds or removes an underline.

Optional colors for foreground_color and background_color (can be abbreviated to 3 letters):

- `default` or `normal` uses the default color as defined by the current color theme in the console window.
- `black`, `red`, `green`, `yellow`, `blue`, `cyan`, `magenta`, `white` are the basic colors names.
- `bright` can be combined with any of the other color names to make them bright (high intensity).

Examples (specific results may depend on the console host program):

- `bri yel` for bright yellow foreground on default background color.
- `bold` for bright default foreground on default background color.
- `underline bright black on white` for dark gray (bright black) foreground on light gray (white) background.
- `default on blue` for default foreground color on blue background.

### Alternative SGR Syntax

It's also possible to set any ANSI SGR escape code using `sgr SGR_parameters` (for example `sgr 7` is the code for reverse video, which swaps the foreground and background colors).

Be careful, since some escape code sequences might behave strangely.

## File Locations

Settings and history are persisted to disk from session to session. By default Clink uses the current user's non-roaming application data directory. This user directory is usually found in one of the following locations;

- Windows XP: `c:\Documents and Settings\<username>\Local Settings\Application Data\clink`
- Windows Vista onwards: `c:\Users\<username>\AppData\Local\clink`

All of the above locations can be overridden using the `--profile path` command line option which is specified when injecting Clink into cmd.exe using `clink inject`. Or with the `%CLINK_PROFILE%` environment variable if it is already present when Clink is injected (this envvar takes precedence over any other mechanism of specifying a profile directory, if more than one was used).

You can use `clink info` to find the directories and configuration files for the current Clink session.

### Files

.inputrc
  This configures the Readline library used by Clink; it can contain key bindings and various settings. See Readline Init File for details, or see Create a .inputrc file for help getting started.

clink_settings
  This is where Clink stores its settings. See Clink Settings for more information.

  The location of the `clink_settings` file may also be overridden with the `%CLINK_SETTINGS%` environment variable. This is not recommended because it can be confusing; if the environment variable gets cleared or isn't always set then a different settings file may get used sometimes. But, one reason to use it is to make your settings sync with other computers.

  - `set CLINK_SETTINGS=%USERPROFILE%\OneDrive\clink` can let settings sync between computers through your OneDrive account.
  - `set CLINK_SETTINGS=%USERPROFILE%\AppData\Roaming` can let settings sync between computers in a work environment.

clink_history
  This is where Clink stores command history. See Saved Command History for more information.

clink.log
  The log file is written in the profile directory. Clink writes diagnostic information to the log file while Clink is running. Use `clink info` to find where it is located.

default_settings
  This is an optional file. When Clink loads its settings, it first tries to load default values for settings from a `default_settings` file in either the profile directory or the binaries directory. Then it loads the `clink_settings` file from the profile directory.

  The `default_settings` file can be useful for portable installations or when sharing your favorite Clink configuration with friends.

default_inputrc
  This is an optional file. When Clink loads the Readline Init File, it first tries to load default values from a `default_inputrc` file in either the profile directory or the binaries directory. Then it loads the `.inputrc` file.

  The `default_inputrc` file can be useful for portable installations or when sharing your favorite Clink configuration with friends.

## Command Line Options

clink
  Shows command line usage help.

clink inject
  Injects Clink into a CMD.EXE process.
  See `clink inject --help` for more information.

clink autorun
  Manages Clink's entry in CMD.EXE's autorun section, which can automatically inject Clink when starting CMD.EXE.
  When Clink is installed for autorun, the automatic inject can be overridden by setting the `CLINK_NOAUTORUN` environment variable (to any value).
  See `clink autorun --help` for more information.

clink set
  `clink set` by itself lists all settings and their values.
  `clink set --describe` by itself lists all settings and their descriptions (instead of their values).
  `clink set setting_name` describes the setting and shows its current value.
  `clink set setting_name clear` resets the setting to its default value.
  `clink set setting_name value` sets the setting to the specified value.

clink installscripts
  Adds a path to search for Lua scripts.
  The path is stored in the registry and applies to all installations of Clink, regardless where their config paths are, etc. This is intended to make it easy for package managers like Scoop to be able to install (and uninstall) scripts for use with Clink. See `clink installscripts --help` for more information.

clink uninstallscripts
  Removes a path added by `clink installscripts`. See `clink uninstallscripts --help` for more information.

clink history
  Lists the command history.
  See `clink history --help` for more information.
  Also, Clink automatically defines `history` as an alias for `clink history`.

clink info
  Prints information about Clink, including the version and various configuration directories and files.
  Or `clink --version` shows just the version number.

clink echo
  Echos key sequences to use in the .inputrc files for binding keys to Clink commands. Each key pressed prints the associated key sequence on a separate line, until `Ctrl`+`C` is pressed.

## Portable Configuration

Sometimes it's useful to run Clink from a flash drive or from a network share, especially if you want to use Clink on someone else's computer.

Here's how you can set up a portable configuration for Clink:

1. Put your Lua scripts and other tools in the same directory as the Clink executable files. For example fzf.exe, z.cmd, oh-my-posh.exe, starship.exe etc can all go in the same directory on a flash drive or network share.
2. Make a batch file such as `portable.bat` that injects Clink using a specific profile directory.
   - On a flash drive, you can have a portable profile in a subdirectory under the Clink directory.
   - On a network share, you'll want to copy some initial settings into a local profile directory (a profile directory on a network share will be slow).
3. In any cmd.exe window on any computer, you can then run the `portable.bat` script to inject Clink and have all your favorite settings and key bindings work.

Here are some sample scripts:

### portable.bat (on a flash drive)

This sample script assumes the portable.bat script is in the Clink directory, and it uses a `clink_portable` profile directory under the Clink directory.

    @echo off
    rem -- Do any other desired configuration here, such as loading a doskey macro file.
    call "%~dp0clink.bat" inject --profile "%~dp0clink_portable" %1 %2 %3 %4 %5 %6 %7 %8 %9

### portable.bat (on a network share)

This sample script assumes the portable.bat script is in the Clink directory, and that there is a file `portable_clink_settings` with the settings you want to copy to the local profile directory.

    @echo off
    if not exist "%TEMP%\clink_portable" md "%TEMP%\clink_portable" >nul
    if not exist "%TEMP%\clink_portable\clink_settings" copy "%~dp0portable_clink_settings" "%TEMP%\clink_portable\clink_settings" >nul
    rem -- Do any other desired configuration here, such as loading a doskey macro file.
    call "%~dp0clink.bat" inject --profile "%TEMP%\clink_portable" %1 %2 %3 %4 %5 %6 %7 %8 %9

# Configuring Readline

The Readline library used by Clink can be configured to add custom keybindings and macros by creating a Readline init file. There is excellent documentation for all the options and commands available to configure Readline in the Readline manual.

Init File | About the .inputrc init file.
Completion Colors | How to customize the completion colors.
Popup Windows | Using the popup windows.

## Init File

A Readline init file defines key binding customizations and sets Readline configuration variables.

A Readline init file is named `.inputrc` or `_inputrc`. Clink searches the directories referenced by the following environment variables in the order listed here, and loads the first `.inputrc` or `_inputrc` file it finds:

- `%CLINK_INPUTRC%`
- The Clink profile directory (see the "state" line from `clink info`; by default this is the same as `%USERPROFILE%` but it can be overridden by the `clink inject` command).
- `%USERPROFILE%`
- `%LOCALAPPDATA%`
- `%APPDATA%`
- `%HOME%`

Other software that also uses the Readline library will also look for the `.inputrc` file (and possibly the `_inputrc` file too). To set macros and keybindings intended only for Clink, one can use the Readline init file conditional construct like this; `$if clink [...] $endif`.

You can use `clink info` to find the directories and configuration file for the current Clink session.

> Compatibility Notes:

> - The `clink_inputrc_base` file from v0.4.8 is no longer used.
> - For backward compatibility, `clink_inputrc` is also loaded from the above locations, but it has been deprecated and may be removed in the future.
> - Clink v1.0.0a0 through Clink v1.2.27 accidentally loaded up to one Readline init file from each of the searched directories. That was incorrect behavior for loading Readline init files and has been fixed. If similar behavior is still desired, consider using the `$include` directive in the Readline init file, to load additional files.

### Basic Format

The `.inputrc` file will mostly use these kinds of lines:

Line | Description
--- | ---
`keyname: command` | Binds a named command to a key.
`keyname: "literal text"` | Binds a macro to a key. A macro inserts the literal text into the input line.
`keyname: "luafunc:lua_function_name"` | Binds a named Lua function to a key. See Lua key bindings for more information.
`set varname value` |

See Discovering Clink key sequences for how to find the keyname for the key you want to bind. See Customizing Key Bindings for more information about binding keys in Clink.

Refer to the Readline manual for a more thorough explanation of the .inputrc file format, list of available commands, and list of configuration variables and their values.

### New Configuration Variables

Clink adds some new configuration variables to Readline, beyond what's described in the Readline manual:

Name | Default | Description
--- | --- | ---
`completion-auto-query-items` | on | Automatically prompts before displaying completions if they need more than half a screen page.
`history-point-at-end-of-anchored-search` | off | Puts the cursor at the end of the line when using `history-search-forward` or `history-search-backward`.
`menu-complete-wraparound` | on | The `menu-complete` family of commands wraps around when reaching the end of the possible completions.
`search-ignore-case` | on | Controls whether the history search commands ignore case.

### New Commands

Clink adds some new commands to Readline, beyond what's described in the Readline manual:

Name | Description
--- | ---
`add-history` | Adds the current line to the history without executing it, and clears the editing line.
`alias-expand-line` | A synonym for `clink-expand-doskey-alias`.
`clink-complete-numbers` | Like `complete`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-copy-cwd` | Copy the current working directory to the clipboard.
`clink-copy-line` | Copy the current line to the clipboard.
`clink-copy-word` | Copy the word at the cursor to the clipboard, or copies the nth word if a numeric argument is provided via the `digit-argument` keys.
`clink-ctrl-c` | Discards the current line and starts a new one (like `Ctrl`+`C` in CMD.EXE).
`clink-diagnostics` | Show internal diagnostic information.
`clink-exit` | Replaces the current line with `exit` and executes it (exits the shell instance).
`clink-expand-doskey-alias` | Expand the doskey alias (if any) at the beginning of the line.
`clink-expand-env-var` | Expand the environment variable (e.g. `%FOOBAR%`) at the cursor.
`clink-expand-history` | Perform history expansion in the current input line.
`clink-expand-history-and-alias` | Perform history and doskey alias expansion in the current input line.
`clink-expand-line` | Perform history, doskey alias, and environment variable expansion in the current input line.
`clink-find-conhost` | Activates the "Find" dialog when running in a standard console window (hosted by the OS conhost). This is equivalent to picking "Find..." from the console window's system menu.
`clink-insert-dot-dot` | Inserts `..\` at the cursor.
`clink-magic-suggest-space` | Inserts the next full word of the suggestion (if any) up to a space, and also inserts a space.
`clink-mark-conhost` | Activates the "Mark" mode when running in a standard console window (hosted by the OS conhost). This is equivalent to picking "Mark" from the console window's system menu.
`clink-menu-complete-numbers` | Like `menu-complete`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-menu-complete-numbers-backward` | Like `menu-complete-backward`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-old-menu-complete-numbers` | Like `old-menu-complete`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-old-menu-complete-numbers-backward` | Like `old-menu-complete-backward`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-paste` | Paste the clipboard at the cursor.
`clink-popup-complete` | Show a popup window that lists the available completions.
`clink-popup-complete-numbers` | Like `clink-popup-complete`, but for numbers from the console screen (3 digits or more, up to hexadecimal).
`clink-popup-directories` | Show a popup window of recent current working directories. In the popup, use `Enter` to `cd /d` to the highlighted directory.
`clink-popup-history` | Show a popup window that lists the command history (if any text precedes the cursor then it uses an anchored search to filter the list). In the popup, use `Enter` to execute the highlighted command.
`clink-popup-show-help` | Show a popup window that lists the currently active key bindings, and can invoke a selected key binding. The default key binding for this is `Ctrl`+`Alt`+`H`.
`clink-reload` | Reloads the .inputrc file and the Lua scripts.
`clink-reset-line` | Clears the current line.
`clink-scroll-bottom` | Scroll the console window to the bottom (the current input line).
`clink-scroll-line-down` | Scroll the console window down one line.
`clink-scroll-line-up` | Scroll the console window up one line.
`clink-scroll-page-down` | Scroll the console window down one page.
`clink-scroll-page-up` | Scroll the console window up one page.
`clink-scroll-top` | Scroll the console window to the top.
`clink-select-complete` | Like `complete`, but shows interactive menu of matches and responds to arrow keys and typing to filter the matches. While completing, `F1` toggles showing match descriptions at the bottom vs next to each match.
`clink-selectall-conhost` | Mimics the "Select All" command when running in a standard console window (hosted by the OS conhots). Selects the input line text. If already selected, then it invokes the "Select All" command from the console window's system menu and selects the entire screen buffer's contents.
`clink-shift-space` | Invokes the normal `Space` key binding, so that `Shift`+`Space` behaves the same as `Space`.
`clink-show-help` | Lists the currently active key bindings using friendly key names. A numeric argument affects showing categories and descriptions: 0 for neither, 1 for categories, 2 for descriptions, 3 for categories and descriptions (the default), 4 for all commands (even if not bound to a key).
`clink-show-help-raw` | Lists the currently active key bindings using raw key sequences. A numeric argument affects showing categories and descriptions: 0 for neither, 1 for categories, 2 for descriptions, 3 for categories and descriptions (the default), 4 for all commands (even if not bound to a key).
`clink-up-directory` | Changes to the parent directory.
`clink-what-is` | Show the key binding for the next key sequence that is input.
`cua-backward-char` | Extends the selection and moves back a character.
`cua-backward-word` | Extends the selection and moves back a word.
`cua-beg-of-line` | Extends the selection and moves to the start of the current line.
`cua-copy` | Copies the selection to the clipboard.
`cua-cut` | Cuts the selection to the clipboard.
`cua-end-of-line` | Extends the selection and moves to the end of the line.
`cua-forward-char` | Extends the selection and moves forward a character, or inserts the next full suggested word up to a space.
`cua-forward-word` | Extends the selection and moves forward a word.
`cua-select-all` | Extends the selection to the entire current line.
`cua-select-word` | Selects the word at the cursor.
`edit-and-execute-command` | Invoke an editor on the current input line, and execute the result as commands. This attempts to invoke %VISUAL%, %EDITOR%, or notepad.exe as the editor, in that order.
`glob-complete-word` | Perform wildcard completion on the text before the cursor point, with a `*` implicitly appended.
`glob-expand-word` | Insert all the wildcard completions that `glob-list-expansions` would list. If a numeric argument is supplied, a `*` is implicitly appended before completion.
`glob-list-expansions` | List the possible wildcard completions of the text before the cursor point. If a numeric argument is supplied, a `*` is implicitly appended before completion.
`history-and-alias-expand-line` | A synonym for `clink-expand-history-and-alias`.
`history-expand-line` | A synonym for `clink-expand-history`.
`insert-last-argument` | A synonym for `yank-last-arg`.
`magic-space` | Perform history expansion on the text before the cursor position and insert a space.
`old-menu-complete-backward` | Like `old-menu-complete`, but in reverse.
`remove-history` | While searching history, removes the current line from the history.
`shell-expand-line` | A synonym for `clink-expand-line`.
`win-copy-history-number` | Enter a history number and replace the input line with the history line (mimics Windows console `F9`).
`win-copy-up-to-char` | Enter a character and copy up to it from the previous command (mimics Windows console `F2`).
`win-copy-up-to-end` | Copy the rest of the previous command (mimics Windows console `F3`).
`win-cursor-forward` | Move cursor forward, or at end of line copy character from previous command, or insert suggestion (mimics Windows console `F1` and `Right`).
`win-delete-up-to-char` | Enter a character and delete up to it in the input line (mimics Windows console `F4`).
`win-history-list` | Executes a history entry from a list (mimics Windows console `F7`).
`win-insert-eof` | Insert ^Z (mimics Windows console `F6`).

## Completion Colors

The `%LS_COLORS%` environment variable provides color definitions as a series of color definitions separated by colons (`:`). Each definition is a either a two character type id or a file extension, followed by an equals sign and then the SGR parameters for an ANSI escape code. The two character type ids are listed below.

When the `colored-completion-prefix` Readline setting is configured to `on`, then the "so" color from `%LS_COLORS%` is used to color the common prefix when displaying possible completions. The default for "so" is magenta, but for example `set LS_COLORS=so=90` sets the color to bright black (which shows up as a dark gray).

When `colored-stats` is configured to `on`, then the color definitions from `%LS_COLORS%` are used to color file completions according to their file type or extension. Multiple definitions are separated by colons. Also, since `%LS_COLORS%` doesn't cover readonly files, hidden files, doskey aliases, or shell commands the color.readonly, color.hidden, color.doskey, and color.cmd Clink settings exist to cover those.

Type | Description | Default
--- | --- | ---
`di` | Directories. | `01;34` (bright blue)
`ex` | Executable files. | `01;32` (bright green)
`fi` | Normal files. |
`ln` | Symlinks. When `ln=target` then symlinks are colored according to the target of the symlink. | `target`
`mi` | Missing file or directory. |
`no` | Normal color. This is used for anything not covered by one of the other types. It may be overridden by various other Clink color settings as appropriate depending on the completion type. |
`or` | Orphaned symlink (the target of the symlink is missing). |
`so` | Common prefix for possible completions. | `01;35` (bright magenta)

Here is an example where `%LS_COLORS%` defines colors for various types.

    set LS_COLORS=so=90:fi=97:di=93:ex=92:*.pdf=30;105:*.md=4

- `so=90` uses bright black (dark gray) for the common prefix for possible completions.
- `fi=97` uses bright white for files.
- `di=93` uses bright yellow for directories.
- `ex=92` uses bright green for executable files.
- `*.pdf=30;105` uses black on bright magenta for .pdf files.
- `*.md=4` uses underline for .md files.

## Popup Windows

Some commands show a searchable popup window that lists the available completions, directory history, or command history.

For example, `win-history-list` (`F7`) and `clink-popup-directories` (`Ctrl`+`Alt`+`PgUp`) show popup windows.

Here's how the popup windows work:

Key | Description
--- | ---
`Escape` | Cancels the popup.
`Enter` | Inserts the highlighted completion, changes to the highlighted directory, or executes the highlighted command.
`Shift`+`Enter` | Inserts the highlighted completion, inserts the highlighted directory, or jumps to the highlighted command history entry without executing it.
`Ctrl`+`Enter` | Same as `Shift`+`Enter`.
`Del` | In a command history popup, `Del` deletes the selected history entry.

Most of the popup windows also have incremental search:

Key | Description
--- | ---
Typing | Typing does an incremental search.
`F3` | Go to the next match.
`Ctrl`+`L` | Go to the next match.
`Shift`+`F3` | Go to the previous match.
`Ctrl`+`Shift`+`L` | Go to the previous match.

The `win-history-list` command has a different search feature. Typing digits `0`-`9` jumps to the numbered history entry, or typing a letter jumps to the preceding history entry that begins with the typed letter. This is for compatibility with the `F7` behavior built into Windows console prompts. Use the `clink-popup-history` command instead if you prefer for typing to do an incremental search.

# Extending Clink With Lua

Clink can be extended with Lua scripts to customize startup actions, create completion matches, customize the prompt, and more. The following sections describe these in more detail and show some examples.

Location of Lua Scripts | Locations from which scripts are loaded.
Match Generators | How to write match generators, or custom completion providers.
Argument Completion | How to give commands contextual match generators for their arguments.
Coloring the Input Text | How to make a match generator or argument matcher override the input coloring.
Customizing the Prompt | How to write custom prompt filters.
Customizing Suggestions | How to write custom suggestion generators.

## Location of Lua Scripts

Clink loads all Lua scripts it finds in these directories:

1. All directories listed in the `clink.path` setting, separated by semicolons.
2. If `clink.path` is not set, then the DLL directory and the profile directory are used (see File Locations for info about the profile directory).
3. All directories listed in the `%CLINK_PATH%` environment variable, separated by semicolons.
4. All directories registered by the `clink installscripts` command.

Lua scripts are loaded once and are only reloaded if forced because the scripts locations change, the `clink-reload` command is invoked (`Ctrl`+`X`,`Ctrl`+`R`), or the `lua.reload_scripts` setting changes (or is True).

Run `clink info` to see the script paths for the current session.

### Tips for starting to write Lua scripts

- Loading a Lua script executes it; so when Clink loads Lua scripts from the locations above, it executes the scripts.
- Code not inside a function is executed immediately when the script is loaded.
- Usually scripts will register functions to customize various behaviors:
  - Generate completion matches.
  - Apply color to input text.
  - Customize the prompt.
  - Perform actions before or after the user gets to edit each input line.
  - Provide new custom commands that can be bound to keys via the luafunc: key macro syntax.
- Often scripts will also define some functions and variables for use by itself and/or other scripts.

The following sections describe these in more detail and show some examples.

## Match Generators

These are Lua functions that are called as part of Readline's completion process (for example when pressing `Tab`).

First create a match generator object:

    local my_generator = clink.generator(priority)

The priority argument is a number that influences when the generator gets called, with lower numbers going before higher numbers.

### The :generate() Function

Next define a match generator function on the object, taking the following form:

    function my_generator:generate(line_state, match_builder)
        -- Use the line_state object to examine the current line and create matches.
        -- Submit matches to Clink using the match_builder object.
        -- Return true or false.
    end

line_state is a line_state object that has information about the current line.

match_builder is a builder object to which matches can be added.

If no further match generators need to be called then the function should return true. Returning false or nil continues letting other match generators get called.

Here is an example script that supplies git branch names as matches for `git checkout`. This example doesn't handle git aliases, but that could be added with additional script code.

    local git_branch_autocomplete = clink.generator(1)

    local function starts_with(str, start)
        return string.sub(str, 1, string.len(start)) == start
    end

    local function is_checkout_ac(text)
        if starts_with(text, "git checkout") then
            return true
        end
        return false
    end

    local function get_branches()
        -- Run git command to get branches.
        local handle = io.popen("git branch -a 2>&1")
        local result = handle:read("*a")
        handle:close()
        -- Parse the branches from the output.
        local branches = {}
        if starts_with(result, "fatal") == false then
            for branch in string.gmatch(result, "  %S+") do
                branch = string.gsub(branch, "  ", "")
                if branch ~= "HEAD" then
                    table.insert(branches, branch)
                end
            end
        end
        return branches
    end

    function git_branch_autocomplete:generate(line_state, match_builder)
        -- Check if it's a checkout command.
        if not is_checkout_ac(line_state:getline()) then
            return false
        end
        -- Get branches and add them (does nothing if not in a git repo).
        local matchCount = 0
        for _, branch in ipairs(get_branches()) do
            match_builder:addmatch(branch)
            matchCount = matchCount + 1
        end
        -- If we found branches, then stop other match generators.
        return matchCount > 0
    end

### The :getwordbreakinfo() Function

If needed, a generator can optionally influence word breaking for the end word by defining a `:getwordbreakinfo()` function.

The function takes a line_state line_state object that has information about the current line. If it returns nil or 0, the end word is truncated to 0 length. This is the normal behavior, which allows Clink to collect and cache all matches and then filter them based on typing. Or it can return two numbers: word break length and an optional end word length. The end word is split at the word break length: one word contains the first word break length characters from the end word (if 0 length then it's discarded), and the next word contains the rest of the end word truncated to the optional word length (0 if omitted).

A good example to look at is Clink's own built-in environment variable match generator. It has a `:getwordbreakinfo()` function that understands the `%` syntax of environment variables and produces word break info accordingly.

When the environment variable match generator's `:getwordbreakinfo()` function sees the end word is `abc%USER` it returns `3,1` so that the last two words become "abc" and "%" so that its generator knows it can do environment variable matching. But when it sees `abc%FOO%def` it returns `8,0` so that the last two words become "abc%FOO%" and "" so that its generator won't do environment variable matching, and also so other generators can produce matches for what follows, since "%FOO%" is an already-completed environment variable and therefore should behave like a word break. In other words, it breaks the end word differently depending on whether the number of percent signs is odd or even, to account for environent variable syntax rules.

And when an argmatcher sees the end word begins with a flag character it returns `0,1` so the end word contains only the flag character in order to switch from argument matching to flag matching.

> Note: The `:getwordbreakinfo()` function is called very often, so it needs to be very fast or it can cause responsiveness problems while typing.

    local envvar_generator = clink.generator(10)

    function envvar_generator:generate(line_state, match_builder)
        -- Does the word end with a percent sign?
        local word = line_state:getendword()
        if word:sub(-1) ~= "%" then
            return false
        end

        -- Add env vars as matches.
        for _, i in ipairs(os.getenvnames()) do
            match_builder:addmatch("%"..i.."%", "word")
        end

        match_builder:setsuppressappend()   -- Don't append a space character.
        match_builder:setsuppressquoting()  -- Don't quote envvars.
        return true
    end

    function envvar_generator:getwordbreakinfo(line_state)
        local word = line_state:getendword()
        local in_out = false
        local index = nil

        -- Paired percent signs denote already-completed environment variables.
        -- So use envvar completion for abc%foo%def%USER but not for abc%foo%USER.
        for i = 1, #word do
            if word:sub(i, i) == "%" then
                in_out = not in_out
                if in_out then
                    index = i - 1
                else
                    index = i
                end
            end
        end

        -- If there were any percent signs, return word break info to influence the
        -- match generators.
        if index then
            return index, (in_out and 1) or 0
        end
    end

### More Advanced Stuff

#### Filtering Match Completions

A match generator or luafunc: key binding can use clink.onfiltermatches() to register a function that will be called after matches are generated but before they are displayed or inserted.

The function receives a table argument containing the matches to be displayed, a string argument indicating the completion type, and a boolean argument indicating whether filename completion is desired. The table argument has a `match` string field and a `type` string field; these are the same as in builder:addmatch().

The possible completion types are:

Type | Description | Example
--- | --- | ---
`"?"` | List the possible completions. | `possible-completions` or `popup-complete`
`"*"` | Insert all of the possible completions. | `insert-completions`
`"\t"` | Do standard completion. | `complete`
`"!"` | Do standard completion, and list all possible completions if there is more than one. | `complete` (when the `show-all-if-ambiguous` config variable is set)
`"@"` | Do standard completion, and list all possible completions if there is more than one and partial completion is not possible. | `complete` (when the `show-all-if-unmodified` config variable is set)
`"%"` | Do menu completion (cycle through possible completions). | `menu-complete` or `old-menu-complete`

The return value is a table with the input matches filtered as desired. The match filter function can remove matches, but cannot add matches (use a match generator instead). If only one match remains after filtering, then many commands will insert the match without displaying it. This makes it possible to spawn a process (such as fzf) to perform enhanced completion by interactively filtering the matches and keeping only one selected match.

    settings.add("fzf.height", "40%", "Height to use for the --height flag")
    settings.add("fzf.exe_location", "", "Location of fzf.exe if not on the PATH")

    -- Build a command line to launch fzf.
    local function get_fzf()
        local height = settings.get("fzf.height")
        local command = settings.get("fzf.exe_location")
        if not command or command == "" then
            command = "fzf.exe"
        else
            command = os.getshortname(command)
        end
        if height and height ~= "" then
            command = command..' --height '..height
        end
        return command
    end

    local fzf_complete_intercept = false

    -- Sample key binding in .inputrc:
    --      M-C-x: "luafunc:fzf_complete"
    function fzf_complete(rl_buffer)
        fzf_complete_intercept = true
        rl.invokecommand("complete")
        if fzf_complete_intercept then
            rl_buffer:ding()
        end
        fzf_complete_intercept = false
        rl_buffer:refreshline()
    end

    local function filter_matches(matches, completion_type, filename_completion_desired)
        if not fzf_complete_intercept then
            return
        end
        -- Start fzf.
        local r,w = io.popenrw(get_fzf()..' --layout=reverse-list')
        if not r or not w then
            return
        end
        -- Write matches to the write pipe.
        for _,m in ipairs(matches) do
            w:write(m.match.."\n")
        end
        w:close()
        -- Read filtered matches.
        local ret = {}
        while (true) do
            local line = r:read('*line')
            if not line then
                break
            end
            for _,m in ipairs(matches) do
                if m.match == line then
                    table.insert(ret, m)
                end
            end
        end
        r:close()
        -- Yay, successful; clear it to not ding.
        fzf_complete_intercept = false
        return ret
    end

    local interceptor = clink.generator(0)
    function interceptor:generate(line_state, match_builder)
        -- Only intercept when the specific command was used.
        if fzf_complete_intercept then
            clink.onfiltermatches(filter_matches)
        end
        return false
    end

#### Filtering the Match Display

In some instances it may be preferable to display different text when listing potential matches versus when inserting a match in the input line, or to display a description next to a match. For example, it might be desirable to display a `*` next to some matches, or to show additional information about some matches.

The simplest way to do that is just include the `display` and/or `description` fields when using builder:addmatch(). Refer to that function's documentation for usage details.

However, older versions of Clink don't support those fields. And it may in some rare cases it may be desirable to display a list of possible completions that includes extra matches, or omits some matches (but that's discouraged because it can be confusing to users).

A match generator can alternatively use clink.ondisplaymatches() to register a function that will be called before matches are displayed (this is reset every time match generation is invoked).

The function receives a table argument containing the matches to be displayed, and a boolean argument indicating whether they'll be displayed in a popup window. The table argument has a `match` string field and a `type` string field; these are the same as in builder:addmatch(). The return value is a table with the input matches filtered as required by the match generator.

The returned table can also optionally include a `display` string field and a `description` string field. When present, `display` will be displayed instead of the `match` field, and `description` will be displayed next to the match. Putting the description in a separate field enables Clink to align the descriptions in a column.

Filtering the match display can affect completing matches: the `match` field is what gets inserted. It can also affect displaying matches: the `display` field is displayed if present, otherwise the `match` field is displayed.

If a match's `type` is "none" or its `match` field is different from its `display` field then the match is displayed using the color specified by the color.filtered Clink setting, otherwise normal completion coloring is applied. The `display` and `description` fields can include ANSI escape codes to apply other colors if desired.

    local function my_filter(matches, popup)
        local new_matches = {}
        local magenta = "\x1b[35m"
        local filtered = settings.get("color.filtered")
        for _,m in ipairs(matches) do
            if m.match:find("[0-9]") then
                -- Ignore matches with one or more digits.
            else
                -- Keep the match, and also add a magenta * prefix to directory matches.
                if m.type:find("^dir") then
                    m.display = magenta.."*"..filtered..m.match
                end
                table.insert(new_matches, m)
            end
        end
        return new_matches
    end

    function my_match_generator:generate(line_state, match_builder)
        ...
        clink.ondisplaymatches(my_filter)
    end

> Note: In v1.3.1 and higher, the table received by the registered ondisplaymatches function includes all the match fields (such as `display`, `description`, `appendchar`, etc), and the returned table can also include any of these fields. In other words, in v1.3.1 and higher match filtering supports all the same fields as builder:addmatch().

## Argument Completion

Clink provides a framework for writing complex argument match generators in Lua. It works by creating a parser object that describes a command's arguments and flags and associating the parser with one or more commands. When Clink detects a parser is associated with the command being edited, it uses the parser to generate matches.

Here is an example of a simple parser for the command `foobar`;

    clink.argmatcher("foobar")
    :addflags("-foo", "-bar")          -- Flags
    :addarg({ "hello", "hi" })         -- Completions for arg #1
    :addarg({ "world", "wombles" })    -- Completions for arg #2

This parser describes a command that has two positional arguments each with two potential options. It also has two flags which the parser considers to be position independent meaning that provided the word being completed starts with a certain prefix the parser with attempt to match the from the set of flags.

On the command line completion would look something like this:

    C:>foobar hello -foo wo
    wombles  wonder   world
    C:>foobar hello -foo wo_

When displaying possible completions, flag matches are only shown if the flag character has been input (so `command` and `Alt`+`=` would list only non-flag matches, or `command -` and `Alt`+`=` would list only flag matches).

If a command doesn't have an argmatcher but is a doskey macro, Clink automatically expands the doskey macro and looks for an argmatcher for the expanded command. A macro like `gco=git checkout $*` automatically reuses a `git` argmatcher and produces completions for its `checkout` argument. However, it only expands the doskey macro up to the first `$`, so complex aliases like `foo=app 2$gnul text $*` or `foo=$2 $1` might behave strangely.

### Descriptions for Flags and Arguments

Flags and arguments may optionally have descriptions associated with them. The descriptions, if any, are displayed when listing possible completions.

Use _argmatcher:adddescriptions() to add descriptions for flags and/or arguments. Refer to its documentation for further details about how to use it, including how to also show arguments that a flag accepts.

For example, with the following matcher, typing `foo -``Alt`+`=` will list all of the flags, plus descriptions for each.

    clink.argmatcher("foo")
    :addflags("-?", "-h", "-n", "-v", "--help", "--nothing", "--verbose")
    :addarg("print", "delete")
    :addarg(clink.filematches)
    :nofiles()
    :adddescriptions(
        { "-n", "--nothing",    description = "Do nothing; show what would happen without doing it" },
        { "-v", "--verbose",    description = "Verbose output" },
        { "-h", "--help", "-?", description = "Show help text" },
        { "print",              description = "Print the specified file" },
        { "delete",             description = "Delete the specified file" },
    )

### More Advanced Stuff

#### Linking Parsers

There are often situations where the parsing of a command's arguments is dependent on the previous words (`git merge ...` compared to `git log ...` for example). For these scenarios Clink allows you to link parsers to arguments' words using Lua's concatenation operator.

    local a_parser = clink.argmatcher():addarg({ "foo", "bar" })
    local b_parser = clink.argmatcher():addarg({ "abc", "123" })
    local c_parser = clink.argmatcher()
    c_parser:addarg({ "foobar" .. a_parser })   -- Arg #1 is "foobar", which has args "foo" or "bar".
    c_parser:addarg({ b_parser })               -- Arg #2 is "abc" or "123".

As the example above shows, it is also possible to use a parser without concatenating it to a word.

When Clink follows a link to a parser it will only return to the previous parser when the linked parser runs out of arguments.

#### Flags With Arguments

Parsers can be concatenated with flags, too.

Here's an example of a flag that takes an argument:

    clink.argmatcher("git")
    :addarg({
        "merge"..clink.argmatcher():addflags({
            "--strategy"..clink.argmatcher():addarg({
                "resolve",
                "recursive",
                "ours",
                "octopus",
                "subtree",
            })
        })
    })

A `:` or `=` at the end of a flag indicates the flag takes an argument but requires no space between the flag and its argument. If such a flag is not linked to a parser, then it automatically gets linked to a parser to match files. Here's an example with a few flags that take arguments without a space in between:

    clink.argmatcher("findstr")
    :addflags({
        "/b", "/e", "/l", "/r", "/s", "/i", "/x", "/v", "/n", "/m", "/o", "/p", "/offline",
        "/a:"..clink.argmatcher():addarg( "attr" ),
        "/f:"..clink.argmatcher():addarg( clink.filematches ),
        "/c:"..clink.argmatcher():addarg( "search_string" ),
        "/g:", -- This is the same as linking with clink.argmatcher():addarg(clink.filematches).
        "/d:"..clink.argmatcher():addarg( clink.dirmatches )
    })

#### Functions As Argument Options

Argument options are not limited solely to strings. Clink also accepts functions too so more context aware argument options can be used.

The function is called each time matches are generated for the argument position.

    local function rainbow_function(word)
        return { "red", "white", "blue" }
    end

    local the_parser = clink.argmatcher()
    the_parser:addarg({ "zippy", "bungle", "george" })
    the_parser:addarg({ rainbow_function, "yellow", "green" })

The functions are passed five arguments, and should return a table of potential matches.

- `word` is a partial string for the word under the cursor, corresponding to the argument for which matches are being generated: it is an empty string, or if a filename is being entered then it will be the path portion (e.g. for "dir1\dir2\pre" `word` will be "dir1\dir2").
- `word_index` is the word index in `line_state`, corresponding to the argument for which matches are being generated.
- `line_state` is a line_state object that contains the words for the associated command line.
- `match_builder` is a builder object (but for adding matches the function should return them in a table).
- `user_data` is a table that the argmatcher can use to help it parse the input line. See Responding to Arguments in Argmatchers for more information about the `user_data` table.

> Compatibility Note: When a function argument uses the old v0.4.9 `clink.match_display_filter` approach, then the `word` argument will be the full word under the cursor, for compatibility with the v0.4.9 API.

Some built-in matcher functions are available:

Function | Description
--- | ---
clink.dirmatches | Generates directory matches.
clink.filematches | Generates file matches.

#### Generate Matches From History

An argument position can collect matches from the history file. When an argument table contains `fromhistory=true` then additional matches are generated by parsing the history file to find values for that argument slot from commands in the history file.

This example generates matches for arguments to a `--host` flag by parsing the history file for host names used in the past, and also includes the current computer name.

    local host_parser = clink.argmatcher():addarg({ fromhistory=true, os.getenv("COMPUTERNAME") })
    clink.argmatcher("program"):addflags({ "--host"..host_parser })

#### Disable Sorting Matches

Match completions are normally listed in sorted order. In some cases it may be desirable to disable sorting and list match completions in a specific order. To disable sorting, include `nosort=true` in the argument table. When sorting is disabled, matches are listed in the order they were added.

    local the_parser = clink.argmatcher()
    the_parser:addarg({ nosort=true, "red", "orange", "yellow", "green", "blue", "indigo", "violet" })

#### Adaptive Argmatchers

Some argmatchers may need to adapt on the fly. For example, a program may have different features available depending on the current directory, or may want to define its arguments and flags by parsing the `--help` text from running a program.

An argmatcher can define a "delayed initialization" callback function that gets calls when the argmatcher gets used, allowing it to defer potentially expensive initialization work until it's actually needed. An argmatcher can also define a separate "delayed initialization" function for each argument position.

##### Delayed initialization for the argmatcher

You can use _argmatcher:setdelayinit() to set a function that performs delayed initialization for the argmatcher. The function receives one parameter:

- `argmatcher` is the argmatcher to be initialized.

If the definition needs to adapt based on the current directory or other criteria, then the callback function should first test whether the definition needs to change. If so, first reset the argmatcher and then initialize it. To reset the argmatcher, use _argmatcher:reset() which resets it back to an empty, freshly created state.

    local prev_dir = ""

    -- Initialize the argmatcher.
    -- v1.3.12 and higher receive a command_word parameter as well, which is the
    -- word in the command line that matched this argmatcher.
    local function init(argmatcher, command_word)
        local r = io.popen("some_command --help 2>nul")
        for line in r:lines() do
            -- PUT PARSING CODE HERE.
            -- Use the Lua string functions to parse the lines.
            -- Use argmatcher:addflags(), argmatcher:addarg(), etc to initialize the argmatcher.
        end
        r:close()
    end

    -- This function has the opportunity to reset and (re)initialize the argmatcher.
    local function ondelayinit(argmatcher)
        local dir = os.getcwd()
        if prev_dir ~= dir then  -- When current directory has changed,
            prev_dir = dir      -- Remember the new current directory,
            argmatcher:reset()  -- Reset the argmatcher,
            init(argmatcher)    -- And re-initialize it.
        end
    end

    -- Create the argmatcher and set up delayed initialization.
    local m = clink.argmatcher("some_command")
    if m.setdelayinit then        -- Can't use setdelayinit before Clink v1.3.10.
        m:setdelayinit(ondelayinit)
    end

##### Delayed initialization for an argument position

If the overall flags and meaning of the argument positions don't need to be updated, and only the possible values need to be updated within certain argument positions, then you can include `delayinit=function` in the argument table.

The function should return a table of matches which will be added to the values for the argument position. The table of matches supports the same syntax as _argmatcher:addarg(). The function receives two parameters:

- `argmatcher` is the current argmatcher.
- `argindex` is the argument position in the argmatcher (0 is flags, 1 is the first argument position, 2 is the second argument position, and so on).

The function is called only once, the first time the argument position is used. The only way for the function to be called again for that argmatcher is to use Delayed initialization for the argmatcher and reset the argmatcher and then re-initialize it.

Delayed initialization for an argument position is different from Functions As Argument Options. The `delayinit` function is called the first time the argmatcher is used, and the results are added to the matches for the rest of the Clink session. But a function as an argument option is called every time matches are generated for the argument position, and it is never called when applying input line coloring.

    -- A function to delay-initialize argument values.
    -- This function is used to delay-initialize two different argument positions,
    -- and so it gets called up to two separate times (once for each position where
    -- it is specified).
    -- If the function needs to behave slightly differently for different
    -- argmatchers or argument positions, it can use the two parameters it receives
    -- to identify the specific context in which it is being called.
    local function sc_init_dirs(argmatcher, argindex)
        return {
            path.join(os.getenv("USERPROFILE"), "Documents"),
            path.join(os.getenv("USERPROFILE"), "Pictures")
        }
    end

    -- A function to delay-initialize flag values.
    local function sc_init_flags(argmatcher)
        -- This calls sc_init_dirs() when the '--dir=' flag is used.
        return { "--dir=" .. clink.argmatcher():addarg({ delayinit=sc_init_dirs }) }
    end

    -- Define an argmatcher with two argument positions, and the second one uses
    -- delayed initialization.
    local m = clink.argmatcher("some_command")
    m:addarg({ "abc", "def", "ghi" })
    m:addarg({ delayinit=sc_init_dirs }) -- This sc_init_dirs() when the second arg position is used.

    -- You can also use delayinit with flags, but you must set the flag prefix
    -- character(s) so that Clink can know when to call the delayinit function.
    m:addflags({ delayinit=sc_init_flags })
    m:setflagprefix("-")

#### Responding to Arguments in Argmatchers

Argmatchers can be more involved in parsing the command line, if they wish.

An argmatcher can supply an "on arg" function to be called when the argmatcher parses an argument position. The function can influence parsing the rest of the input line. For example, the presence of a flag `--only-dirs` might change what match completions should be provided somewhere else in the input line.

Supply an "on arg" function by including `onarg=function` in the argument table with _argmatcher:addarg(). The function is passed five arguments, and it doesn't return anything (the function receives the same arguments as Functions As Argument Options).

- `word` is a partial string for the word under the cursor, corresponding to the argument for which matches are being generated: it is an empty string, or if a filename is being entered then it will be the path portion (e.g. for "dir1\dir2\pre" `word` will be "dir1\dir2").
- `word_index` is the word index in `line_state`, corresponding to the argument for which matches are being generated.
- `line_state` is a line_state object that contains the words for the associated command line.
- `match_builder` is a builder object (but for adding matches the function should return them in a table).
- `user_data` is a table that the argmatcher can use to help it parse the input line.

When parsing begins, the `user_data` is an empty table. Each time a flag or argument links to another argmatcher, the new argmatcher gets a separate new empty `user_data` table. Your "on arg" functions can set data from the table, and then can also get data that was set earlier by your "on arg" functions.

An "on arg" function can also use os.chdir() to set the current directory. Generating match completions saves and restores the current directory when finished, so argmatcher "on arg" functions can set the current directory and thus cause match completion later in the input line to complete file names relative to the change directory. For example, the built-in `cd` and `pushd` argmatches use an "on arg" function so that `pushd \other_dir & program` `Tab` can complete file names from `\other_dir` instead of the (real) current directory.

    local function onarg_pushd(arg_index, word, word_index, line_state)
        -- Match generation after this is relative to the new directory.
        if word ~= "" then
            os.chdir(word)
        end
    end

    clink.argmatcher("pushd")
    :addarg({
        onarg=onarg_pushd,  -- Chdir to the directory argument.
        clink.dirmatches,   -- Generate directory matches.
    })
    :nofiles()

#### Shorthand

It is also possible to omit the `addarg` and `addflags` function calls and use a more declarative shorthand form:

    -- Shorthand form; requires tables.
    clink.argmatcher()
        { "one", "won" }                -- Arg #1
        { "two", "too" }                -- Arg #2
        { "-a", "-b", "/?", "/h" }      -- Flags

    -- Normal form:
    clink.argmatcher()
    :addarg({ "one", "won" })           -- Arg #1
    :addarg({ "two", "too" })           -- Arg #2
    :addflags("-a", "-b", "/?", "/h")   -- Flags

With the shorthand form flags are implied rather than declared. When a shorthand table's first value is a string starting with `-` or `/` then the table is interpreted as flags. Note that it's still possible with shorthand form to mix flag prefixes, and even add additional flag prefixes, such as `{ '-a', '/b', '=c' }`.

## Coloring the Input Text

When the `clink.colorize_input` setting is enabled, argmatcher automatically apply colors to the input text by parsing it.

It's possible for an argmatcher to provide a function to override how its arguments are colored. This function is called once for each of the argmatcher's arguments.

It's also possible to register a classifier function for the whole input line. This function is very similar to a match generator; classifier functions are called in priority order, and a classifier can choose to stop the classification process.

### More Advanced Stuff

#### Setting a classifier function in an argmatcher

In cases where an argmatcher isn't able to color the input text in the desired manner, it's possible to supply a classifier function that overrides how the argmatcher colors the input text. An argmatcher's classifier function is called once for each word the argmatcher parses, but it can classify any words (not just the word it was called for). Each argmatcher can have its own classifier function, so when there are linked argmatchers more than one function may be invoked.

Words are colored by classifying the words, and each classification has an associated color. See word_classifications:classifyword() for the available classification codes.

The `clink set` command has different syntax depending on the setting type, so the argmatcher for `clink` needs help in order to get everything right. A custom generator function parses the input text to provide appropriate matches, and a custom classifier function applies appropriate coloring.

    -- In this example, the argmatcher matches a directory as the first argument and
    -- a file as the second argument.  It uses a word classifier function to classify
    -- directories (words that end with a path separator) as "unexpected" in the
    -- second argument position.

    local function classify_handler(arg_index, word, word_index, line_state, classifications)
        -- `arg_index` is the argument position in the argmatcher.
        -- In this example only position 2 needs special treatent.
        if arg_index ~= 2 then
            return
        end

        -- `arg_index` is the argument position in the argmatcher.
        -- `word_index` is the word position in the `line_state`.
        -- Ex1: in `samp dir file` for the word `dir` the argument index is 1 and
        -- the word index is 2.
        -- Ex2: in `samp --help dir file` for the word `dir` the argument index is
        -- still 1, but the word index is 3.

        -- `word` is the word the classifier function was called for and `word_index`
        -- is its position in the line.  Because `line_state` is also provided, the
        -- function can examine any words in the input line.
        if word:sub(-1) == "\\" then
            -- The word appears to be a directory, but this example expects only
            -- files in argument position 2.  Here the word gets classified as "n"
            -- (unexpected) so it gets colored differently.
            classifications:classifyword(word_index, "n")
        end
    end

    local matcher = clink.argmatcher("samp")
    :addflags("--help")
    :addarg({ clink.dirmatches })
    :addarg({ clink.filematches })
    :setclassifier(classify_handler)

#### Setting a classifier function for the whole input line

In some cases it may be desireable to use a custom classifier to apply coloring in an input line.

First create a classifier object:

    local my_classifier = clink.classifier(priority)

The priority argument is a number that influences when the classifier gets called, with lower numbers going before higher numbers.

Next define a classify function on the object, taking the following form:

    function my_classifier:classify(commands)
        -- See further below for how to use the commands argument.
        -- Returning true stops any further classifiers from being called, or
        -- returning false or nil continues letting other classifiers get called.
    end

commands is a table of tables, with the following scheme:

    -- commands[n].line_state           [line_state] Contains the words for the Nth command.
    -- commands[n].classifications      [word_classifications] Use this to classify the words.

The `line_state` field is a line_state object that contains the words for the associated command line.

The `classifications` field is a word_classifications object to use for classifying the words in the associated command line.

    -- In this example, a custom classifier applies colors to environment variables
    -- in the input line.
    local envvar_classifier = clink.classifier(50)
    function envvar_classifier:classify(commands)
        -- This example doesn't need to parse words within commands, it just wants
        -- to parse the whole line.
        --
        -- So it can simply use the first command's `classifications` object because
        -- the `classifications:applycolor()` method can apply color anywhere in the
        -- entire input line.
        --
        -- (Note that the `classifications:classifyword()` method can only affect
        -- the words for its corresponding command.)
        if commands[1] then
            local line_state = commands[1].line_state
            local classifications = commands[1].classifications
            local line = line_state:getline()
            local len = #line

            -- Loop through the line looking for environment variables, starting at
            -- the first character of the line.
            local idx = 1
            while (idx <= len) do
                -- Find the next percent sign (idx is walking through the line).
                local pos = line:find('%', idx, true--[[plain]])
                if not pos then
                    -- No more?  Then all done.
                    break
                end

                -- Find the next percent sign (which would close the possible
                -- environment variable).
                local posend = line:find('%', pos + 1, true--[[plain]])
                if not posend then
                    -- No close?  Then all done.
                    break
                end

                -- Extract the text between the percent signs and check if there
                -- is an environment variable by that name.
                local name = line:sub(pos + 1, posend - 1)
                if name == '' then
                    -- Skip a double percent.  It's an escaped percent sign, not an
                    -- environment variable.
                    idx = posend + 1
                elseif os.getenv(name) then
                    -- Apply a color to the environment variable.
                    classifications:applycolor(pos, posend - pos + 1, "95")
                    idx = posend + 1
                else
                    -- Ignore the percent sign, but continue looking for more.
                    idx = idx + 1
                end
            end
        end
    end

## Customizing the Prompt

Before Clink displays the prompt it filters the prompt through Lua so that the prompt can be customized. This happens each and every time that the prompt is shown which allows for context sensitive customizations (such as showing the current branch of a git repository).

Writing a prompt filter is straightforward:

1. Create a new prompt filter by calling clink.promptfilter() along with a priority id which dictates the order in which filters are called. Lower priority ids are called first.
2. Define a `:filter()` function on the returned prompt filter.

The filter function takes a string argument that contains the filtered prompt so far. If the filter function returns nil, it has no effect. If the filter function returns a string, that string is used as the new filtered prompt (and may be further modified by other prompt filters with higher priority ids). If the filter function returns a string and a boolean, then if the boolean is false the prompt filtering is done and no further filter functions are called.

    local p = clink.promptfilter(30)
    function p:filter(prompt)
        return "new prefix "..prompt.." new suffix" -- Add ,false to stop filtering.
    end

The following example illustrates setting the prompt, modifying the prompt, using ANSI escape code for colors, running a git command to find the current branch, and stopping any further processing.

    local green  = "\x1b[92m"
    local yellow = "\x1b[93m"
    local cyan   = "\x1b[36m"
    local normal = "\x1b[m"

    -- A prompt filter that discards any prompt so far and sets the
    -- prompt to the current working directory.  An ANSI escape code
    -- colors it yellow.
    local cwd_prompt = clink.promptfilter(30)
    function cwd_prompt:filter(prompt)
        return yellow..os.getcwd()..normal
    end

    -- A prompt filter that inserts the date at the beginning of the
    -- the prompt.  An ANSI escape code colors the date green.
    local date_prompt = clink.promptfilter(40)
    function date_prompt:filter(prompt)
        return green..os.date("%a %H:%M")..normal.." "..prompt
    end

    -- A prompt filter that may stop further prompt filtering.
    -- This is a silly example, but on Wednesdays, it stops the
    -- filtering, which in this example prevents git branch
    -- detection and the line feed and angle bracket.
    local wednesday_silliness = clink.promptfilter(60)
    function wednesday_silliness:filter(prompt)
        if os.date("%a") == "Wed" then
            -- The ,false stops any further filtering.
            return prompt.." HAPPY HUMP DAY! ", false
        end
    end

    -- A prompt filter that appends the current git branch.
    local git_branch_prompt = clink.promptfilter(65)
    function git_branch_prompt:filter(prompt)
        local line = io.popen("git branch --show-current 2>nul"):read("*a")
        local branch = line:match("(.+)\n")
        if branch then
            return prompt.." "..cyan.."["..branch.."]"..normal
        end
    end

    -- A prompt filter that adds a line feed and angle bracket.
    local bracket_prompt = clink.promptfilter(150)
    function bracket_prompt:filter(prompt)
        return prompt.."\n> "
    end

The resulting prompt will look like this:

    Wed 12:54 c:\dir [master]
    > _

...except on Wednesdays, when it will look like this:

    Wed 12:54 c:\dir HAPPY HUMP DAY! _

### ANSI escape codes in the prompt string

Readline needs to be told which characters in the prompt are unprintable or invisible. To help with that, Clink automatically detects most standard ANSI escape codes (and most of ConEmu's non-standard escape codes) and the BEL character (^G, audible bell) and surrounds them with `\001` (^A) and `\002` (^B) characters. For any other unprintable characters, the `\001` and `\002` characters need to be added manually. Otherwise Readline misinterprets the length of the prompt and can display the prompt and input line incorrectly in some cases (especially if the input line wraps onto a second line).

### More Advanced Stuff

#### Right Side Prompt

In addition to the normal prompt filtering, Clink can also show a prompt on the right side of the first line of input. The right side prompt defaults to the value of the `%CLINK_RPROMPT%` environment variable, if set, otherwise it is blank. This right side prompt is automatically hidden if the input line text reaches it.

Clink expands CMD prompt `$` codes in `%CLINK_RPROMPT%`, with a few exceptions: `$+` is not supported, `$_` ends the prompt string (it can't be more than one line), and `$V` is not supported. Additionally, if `%CLINK_RPROMPT%` ends with `$M` then trailing spaces are trimmed from the expanded string, to maintain right alignment since `$M` includes a space if the current drive is a network drive (so e.g. `$t $d $m` is right-aligned regardless whether the current drive has a remote name).

The right side prompt can be filtered through Lua just like the normal prompt can be. Simply define a `:rightfilter()` function on the prompt filter returned by a call to clink.promptfilter(). A prompt filter can define both `:filter()` and `:rightfilter()`, or can define only `:filter()`.

The `:rightfilter()` function works the same as the `:filter()` function, except that it operates on the right side prompt. It takes a string argument that contains the filtered right side prompt so far. If the rightfilter function returns nil, it has no effect. If the rightfilter function returns a string, that string is used as the new filtered right side prompt (and may be further modified by other prompt filters with higher priority ids). If either the rightfilter function or the normal filter function returns a string and a boolean, then if the boolean is false the prompt filtering is done and no further filter functions are called.

This example modifies the right side prompt by prepending the current date:

    local p = clink.promptfilter(30)
    function p:filter(prompt)
        -- The :filter() function must be defined.  But if the prompt filter is
        -- only interested in modifying the right side prompt, then the :filter()
        -- function may do nothing.
    end
    function p:rightfilter(prompt)
        local sep = #prompt > 0 and "  " or ""
        return os.date()..sep..prompt
    end

> Notes:

> - If the console font and encoding are mismatched, or if some kinds of emoji are present, then the right side prompt might show up positioned incorrectly. If that happens, try adjusting the font or encoding (e.g. sometimes running `chcp utf-8` can resolve positioning issues).
> - If the `:filter()` function returns a string and false to stop filtering, then the `:rightfilter()` is not called (because no further filter functions are called). If you want to stop filtering but have both a left and right side prompt, then return only a string from `:filter()` and return a string and false from `:rightfilter()`.

#### Asynchronous Prompt Filtering

Prompt filtering needs to be fast, or it can interfere with using the shell (e.g. `git status` can be slow in a large repo).

Clink provides a way for prompt filters to do some initial work and set the prompt, continue doing work in the background, and then refresh the prompt again when the background work is finished. This is accomplished by using Lua coroutines, but Clink simplifies and streamlines the process.

A prompt filter can call clink.promptcoroutine(my_func) to run `my_func()` inside a coroutine. Clink will automatically resume the coroutine repeatedly while input line editing is idle. When `my_func()` completes, Clink will automatically refresh the prompt by triggering prompt filtering again.

Typically the motivation to use asynchronous prompt filtering is that one or more `io.popen("some slow command")` calls take too long. They can be replaced with io.popenyield() calls inside the prompt coroutine to let them run in the background.

> Global data: If `my_func()` needs to use any global data, then it's important to use clink.onbeginedit() to register an event handler that can reset the global data for each new input line session. Otherwise the data may accidentally "bleed" across different input line sessions.

> Backward compatibility: A prompt filter must handle backward compatibility itself if it needs to run on versions of Clink that don't support asynchronous prompt filtering (v1.2.9 and lower). E.g. you can use `if clink.promptcoroutine then` to test whether the API exists.

The following example illustrates running `git status` in the background. It also remembers the status from the previous input line, so that it can reduce flicker by using the color from last time until the background status operation completes.

    local prev_dir      -- Most recent git repo visited.
    local prev_info     -- Most recent info retrieved by the coroutine.

    local function get_git_dir(dir)
        -- Check if the current directory is in a git repo.
        local child
        repeat
            if os.isdir(path.join(dir, ".git")) then
                return dir
            end
            -- Walk up one level to the parent directory.
            dir,child = path.toparent(dir)
            -- If child is empty, we've reached the top.
        until (not child or child == "")
        return nil
    end

    local function get_git_branch()
        -- Get the current git branch name.
        local file = io.popen("git branch --show-current 2>nul")
        local branch = file:read("*a"):match("(.+)\n")
        file:close()
        return branch
    end

    local function get_git_status()
        -- The io.popenyield API is like io.popen, but it yields until the output is
        -- ready to be read.
        local file = io.popenyield("git --no-optional-locks status --porcelain 2>nul")
        local status = false
        for line in file:lines() do
            -- If there's any output, the status is not clean.  Since this example
            -- doesn't analyze the details, it can stop once it knows there's any
            -- output at all.
            status = true
            break
        end
        file:close()
        return status
    end

    local function get_git_conflict()
        -- The io.popenyield API is like io.popen, but it yields until the output is
        -- ready to be read.
        local file = io.popenyield("git diff --name-only --diff-filter=U 2>nul")
        local conflict = false
        for line in file:lines() do
            -- If there's any output, there's a conflict.
            conflict = true
            break
        end
        file:close()
        return conflict
    end

    local function collect_git_info()
        -- This is run inside the coroutine, which happens while idle while waiting
        -- for keyboard input.
        local info = {}
        info.status = get_git_status()
        info.conflict = get_git_conflict()
        -- Until this returns, the call to clink.promptcoroutine() will keep
        -- returning nil.  After this returns, subsequent calls to
        -- clink.promptcoroutine() will keep returning this return value, until a
        -- new input line begins.
        return info
    end

    local git_prompt = clink.promptfilter(55)
    function git_prompt:filter(prompt)
        -- Do nothing if not a git repo.
        local dir = get_git_dir(os.getcwd())
        if not dir then
            return
        end
        -- Reset the cached status if in a different repo.
        if prev_dir ~= dir then
            prev_info = nil
            prev_dir = dir
        end
        -- Do nothing if git branch not available.  Getting the branch name is fast,
        -- so it can run outside the coroutine.  That way the branch name is visible
        -- even while the coroutine is running.
        local branch = get_git_branch()
        if not branch or branch == "" then
            return
        end
        -- Start a coroutine to collect various git info in the background.  The
        -- clink.promptcoroutine() call returns nil immediately, and the
        -- coroutine runs in the background.  After the coroutine finishes, prompt
        -- filtering is triggered again, and subsequent clink.promptcoroutine()
        -- calls from this prompt filter immediately return whatever the
        -- collect_git_info() function returned when it completed.  When a new input
        -- line begins, the coroutine results are reset to nil to allow new results.
        local info = clink.promptcoroutine(collect_git_info)
        -- If no status yet, use the status from the previous prompt.
        if info == nil then
            info = prev_info or {}
        else
            prev_info = info
        end
        -- Choose color for the git branch name:  green if status is clean, yellow
        -- if status is not clean, red if conflict is present, or default color if
        -- status isn't known yet.
        local sgr = "37;1"
        if info.conflict then
            sgr = "31;1"
        elseif info.status ~= nil then
            sgr = info.status and "33;1" or "32;1"
        end
        -- Prefix the prompt with "[branch]" using the status color.
        return "\x1b["..sgr.."m["..branch.."]\x1b[m  "..prompt
    end

#### Transient Prompt

Clink can replace a past prompt with a differently formatted "transient" prompt. For example, if your normal prompt contains many bits of information that don't need to be seen later, then it may be desirable to replace past prompts with a simpler prompt. Or it may be useful to update the timestamp in a prompt to indicate when the prompt was completed, rather than when it was first shown.

The `%CLINK_TRANSIENT_PROMPT%` environment variable provides the initial prompt string for the transient prompt.

Turn on the transient prompt with `clink set prompt.transient always`. Or use `same_dir` instead of `always` to only use a transient prompt when the current directory is the same as the previous prompt.

The transient prompt can be customized by a prompt filter:

1. Create a new prompt filter by calling clink.promptfilter() along with a priority id which dictates the order in which filters are called. Lower priority ids are called first.
2. Define a `:transientfilter()` function on the returned prompt filter.

The transient filter function takes a string argument that contains the filtered prompt so far. If the filter function returns nil, it has no effect. If the filter function returns a string, that string is used as the new filtered prompt (and may be further modified by other prompt filters with higher priority ids). If the filter function returns a string and a boolean, then if the boolean is false the prompt filtering is done and no further filter functions are called.

A transient right side prompt is also possible (similar to the usual right side prompt). The `%CLINK_TRANSIENT_RPROMPT%` environment variable (note the `R` in `_RPROMPT`) provides the initial prompt string for the transient right side prompt, which can be customized by a `:transientrightfilter()` function on a prompt filter.

A prompt filter must have a `:filter()` function defined on it, and may in addition have any combination of `:rightfilter()`, `:transientfilter()`, and `:transientrightfilter()` functions defined on it.

The next example shows how to make a prompt that shows:

1. The current directory and `>` on the left, and the date and time on the right.
2. Just `>` on the left, for past commands.

    -- Colors for the prompt strings.
    local cwd_color  = "\x1b[0;1;37;44m"
    local symbol_color = "\x1b[0;1;34m"
    local date_color = "\x1b[0;36m"
    local normal = "\x1b[m"

    -- Create prompt filter.
    local pf = clink.promptfilter(10)

    -- Customize the normal prompt.
    function pf:filter(prompt)
        -- Don't return false yet; let rightfilter have a chance.
        return cwd_color.." "..os.getcwd().." "..symbol_color.." > "..normal
    end

    -- Customize the normal right side prompt.
    function pf:rightfilter(prompt)
        -- Returns false to stop filtering.
        return date_color..os.date(), false
    end

    -- Customize the transient prompt.
    function pf:transientfilter(prompt)
        -- Don't return false yet; let transientrightfilter have a chance.
        return symbol_color.."> "..normal
    end

    -- Customize the transient right side prompt.
    function pf:transientrightfilter(prompt)
        -- Returns false to stop filtering.
        return "", false
    end

    -- Show a reminder to turn on the transient prompt, to try out the example.
    if settings.get("prompt.transient") == "off" then
        print("Use 'clink set prompt.transient same_dir' to enable the transient prompt.")
    end

## Customizing Suggestions

Clink can offer suggestions how to complete a command as you type, and you can select how it generates suggestions.

Turn on automatic suggestions with `clink set autosuggest.enable true`. Once enabled, Clink will show suggestions in a muted color after the end of the typed command. Accept the whole suggestion with the `Right` arrow or `End` key, accept the next word of the suggestion with `Ctrl`+`Right`, or accept the next full word of the suggestion up to a space with `Shift`+`Right`. You can ignore the suggestion if it isn't what you want; suggestions have no effect unless you accept them first.

Scripts can provide custom suggestion generators, in addition to the built-in options:

1. Create a new suggestion generator by calling [clink.suggester()][#clink.suggester] along with a name that identifies the suggestion generator, and can be added to the `autosuggest.strategy` setting.
2. Define a `:suggest()` function on the returned suggestion generator.

The function takes a line_state argument that contains the input line, and a matches argument that contains the possible matches from the completion engine. If the function returns nil, the next generator listed in the strategy is called. If the function returns a string (even an empty string), then the string is used as the suggestion.

The function can optionally return a string and an offset to where the suggestion begins in the input line. This makes it easier to return suggestions in some cases, and also makes it possible to update the capitalization of the whole accepted suggestion (even the part that's already been typed).

This example illustrates how to make a suggestion generator that returns the longest common prefix of the possible matches.

    local prefix_suggestor = clink.suggester("completion_prefix")

    function prefix_suggestor:suggest(line_state, matches)
        -- If the input line is empty or only spaces, don't suggest anything.
        if not line_state:getline():match("[^ ]") then
            return
        end

        -- If there is no common prefix, don't suggest anything.
        local prefix = matches:getprefix()
        if prefix == "" then
            return
        end

        -- Return the common prefix as the suggestion.
        local info = line_state:getwordinfo(line_state:getwordcount())
        return prefix, info.offset
    end

# Miscellaneous

These sections provide more information about various aspects of Clink:

Customizing Key Bindings | How to customize key bindings.
Saved Command History | How the saved command history works.
Using History Expansion | How to use history expansion.
Popular Scripts | Some popular scripts to enhance Clink.
Terminal Support | Information about how Clink's terminal support works.
Troubleshooting Tips | How to troubleshoot and report problems.
Privacy | Privacy statement for Clink.

## Customizing Key Bindings

Key bindings are defined in .inputrc files.

The `clink-show-help` command is bound to `Alt`+`H` and lists all currently active key bindings. The list displays "friendly" key names, and these names are generally not suitable for use in .inputrc files. For example "Up" is the friendly name for `"\e[A"`, and "A-C-F2" is the friendly name for `"\e\e[1;5Q"`. To see key sequence strings suitable for use in .inputrc files use `clink echo` as described below.

The .inputrc file | A quick summary of what key binding lines look like.
Sample .inputrc file | Some sample key bindings.
Discovering Clink key sequences | How to find key names to use for key bindings.
Binding special keys | A table of special key names.
Lua key bindings | How to bind keys to Lua functions.

### The .inputrc file

You can use `clink info` to find the directories and configuration files for the current Clink session, including where the .inputrc file is located, or can be located. See the Readline Init File section for detailed information about .inputrc files.

Here is a quick summary about key binding lines in .inputrc files:

- A key binding is `name: function` or `name: "literal text"`.
- Key names are like this:
  - `C-a` and `"\C-a"` are both `Ctrl`+`a`.
  - `M-a` and `"\M-a"` are both `Alt`+`a`.
  - `M-C-a` and `"\M-\C-a"` are both `Alt`+`Ctrl`+`a`.
  - `hello` is just `h`; the `ello` is a syntax error and is silently discarded by Readline.
  - `"hello"` is the series of keys `h`,`e`,`l`,`l`,`o`.
  - Special keys like `Up` are represented by VT220 escape codes such as`"\e[A"` (see Binding special keys for more info).
- Key bindings can be either functions or macros (literal text):
  - `blah-blah` binds to a function named "blah-blah".
  - `"blah-blah"` inserts the literal text "blah-blah".

See Discovering Clink key sequences to learn how to find key names for keys that you want to bind.

### Sample .inputrc file

Here is a sample `.inputrc` file with some of the key bindings that I use:

    $if clink           # begin clink-only section

    # The following key bindings are for emacs mode.
    set keymap emacs

    # Completion key bindings.
    "\t":               old-menu-complete               # Tab
    "\e[Z":             old-menu-complete-backward      # Shift+Tab
    "\e[27;5;9~":       clink-popup-complete            # Ctrl+Tab

    # Some key bindings I got used to from 4Dos/4NT/Take Command.
    C-b:                                                # Ctrl+B (cleared because I redefined Ctrl+F)
    C-d:                remove-history                  # Ctrl+D (replaces `delete-char`)
    C-f:                clink-expand-doskey-alias       # Ctrl+F (replaces `forward-char`)
    C-k:                add-history                     # Ctrl+K (replaces `kill-line`)
    "\e[A":             history-search-backward         # Up (replaces `previous-history`)
    "\e[B":             history-search-forward          # Down (replaces `next-history`)
    "\e[5~":            clink-popup-history             # PgUp (replaces `history-search-backward`)
    "\e[6~":                                            # PgDn (cleared because I redefined PgUp)
    "\e[1;5F":          end-of-line                     # Ctrl+End (replaces `kill-line`)
    "\e[1;5H":          beginning-of-line               # Ctrl+Home (replaces `backward-kill-line`)

    # Some key bindings handy in default (conhost) console windows.
    M-b:                                                # Alt+B (cleared because I redefined Alt+F)
    M-f:                clink-find-conhost              # Alt+F for "Find..." from the console's system menu
    M-m:                clink-mark-conhost              # Alt+M for "Mark" from the console's system menu

    # Some key bindings for interrogating the Readline configuration.
    "\C-x\C-f":         dump-functions                  # Ctrl+X, Ctrl+F
    "\C-x\C-m":         dump-macros                     # Ctrl+X, Ctrl+M
    "\C-x\C-v":         dump-variables                  # Ctrl+X, Ctrl+V

    # Misc other key bindings.
    "\e[27;2;32~":      clink-magic-suggest-space       # Shift+Space
    "\e[5;6~":          clink-popup-directories         # Ctrl+Shift+PgUp
    C-_:                kill-line                       # Ctrl+- (replaces `undo`)

    $endif              # end clink-only section

> Note: Third party console hosts such as ConEmu may have their own key bindings that supersede Clink. They usually have documentation for how to change or disable their key bindings to allow console programs to handle the keys instead.

### Discovering Clink key sequences

Clink provides an easy way to find the key sequence for any key combination that Clink supports. Run `clink echo` and then press key combinations; the associated key binding sequence is printed to the console output and can be used for a key binding in the inputrc file.

A chord can be formed by concatenating multiple key binding sequences. For example, `"\C-X"` and `"\e[H"` can be concatenated to form `"\C-X\e[H"` representing the chord `Ctrl`+`X`,`Home`.

When finished, press `Ctrl`+`C` to exit from `clink echo`.

> Note: With non-US keyboard layouts, `clink echo` is not able to ignore dead key input (accent keys, for example). It prints the key sequence for the dead key itself, which is not useful. You can ignore that and press the next key, and then it prints the correct key sequence to use in key bindings.

### Binding special keys

Here is a table of the key binding sequences for the special keys. Clink primarily uses VT220 emulation for keyboard input, but also uses some Xterm extended key sequences.

| Normal | Shift | Ctrl | Ctrl+Shift | Alt | Alt+Shift | Alt+Ctrl | Alt+Ctrl+Shift
--- | --- | --- | --- | --- | --- | --- | --- | ---
Up | `\e[A` | `\e[1;2A` | `\e[1;5A` | `\e[1;6A` | `\e[1;3A` | `\e[1;4A` | `\e[1;7A` | `\e[1;8A`
Down | `\e[B` | `\e[1;2B` | `\e[1;5B` | `\e[1;6B` | `\e[1;3B` | `\e[1;4B` | `\e[1;7B` | `\e[1;8B`
Left | `\e[D` | `\e[1;2D` | `\e[1;5D` | `\e[1;6D` | `\e[1;3D` | `\e[1;4D` | `\e[1;7D` | `\e[1;8D`
Right | `\e[C` | `\e[1;2C` | `\e[1;5C` | `\e[1;6C` | `\e[1;3C` | `\e[1;4C` | `\e[1;7C` | `\e[1;8C`
Insert | `\e[2~` | `\e[2;2~` | `\e[2;5~` | `\e[2;6~` | `\e[2;3~` | `\e[2;4~` | `\e[2;7~` | `\e[2;8~`
Delete | `\e[3~` | `\e[3;2~` | `\e[3;5~` | `\e[3;6~` | `\e[3;3~` | `\e[3;4~` | `\e[3;7~` | `\e[3;8~`
Home | `\e[H` | `\e[1;2H` | `\e[1;5H` | `\e[1;6H` | `\e[1;3H` | `\e[1;4H` | `\e[1;7H` | `\e[1;8H`
End | `\e[F` | `\e[1;2F` | `\e[1;5F` | `\e[1;6F` | `\e[1;3F` | `\e[1;4F` | `\e[1;7F` | `\e[1;8F`
PgUp | `\e[5~` | `\e[5;2~` | `\e[5;5~` | `\e[5;6~` | `\e[5;3~` | `\e[5;4~` | `\e[5;7~` | `\e[5;8~`
PgDn | `\e[6~` | `\e[6;2~` | `\e[6;5~` | `\e[6;6~` | `\e[6;3~` | `\e[6;4~` | `\e[6;7~` | `\e[6;8~`
Tab | `\t` | `\e[Z` | `\e[27;5;9~` | `\e[27;6;9~` | - | - | - | -
Space | `Space` | `\e[27;2;32~` | `\e[27;5;32~` | `\e[27;6;32~` | - | - | `\e[27;7;32~` | `\e[27;8;32~`
Backspace | `^h` | `\e[27;2;8~` | `Rubout` | `\e[27;6;8~` | `\e^h` | `\e[27;4;8~` | `\eRubout` | `\e[27;8;8~`
F1 | `\eOP` | `\e[1;2P` | `\e[1;5P` | `\e[1;6P` | `\e\eOP` | `\e\e[1;2P` | `\e\e[1;5P` | `\e\e[1;6P`
F2 | `\eOQ` | `\e[1;2Q` | `\e[1;5Q` | `\e[1;6Q` | `\e\eOQ` | `\e\e[1;2Q` | `\e\e[1;5Q` | `\e\e[1;6Q`
F3 | `\eOR` | `\e[1;2R` | `\e[1;5R` | `\e[1;6R` | `\e\eOR` | `\e\e[1;2R` | `\e\e[1;5R` | `\e\e[1;6R`
F4 | `\eOS` | `\e[1;2S` | `\e[1;5S` | `\e[1;6S` | `\e\eOS` | `\e\e[1;2S` | `\e\e[1;5S` | `\e\e[1;6S`
F5 | `\e[15~` | `\e[15;2~` | `\e[15;5~` | `\e[15;6~` | `\e\e[15~` | `\e\e[15;2~` | `\e\e[15;5~` | `\e\e[15;6~`
F6 | `\e[17~` | `\e[17;2~` | `\e[17;5~` | `\e[17;6~` | `\e\e[17~` | `\e\e[17;2~` | `\e\e[17;5~` | `\e\e[17;6~`
F7 | `\e[18~` | `\e[18;2~` | `\e[18;5~` | `\e[18;6~` | `\e\e[18~` | `\e\e[18;2~` | `\e\e[18;5~` | `\e\e[18;6~`
F8 | `\e[19~` | `\e[19;2~` | `\e[19;5~` | `\e[19;6~` | `\e\e[19~` | `\e\e[19;2~` | `\e\e[19;5~` | `\e\e[19;6~`
F9 | `\e[20~` | `\e[20;2~` | `\e[20;5~` | `\e[20;6~` | `\e\e[20~` | `\e\e[20;2~` | `\e\e[20;5~` | `\e\e[20;6~`
F10 | `\e[21~` | `\e[21;2~` | `\e[21;5~` | `\e[21;6~` | `\e\e[21~` | `\e\e[21;2~` | `\e\e[21;5~` | `\e\e[21;6~`
F11 | `\e[23~` | `\e[23;2~` | `\e[23;5~` | `\e[23;6~` | `\e\e[23~` | `\e\e[23;2~` | `\e\e[23;5~` | `\e\e[23;6~`
F12 | `\e[24~` | `\e[24;2~` | `\e[24;5~` | `\e[24;6~` | `\e\e[24~` | `\e\e[24;2~` | `\e\e[24;5~` | `\e\e[24;6~`

When the `terminal.differentiate_keys` setting is enabled then the following key bindings are also available:

| Ctrl | Ctrl+Shift | Alt | Alt+Shift | Alt+Ctrl | Alt+Ctrl+Shift
--- | --- | --- | --- | --- | --- | ---
`H` | `\e[27;5;72~` | `\e[27;6;72~` | `\eh` | `\eH` | `\e[27;7;72~` | `\e[27;8;72~`
`I` | `\e[27;5;73~` | `\e[27;6;73~` | `\ei` | `\eI` | `\e[27;7;73~` | `\e[27;8;73~`
`M` | `\e[27;5;77~` | `\e[27;6;77~` | `\em` | `\eM` | `\e[27;7;77~` | `\e[27;8;77~`
`[` | `\e[27;5;219~` | `\e[27;6;219~` | `\e[27;3;219~` | `\e[27;4;219~` | `\e[27;7;219~` | `\e[27;8;219~`

The `terminal.raw_esc` setting controls the binding sequence for the `Esc` key and a couple of other keys:

`terminal.raw_esc` Setting Value | Esc | Alt+[ | Alt+Shift+O
--- | --- | --- | ---
False (the default) | `\e[27;27~` | `\e[27;3;91~` | `\e[27;4;79~`
True (replicate Unix terminal input quirks and issues) | `\e` | `\e[` | `\eO`

### Lua key bindings

You can bind a key to a Lua function by binding it to a macro that begins with "luafunc:". Clink will invoke the named Lua function when the key binding is input. Function names can include periods (such as `foo.bar`) but cannot include any other punctuation.

The Lua function receives two arguments:

rl_buffer gives it access to the input buffer.

line_state gives it access to the same line state that a match generator receives.

Lua functions can print output, but should first call rl_buffer:beginoutput() so that the output doesn't overwrite the displayed input line.

> Notes:

> - The line_state is nil if not using Clink v1.2.34 or higher.
> - The end word is always empty for generators. So to get the word at the cursor use:

>       local info = line_state:getwordinfo(line_state:getwordcount())
>       local word_at_cursor = line_state:getline():sub(info.offset, line_state:getcursor())

#### Basic example

Example of a Lua function key binding in a .inputrc file:

    M-C-y:          "luafunc:insert_date"
    M-C-z:          "luafunc:print_date"

Example functions to go with that:

    function insert_date(rl_buffer)
        rl_buffer:insert(os.date("%x %X"))
    end

    function print_date(rl_buffer)
        rl_buffer:beginoutput()
        print(os.date("%A %B %d, %Y   %I:%M %p"))
    end

#### Advanced example

Here is an example that makes `F7`/`F8` jump to the previous/next screen line containing "error" or "warn" colored red or yellow, and makes `Shift`+`F7`/`Shift`+`F8` jump to the previous/next prompt line.

One way to use these is when reviewing compiler errors after building a project at the command line. Press `Shift`+`F7` to jump to the previous prompt line, and then use `F8` repeatedly to jump to each next compiler warning or error listed on the screen.

Example key bindings for the .inputrc file:

    "\e[18~":       "luafunc:find_prev_colored_line"
    "\e[19~":       "luafunc:find_next_colored_line"
    "\e[18;2~":     "luafunc:find_prev_prompt"
    "\e[19;2~":     "luafunc:find_next_prompt"

Example functions to go in a Lua script file:

    local max_recent_prompts = 10   -- Keep track of up to this many recent prompts.
    local min_match_text = 10       -- Minimum length of text to count as a match.

    local recent_prompts = {}       -- Queue of recent prompt match strings.
    local scroll_stack = {}         -- Stack of found scroll positions.

    -- Remember our most recent scroll position, so that if something else scrolls
    -- the screen we can reset the find_prev_prompt/find_next_prompt stack.
    local was_top

    local function add_recent_prompt(text)
        -- Escape characters that have special meaning in regular expressions.
        text = "^"..text:gsub("([!-/:-@[-`{-~])", "\\%1")

        -- Add new entry at the beginning of the queue.
        table.insert(recent_prompts, 1, text)

        -- Discard excess entries from the end of the queue.
        while #recent_prompts > max_recent_prompts do
            table.remove(recent_prompts)
        end
    end

    local function reset_prompt_scroll_stack()
        was_top = nil
        scroll_stack = {}
    end

    local function update_recent_prompt_queue()
        -- Offset minus one because onendedit happens after the cursor moves down
        -- past the end of the input area, which skews the info returned from
        -- rl.getpromptinfo().
        local offset = -1
        local info = rl.getpromptinfo()
        local line = info.promptline + offset
        local last_line = console.getnumlines()

        -- Find a long enough string to be considered part of the prompt.
        while line <= last_line do
            local text = console.getlinetext(line)
            text = text:gsub("%s+$", "")
            if #text >= min_match_text then
                add_recent_prompt(text)
                break
            end
            line = line + 1
        end
    end

    -- Register for events to maintain the scroll stack and recent prompt queue.
    clink.onbeginedit(reset_prompt_scroll_stack)
    clink.onendedit(update_recent_prompt_queue)

    -- Jumps to the previous prompt on the screen (i.e. move upward, searching for
    -- preceding recent prompts).
    function find_prev_prompt(rl_buffer)
        local height = console.getheight()
        local offset = math.modf((height - 1) / 2)

        local top = console.gettop()
        if was_top and was_top ~= top then
            reset_prompt_scroll_stack()
        end
        if not was_top then
            was_top = top
        end

        if top <= 1 then
            console.scroll("absolute", 1)
            return
        end

        -- Init the stack if it's empty.
        if #scroll_stack == 0 then
            local info = rl.getpromptinfo()
            scroll_stack[1] = info.promptline
        end

        local count = #scroll_stack
        local start = scroll_stack[count] - 1
        local text = recent_prompts[count]

        if not text then
            if count == 1 then
                -- Only ding if there are none; otherwise visual bell will
                -- scroll back to the bottom.
                rl_buffer:ding()
            else
                -- No more recent prompts?  Maintain the scroll position.
                console.scroll("absolute", scroll_stack[count] - offset)
                was_top = console.gettop()
            end
            return
        end

        -- Search upwards for the next most recent prompt.
        local match
        repeat
            match = console.findprevline(start, text, "regex", {})
            if match <= 0 then
                -- Can't find it?  Maintain the scroll position.
                console.scroll("absolute", scroll_stack[count] - offset)
                was_top = console.gettop()
                return
            end
            start = match - 1
        until match - offset < was_top

        -- Add the found prompt to the stack.
        table.insert(scroll_stack, match)

        -- Scroll to the prompt position
        console.scroll("absolute", match - offset)
        was_top = console.gettop()
    end

    -- Jump to the next prompt on the screen (i.e. move downward, backtracking over
    -- the prompts already visited by find_prev_prompt).
    function find_next_prompt(rl_buffer)
        local height = console.getheight()
        local offset = math.modf((height - 1) / 2)

        -- Pop the last found prompt.  If the stack is empty, ding.
        if #scroll_stack > 0 then
            table.remove(scroll_stack)
        end
        if #scroll_stack == 0 then
            rl_buffer:ding()
            return
        end

        -- Get the scroll position of the next to last found prompt.
        local top = scroll_stack[#scroll_stack] - offset
        if #scroll_stack == 1 then
            -- If it's the last prompt, pop it to reset the stack.
            top = console.getnumlines()
            table.remove(scroll_stack, #scroll_stack)
        end

        -- Scroll to the prompt position.
        console.scroll("absolute", top)
        was_top = console.gettop()
    end

    -- Searches upwards for a line containing "warn" or "error"
    -- colored red or yellow.
    function find_prev_colored_line(rl_buffer)
        local height = console.getheight()
        local cur_top = console.gettop()
        local offset = math.modf((height - 1) / 2) -- For vertically centering the found line.
        local start = cur_top + offset
        local found_index

        -- Only search if there's still room to scroll up.
        if start - offset > 1 then
            local match = console.findprevline(start - 1, "warn|error", "regex", {4,12,14}, "fore")
            if match ~= nil and match > 0 then
                found_index = match
            end
        end

        -- If scrolled up but no more matches, maintain the scroll position.
        if found_index == nil and cur_top <= console.getnumlines() - height then
            found_index = start
        end

        if found_index ~= nil then
            console.scroll("absolute", found_index - offset)
        else
            rl_buffer:ding()
        end
    end

    -- Searches downwards for a line containing "warn" or "error"
    -- colored red or yellow.
    function find_next_colored_line(rl_buffer)
        local height = console.getheight()
        local cur_top = console.gettop()
        local bottom = console.getnumlines()
        local offset = math.modf((height - 1) / 2) -- For vertically centering the found line.
        local start = cur_top + offset
        local found_index

        if cur_top > bottom - height then
            rl_buffer:ding()
            return
        end

        -- Only search if there's still room to scroll down.
        if start - offset + height - 1 < bottom then
            local match = console.findnextline(start + 1, "warn|error", "regex", {4,12,14}, "fore")
            if match ~= nil and match > 0 then
                found_index = match
            end
        end

        if found_index ~= nil then
            console.scroll("absolute", found_index - offset)
        else
            rl_buffer:ding()
        end
    end

## Saved Command History

Clink has a list of commands from the current session, and it can be saved and loaded across sessions.

A line won't be added to history if either of the following are true:

- The first word in the line matches one of the words in the `history.dont_add_to_history_cmds` setting.
- The line begins with a space character.

To prevent doskey alias expansion while still adding the line to history, you can start the line with a semicolon.

Line | Description
--- | ---
`somecmd` | Expands doskey alias and adds to history.
`somecmd` | Doesn't expand doskey alias and doesn't add to history.
`;somecmd` | Doesn't expand doskey alias but does add to history.

There are several settings that control how history works. Run `clink set history*` to see them.

### The master history file

When the `history.saved` setting is enabled, then the command history is loaded and saved as follows (or when the setting is disabled, then it isn't saved between sessions).

Every time a new input line starts, Clink reloads the master history list and prunes it not to exceed the `history.max_lines` setting.

For performance reasons, deleting a history line marks the line as deleted without rewriting the history file. When the number of deleted lines gets too large (exceeding the max lines or 200, whichever is larger) then the history file is compacted: the file is rewritten with the deleted lines removed.

You can force the history file to be compacted regardless of the number of deleted lines by running `history compact`.

### Shared command history

When the `history.shared` setting is enabled, then all instances of Clink update the master history file and reload it every time a new input line starts. This gives the effect that all instances of Clink share the same history -- a command entered in one instance will appear in other instances' history the next time they start an input line.

When the setting is disabled, then each instance of Clink loads the master file but doesn't append its own history back to the master file until after it exits, giving the effect that once an instance starts its history is isolated from other instances' history.

### Multiple master history files

Normally Clink saves a single saved master history list. All instances of Clink load and save the same master history list.

It's also possible to make one or more instances of Clink use a different saved master history list by setting the `%CLINK_HISTORY_LABEL%` environment variable. This can be up to 32 alphanumeric characters, and is appended to the master history file name. Changing the `%CLINK_HISTORY_LABEL%` environment variable takes effect at the next input line.

## Using History Expansion

Clink uses Readline's History library to add history expansion capabilities. If these are undesirable, they can be turned off by running `clink set history.expand_mode off`.

The History library provides a history expansion feature that is similar to the history expansion provided by `csh`. This section describes the syntax used to manipulate the history information.

History expansions introduce words from the history list into the input stream, making it easy to repeat commands, insert the arguments to a previous command into the current input line, or fix errors in previous commands quickly.

History expansion takes place in two parts. The first is to determine which line from the history list should be used during substitution. The second is to select portions of that line for inclusion into the current one. The line selected from the history is called the "event", and the portions of that line that are acted upon are called "words". Various "modifiers" are available to manipulate the selected words. The line is broken into words in the same fashion that Bash does, so that several words surrounded by quotes are considered one word. History expansions are introduced by the appearance of the history expansion character, which is `!`.

History expansion implements shell-like quoting conventions: a backslash can be used to remove the special handling for the next character; single quotes enclose verbatim sequences of characters, and can be used to inhibit history expansion; and characters enclosed within double quotes may be subject to history expansion, since backslash can escape the history expansion character, but single quotes may not, since they are not treated specially within double quotes.

Event Designators | How to specify which history line to use.
Word Designators | Specifying which words are of interest.
Modifiers | Modifying the results of substitution.

### Event Designators

An event designator is a reference to a command line entry in the history list. Unless the reference is absolute, events are relative to the current position in the history list.

`!` | Start a history substitution, except when followed by a space, tab, the end of the line, or `=`.
`!n` | Refer to command line n.
`!-n` | Refer to the command n lines back.
`!!` | Refer to the previous command. This is a synonym for `!-1`.
`!string` | Refer to the most recent command preceding the current position in the history list starting with string.
`!?string[?]` | Refer to the most recent command preceding the current position in the history list containing string. The trailing `?` may be omitted if the string is followed immediately by a newline. If string is missing, the string from the most recent search is used; it is an error if there is no previous search string.
`^string1^string2^` | Quick Substitution. Repeat the last command, replacing string1 with string2. Equivalent to `!!:s^string1^string2^`.
`!#` | The entire command line typed so far.

### Word Designators

Word designators are used to select desired words from the event. A `:` separates the event specification from the word designator. It may be omitted if the word designator begins with a `^`, `$`, `*`, `-`, or `%`. Words are numbered from the beginning of the line, with the first word being denoted by 0 (zero). Words are inserted into the current line separated by single spaces.

For example,

`!!` | designates the preceding command. When you type this, the preceding command is repeated in toto.
`!!:$` | designates the last argument of the preceding command. This may be shortened to `!$`.
`!fi:2` | designates the second argument of the most recent command starting with the letters `fi`.

Here are the word designators:

`0 (zero)` | The 0th word. For many applications, this is the command word.
`n` | The nth word.
`^` | The first argument; that is, word 1.
`$` | The last argument.
`%` | The first word matched by the most recent `!?string?` search, if the search string begins with a character that is part of a word.
`x-y` | A range of words; `-y` abbreviates `0-y`.
`*` | All of the words, except the 0th. This is a synonym for `1-$`. It is not an error to use `*` if there is just one word in the event; the empty string is returned in that case.
`x*` | Abbreviates `x-$`
`x-` | Abbreviates `x-$` like `x*`, but omits the last word. If `x` is missing, it defaults to 0.

If a word designator is supplied without an event specification, the previous command is used as the event.

### Modifiers

After the optional word designator, you can add a sequence of one or more of the following modifiers, each preceded by a `:`. These modify, or edit, the word or words selected from the history event.

`h` | Remove a trailing pathname component, leaving only the head.
`t` | Remove all leading pathname components, leaving the tail.
`r` | Remove a trailing suffix of the form `.suffix`, leaving the basename.
`e` | Remove all but the trailing suffix.
`p` | Print the new command but do not execute it.
`s/old/new/` | Substitute new for the first occurrence of old in the event line. Any character may be used as the delimiter in place of `/`. The delimiter may be quoted in old and new with a single backslash. If `&` appears in new, it is replaced by old. A single backslash will quote the `&`. If old is null, it is set to the last old substituted, or, if no previous history substitutions took place, the last string in a `!?string?` search. If new is is null, each matching old is deleted. The final delimiter is optional if it is the last character on the input line.
`&` | Repeat the previous substitution.
`g` | Cause changes to be applied over the entire event line. Used in conjunction with `s`, as in `gs/old/new/`, or with `&`.
`a` | The same as `g`.
`G` | Apply the following `s` or `&` modifier once to each word in the event.

## Popular Scripts

Here are some popular scripts that show off what can be done with Clink.

### clink-completions

The clink-completions collection of scripts has a bunch of argument matchers and completion generators for things like git, mercurial, npm, and more.

### clink-flex-prompt

The clink-flex-prompt script is similar to the zsh powerlevel10k theme. It gives Clink a very customizable prompt, with many style options. It's extensible so you can add your own segments.

It also takes advantage of Clink's asynchronous prompt refresh to make prompts show up instantly, even in large git repos, for example.

### clink-fzf

The clink-fzf script integrates the popular fzf "fuzzy finder" tool with Clink.

### oh-my-posh

The oh-my-posh program can generate fancy prompts. Refer to its documentation for how to configure it, and for sample themes.

Integrating oh-my-posh with Clink is easy: just save the following text to an `oh-my-posh.lua` file in your Clink scripts directory (run `clink info` to find that), and make sure the `oh-my-posh.exe` program is in a directory listed in the `%PATH%` environment variable (or edit the script below to provide a fully qualified path to the oh-my-posh.exe program). Replace the config with your own configuration and you're good to go.

    -- oh-my-posh.lua
    load(io.popen('oh-my-posh.exe --config="C:/Users/me/jandedobbeleer.omp.json" --init --shell cmd'):read("*a"))()

### starship

The starship program can also generate fancy prompts. Refer to its documentation for how to configure it.

Integrating starship with Clink is just as easy: save the following text to a `starship.lua` file in your Clink scripts directory (run `clink info` to find that), and make sure the `starship.exe` program is in a directory listed in the `%PATH%` environment variable (or edit the script below to provide a fully qualified path to the starship.exe program). The config file for starship is located at `C:\Users\<username>\.config\starship.toml`.

    -- starship.lua
    load(io.popen('starship.exe init cmd'):read("*a"))()

### z.lua

The z.lua tool is a faster way to navigate directories, and it integrates with Clink.

## Terminal Support

Windows programs generally don't need to worry about terminal support. But the Readline library used by Clink comes from Unix, where there are many different kinds of terminals, and the library requires certain kinds of terminal support.

Clink's keyboard driver generally produces VT220 style key sequences, but it also includes many extensions from Xterm and other sources. Use `clink echo` to find key sequences for specific inputs.

Clink's terminal output driver is designed for use with Windows and its console subsystem. Clink can optionally handle output itself instead, and emulate terminal output support when the `terminal.emulation` setting is `emulate`, or when `auto` and Clink is running on an older version of Windows that doesn't support ANSI escape codes. In emulation mode, 8 bit and 24 bit color escape codes are mapped to the nearest 4 bit colors.

By default Clink sets the cursor style to a blinking horizontal partial-height block, or to a blink full-height solid block. Some terminals support escape codes to select alternative cursor styles. Clink provides environment variables where you may optionally provide escape codes to override the cursor style. `%CLINK_TERM_VE%` selects the style for the normal cursor (insert mode), `%CLINK_TERM_VS%` selects the style for the enhanced cursor (overwrite mode).

Special codes recognized in the cursor style escape code strings:

Code | Description
--- | ---
`\e` | Translated to the ESC character (27 decimal, 0x1b hex).
`\xHH` | Translated to the character matching the hex HH value. E.g. `\x1b` is the same as `\e`, or `\x08` is a backspace, etc.
`\\` | Translated to the `\` character.
``\c`` | Any other backslash is translate to whatever character immediately follows it. E.g. `\a` becomes `a`.

Refer to the documentation for individual terminal programs to find what (if any) escape codes they may support. The default console in Windows 10 supports the DECSCUSR escape codes for selecting cursor shape.

This .cmd script sets the normal cursor to a blinking vertical bar, and the enhanced cursor to a non-blinking solid box:

    set CLINK_TERM_VE=\e[5 q
    set CLINK_TERM_VS=\e[2 q

Or this .cmd script sets the normal cursor to blink, and the enhanced cursor to not blink:

    set CLINK_TERM_VE=\e[?12h
    set CLINK_TERM_VS=\e[?12l

## Troubleshooting Tips

If something seems to malfunction, here are some things to try that often help track down what's going wrong:

- Check if anti-malware software blocked Clink from injecting.
  - Consider adding an exclusion for Clink.
  - The contents of the `clink.log` file often help in determining whether anti-malware software blocked Clink.
  - If it's indeed being blocked by anti-malware software, report the false positive to the publisher of the anti-malware software so they can confirm and update the detection signatures. There's nothing Clink can do about it.
- Check `clink info`. E.g. does the state dir look right, do the script paths look right, do the inputrc files look right?
- Check `clink set`. E.g. do the settings look right?
- Check the `clink.log` file for clues (its location is reported by `clink info`).

When reporting an issue, please include the following which saves time by answering in advance the usual questions:

- Please describe what was expected to happen.
- Please describe what actually happened.
- Please include the output from `clink info` and `clink set`.
- Please include the `clink.log` file (the location is reported by `clink info`).

## Privacy

Clink does not collect user data. Clink writes diagnostic information to its local log file, and does not transmit the log file off the local computer. For the location of the log file, refer to File Locations or run `clink info`.

# Lua API Reference

This section describes the Clink Lua API extensions. Also see Lua Documentation and the Lua 5.2 Manual for more information about the Lua programming language.

### API groups

##### _argmatcher

_argmatcher:addarg
( choices...:string|table ) : self
v1.0.0 and newer

This adds argument matches. Arguments can be a string, a string linked to another parser by the concatenation operator, a table of arguments, or a function that returns a table of arguments. See Argument Completion for more information.

    local my_parser = clink.argmatcher("git")
    :addarg("add", "status", "commit", "checkout")

_argmatcher:addargunsorted
( choices...:string|table ) : self
v1.3.3 and newer

This is the same as _argmatcher:addarg except that this disables sorting the matches.

_argmatcher:adddescriptions
( [descriptions...:table] ) : self
v1.2.38 and newer

Adds descriptions for arg matches and/or flag matches. Descriptions are displayed for their associated args or flags whenever possible completions are listed, for example by the `complete` or `clink-select-complete` or `possible-completions` commands.

Any number of descriptions tables may be passed to the function, and each table must use one of the following schemes:

- One or more string values that are args or flags, and a `description` field that is the associated description string.
- Key/value pairs where each key is an arg or flag, and its value is either a description string or a table containing an optional arguments string and a description string. If an arguments string is provided, it is appended to the arg or flag string when listing possible completions. For example, `["--user"] = { " name", "Specify username"}` gets printed as:

       --user name    Specify username

    local foo = clink.argmatcher("foo")
    foo:addflags("-h", "--help", "--user")
    foo:addarg("info", "set")
    -- Example using first scheme and one table per description:
    foo:adddescriptions(
        { "-h", "--help",   description = "Show help" },
        { "--user",         description = "Specify user name" },
        { "info",           description = "Prints information" },
        { "set",            description = "Show or change settings" },
    )
    -- Example using second scheme and just one table:
    foo:adddescriptions( {
        ["-h"]              = "Show help",
        ["--help"]          = "Show help",
        ["--user"]          = { " name", "Specify user name" },
        ["info"]            = { "Prints information" },
        ["set"]             = { " var[=value]", "Show or change settings" },
    } )

You can make your scripts backward compatible with older Clink versions by adding a helper function. The following is the safest and simplest way to support backward compatibility:

    -- Helper function to add descriptions, when possible.
    local function maybe_adddescriptions(matcher, ...)
        if matcher and matcher.adddescriptions then
            matcher:adddescriptions(...)
        end
    end

    -- This adds descriptions only if the Clink version being used
    -- supports them, otherwise it does nothing.
    maybe_adddescriptions(foo, {
        ["-h"] = "Show help",
        -- etc
    })

_argmatcher:addflags
( flags...:string ) : self
v1.0.0 and newer

This adds flag matches. Flags are separate from arguments: When listing possible completions for an empty word, only arguments are listed. But when the word being completed starts with the first character of any of the flags, then only flags are listed. See Argument Completion for more information.

    local my_parser = clink.argmatcher("git")
    :addarg({ "add", "status", "commit", "checkout" })
    :addflags("-a", "-g", "-p", "--help")

_argmatcher:addflagsunsorted
( flags...:string ) : self
v1.3.3 and newer

This is the same as _argmatcher:addflags except that this also disables sorting for flags.

_argmatcher:chaincommand
() : self
v1.3.13 and newer

This makes the rest of the line be parsed as a separate command. You can use it to "chain" from one parser to another.

For example, `cmd.exe program arg` is example of a line where one command can have another command within it. `:chaincommand()` enables `program arg` to be parsed separately. If `program` has an argmatcher, then it takes over and parses the rest of the input line.

    clink.argmatcher("program"):addflags("/x", "/y")
    clink.argmatcher("cmd"):addflags("/c", "/k"):chaincommand()
    -- Consider the following input:
    --    cmd /c program /
    -- "cmd" is colored as an argmatcher.
    -- "/c" is colored as a flag (by the "cmd" argmatcher).
    -- "program" is colored as an argmatcher.
    -- "/" generates completions "/x" and "/y".

_argmatcher:hideflags
( flags...:string ) : self
v1.3.3 and newer

This hides the specified flags when displaying possible completions (the flags are still recognized).

This is intended for use when there are several synonyms for a flag, so that input coloring and linked argmatchers work, without cluttering the possible completion list.

    local dirs = clink.argmatcher():addarg(clink.dirmatches)
    local my_parser = clink.argmatcher("mycommand")
    :addflags("-a", "--a", "--al", "--all",
    "-d"..dirs, "--d"..dirs, "--di"..dirs, "--dir"..dirs)
    :hideflags("--a", "--al", "--all",      -- Only "-a" is displayed.
    "-d", "--d", "--di")         -- Only "--dir" is displayed.

_argmatcher:loop
( [index:integer] ) : self
v0.4.9 and newer

This makes the parser loop back to argument position index when it runs out of positional sets of arguments (if index is omitted it loops back to argument position 1).

    clink.argmatcher("xyzzy")
    :addarg("zero", "cero")     -- first arg can be zero or cero
    :addarg("one", "uno")       -- second arg can be one or uno
    :addarg("two", "dos")       -- third arg can be two or dos
    :loop(2)    -- fourth arg loops back to position 2, for one or uno, and so on

_argmatcher:nofiles
() : self
v1.0.0 and newer

This makes the parser prevent invoking match generators. You can use it to "dead end" a parser and suggest no completions.

_argmatcher:reset
() : self
v1.3.10 and newer

Resets the argmatcher to an empty state. All flags, arguments, and settings are cleared and reset back to a freshly-created state.

See Adaptive Argmatchers for more information.

_argmatcher:setclassifier
( func:function ) : self
v1.1.18 and newer

This registers a function that gets called for each word the argmatcher handles, to classify the word as part of coloring the input text. See Coloring the Input Text for more information.

_argmatcher:setdelayinit
( func:function ) : self
v1.3.10 and newer

This registers a function that gets called the first time the argmatcher is used in each edit line session. See Adaptive Argmatchers for more information.

_argmatcher:setendofflags
( [endofflags:string|boolean] ) : self
v1.3.12 and newer

When endofflags is a string, it is a special flag that signals the end of flags. When endflags is true or nil, then "`--`" is used as the end of flags string. Otherwise, the end of flags string is cleared.

_argmatcher:setflagprefix
( [prefixes...:string] ) : self
v1.0.0 and newer

This is almost never needed, because `:addflags()` automatically identifies flag prefix characters.

However, any flags generated by functions can't influence the automatic flag prefix character(s) detection. So in some cases it may be necessary to directly set the flag prefix.

Note: `:setflagprefix()` behaves differently in different versions of Clink:

Version | Description
--- | ---
v1.0.0 through v1.1.3 | Sets the flag prefix characters.
v1.1.4 through v1.2.35 | Only sets flag prefix characters in an argmatcher created using the deprecated clink.arg.register_parser() function. Otherwise it has no effect.
v1.2.36 through v1.3.8 | Does nothing.
v1.3.9 onward | Adds flag prefix characters, in addition to the ones automatically identified.

    local function make_flags()
        return { '-a', '-b', '-c' }
    end

    clink.argmatcher('some_command')
    :addflags(make_flags)   -- Only a function is added, so flag prefix characters cannot be determined automatically.
    :setflagprefix('-')     -- Force '-' to be considered as a flag prefix character.

_argmatcher:setflagsanywhere
( anywhere:boolean ) : self
v1.3.12 and newer

When anywhere is false, flags are only recognized until an argument is encountered. Otherwise they are recognized anywhere (which is the default).

##### builder

builder:addmatch
( match:string|table, [type:string] ) : boolean
v1.0.0 and newer

Adds a match.

The match argument is the match string to add.

The type argument is the optional match type, or "none" if omitted (see below for the possible match types).

Alternatively, the match argument can be a table with the following scheme:

    {
        match           = "..."    -- [string] The match text.
        display         = "..."    -- [string] OPTIONAL; alternative text to display when listing possible completions.
        description     = "..."    -- [string] OPTIONAL; a description for the match.
        type            = "..."    -- [string] OPTIONAL; the match type.
        appendchar      = "..."    -- [string] OPTIONAL; character to append after the match.
        suppressappend  = t_or_f   -- [boolean] OPTIONAL; whether to suppress appending a character after the match.
    }

- The `display` field is optional, and is displayed instead of the `match` field when listing possible completions. It can even include ANSI escape codes for colors, etc. (Requires v1.2.38 or greater.)
- The `description` field is optional, and is displayed in addition to `match` or `display` when listing possible completions. (Requires v1.2.38 or greater.)
- The `type` field is optional. If omitted, then the type argument is used for that element.
- The `appendchar` field is optional, and overrides the normal behavior for only this match. (Requires v1.3.1 or greater.)
- The `suppressappend` field is optional, and overrides the normal behavior for only this match. (Requires v1.3.1 or greater.)

The match type affects how the match is inserted, displayed, and colored. Some type modifiers may be combined with a match type.

Type | Description
--- | ---
"word" | Shows the whole word even if it contains slashes.
"arg" | Avoids appending a space if the match ends with a colon or equal sign.
"command" | Displays the match using color.cmd.
"alias" | Displays the match using color.doskey.
"file" | Shows only the last path component, with appropriate file coloring.
"dir" | Shows only the last path component and adds a trailing path separator, with appropriate directory coloring.
"none" | For backward compatibility the match is treated like "file", unless it ends with a path separator in which case it's treated like "dir".

Modifier | Description
--- | ---
"hidden" | This can be combined with "file" or "dir" to use color.hidden (e.g. "file,hidden").
"readonly" | This can be combined with "file" or "dir" to use color.readonly (e.g. "file,readonly").
"link" | This can be combined with "file" or "dir" to appropriate symlink coloring (e.g. "file,link").
"orphaned" | This can be combined with "link" to use appropriate orphaned symlink coloring (e.g. "file,link,orphaned").

See Completion Colors and Color Settings for more information about colors.

    builder:addmatch("hello") -- type is "none"
    builder:addmatch("some_word", "word")
    builder:addmatch("/flag", "arg")
    builder:addmatch("abbrev", "alias")
    builder:addmatch({ match="foo.cpp", type="file" })
    builder:addmatch({ match="bar", type="dir" })
    builder:addmatch({ match=".git", type="dir,hidden" })

builder:addmatches
( matches:table, [type:string] ) : integer, boolean
v1.0.0 and newer

This is the equivalent of calling builder:addmatch() in a for-loop. Returns the number of matches added and a boolean indicating if all matches were added successfully.

The matches argument can be a table of match strings, or a table of tables describing the matches.

The type argument is used as the type when a match doesn't explicitly include a type, and is "none" if omitted.

    builder:addmatches({"abc", "def"}) -- Adds two matches of type "none"
    builder:addmatches({"abc", "def"}, "file") -- Adds two matches of type "file"
    builder:addmatches({
        -- Same table scheme per entry here as in builder:addmatch()
        { match="remote/origin/master", type="word" },
        { match="remote/origin/topic", type="word" }
    })

builder:isempty
() : boolean
v1.3.9 and newer

Returns whether the match builder is empty. It is empty when no matches have been added yet.

builder:setappendcharacter
( [append:string] ) : nil
v1.1.2 and newer

Sets character to append after matches. For example the `set` match generator uses this to append "=" when completing matches, so that completing `set USER` becomes `set USERDOMAIN=` (rather than `set USERDOMAIN` ).

builder:setnosort
() : nil
v1.3.3 and newer

Turns off sorting the matches.

builder:setsuppressappend
( [state:boolean] ) : nil
v1.1.2 and newer

Sets whether to suppress appending anything after the match except a possible closing quote. For example the env var match generator uses this.

builder:setsuppressquoting
( [state:integer] ) : nil
v1.1.2 and newer

Sets whether to suppress quoting for the matches. Set to 0 for normal quoting, or 1 to suppress quoting, or 2 to suppress end quotes. For example the env var match generator sets this to 1 to overcome the quoting that would normally happen for "%" characters in filenames.

##### clink

clink.argmatcher
( [priority:integer], commands...:string ) : _argmatcher
v1.0.0 and newer

Creates and returns a new argument matcher parser object. Use :addarg() and etc to add arguments, flags, other parsers, and more. See Argument Completion for more information.

If one command is provided and there is already an argmatcher for it, then this returns the existing parser rather than creating a new parser. Using :addarg() starts at arg position 1, making it possible to merge new args and etc into the existing parser.

Note: Merging linked argmatchers only merges the first argument position. The merge is simple, but should be sufficient for common simple cases.

clink.classifier
( [priority:integer] ) : table
v1.1.49 and newer

Creates and returns a new word classifier object. Define on the object a `:classify()` function which gets called in increasing priority order (low values to high values) when classifying words for coloring the input. See Coloring the Input Text for more information.

clink.dirmatches
( word:string ) : table
v1.1.18 and newer

You can use this function in an argmatcher to supply directory matches. This automatically handles Readline tilde completion.

    -- Make "cd" generate directory matches (no files).
    clink.argmatcher("cd")
    :addflags("/d")
    :addarg({ clink.dirmatches })

clink.filematches
( word:string ) : table
v1.1.18 and newer

You can use this function in an argmatcher to supply file matches. This automatically handles Readline tilde completion.

Argmatchers default to matching files, so it's unusual to need this function. However, some exceptions are when a flag needs to accept file matches but other flags and arguments don't, or when matches need to include more than files.

    -- Make "foo --file" generate file matches, but other flags and args don't.
    -- And the third argument can be a file or $stdin or $stdout.
    clink.argmatcher("foo")
    :addflags(
        "--help",
        "--file"..clink.argmatcher():addarg({ clink.filematches })
    )
    :addarg({ "one", "won" })
    :addarg({ "two", "too" })
    :addarg({ clink.filematches, "$stdin", "$stdout" })

clink.generator
( [priority:integer] ) : table
v1.0.0 and newer

Creates and returns a new match generator object. Define on the object a `:generate()` function which gets called in increasing priority order (low values to high values) when generating matches for completion. See Match Generators for more information.

clink.getansihost
() : string
v1.1.48 and newer

Returns a string indicating who Clink thinks will currently handle ANSI escape codes. This can change based on the `terminal.emulation` setting. This always returns `"unknown"` until the first edit prompt (see clink.onbeginedit()).

This can be useful in choosing what kind of ANSI escape codes to use, but it is a best guess and is not necessarily 100% reliable.

Return | Description
--- | ---
"unknown" | Clink doesn't know.
"clink" | Clink is emulating ANSI support. 256 color and 24 bit color escape codes are mapped to the nearest of the 16 basic colors.
"conemu" | Clink thinks ANSI escape codes will be handled by ConEmu.
"ansicon" | Clink thinks ANSI escape codes will be handled by ANSICON.
"winterminal" | Clink thinks ANSI escape codes will be handled by Windows Terminal.
"winconsole" | Clink thinks ANSI escape codes will be handled by the default console support in Windows, but Clink detected a terminal replacement that won't support 256 color or 24 bit color.
"winconsolev2" | Clink thinks ANSI escape codes will be handled by the default console support in Windows, or it might be handled by a terminal replacement that Clink wasn't able to detect.

clink.getargmatcher
( find:string|line_state ) : argmatcher|nil
v1.3.12 and newer

Finds the argmatcher registered to handle a command, if any.

When find is a string it is interpreted as the name of a command, and this looks up the argmatcher for the named command.

When find is a line_state this looks up the argmatcher for the command line.

If no argmatcher is found, this returns nil.

clink.getsession
() : string
v1.1.44 and newer

Returns the current Clink session id.

This is needed when using `io.popen()` (or similar functions) to invoke `clink history` or `clink info` while Clink is installed for autorun. The popen API spawns a new CMD.exe, which gets a new Clink instance injected, so the history or info command will use the new session unless explicitly directed to use the calling session.

    local c = os.getalias("clink")
    local r = io.popen(c.." --session "..clink.getsession().." history")

clink.lower
( text:string ) : string
v0.4.9 and newer

This API correctly converts UTF8 strings to lowercase, with international linguistic awareness.

    clink.lower("Hello World") -- returns "hello world"

clink.onaftercommand
( func:function ) : nil
v1.2.50 and newer

Registers func to be called after every editing command (key binding).

clink.onbeginedit
( func:function ) : nil
v1.1.11 and newer

Registers func to be called when Clink's edit prompt is activated. The function receives no arguments and has no return values.

clink.oncommand
( func:function ) : nil
v1.3.12 and newer

Registers func to be called when the command word changes in the edit line.

The function receives 2 arguments: the line_state for the command, and a table with the following scheme:

    {
        command =   -- [string] The command.
        quoted  =   -- [boolean] Whether the command is quoted in the command line.
        type    =   -- [string] "unrecognized", "executable", or "command" (a CMD command name).
        file    =   -- [string] The file that would be executed, or an empty string.
    }

The function has no return values.

clink.ondisplaymatches
( func:function ) : nil
v1.1.12 and newer

Registers func to be called when Clink is about to display matches. See Filtering the Match Display for more information.

    local function my_filter(matches, popup)
        local new_matches = {}
        for _,m in ipairs(matches) do
            if m.match:find("[0-9]") then
                -- Ignore matches with one or more digits.
            else
                -- Keep the match, and also add * prefix to directory matches.
                if m.type:find("^dir") then
                    m.display = "*"..m.match
                end
                table.insert(new_matches, m)
            end
        end
        return new_matches
    end

    function my_match_generator:generate(line_state, match_builder)
        ...
        clink.ondisplaymatches(my_filter)
    end

clink.onendedit
( func:function ) : nil
v1.1.20 and newer

Registers func to be called when Clink's edit prompt ends. The function receives a string argument containing the input text from the edit prompt.

Breaking Change in v1.2.16: The ability to replace the user's input has been moved to a separate onfilterinput event.

clink.onfilterinput
( func:function ) : nil
v1.2.16 and newer

Registers func to be called after Clink's edit prompt ends (it is called after the onendedit event). The function receives a string argument containing the input text from the edit prompt. The function returns up to two values. If the first is not nil then it's a string that replaces the edit prompt text. If the second is not nil and is false then it stops further onfilterinput handlers from running.

Starting in v1.3.13 func may return a table of strings, and each is executed as a command line.

Note: Be very careful if you replace the text; this has the potential to interfere with or even ruin the user's ability to enter command lines for CMD to process.

clink.onfiltermatches
( func:function ) : nil
v1.1.41 and newer

Registers func to be called after Clink generates matches for completion. See Filtering Match Completions for more information.

clink.oninject
( func:function ) : nil
v1.1.21 and newer

Registers func to be called when Clink is injected into a CMD process. The function is called only once per session.

clink.popuplist
( title:string, items:table, [index:integer] ) : string, boolean, integer
v1.2.17 and newer

Displays a popup list and returns the selected item. May only be used within a luafunc: key binding.

title is required and captions the popup list.

items is a table of strings to display.

index optionally specifies the default item (or 1 if omitted).

The function returns one of the following:

- nil if the popup is canceled or an error occurs.
- string indicating the `value` field from the selected item (or the `display` field if no value field is present).
- boolean which is true if the item was selected with `Shift` or `Ctrl` pressed.
- integer indicating the index of the selected item in the original items table.

Alternatively, the items argument can be a table of tables with the following scheme:

    {
        {
            value       = "...",   -- Required; this is returned if the item is chosen.
            display     = "...",   -- Optional; displayed instead of value.
            description = "...",   -- Optional; displayed in a dimmed color in a second column.
        },
        ...
    }

The `value` field is returned if the item is chosen.

The optional `display` field is displayed in the popup list instead of the `value` field.

The optional `description` field is displayed in a dimmed color in a second column. If it contains tab characters (`"\t"`) the description string is split into multiple columns (up to 3).

clink.print
( ... ) : nil
v1.2.11 and newer

This works like `print()`, but this supports ANSI escape codes.

If the special value `NONL` is included anywhere in the argument list then the usual trailing newline is omitted. This can sometimes be useful particularly when printing certain ANSI escape codes.

Note: In Clink versions before v1.2.11 the `clink.print()` API exists (undocumented) but accepts exactly one string argument and is therefore not fully compatible with normal `print()` syntax. If you use fewer or more than 1 argument or if the argument is not a string, then first checking the Clink version (e.g. clink.version_encoded) can avoid runtime errors.

    clink.print("\x1b[32mgreen\x1b[m \x1b[35mmagenta\x1b[m")
    -- Outputs green in green, a space, and magenta in magenta.

    local a = "hello"
    local world = 73
    clink.print("a", a, "world", world)
    -- Outputs a       hello   world   73.

    clink.print("hello", NONL)
    clink.print("world")
    -- Outputs helloworld.

clink.promptcoroutine
( func:function ) : [return value from func]
v1.2.10 and newer

Creates a coroutine to run the func function in the background. Clink will automatically resume the coroutine repeatedly while input line editing is idle. When the func function completes, Clink will automatically refresh the prompt by triggering prompt filtering again.

A coroutine is only created the first time each prompt filter calls this API during a given input line session. Subsequent calls reuse the already-created coroutine. (E.g. pressing `Enter` ends an input line session.)

The API returns nil until the func function has finished. After that, the API returns whatever the func function returned. The API returns one value; if multiple return values are needed, return them in a table.

If the `prompt.async` setting is disabled, then the coroutine runs to completion immediately before returning. Otherwise, the coroutine runs during idle while editing the input line. The func function receives one argument: true if it's running in the background, or false if it's running immediately.

See Asynchronous Prompt Filtering for more information.

Note: each prompt filter can have at most one prompt coroutine.

clink.promptfilter
( [priority:integer] ) : table
v1.0.0 and newer

Creates and returns a new promptfilter object that is applied in increasing priority order (low values to high values). Define on the object a `:filter()` function that takes a string argument which contains the filtered prompt so far. The function can return nil to have no effect, or can return a new prompt string. It can optionally stop further prompt filtering by also returning false. See Customizing the Prompt for more information.

    local foo_prompt = clink.promptfilter(80)
    function foo_prompt:filter(prompt)
        -- Insert the date at the beginning of the prompt.
        return os.date("%a %H:%M").." "..prompt
    end

clink.reclassifyline
() : nil
v1.3.9 and newer

Reclassify the input line text again and refresh the input line display.

clink.refilterprompt
() : nil
v1.2.46 and newer

Invoke the prompt filters again and refresh the prompt.

Note: this can potentially be expensive; call this only infrequently.

clink.reload
() : nil
v1.2.29 and newer

Reloads Lua scripts and Readline config file at the next prompt.

clink.runcoroutineuntilcomplete
( coroutine:coroutine ) : nil
v1.3.5 and newer

By default, a coroutine is canceled if it doesn't complete before an edit line ends. In some cases it may be necessary for a coroutine to run until it completes, even if it spans multiple edit lines.

Note: Use with caution. This can potentially cause performance problems or cause prompt filtering to experience delays.

clink.setcoroutineinterval
( coroutine:coroutine, [interval:number] ) : nil
v1.3.1 and newer

Overrides the interval at which a coroutine is resumed. All coroutines are automatically added with an interval of 0 by default, so calling this is only needed when you want to change the interval.

Coroutines are automatically resumed while waiting for input while editing the input line.

If a coroutine's interval is less than 5 seconds and the coroutine has been alive for more than 5 seconds, then the coroutine is throttled to run no more often than once every 5 seconds (regardless how much total time is has spent running). Throttling is meant to prevent long-running coroutines from draining battery power, interfering with responsiveness, or other potential problems.

clink.setcoroutinename
( coroutine:coroutine, name:string ) : nil
v1.3.1 and newer

Sets a name for the coroutine. This is purely for diagnostic purposes.

clink.suggester
( name:string ) : table
v1.2.47 and newer

Creates and returns a new suggester object. Suggesters are consulted in the order their names are listed in the `autosuggest.strategy` setting.

Define on the object a `:suggest()` function that takes a line_state argument which contains the input line, and a matches argument which contains the possible completions. The function can return nil to give the next suggester a chance, or can return a suggestion (or an empty string) to stop looking for suggestions.

In Clink v1.2.51 and higher, the function may return a suggestion and an offset where the suggestion begins in the line. This is useful if the suggester wants to be able to insert the suggestion using the original casing. For example if you type "set varn" and a history entry is "set VARNAME" then returning `"set VARNAME", 1` or `"VARNAME", 5` can accept "set VARNAME" instead of "set varnAME".

See Customizing Suggestions for more information.

    local doskeyarg = clink.suggester("doskeyarg")
    function doskeyarg:suggest(line, matches)
        if line:getword(1) == "doskey" and
                line:getline():match("[ \t][^ \t/][^ \t]+=") and
                not line:getline():match("%$%*") then
            -- If the line looks like it defines a macro and doesn't yet add all
            -- arguments, suggest adding all arguments.
            if line:getline():sub(#line:getline()) == " " then
                return "$*"
            else
                return " $*"
            end
        end
    end

clink.translateslashes
( [mode:integer] ) : integer
v1.2.7 and newer

This overrides how Clink translates slashes in completion matches, which is normally determined by the `match.translate_slashes` setting.

This is reset every time match generation is invoked, so use a generator to set this.

The mode specifies how to translate slashes when generators add matches:

Mode | Description
--- | ---
`0` | No translation.
`1` | Translate using the system path separator (backslash on Windows).
`2` | Translate to slashes (`/`).
`3` | Translate to backslashes (`\`).

If mode is omitted, then the function returns the current slash translation mode without changing it.

Note: Clink always generates file matches using the system path separator (backslash on Windows), regardless what path separator may have been typed as input. Setting this to `0` does not disable normalizing typed input paths when invoking completion; it only disables translating slashes in custom generators.

    -- This example affects all match generators, by using priority -1 to
    -- run first and returning false to let generators continue.
    -- To instead affect only one generator, call clink.translateslashes()
    -- in its :generate() function and return true.
    local force_slashes = clink.generator(-1)
    function force_slashes:generate()
        clink.translateslashes(2)  -- Convert to slashes.
        return false               -- Allow generators to continue.
    end

clink.upper
( text:string ) : string
v1.1.5 and newer

This API correctly converts UTF8 strings to uppercase, with international linguistic awareness.

    clink.upper("Hello World") -- returns "HELLO WORLD"

clink.version_commit
string variable
v1.1.10 and newer

The commit part of the Clink version number. For v1.2.3.a0f14d the commit part is a0f14d.

clink.version_encoded
integer variable
v1.1.10 and newer

The Clink version number encoded as a single integer following the format Mmmmpppp where M is the major part, m is the minor part, and p is the patch part of the version number.

For example, Clink v95.6.723 would be `950060723`.

This format makes it easy to test for feature availability by encoding version numbers from the release notes.

clink.version_major
integer variable
v1.1.10 and newer

The major part of the Clink version number. For v1.2.3.a0f14d the major version is 1.

clink.version_minor
integer variable
v1.1.10 and newer

The minor part of the Clink version number. For v1.2.3.a0f14d the minor version is 2.

clink.version_patch
integer variable
v1.1.10 and newer

The patch part of the Clink version number. For v1.2.3.a0f14d the patch version is 3.

##### console

console.cellcount
( text:string ) : integer
v1.2.5 and newer

Returns the count of visible character cells that would be consumed if the text string were output to the console, accounting for any ANSI escape codes that may be present in the text.

Note: backspace characters and line endings are counted as visible character cells and will skew the resulting count.

console.findnextline
( starting_line:integer, [text:string], [mode:string], [attr:integer], [attrs:table of integers], [mask:string] ) : integer
v1.1.21 and newer

Searches downwards (forwards) for a line containing the specified text and/or attributes, starting at line starting_line. The matching line number is returned, or 0 if no matching line is found.

This behaves the same as console.findprevline() except that it searches in the opposite direction.

console.findprevline
( starting_line:integer, [text:string], [mode:string], [attr:integer], [attrs:table of integers], [mask:string] ) : integer
v1.1.21 and newer

Searches upwards (backwards) for a line containing the specified text and/or attributes, starting at line starting_line. The matching line number is returned, or 0 if no matching line is found, or -1 if an invalid regular expression is provided.

You can search for text, attributes, or both. Include the text argument to search for text, and include either the attr or attrs argument to search for attributes. If both text and attribute(s) are passed, then the attribute(s) must be found within the found text. If only attribute(s) are passed, then they must be found anywhere in the line. See console.linehascolor() for more information about the color codes.

The mode argument selects how the search behaves. To use a regular expression, pass "regex". To use a case insensitive search, pass "icase". These can be combined by separating them with a comma. The regular expression syntax is the ECMAScript syntax described here.

Any trailing whitespace is ignored when searching. This especially affects the `$` (end of line) regex operator.

mask is optional and can be "fore" or "back" to only match foreground or background colors, respectively.

Note: Although most of the arguments are optional, the order of provided arguments is important.

For more information, see this example of using this in some luafunc: macros.

console.getheight
() : integer
v1.1.20 and newer

Returns the number of visible lines of the console screen buffer.

console.getlinetext
( line:integer ) : string
v1.1.20 and newer

Returns the text from line number line, from 1 to console.getnumlines().

Any trailing whitespace is stripped before returning the text.

console.getnumlines
() : integer
v1.1.20 and newer

Returns the total number of lines in the console screen buffer.

console.gettitle
() : string
v1.1.32 and newer

Returns the console title text.

console.gettop
() : integer
v1.1.20 and newer

Returns the current top line (scroll position) in the console screen buffer.

console.getwidth
() : integer
v1.1.20 and newer

Returns the width of the console screen buffer in characters.

console.islinedefaultcolor
( line:integer ) : boolean
v1.1.20 and newer

Returns whether line number line uses only the default text color.

console.linehascolor
( line:integer, [attr:integer], [attrs:table of integers], [mask:string] ) : boolean
v1.1.21 and newer

Returns whether line number line contains the DOS color code attr, or any of the DOS color codes in attrs (either an integer or a table of integers must be provided, but not both). mask is optional and can be "fore" or "back" to only match foreground or background colors, respectively.

The low 4 bits of the color code are the foreground color, and the high 4 bits of the color code are the background color. This refers to the default 16 color palette used by console windows. When 256 color or 24-bit color ANSI escape codes have been used, the closest of the 16 colors is used.

To build a color code, add the corresponding Foreground color and the Background color values from this table:

Foreground | Background | Color
--- | --- | ---
0 | 0 | Black
1 | 16 | Dark Blue
2 | 32 | Dark Green
3 | 48 | Dark Cyan
4 | 64 | Dark Red
5 | 80 | Dark Magenta
6 | 96 | Dark Yellow
7 | 112 | Gray
8 | 128 | Dark Gray
9 | 144 | Bright Blue
10 | 160 | Bright Green
11 | 176 | Bright Cyan
12 | 192 | Bright Red
13 | 208 | Bright Magenta
14 | 224 | Bright Yellow
15 | 240 | White

console.plaintext
( text:string ) : string, integer
v1.2.5 and newer

Returns the input text with ANSI escape codes removed, and the count of visible character cells that would be consumed if the text were output to the console.

Note: backspace characters and line endings are counted as visible character cells and will skew the resulting count.

console.readinput
() : string | nil
v1.2.29 and newer

Reads one key sequence from the console input. If no input is available, it waits until input becomes available.

This returns the full key sequence string for the pressed key. For example, `A` is `"A"` and `Home` is `"\027[A"`, etc.

See Discovering Key Sequences for information on how to find the key sequence for a key.

console.screengrab
( candidate_pattern:string, accept_pattern:string ) : table
v1.1.40 and newer

Uses the provided Lua string patterns to collect text from the current console screen and returns a table of matching text snippets. The snippets are ordered by distance from the input line.

For example candidate_pattern could specify a pattern that identifies words, and accept_pattern could specify a pattern that matches words composed of hexadecimal digits.

    local matches = console.screengrab(
            "[^%w]*(%w%w[%w]+)",   -- Words with 3 or more letters are candidates.
            "^%x+$")               -- A candidate containing only hexadecimal digits is a match.

console.scroll
( mode:string, amount:integer ) : integer
v1.1.20 and newer

Scrolls the console screen buffer and returns the number of lines scrolled up (negative) or down (positive).

The mode specifies how to scroll:

Mode | Description
--- | ---
"line" | Scrolls by amount lines; negative is up and positive is down.
"page" | Scrolls by amount pages; negative is up and positive is down.
"end" | Scrolls to the top if amount is negative, or to the bottom if positive.
"absolute" | Scrolls to line amount, from 1 to console.getnumlines().

console.settitle
( title:string ) : nil
v1.1.32 and newer

Sets the console title text.

##### io

io.popenrw
( command:string, [mode:string] ) : file, file
v1.1.42 and newer

Runs `command` and returns two file handles: a file handle for reading output from the command, and a file handle for writing input to the command.

mode can be "t" for text mode (the default if omitted) or "b" for binary mode.

If the function fails it returns nil, an error message, and an error number.

Warning This can result in deadlocks unless the command fully reads all of its input before writing any output. This is because Lua uses blocking IO to read and write file handles. If the write buffer fills (or the read buffer is empty) then the write (or read) will block and can only become unblocked if the command correspondingly reads (or writes). But the other command can easily experience the same blocking IO problem on its end, resulting in a deadlock: process 1 is blocked from writing more until process 2 reads, but process 2 can't read because it is blocked from writing until process 1 reads.

    local r,w = io.popenrw("fzf.exe --height 40%")

    w:write("hello\n")
    w:write("world\n")
    w:close()

    while (true) do
        local line = r:read("*line")
        if not line then
            break
        end
        print(line)
    end
    r:close()

io.popenyield
( command:string, [mode:string] ) : file
v1.2.10 and newer

This is the same as `io.popen(command, mode)` except that it only supports read mode and it yields until the command has finished:

Runs command and returns a read file handle for reading output from the command. It yields until the command has finished and the complete output is ready to be read without blocking.

The mode can contain "r" (read mode) and/or either "t" for text mode (the default if omitted) or "b" for binary mode. Write mode is not supported, so it cannot contain "w".

Note: if the `prompt.async` setting is disabled, or while a transient prompt filter is executing, then this behaves like `io.popen(command, mode)` instead.

    local file = io.popenyield("git status")

    while (true) do
        local line = file:read("*line")
        if not line then
            break
        end
        do_things_with(line)
    end
    file:close()

##### line_state

line_state:getcommandoffset
() : integer
v1.0.0 and newer

Returns the offset to the start of the delimited command in the line that's being effectively edited. Note that this may not be the offset of the first command of the line unquoted as whitespace isn't considered for words.

    -- Given the following line; abc&123
    -- where commands are separated by & symbols.
    line_state:getcommandoffset() == 5

The command offset points to the beginning of the command, but that might be a space character. Two spaces after a command separator is like one space at the beginning of a line; it disables doskey alias expansion. So, if the command offset points at a space, then you know the first word will not be treated as a doskey alias.

    -- Given the following line; abc&  123
    -- where commands are separated by & symbols.
    line_state:getcommandoffset() == 6

line_state:getcommandwordindex
() : integer
v1.2.27 and newer

Returns the index of the command word. Usually the index is 1, but if a redirection symbol occurs before the command name then the index can be greater than 1.

    -- Given the following line; >x abc
    -- the first word is "x" and is an argument to the redirection symbol,
    -- and the second word is "abc" and is the command word.
    line_state:getcommandwordindex() == 2

line_state:getcursor
() : integer
v1.0.0 and newer

Returns the position of the cursor.

line_state:getendword
() : string
v1.0.0 and newer

Returns the last word of the line. This is the word that matches are being generated for.

Note: The returned word omits any quotes. This helps generators naturally complete `"foo\"ba` to `"foo\bar"`. The raw word including quotes can be obtained using the `offset` and `length` fields from line_state:getwordinfo() to extract a substring from the line returned by line_state:getline().

    line_state:getword(line_state:getwordcount()) == line_state:getendword()

line_state:getline
() : string
v1.0.0 and newer

Returns the current line in its entirety.

line_state:getword
( index:integer ) : string
v1.0.0 and newer

Returns the word of the line at index.

Note: The returned word omits any quotes. This helps generators naturally complete `"foo\"ba` to `"foo\bar"`. The raw word including quotes can be obtained using the `offset` and `length` fields from line_state:getwordinfo() to extract a substring from the line returned by line_state:getline().

line_state:getwordcount
() : integer
v1.0.0 and newer

Returns the number of words in the current line.

line_state:getwordinfo
( index:integer ) : table
v1.0.0 and newer

Returns a table of information about the Nth word in the line.

Note: The length refers to the substring in the line; it omits leading and trailing quotes, but includes embedded quotes. line_state:getword() conveniently strips embedded quotes to help generators naturally complete `"foo\"ba` to `"foo\bar"`.

The table returned has the following scheme:

    local t = line_state:getwordinfo(word_index)
    -- t.offset     [integer] Offset where the word starts in the line_state:getline() string.
    -- t.length     [integer] Length of the word (includes embedded quotes).
    -- t.quoted     [boolean] Indicates whether the word is quoted.
    -- t.delim      [string] The delimiter character, or an empty string.
    -- t.alias      [boolean | nil] true if the word is a doskey alias, otherwise nil.
    -- t.redir      [boolean | nil] true if the word is a redirection arg, otherwise nil.

##### log

log.info
( message:string ) : nil
v1.1.3 and newer

Writes info message to the Clink log file. Use this sparingly, or it could cause performance problems or disk space problems.

##### matches

matches:getcount
() : integer
v1.2.47 and newer

Returns the number of available matches.

matches:getmatch
( index:integer ) : string
v1.2.47 and newer

Returns the match text for the index match.

matches:getprefix
() : string
v1.2.47 and newer

Returns the longest common prefix of the available matches.

##### matches_lua

matches_lua:gettype
( index:integer ) : string
v1.2.47 and newer

Returns the match type for the index match.

##### os

os.chdir
( path:string ) : boolean
v1.0.0 and newer

Changes the current directory to path and returns whether it was successful.

os.clock
() : number
v1.2.30 and newer

This returns the number of seconds since the program started.

Normally, Lua's os.clock() has millisecond precision until the program has been running for almost 25 days, and then it suddenly breaks and starts always returning -0.001 seconds.

Clink's version of os.clock() has microsecond precision until the program has been running for many weeks. It maintains at least millisecond precision until the program has been running for many years.

It was necessary to replace os.clock() in order for asynchronous prompt filtering to continue working when CMD has been running for more than 25 days.

os.copy
( src:string, dest:string ) : boolean
v1.0.0 and newer

Copies the src file to the dest file.

os.createtmpfile
( [prefix:string], [ext:string], [path:string], [mode:string] ) : file, string
v1.1.42 and newer

Creates a uniquely named file, intended for use as a temporary file. The name pattern is "location `\` prefix `_` processId `_` uniqueNum extension".

prefix optionally specifies a prefix for the file name and defaults to "tmp".

ext optionally specifies a suffix for the file name and defaults to "" (if ext starts with a period "." then it is a filename extension).

path optionally specifies a path location in which to create the file. The default is the system TEMP directory.

mode optionally specifies "t" for text mode (line endings are translated) or "b" for binary mode (untranslated IO). The default is "t".

When successful, the function returns a file handle and the file name.

Note: Be sure to delete the file when finished, or it will be leaked.

If the function is unable to create a file it returns nil, an error message, and an error number. For example if the directory is inaccessible, or if there are already too many files, or invalid file name characters are used, or etc.

os.debugprint
( ... ) : nil
v1.2.20 and newer

This works like `print()` but writes the output via the OS `OutputDebugString()` API.

This function has no effect if the `lua.debug` Clink setting is off.

    clink.debugprint("my variable = "..myvar)

os.expandenv
( value:string ) : string
v1.2.5 and newer

Returns value with any `%name%` environment variables expanded. Names are case insensitive. Special CMD syntax is not supported (e.g. `%name:str1=str2%` or `%name:~offset,length%`).

Note: See os.getenv() for a list of special variable names.

os.getalias
( name:string ) : string | nil
v1.1.4 and newer

Returns command string for doskey alias name, or nil if the named alias does not exist.

os.getaliases
() : table
v1.0.0 and newer

Returns doskey alias names in a table of strings.

os.getbatterystatus
() : table
v1.1.17 and newer

Returns a table containing the battery status for the device, or nil if an error occurs. The returned table has the following scheme:

    local t = os.getbatterystatus()
    -- t.level              [integer] The battery life from 0 to 100, or -1 if error or no battery.
    -- t.acpower            [boolean] Whether the device is connected to AC power.
    -- t.charging           [boolean] Whether the battery is charging.
    -- t.batterysaver       [boolean] Whether Battery Saver mode is active.

os.getclipboardtext
() : string | nil
v1.2.32 and newer

This returns the text from the system clipboard, or nil if there is no text on the system clipboard.

os.getcwd
() : string
v1.0.0 and newer

Returns the current directory.

os.getenv
( name:string ) : string | nil
v1.0.0 and newer

Returns the value of the named environment variable, or nil if it doesn't exist.

Note: Certain environment variable names receive special treatment:

Name | Special Behavior
--- | ---
`"HOME"` | If %HOME% is not set then a return value is synthesized from %HOMEDRIVE% and %HOMEPATH%, or from %USERPROFILE%.
`"ERRORLEVEL"` | When the `cmd.get_errorlevel` setting is enabled (it is off by default) this returns the most recent exit code, just like the `echo %ERRORLEVEL%` command displays. Otherwise this returns 0.

os.getenvnames
() : table
v1.0.0 and newer

Returns all environment variables in a table with the following scheme:

    local t = os.getenvnames()
    -- t[index].name        [string] The environment variable's name.
    -- t[index].value       [string] The environment variable's value.

os.geterrorlevel
() : integer
v1.2.14 and newer

Returns the last command's exit code, if the `cmd.get_errorlevel` setting is enabled (it is disabled by default). Otherwise it returns 0.

os.getfullpathname
( path:string ) : string
v1.1.42 and newer

Returns the full path name for path.

os.gethost
() : string
v1.0.0 and newer

Returns the fully qualified file name of the host process. Currently only CMD.EXE can host Clink.

os.getlongpathname
( path:string ) : string
v1.1.42 and newer

Returns the long path name for path.

os.getnetconnectionname
( path:string ) : string
v1.2.27 and newer

Returns the remote name associated with path, or an empty string if it's not a network drive.

os.getpid
() : integer
v1.1.41 and newer

Returns the CMD.EXE process ID. This is mainly intended to help with salting unique resource names (for example named pipes).

os.getscreeninfo
() : table
v1.1.2 and newer

Returns dimensions of the terminal's buffer and visible window. The returned table has the following scheme:

    local info = os.getscreeninfo()
    -- info.bufwidth        [integer] Width of the screen buffer.
    -- info.bufheight       [integer] Height of the screen buffer.
    -- info.winwidth        [integer] Width of the visible window.
    -- info.winheight       [integer] Height of the visible window.

os.getshortpathname
( path:string ) : string
v1.1.42 and newer

Returns the 8.3 short path name for path. This may return the input path if an 8.3 short path name is not available.

os.globdirs
( globpattern:string, [extrainfo:integer|boolean] ) : table
v1.0.0 and newer

Collects directories matching globpattern and returns them in a table of strings.

The optional extrainfo argument can return a table of tables instead, where each sub-table corresponds to one directory and has the following scheme:

    local t = os.globdirs(pattern, extrainfo)
    -- Included when extrainfo is true or >= 1:
    --   t[index].name      -- [string] The directory name.
    --   t[index].type      -- [string] The match type (see below).
    -- Included when extrainfo is 2:
    --   t[index].size      -- [number] The file size, in bytes.
    --   t[index].atime     -- [number] The access time, compatible with os.time().
    --   t[index].mtime     -- [number] The modified time, compatible with os.time().
    --   t[index].ctime     -- [number] The creation time, compatible with os.time().

The type string is "dir", and may also contain ",hidden", ",readonly", ",link", and ",orphaned" depending on the attributes (making it usable as a match type for builder:addmatch()).

Starting in v1.3.1, when this is used in a coroutine it automatically yields periodically.

Note: any quotation marks (`"`) in globpattern are stripped.

os.globfiles
( globpattern:string, [extrainfo:integer|boolean] ) : table
v1.0.0 and newer

Collects files and/or directories matching globpattern and returns them in a table of strings.

The optional extrainfo argument can return a table of tables instead, where each sub-table corresponds to one file or directory and has the following scheme:

    local t = os.globfiles(pattern, extrainfo)
    -- Included when extrainfo is true or >= 1:
    --   t[index].name      -- [string] The directory name.
    --   t[index].type      -- [string] The match type (see below).
    -- Included when extrainfo is 2:
    --   t[index].size      -- [number] The file size, in bytes.
    --   t[index].atime     -- [number] The access time, compatible with os.time().
    --   t[index].mtime     -- [number] The modified time, compatible with os.time().
    --   t[index].ctime     -- [number] The creation time, compatible with os.time().

The type string can be "file" or "dir", and may also contain ",hidden", ",readonly", ",link", and ",orphaned" depending on the attributes (making it usable as a match type for builder:addmatch()).

Starting in v1.3.1, when this is used in a coroutine it automatically yields periodically.

Note: any quotation marks (`"`) in globpattern are stripped.

os.isdir
( path:string ) : boolean
v1.0.0 and newer

Returns whether path is a directory.

os.isfile
( path:string ) : boolean
v1.0.0 and newer

Returns whether path is a file.

os.issignaled
() : boolean
v1.3.14 and newer

Returns whether a Ctrl+`Break` has been received. Scripts may use this to decide when to end work early.

os.mkdir
( path:string ) : boolean
v1.0.0 and newer

Creates the directory path and returns whether it was successful.

os.move
( src:string, dest:string ) : boolean
v1.0.0 and newer

Moves the src file to the dest file.

os.resolvealias
( text:string ) : table|nil
v1.3.12 and newer

Identifies whether text begins with a doskey alias, and expands the doskey alias.

Returns a table of strings, or nil if there is no associated doskey alias. The return type is a table of strings because doskey aliases can be defined to expand into multiple command lines: one entry in the table per resolved command line. Most commonly, the table will contain one string.

os.rmdir
( path:string ) : boolean
v1.0.0 and newer

Removes the directory path and returns whether it was successful.

os.setclipboardtext
() : boolean
v1.2.32 and newer

This sets the text onto the system clipboard, and returns whether it was successful.

os.setenv
( name:string, value:string ) : boolean
v1.0.0 and newer

Sets the name environment variable to value and returns whether it was successful.

os.touch
( path:string, [atime:number], [mtime:number] ) : nil
v1.2.31 and newer

Sets the access and modified times for path.

The second argument is atime and is a time to set as the file's access time. If omitted, the current time is used. If present, the value must use the same format as `os.time()`.

The third argument is mtime and is a time to set as the file's modified time. If omitted, the atime value is used (or the current time). If present, the value must use the same format as `os.time()`. In order to pass mtime it is necessary to also pass atime.

os.unlink
( path:string ) : boolean
v1.0.0 and newer

Deletes the file path and returns whether it was successful.

##### path

path.getbasename
( path:string ) : string
v1.1.0 and newer

    path.getbasename("/foo/bar.ext")    -- returns "bar"
    path.getbasename("")                -- returns ""
    path.getbasename(nil)               -- returns nil

path.getdirectory
( path:string ) : nil or string
v1.1.0 and newer

This is similar to path.toparent() but can behave differently when the input path ends with a path separator. This is the recommended API for parsing a path into its component pieces, but is not recommended for walking up through parent directories.

    path.getdirectory("foo")                -- returns nil
    path.getdirectory("\foo")               -- returns "\"
    path.getdirectory("c:foo")              -- returns "c:"
    path.getdirectory([[c:\]])              -- returns "c:\"
    path.getdirectory("c:\foo")             -- returns "c:\"
    path.getdirectory("c:\foo\bar")         -- returns "c:\foo"
    path.getdirectory("\\foo\bar")          -- returns "\\foo\bar"
    path.getdirectory("\\foo\bar\dir")      -- returns "\\foo\bar"
    path.getdirectory("")                   -- returns nil
    path.getdirectory(nil)                  -- returns nil

    -- These split the path components differently than path.toparent().
    path.getdirectory([[c:\foo\bar\]])      -- returns "c:\foo\bar"
    path.getdirectory([[\\foo\bar\dir\]])   -- returns "\\foo\bar\dir"

path.getdrive
( path:string ) : nil or string
v1.1.0 and newer

    path.getdrive("e:/foo/bar")     -- returns "e:"
    path.getdrive("foo/bar")        -- returns nil
    path.getdrive("")               -- returns nil
    path.getdrive(nil)              -- returns nil

path.getextension
( path:string ) : string
v1.1.0 and newer

    path.getextension("bar.ext")    -- returns ".ext"
    path.getextension("bar")        -- returns ""
    path.getextension("")           -- returns ""
    path.getextension(nil)          -- returns nil

path.getname
( path:string ) : string
v1.1.0 and newer

    path.getname("/foo/bar.ext")    -- returns "bar.ext"
    path.getname("")                -- returns ""
    path.getname(nil)               -- returns nil

path.isexecext
( path:string ) : boolean
v1.1.5 and newer

Examines the extension of the path name. Returns true if the extension is listed in %PATHEXT%. This caches the extensions in a map so that it's more efficient than getting and parsing %PATHEXT% each time.

    path.isexecext("program.exe")   -- returns true
    path.isexecext("file.doc")      -- returns false
    path.isexecext("")              -- returns false
    path.isexecext(nil)             -- returns nil

path.join
( left:string, right:string ) : string
v1.1.0 and newer

    path.join("/foo", "bar")    -- returns "/foo\bar"
    path.join("", "bar")        -- returns "bar"
    path.join("/foo", "")       -- returns "/foo\"
    path.join(nil, "bar")       -- returns nil
    path.join("/foo", nil)      -- returns nil

path.normalise
( path:string, [separator:string] ) : string
v1.1.0 and newer

Cleans path by normalising separators and removing "." and ".." elements. If separator is provided it is used to delimit path elements, otherwise a system-specific delimiter is used.

    path.normalise("a////b/\\/c/")  -- returns "a\b\c\"
    path.normalise("")              -- returns ""
    path.normalise(nil)             -- returns nil

path.toparent
( path:string ) : parent:string, child:string
v1.1.20 and newer

Splits the last path component from path, if possible. Returns the result and the component that was split, if any.

This is similar to path.getdirectory() but can behave differently when the input path ends with a path separator. This is the recommended API for walking up through parent directories.

    local parent,child
    parent,child = path.toparent("foo")             -- returns "", "foo"
    parent,child = path.toparent("\foo")            -- returns "\", "foo"
    parent,child = path.toparent("c:foo")           -- returns "c:", "foo"
    parent,child = path.toparent([[c:\]])           -- returns "c:\", ""
    parent,child = path.toparent("c:\foo")          -- returns "c:\", "foo"
    parent,child = path.toparent("c:\foo\bar")      -- returns "c:\foo", "bar"
    parent,child = path.toparent("\\foo\bar")       -- returns "\\foo\bar", ""
    parent,child = path.toparent("\\foo\bar\dir")   -- returns "\\foo\bar", "dir"
    parent,child = path.toparent("")                -- returns "", ""
    parent,child = path.toparent(nil)               -- returns nil

    -- These split the path components differently than path.getdirectory().
    parent,child = path.toparent([[c:\foo\bar\]])   -- returns "c:\foo", "bar"
    parent,child = path.toparent([[\\foo\bar\dir\]])-- returns "\\foo\bar", "dir"

##### rl

rl.collapsetilde
( path:string, [force:boolean] ) : string
v1.1.6 and newer

Undoes Readline tilde expansion. See rl.expandtilde for more information.

    rl.collapsetilde("C:\Users\yourusername\Documents")

    -- The return value depends on the expand-tilde configuration variable:
    -- When "on", the function returns "C:\Users\yourusername\Documents".
    -- When "off", the function returns "~\Documents".

    -- Or when force is true, the function returns "~\Documents".

rl.expandtilde
( path:string ) : string, boolean
v1.1.6 and newer

Performs Readline tilde expansion.

When generating filename matches for a word, use the rl.expandtilde and rl.collapsetilde helper functions to perform tilde completion expansion according to Readline's configuration.

Use rl.expandtilde to do tilde expansion before collecting file matches (e.g. via os.globfiles). If it indicates that it expanded the string, then use rl.collapsetilde to put back the tilde before returning a match.

    local result, expanded = rl.expandtilde("~\Documents")
    -- result is "C:\Users\yourusername\Documents"
    -- expanded is true

    -- This dir_matches function demonstrates efficient use of rl.expandtilde()
    -- and rl.collapsetilde() to generate directory matches from the file system.
    function dir_matches(match_word, word_index, line_state)
        -- Expand tilde before scanning file system.
        local word = line_state:getword(word_index)
        local expanded
        word, expanded = rl.expandtilde(word)

        -- Get the directory from 'word', and collapse tilde before generating
        -- matches.  Notice that collapsetilde() only needs to be called once!
        local root = path.getdirectory(word) or ""
        if expanded then
            root = rl.collapsetilde(root)
        end

        local matches = {}
        for _, d in ipairs(os.globdirs(word.."*", true)) do
            -- Join the filename with the input directory (might have a tilde).
            local dir = path.join(root, d.name)
            table.insert(matches, { match = dir, type = d.type })
        end
        return matches
    end

rl.getbinding
( key:string, [keymap:string] ) : binding:string, type:string
v1.2.46 and newer

Returns the command or macro bound to key, and the type of the binding.

If nothing is bound to the specified key sequence, the returned binding will be nil.

The returned type can be `"function"`, `"macro"`, or `"keymap"` (if key is an incomplete key sequence).

If an error occurs, only nil is returned.

The key sequence string is the same format as from `clink echo`. See Discovering Clink key sindings for more information.

An optional keymap may be specified as well. If it is omitted or nil, then the current keymap is searched. Otherwise it may refer to one of the three built in keymaps:

Keymap | Description
--- | ---
`"emacs"` | The Emacs keymap, which is the default keymap.
`"vi"`, `"vi-move"`, or `"vi-command"` | The VI command mode keymap.
`"vi-insert"` | The VI insertion mode keymap.

The return value can be passed as input to rl.setbinding() or rl.invokecommand().

    local b,t = rl.getbinding([["\e[H"]], "emacs")
    if b then
        print("Home is bound to "..b.." ("..t..") in emacs mode.")
    else
        print("Home is not bound in emacs mode.")
    end

rl.getkeybindings
( raw:boolean, [mode:integer] ) : table
v1.2.16 and newer

Returns key bindings in a table with the following scheme:

    local t = rl.getkeybindings()
    -- t[index].key         [string] Key name.
    -- t[index].binding     [string] Command or macro bound to the key.
    -- t[index].desc        [string] Description of the command.
    -- t[index].category    [string] Category of the command.

When raw is true, the key names are the literal key sequences without being converted to user-friendly key names.

The optional mode specifies bit flags that control how the returned table is sorted, and whether it includes commands that are not bound to any key.

Mode | Description
--- | ---
0 | Key bindings, sorted by key (this is the default).
1 | Key bindings, sorted by category and then key.
4 | All commands, sorted by key.
5 | All commands, sorted by category and then key.

The following example demonstrates using this function in a luafunc: key binding to invoke clink.popuplist() to show a searchable list of key bindings, and then invoke whichever key binding is selected.

    function luafunc_showkeybindings(rl_buffer)
        local bindings = rl.getkeybindings()
        if #bindings <= 0 then
            rl_buffer:refreshline()
            return
        end

        local items = {}
        for _,kb in ipairs(bindings) do
            table.insert(items, {
                value = kb.binding,     -- Return the binding when selected, so it can be invoked.
                display = kb.key,       -- Display the key name.
                description = kb.binding.."\t"..kb.desc -- Also display the command and description.
            })
        end

        -- Show a popup that lists the items from above.
        local binding, _, index = clink.popuplist("Key Bindings", items)
        rl_buffer:refreshline()
        if binding then
            -- Invoke the selected binding (a command or macro).
            rl.invokecommand(binding)
        end
    end

rl.getlastcommand
() : string, function
v1.1.40 and newer

Returns two values:

- The name of the last Readline command invoked by a key binding.
- The name of the last Lua function invoked by a key binding.

If the last key binding invoked a Lua function, then the first return value is an empty string unless the Lua function used rl.invokecommand() to also internally invoke a Readline command. If the last key binding did not invoke a Lua function, then the second return value is an empty string.

    local last_rl_func, last_lua_func = rl.getlastcommand()

rl.getmatchcolor
( match:string|table, [type:string] ) : string
v1.3.4 and newer

Returns the color string associated with the match.

The arguments are the same as in builder:addmatch().

rl.getpromptinfo
() : table
v1.2.28 and newer

Returns information about the current prompt and input line.

Note: the promptline and inputline fields may be skewed if any additional terminal output has occurred (for example if any `print()` calls have happened, or if `rl.getpromptinfo()` is used inside a clink.onendedit() event handler, or any other output that the Readline library wouldn't know about).

The returned table has the following scheme:

    local info = rl.getpromptinfo()
    -- info.promptprefix              [string] The prompt string, minus the last line of the prompt string.
    -- info.promptprefixlinecount     [integer] Number of lines in the promptprefix string.
    -- info.prompt                    [string] The last line of the prompt string.
    -- info.rprompt                   [string or nil] The right side prompt (or nil if none).
    -- info.promptline                [integer] Console line on which the prompt starts.
    -- info.inputline                 [integer] Console line on which the input text starts.
    -- info.inputlinecount            [integer] Number of lines in the input text.

rl.getvariable
( name:string ) : string | nil
v1.1.6 and newer

Returns the value of the named Readline configuration variable as a string, or nil if the variable name is not recognized.

rl.insertmode
( [insert:boolean] ) : boolean
v1.2.50 and newer

Returns true when typing insertion mode is on.

When the optional insert argument is passed, this also sets typing insertion mode on or off accordingly.

rl.invokecommand
( command:string, [count:integer] ) : boolean | nil
v1.1.26 and newer

Invokes a Readline command named command. May only be used within a luafunc: key binding.

count is optional and defaults to 1 if omitted.

Returns true if the named command succeeds, false if the named command fails, or nil if the named command doesn't exist.

Warning: Invoking more than one Readline command in a luafunc: key binding could have unexpected results, depending on which commands are invoked.

rl.ismodifiedline
() : boolean
v1.2.51 and newer

Returns true when the current input line is a history entry that has been modified (i.e. has an undo list).

This enables prompt filters to show a "modmark" of their own, as an alternative to the modmark shown when the `mark-modified-lines` Readline config setting is enabled.

The following sample illustrates a prompt filter that shows a "modified line" indicator when the current line is a history entry and has been modified.

    local p = clink.promptfilter(10)
    local normal = "\x1b[m"

    local function get_settings_color(name)
    return "\x1b[" .. settings.get(name) .. "m"
    end

    function p:filter(prompt)
        prompt = os.getcwd()
        if rl.ismodifiedline() then
            -- If the current line is a history entry and has been modified,
            -- then show an indicator.
            prompt = get_settings_color("color.modmark") .. "*" .. normal .. " " .. prompt
        end
        prompt = prompt .. "\n$ "
        return prompt
    end

    local last_modmark = false

    local function modmark_reset()
        -- Reset the remembered state at the beginning of each edit line.
        last_modmark = rl.ismodifiedline()

        -- Turn off `mark-modified-lines` to avoid two modmarks showing up.
        rl.setvariable("mark-modified-lines", "off")
    end

    local function modmark_refilter()
        -- If the modmark state has changed, refresh the prompt.
        if last_modmark ~= rl.ismodifiedline() then
            last_modmark = rl.ismodifiedline()
            clink.refilterprompt()
        end
    end

    clink.onbeginedit(modmark_reset)
    clink.onaftercommand(modmark_refilter)

rl.isvariabletrue
( name:string ) : boolean | nil
v1.1.6 and newer

Returns a boolean value indicating whether the named Readline configuration variable is set to true (on), or nil if the variable name is not recognized.

rl.setbinding
( key:string, binding:string | nil, [keymap:string] ) : boolean
v1.2.46 and newer

Binds key to invoke binding, and returns whether it was successful.

The key sequence string is the same format as from `clink echo`. See Discovering Clink key sindings for more information.

The binding is either the name of a Readline command, a quoted macro string (just like in the .inputrc config file), or nil to clear the key binding.

An optional keymap may be specified as well. If it is omitted or nil, then the current keymap is searched. Otherwise it may refer to one of the three built in keymaps:

Keymap | Description
--- | ---
`"emacs"` | The Emacs keymap, which is the default keymap.
`"vi"`, `"vi-move"`, or `"vi-command"` | The VI command mode keymap.
`"vi-insert"` | The VI insertion mode keymap.

Using Lua's `[[`..`]]` string syntax conveniently lets you simply copy the key string exactly from the `clink echo` output, without needing to translate the quotes or backslashes.

Note: This does not write the value into a config file. Instead it updates the key binding in memory, temporarily overriding whatever is present in any config files. When config files are reloaded, they may replace the key binding again.

    local old_space = rl.getbinding('" "')
    function hijack_space(rl_buffer)
        rl.invokecommand("clink-expand-line")   -- Expand envvars, etc in the line.
        rl.invokecommand(old_space)             -- Then invoke whatever was previously bound to Space.
    end
    rl.setbinding([[" "]], [["luafunc:hijack_space"]])

    -- The [[]] string syntax lets you copy key strings directly from 'clink echo'.
    -- [["\e[H"]] is much easier than translating to "\"\\e[H\"", for example.
    rl.setbinding([["\e[H"]], [[beginning-of-line]])

rl.setmatches
( matches:table, [type:string] ) : integer, boolean
v1.1.40 and newer

Provides an alternative set of matches for the current word. This discards any matches that may have already been collected and uses matches for subsequent Readline completion commands until any action that normally resets the matches (such as moving the cursor or editing the input line).

May only be used within a luafunc: key binding.

The syntax is the same as for builder:addmatches() with one addition: You can add a `"nosort"` key to the matches table to disable sorting the matches.

    local matches = {}
    matches["nosort"] = true
    rl.setmatches(matches)

This function can be used by a luafunc: key binding to provide matches based on some special criteria. For example, a key binding could collect numbers from the current screen buffer (such as issue numbers, commit hashes, line numbers, etc) and provide them to Readline as matches, making it convenient to grab a number from the screen and insert it as a command line argument.

Match display filtering is also possible by using clink.ondisplaymatches() after setting the matches.

Example .inputrc key binding:

    M-n:            "luafunc:completenumbers"       # Alt+N

Example Lua function:

    function completenumbers()
        local _,last_luafunc = rl.getlastcommand()
        if last_luafunc ~= "completenumbers" then
            -- Collect numbers from the screen (minimum of three digits).
            -- The numbers can be any base up to hexadecimal (decimal, octal, etc).
            local matches = console.screengrab("[^%w]*(%w%w[%w]+)", "^%x+$")
            -- They're already sorted by distance from the input line.
            matches["nosort"] = true
            rl.setmatches(matches)
        end

        rl.invokecommand("old-menu-complete")
    end

rl.setvariable
( name:string, value:string ) : boolean
v1.1.46 and newer

Temporarily overrides the named Readline configuration variable to the specified value. The return value reports whether it was successful, or is nil if the variable name is not recognized.

Note: This does not write the value into a config file. Instead it updates the variable in memory, temporarily overriding whatever is present in any config files. When config files are reloaded, they may replace the value again.

##### rl_buffer

rl_buffer:beginoutput
() : nil
v1.1.20 and newer

Advances the output cursor to the next line after the Readline input buffer so that subsequent output doesn't overwrite the input buffer display.

rl_buffer:beginundogroup
() : nil
v1.1.20 and newer

Starts a new undo group. This is useful for grouping together multiple editing actions into a single undo operation.

rl_buffer:ding
() : nil
v1.1.20 and newer

Dings the bell. If the `bell-style` Readline variable is `visible` then it flashes the cursor instead.

rl_buffer:endundogroup
() : nil
v1.1.20 and newer

Ends an undo group. This is useful for grouping together multiple editing actions into a single undo operation.

Note: all undo groups are automatically ended when a key binding finishes execution, so this function is only needed if a key binding needs to create more than one undo group.

rl_buffer:getanchor
() : integer | nil
v1.2.35 and newer

Returns the anchor position of the currently selected text in the input line, or nil if there is no selection. The value can be from 1 to rl_buffer:getlength() + 1. It can exceed the length of the input line because the anchor can be positioned just past the end of the input line.

rl_buffer:getargument
() : integer | nil
v1.2.22 and newer

Returns any accumulated numeric argument (`Alt`+Digits, etc), or nil if no numeric argument has been entered.

rl_buffer:getbuffer
() : string
v1.0.0 and newer

Returns the current input line.

rl_buffer:getcursor
() : integer
v1.1.20 and newer

Returns the cursor position in the input line. The value can be from 1 to rl_buffer:getlength() + 1. It can exceed the length of the input line because the cursor can be positioned just past the end of the input line.

Note: In v1.1.20 through v1.2.31 this accidentally returned 1 less than the actual cursor position. In v1.2.32 and higher it returns the correct cursor position.

rl_buffer:getlength
() : integer
v1.1.20 and newer

Returns the length of the input line.

rl_buffer:insert
( text:string ) : nil
v1.1.20 and newer

Inserts text at the cursor position in the input line.

rl_buffer:refreshline
() : nil
v1.1.41 and newer

Redraws the input line.

rl_buffer:remove
( from:integer, to:integer ) : nil
v1.1.20 and newer

Removes text from the input line starting at cursor position from through to.

Note: the input line is UTF8, and removing only part of a multi-byte Unicode character may have undesirable results.

rl_buffer:setargument
( argument:integer | nil ) : nil
v1.2.32 and newer

When argument is a number, it is set as the numeric argument for use by Readline commands (as entered using `Alt`+Digits, etc). When argument is nil, the numeric argument is cleared (having no numeric argument is different from having 0 as the numeric argument).

rl_buffer:setcursor
( cursor:integer ) : integer
v1.1.20 and newer

Sets the cursor position in the input line and returns the previous cursor position. cursor can be from 1 to rl_buffer:getlength() + 1. It can exceed the length of the input line because the cursor can be positioned just past the end of the input line.

Note: the input line is UTF8, and setting the cursor position inside a multi-byte Unicode character may have undesirable results.

Note: In v1.1.20 through v1.2.31 this accidentally returned 1 less than the actual cursor position. In v1.2.32 and higher it returns the correct cursor position.

##### settings

settings.add
( name:string, default:..., [short_desc:string], [long_desc:string] ) : boolean
v1.0.0 and newer

Adds a setting to the list of Clink settings and includes it in `clink set`. The new setting is named name and has a default value default when the setting isn't explicitly set.

The type of default determines what kind of setting is added: boolean, integer, and string values add the corresponding setting type. Or if the type is table then an enum setting is added: the table defines the accepted values, and the first value is the default value. Or if it's a string type and the name starts with "color." then a color setting is added.

name can't be more than 32 characters.

short_desc is an optional quick summary description and can't be more than 48 characters.

long_desc is an optional long description.

    settings.add("myscript.myabc", true, "Boolean setting")
    settings.add("myscript.mydef", 100, "Number setting")
    settings.add("myscript.myghi", "abc", "String setting")
    settings.add("myscript.myjkl", {"x","y","z"}, "Enum setting")
    settings.add("color.mymno", "bright magenta", "Color setting")

settings.get
( name:string, [descriptive:boolean] ) : boolean or string or integer
v1.0.0 and newer

Returns the current value of the name Clink setting.

If it's a color setting and the optional descriptive parameter is true then the user friendly color name is returned.

settings.set
( name:string, value:string ) : boolean
v1.0.0 and newer

Sets the name Clink setting to value and returns whether it was successful.

Note: Beginning in Clink v1.2.31 this updates the settings file. Prior to that, it was necessary to separately use `clink set` to update the settings file.

##### string

string.equalsi
( a:string, b:string ) : boolean
v1.1.20 and newer

Performs a case insensitive comparison of the strings with international linguistic awareness. This is more efficient than converting both strings to lowercase and comparing the results.

string.explode
( text:string, [delims:string], [quote_pair:string] ) : table
v1.0.0 and newer

Splits text delimited by delims (or by spaces if not provided) and returns a table containing the substrings.

The optional quote_pair can provide a beginning quote character and an ending quote character. If only one character is provided it is used as both a beginning and ending quote character.

string.hash
( text:string ) : integer
v1.0.0 and newer

Returns a hash of the input text.

string.matchlen
( a:string, b:string ) : integer
v1.1.20 and newer

Returns how many characters match at the beginning of the strings, or -1 if the entire strings match. This respects the `match.ignore_case` and `match.ignore_accents` Clink settings.

    string.matchlen("abx", "a")         -- returns 1
    string.matchlen("abx", "aby")       -- returns 2
    string.matchlen("abx", "abx")       -- returns -1

##### word_classifications

word_classifications:applycolor
( start:integer, length:integer, color:string, [overwrite:boolean] ) : nil
v1.1.49 and newer

Applies an ANSI SGR escape code to some characters in the input line.

start is where to begin applying the SGR code.

length is the number of characters to affect.

color is the SGR parameters sequence to apply (for example `"7"` is the code for reverse video, which swaps the foreground and background colors).

By default the color is applied to the characters even if some of them are already colored. But if overwrite is `false` each character is only colored if it hasn't been yet.

See Coloring the Input Text for more information.

Note: an input line can have up to 100 different unique color strings applied, and then this stops applying new colors. The counter gets reset when the onbeginedit event is sent.

word_classifications:classifyword
( word_index:integer, word_class:string, [overwrite:boolean] ) : nil
v1.1.18 and newer

This classifies the indicated word so that it can be colored appropriately.

The word_class is one of the following codes:

Code | Classification | Clink Color Setting
--- | --- | ---
`"a"` | Argument; used for words that match a list of preset argument matches. | `color.arg` or `color.input`
`"c"` | Shell command; used for CMD command names. | `color.cmd`
`"d"` | Doskey alias. | `color.doskey`
`"f"` | Flag; used for flags that match a list of preset flag matches. | `color.flag`
`"x"` | Executable; used for the first word when it is not a command or doskey alias, but is an executable name that exists. | `color.executable`
`"u"` | Unrecognized; used for the first word when it is not a command, doskey alias, or recognized executable name. | `color.unrecognized`
`"o"` | Other; used for file names and words that don't fit any of the other classifications. | `color.input`
`"n"` | None; used for words that aren't recognized as part of the expected input syntax. | `color.unexpected`
`"m"` | Prefix that can be combined with another code (for the first word) to indicate the command has an argmatcher (e.g. `"mc"` or `"md"`). | `color.argmatcher` or the other code's color

By default the classification is applied to the word even if the word has already been classified. But if overwrite is `false` the word is only classified if it hasn't been yet.

See Coloring the Input Text for more information.

##### [other]

pause
( [message:string], [lines:integer], [force:boolean] ) : nil
v1.0.0 and newer

Breaks into the Lua debugger, if the lua.debug setting is enabled.

If `pause()` is used by itself, the debugger breaks on the line after the pause call.

The message argument can be a message the debugger will display, for example to differentiate between multiple pause calls.

The lines argument indicates how many lines to step further before breaking into the debugger. The default is nil, which breaks on the line immediately following the pause call. Passing an integer value will step some number of lines before breaking (this will produce confusing results and is discouraged).

When the force argument is `true` then it will break into the debugger even if the `poff` debugger command has been used to turn off the pause command.

##### Deprecated

_argmatcher:add_arguments
() : nil

Deprecated; don't use this. See _argmatcher:addarg for more information.

Adds one argument slot per table passed to it (as v0.4.9 did).

Note: v1.3.10 and lower `:add_arguments()` mistakenly added all arguments into the first argument slot.

_argmatcher:add_flags
() : nil

Deprecated; don't use this. See _argmatcher:addflags for more information.

_argmatcher:be_precise
() : self

Deprecated; don't use this.

_argmatcher:disable_file_matching
() : self

Deprecated; don't use this. See _argmatcher:nofiles for more information.

_argmatcher:set_arguments
( choices...:string|table ) : self

Deprecated; don't use this. See _argmatcher:addarg for more information.

Sets one argument slot per table passed to it (as v0.4.9 did).

Note: v1.3.10 and lower `:add_arguments()` mistakenly set all arguments into the first argument slot.

_argmatcher:set_flags
( flags...:string ) : self

Deprecated; don't use this. See _argmatcher:addflags for more information.

Note: The new API has no way to remove flags that were previously added, so converting from `:set_flags()` to `:addflags()` may require the calling script to reorganize how and when it adds flags.

clink.add_match
( match:string ) : nil

Deprecated; don't use this. See builder:addmatch for more information.

This is a shim that lets clink.register_match_generator continue to work for now, despite being obsolete.

clink.addcoroutine
( coroutine:coroutine, [interval:number] ) : nil
v1.2.10 and newer

Deprecated; don't use this. See clink.setcoroutineinterval for more information.

Prior to v1.3.1 this was undocumented, and coroutines had to be manually added in order to be scheduled for resume while waiting for input. Starting in v1.3.1 this is no longer necessary, but it can still be used to override the interval at which to resume the coroutine.

clink.arg.new_parser
( ... ) : table

Deprecated; don't use this. See clink.argmatcher for more information.

Creates a new parser and adds ... to it.

    -- Deprecated form:
    local parser = clink.arg.new_parser(
      { "abc", "def" },       -- arg position 1
      { "ghi", "jkl" },       -- arg position 2
      "--flag1", "--flag2"    -- flags
    )

    -- Replace with form:
    local parser = clink.argmatcher()
    :addarg("abc", "def")               -- arg position 1
    :addarg("ghi", "jkl")               -- arg position 2
    :addflags("--flag1", "--flag2")     -- flags

clink.arg.register_parser
( cmd:string, parser:table ) : table

Deprecated; don't use this. See clink.argmatcher for more information.

Adds parser to the argmatcher for cmd.

If there is already an argmatcher for cmd then the two argmatchers are merged. It is only a simple merge; a more sophisticated merge would be much slower and use much more memory. The simple merge should be sufficient for common simple cases.

Note: In v1.3.11, merging parsers should be a bit improved compared to how v0.4.9 merging worked. In v1.0 through v1.3.10, merging parsers doesn't work very well.

    -- Deprecated form:
    local parser1 = clink.arg.new_parser():set_arguments({ "abc", "def" }, { "old_second" })
    local parser2 = clink.arg.new_parser():set_arguments({ "ghi", "jkl" }, { "new_second" })
    clink.arg.register_parser("foo", parser1)
    clink.arg.register_parser("foo", parser2)
    -- In v0.4.9 that syntax only merged the first argument position, and "ghi" and
    -- "jkl" ended up with no further arguments.  In v1.3.11 and higher that syntax
    -- ends up with "ghi" and "jkl" having only "old_second" as a second argument.

    -- Replace with new form:
    clink.argmatcher("foo"):addarg(parser1)
    clink.argmatcher("foo"):addarg(parser2)
    -- In v1.3.11 and higher this syntax ends up with all 4 first argument strings
    -- having both "old_second" and "new_second" as a second argument.

clink.compute_lcd
( text:string, matches:table ) : string

Deprecated; don't use this.

This is no longer supported, and always returns an empty string.

clink.get_match
( index:integer ) : string

Deprecated; don't use this.

This is no longer supported, and always returns an empty string. If a script needs to access matches it added, the script should keep track of the matches itself.

clink.is_match
( needle:string, candidate:string ) : boolean

Deprecated; don't use this. See clink.generator for more information.

This returns true if needle is a prefix of candidate with a case insensitive comparison.

Normally in Clink v1.x and higher the needle will be an empty string because the generators are no longer responsible for filtering matches. The match pipeline itself handles that internally now.

clink.is_single_match
( matches:table ) : boolean

Deprecated; don't use this.

This is no longer supported, and always returns false.

clink.match_count
() : integer

Deprecated; don't use this.

This is no longer supported, and always returns 0. If a script needs to know how many matches it added, the script should keep track of the count itself.

clink.match_display_filter
function variable

Deprecated; don't use this. See clink.ondisplaymatches for more information.

A match generator can set this varible to a filter function that is called before displaying matches. It is reset every time match generation is invoked. The filter function receives table argument containing the matches that are going to be displayed, and it returns a table filtered as required by the match generator.

See Filtering the Match Display for more information.

clink.match_display_filter
function variable

Deprecated; don't use this. See builder:addmatch for more information.

This is no longer used.

    clink.match_display_filter = function(matches)
      -- Transform matches.
      return matches
    end

clink.match_files
( pattern:string, [full_path:boolean], [find_func:function] ) : nil

Deprecated; don't use this. See clink.filematches for more information.

clink.match_words
( text:string, words:table ) : nil

Deprecated; don't use this. See builder:addmatches for more information.

This adds words that match the text.

clink.matches_are_files
( [files:boolean] ) : nil

Deprecated; don't use this. See builder:addmatch for more information.

This is only needed when using deprecated APIs. It's automatically inferred from the match type when using the current APIs.

clink.prompt.register_filter
( filter_func:function, [priority:integer] ) : table

Deprecated; don't use this. See clink.promptfilter for more information.

Registers a prompt filter function. The capabilities are the same as before but the syntax is changed.

    -- Deprecated form:
    function foo_prompt()
      clink.prompt.value = "FOO "..clink.prompt.value.." >>"
      --return true  -- Returning true stops further filtering.
    end
    clink.prompt.register_filter(foo_prompt, 10)

    -- Replace with new form:
    local foo_prompt = clink.promptfilter(10)
    function foo_prompt:filter(prompt)
      return "FOO "..prompt.." >>" --,false  -- Adding ,false stops further filtering.
    end

clink.quote_split
( str:string, ql:string, qr:string ) : table

Deprecated; don't use this.

clink.register_match_generator
( func:function, priority:integer ) : nil

Deprecated; don't use this. See clink.generator for more information.

Registers a generator function for producing matches. This behaves similarly to v0.4.8, but not identically. The Clink schema has changed significantly enough that there is no direct 1:1 translation; generators are called at a different time than before and have access to more information than before.

    -- Deprecated form:
    local function match_generator_func(text, first, last)
      -- `text` is the word text.
      -- `first` is the index of the beginning of the end word.
      -- `last` is the index of the end of the end word.
      -- `clink.add_match()` is used to add matches.
      -- return true if handled, or false to let another generator try.
    end
    clink.register_match_generator(match_generator_func, 10)

    -- Replace with new form:
    local g = clink.generator(10)
    function g:generate(line_state, match_builder)
      -- `line_state` is a line_state object.
      -- `match_builder:addmatch()` is used to add matches.
      -- return true if handled, or false to let another generator try.
    end

clink.set_match
( index:integer, value:string ) : nil

Deprecated; don't use this.

This is no longer supported, and does nothing.

clink.slash_translation
( type:integer ) : nil

Deprecated; don't use this. See clink.translateslashes for more information.

Controls how Clink will translate the path separating slashes for the current path being completed. Values for type are; -1 - no translation 0 - to backslashes 1 - to forward slashes

clink.split
( str:string, sep:string ) : table

Deprecated; don't use this. See string.explode for more information.

clink.suppress_char_append
() : nil

Deprecated; don't use this. See builder:setsuppressappend for more information.

clink.suppress_quoting
() : nil

Deprecated; don't use this. See builder:setsuppressquoting for more information.

os.ishidden
( path:string ) : boolean

Deprecated; don't use this. See os.globfiles for more information.

Returns whether path has the hidden attribute set.

rl_state
table variable

Deprecated; don't use this. See line_state for more information.

This is an obsolete global variable that was set while running match generators. It has been superseded by the line_state type parameter passed into match generator functions when using the new clink.generator API.

# Changes

### Releases from chrisant996/clink fork

#### v1.3.15

- Fixed #269; reverse video could get confused (regression introduced in v1.3, and incompletely fixed in v1.3.4).

#### v1.3.14

- `Ctrl`+`Break` can now interrupt some operations, including match display and match generators and the `os.globfiles()` and `os.globdirs()` functions in Lua scripts.
- Added `os.issignaled()` so Lua scripts can cooperatively interrupt themselves.
- Improved responsiveness of completion commands when an async prompt filter is still running in the background (`io.popen()` and `os.execute()` are serialized in prompt filter coroutines, and are serialized separately in match generator coroutines, but are not serialized in other coroutines).
- Fixed displaying pasted lines.
- Fixed doskey aliases in pasted lines.
- Fixed #268; crash when `copy` command prompts whether to overwrite a file (regression introduced in v1.3.13).

#### v1.3.13

- Argmatchers can use `:chaincommand()` to treat the rest of the command line as another command.
  - Added an argmatcher for `cmd` that uses `:chaincommand()`.
  - E.g. so that completion after `cmd program` can be parsed by an argmatcher for `program` instead of `cmd`.
- Argmatchers can be more involved in parsing the command line, if they wish. See Responding to Arguments in Argmatchers for more information.
  - A callback function can be assigned to an argument position by including `onarg=your_callback_function` in the table given to `:addarg()`.
  - The `onarg` callback and match functions receive an additional `user_data` parameter. When parsing begins, the `user_data` is an empty table, and your functions can set or get data from the table. Each time a flag or argument links to another argmatcher, the new argmatcher gets a separate new empty `user_data` table.
  - The built-in `cd` and `pushd` argmatchers use this to influence match completion for the rest of the input line. E.g. `pushd \foo & program` `Tab` uses `\foo` as the current directory when generating possible completions.
- Functions registered with `clink.onfilterinput()` may optionally return multiple lines in a table.
- Fixed completions for words that contain `.`, such as `clink set color.``Tab` (regression introduced in v1.3.11).
- Fixed doskey macros that use `echo off $T ...`.
- Fixed input line coloring for a drive letter by itself.
- Fixed input line coloring for a file that exists but is not executable.
- Fixed obscure edge case with delayinit argmatchers and `operate-and-get-next`.
- Fixed potentially inconsistent input line coloring when `classifier:applycolor()` is given an escape code that sets only the foreground or background color.

#### v1.3.12

- Improved `clink-select-complete` to show inline descriptions as long as they don't require more than 9 rows to display the matches.
- Added second argument to the `delayinit` function for an argmatcher.
- Added `argmatcher:setflagsanywhere()` and `argmatcher:setendofflags()` to control where flags are recognized.
- Added `clink.getargmatcher()` to find the argmatcher for a command name or command line (`line_state`).
- Added `os.resolvealias()` to expand doskey alias(es) in a line of text.
- Added `clink.oncommand()` to register a function to be called when a command is entered in the edit line.
- Improved support for argmatcher non-flag argument values that end with `=`: now they can have a linked argmatcher, and input line coloring is applied correctly.
- Fixed quotes during completion (regression introduced in v1.3.11).
- Fixed `cd /d dir` argmatcher (regression introduced in v1.3.11).
- Fixed input line coloring for `"echo"` and other CMD commands; quotes disqualify a word from being a CMD command.
- Fixed redundant argmatcher delayinit for flags.
- Various minor backward compatibility fixes.

#### v1.3.11

- Updated the list of recognized CMD command names.
- Better support for `(` and `)` when expanding doskey macros (e.g. now `( macro foo ) & ( macro bar )` works).
- Fixed word break characters during completion. Only `=` `;` had ever worked before, and now the normal CMD completion word break characters work (including `,` `!` `+` `(` and many others).
- Fixed match display to not force a single column unless there are descriptions present.
- Fixed backward compatibility for `_argmatcher:add_arguments()` and `_argmatcher:set_arguments()` (they were mistakenly adding all the arguments into the first argument position).
- Fixed backward compatibility for merging argmatchers.
  - Merging argmatchers works again. It is still a simple merge similar to v0.4.9, but it should be sufficient for common cases.
  - Fixed some bugs in how Clink v0.4.9 merged argmatchers (the unit tests for merging fail in v0.4.9).
  - Added support for some merging cases that weren't implemented yet in v0.4.9.
- And other obscure minor backward compatibility fixes.

#### v1.3.10

- An argmatcher can extend itself on the fly, when needed. For example, if it needs to parse arguments and flags from `--help` text, or if the available command arguments change based on the current directory, or etc. See Adaptive Argmatchers for more information.
- Recognizes `^` and environment variables when coloring the command word, and when navigating by typing a directory name by itself.
- Added input line coloring for the `rem` command.
- Fixed memory corruption (regression introduced in v1.3.1).
- Fixed input line coloring for `clink set setting value & another command`.
- Fixed argmatcher input line coloring for matches using the `{ match="abc" }` syntax.
- Fixed finding an argmatcher after `(` at the beginning of the line.
- Fixed mouse clicks in `clink-select-complete` to insert the clicked match, in addition to highlighting it.
- Fixed #252; `md` and `rd` should complete more than 1 argument.

#### v1.3.9

- When `argmatcher:addarg()` is passed a table containing `fromhistory=true` then additional matches are generated by parsing the history file to find values for that argument slot from commands in the history file.
- Added `clink.reclassifyline()` which triggers input line coloring and redisplays the input line. This is intended for use by a coroutine that has made changes that will affect input line coloring.
- Added `match_builder:isempty()`.
- Added mouse horizontal wheel support in `clink-select-complete`.
- Added back the `_argmatcher:setflagprefix()` function.
- Loading Lua scripts now reports any syntax errors when the `lua.debug` setting is enabled.
- Incorporate Lua 5.2.4 (minor patches to the Lua language).
- Report a warning if the profile directory is configured to point at a file.
- AutoRun is selected by default again in the installer (reverted change from v1.3.5).
- The `terminal.raw_esc` setting now also address the same kind of problem with `Alt`+`[` and `Alt`+`Shift`+`O` as with the `Esc` key.
- Fixed when an argmatcher adds nested tables of matches using the `{ match="abc" }` syntax, so that the nested matches are added recursively and properly suppress adding a space after argument matches that end with `:` or `=`.
- Fixed when `match_builder:addmatch()` and `match_builder:addmatches()` add nested tables of matches using the `{ match="abc" }` syntax, so that the nested matches are added recursively.
- Fixed when `match_builder:addmatch()` and `match_builder:addmatches()` add an `"arg"` match type, so that they automatically suppress appending a space after matches that end with `:` or `=` (the behavior was documented, but did not work correctly).
- Fixed `remove-history` so that it updates the history offset correctly and subsequent editing operations affect the correct undo list.
- Fixed obscure issues in how certain key binding patterns were reported by `clink-show-help` and `dump-functions`.
- Fixed how `clink echo` reports `Ctrl`+`Backspace` and `Ctrl`+`Alt`+`Backspace`.
- Fixed #249; sending keystrokes from WScript does nothing for some keys.
- Fixed #244; installer did not detect previous installation directory (regression introduced in v1.3.5; the fix takes effect on the next install after an install with the fix).

#### v1.3.8

- Added `terminal.mouse_modifier` setting and `%CLINK_MOUSE_MODIFIER%` environment variable; these can override the modifier keys that activate Clink mouse input.
- Added `%CLINK_SETTINGS%` environment variable; this can override the directory where the `clink_settings` file is located. This can be used to put it in a directory that syncs between computers, for example.
- During `clink-select-complete` `Ctrl`+`Home` or `Ctrl`+`End` select the first or last match.
- When `argmatcher:addarg()` is passed a table containing `nosort=true` then the matches are unsorted (displayed in the order listed in the table).
- The .zip file now contains `_default_settings` and `_default_inputrc` so that they do not take effect unless manually renamed to remove the `_` name prefix. This avoids changing the defaults unexpectedly.
- Fixed mouse click+drag in the input line (it accidentally behaved like double click+drag).
- Fixed the selection highlight width in `clink-select-complete` when some matches have descriptions but some do not.
- Fixed `argmatcher:addargunsorted()` to turn off sort.
- Fixed #239; crash when `F7` and `Del`.

#### v1.3.7

- Mouse click+drag now works.
- Mouse click below `clink-select-complete` list expands the list instead of dismissing it.
- Fixed responding to mouse clicks when the terminal's scrollback buffer is not empty (it only worked in Windows Terminal).
- Fixed #237; installer does not maintain previously selected "Autorun when cmd.exe starts" (regression introduced in v1.3.5).

#### v1.3.6

- Added `terminal.mouse_input` setting; the default is `auto`. `auto` lets mouse input work in ConEmu, or in the default Conhost terminal when Quick Edit mode is unchecked in the console Properties dialog. See the documentation for more information.
- Added `cua-select-word` command that selects the word at the cursor.
- `Ctrl`+`X`,`Ctrl`+`Z` with a numeric argument always includes registered Lua match generators, prompt filters, etc even when the `lua.debug` setting is off.
- Fixed potential for a coroutine to have extra delays sometimes when continuing past the end of one edit line, and into the next edit line.
- Fixed a potential busy loop when the command word is unrecognized.
- Fixed Quick Edit mode in plain Conhost windows; it had always been disabled (I never noticed because I always configure console windows to disable it anyway).

#### v1.3.5

- Raised default `history.max_lines` to 10000.
- Added an optional `default_inputrc` file:
  - It is loaded from the profile directory, or from the binaries directory.
  - It uses the same format as the `.inputrc` file, and is loaded immediately before the `.inputrc` files.
  - It has the effect of superseding built-in default values for Readline configuration variables and key bindings; any settings in the `.inputrc` supersede those in the `default_inputrc` file.
- The installer has a new "Use enhanced default settings" option which installs `default_settings` and `default_inputrc` files to provide default values that activate more of the Clink enhancements (to give a more enhanced experience "out of the box").
- The installer no longer defaults to installing AutoRun.
- The installer no longer has an option to use versioned install directory; files are installed directly in the install directory.
- Added `clink.runcoroutineuntilcomplete()` which allows a coroutine to keep running past the end of one edit line, and into the next edit line.
- Fixed `os.execute()` return values when run in a coroutine (regression introduced in v1.3.2).
- Fixed the selection color in `clink-select-complete` when `colored-stats` is off.
- Fixed problems when displaying matches that exceed the screen width.
- Fixed #231; installer fails sometimes when uncheck "Use versioned install directory".

#### v1.3.4

- Pressing `Del` or `Ctrl`+`D` in a command history popup deletes the selected history entry.
- Changed the default color for directory match completions to bright yellow (bright blue is hard to see).
- Added an argmatcher for `history`.
- Added an optional `default_settings` file:
  - It is loaded from the profile directory, or from the binaries directory.
  - It uses the same format as the `clink_settings` file, and the values in it supersede the built-in default values for settings.
  - Settings are now saved if they are set (vs cleared by `clink set setting.name clear`), even if the set value matches the default value.
- Minor performance improvement when calculating columns widths when `match.fit_columns` is enabled.
- Fixed accidentally using only one column in `clink-select-complete` when there are 9 or fewer matches and none of them have description text (regression introduced in v1.3.3).
- Fixed `Shift`+`Right` to accept the next full word of the suggestion without clearing the rest of the suggestion (regression introduced in v1.3.3).
- Fixed terminal emulation for the reverse video escape codes (this also fixes the right border color of the selected item in popup lists).
- Fixed buffer overrun in Readline `yank-last-arg` when the previous command ends in a backslash.
- Fixed the Readline History library to not apply Unix style backslash escaping in CMD (e.g. in `program subdir\ text` there are 3 arguments; the `\` is not an escaped space).
- Fixed crash when displaying matches and `match.fit_columns` is enabled and the terminal width is greater than 150 characters.
- Fixed potential busy loop during idle (until a key is pressed) in certain cases (regression introduced in v1.3.3).
- Fixed the emulated terminal color conversions from 8-bit and 24-bit.
- Fixed cursor style when using `clink` to start a new command window from inside a Windows Terminal window.
- Fixed quirk when using Clink file completion to complete a directory name for `clink --profile \foo\`, so that the path doesn't end up malformed.
- Fixed a memory leak.

#### v1.3.3

- Match completion display calculates column widths to fit the most columns on the screen. Can be controlled by the `match.fit_columns` and `match.limit_fitted_columns` settings.
- Match descriptions are right-justified when more than one column is displayed, to help more columns fit.
- When multiple columns of matches are displayed with descriptions, the descriptions are bracketed with parentheses for readability and accessibility purposes.
- `F1` in `clink-select-complete` toggles between showing descriptions at the bottom vs with the matches.
- Added `match.substring` setting that uses a substring search for completions if none are found with a prefix search.
- Added `color.executable` and `color.unrecognized` settings. When set, these cause the command word (the first word) to be colored if it is recognized as an executable file, or is not recognized as a command, doskey macro, directory, argmatcher, or executable file. Lookups are asynchronous for optimum responsiveness while typing.
- Argmatchers can hide certain flags (e.g. synonyms) by using `argmatcher:hideflags()`.
- Argmatchers can disable sorting matches by using `argmatcher:addargunsorted()` or `argmatcher:addflagsunsorted()`.
- Generators can disable sorting matches by using `match_builder:setnosort()`.
- Fixed duplicated closing quote in `clink-select-complete`.
- Fixed display of non-directory matches that contain slashes, such as git branch names (regression introduced in v1.3.1).
- Fixed match display filtering in `clink-select-complete` (regression introduced in v1.3.1).
- Fixed the `insert-comment` command (regression introduced in v1.2.44).
- Fixed sorting flag completions so that all `-` flags precede any `--` flags.
- Fixed a couple of memory leaks, and added memory tracking system to more easily catch leaks.
- Various minor fixes in `clink-select-complete`.

#### v1.3.2

- Added `Shift`+`Space` as a recognized key. By default it is bound to `clink-shift-space`, which invokes whatever is bound to the normal `Space` key, so that it continues to behave as before unless you specifically bind something else to the `Shift`+`Space` key.
- Added `clink-magic-suggest-space` command which inserts the next full suggested word (if any) up to a space, and then inserts a space. Binding this to `Shift`+`Space` can be very handy.
- Added `cmd.admin_title_prefix` setting that can replace the "Administrator: " console title prefix.
- When loading settings, if there is no setting file yet then Clink looks for a `default_settings` file in the binaries directory and uses that to initalize the settings.
- Added `CLINK_TERM_VE` and `CLINK_TERM_VS` environment variables that can be set to override the normal (insert mode) and enhanced (overwrite mode) cursor styles, respectively.
- Various minor fixes to how the cursor style is updated; the visible bell now works in Windows Terminal.
- When `os.execute()` is used in a coroutine, it automatically yields until complete.
- Fixed async match generators (during autosuggest) to be allowed to finish, instead of getting canceled on every keystroke if they hadn't finished yet.
- Fixed cursor blink, which was accidentally disabled (regression introduced in v1.2.44).
- Fixed the `win-cursor-forward` command so it doesn't trigger generating a new suggestion if there isn't already one.

#### v1.3.1

- Added `autosuggest.async` setting (on by default) that lets suggestions generate matches asynchronously to stay responsive while typing.
- Added `match.max_rows` setting that limits the number of rows `clink-select-complete` can use.
- Added `match.preview_rows` setting that makes `clink-select-complete` show the specified number of rows of matches as a preview, and expands to show the full set of matches when the selection moves past the preview rows (similar to completion in the fish shell).
- Added `color.comment_row` setting that chooses the color for the comment row in `clink-select-complete`. The comment row shows the "and N more matches" or "rows X to Y of Z" messages.
- Changed arrow keys in `clink-select-complete` to wrap on both horizontal and vertical edges (similar to the fish shell).
- Changed arrow keys in `clink-select-complete` at the beginning and end of the list to wrap to the other end based on the `menu-complete-wraparound` config variable.
- Match generators can now specify an append character (or suppress appending) on a per-match basis.
- The `clink-diagnostics` command lists prompt filters, generators, classifiers, and suggesters when a numeric argument is given (e.g. `Alt`+`1` then `Ctrl`+`X`,`Ctrl`+`Z`).
- The `os.globdirs()` and `os.globfiles()` functions now automatically yield periodically if used inside a coroutine.
- The `io.popen()` function now automatically yields periodically if used in read mode (the default) inside a coroutine.
- The `io.popenyield()` function now automatically falls back to `io.popen()` if used outside a coroutine.
- Fixed input line coloring to operate on only the input line, not including the suggestion.
- Fixed display when typing to filter `clink-select-complete` (regression introduced in v1.2.49).
- Fixed display of `clink-select-complete` when the current match changes the number of visible lines in the edit buffer.
- Fixed displaying matches when only a drive letter is entered.
- Fixed #216; Long escaped URLs do not display correctly in a prompt.

#### v1.3

- Added back `mark-modified-lines` support (was removed in v1.2.36).
- Added `rl.ismodifiedline()` function so prompt filters can show a modified line indicator if they wish.
- Added `autosuggest.original_case` setting (on by default) that controls whether parts of the line are updated to use the suggestion's original capitalization, or to keep the typed capitalization.
- Added `terminal.east_asian_ambiguous` setting that controls how the width is determined for the East Asian Ambiguous range of characters (which includes the lambda character). This may help with working around display issues in some terminal hosts.
- Added help descriptions for many vi mode commands.
- Improved relevance of `completion` suggestions by suppressing them when the word at the cursor is empty.
- The `:suggest()` function on suggesters can now return a suggestion string and an offset where the suggestion begins in the input line.
- Fixed a limitation in Readline so that `completion-prefix-display-length` and `colored-completion-prefix` can coexist.
- Fixed when temp files from `io.popenyield()` get deleted. They were lingering until Lua garbage collection, but they can be deleted almost immediately.
- Fixed the order of initialization: first the Readline .inputrc config file is loaded, and then Lua scripts are loaded. This enables Lua scripts to reliably override Readline config variables if they wish (for example so a prompt filter can clear `emacs-mode-string` and print its own keymap indicator as part of the prompt).
- Fixed transient prompt to not show keymap mode strings or the modified line mark.
- Fixed vi mode key bindings that can accept suggestions.
- Fixed missing `vi-undo` command; it was pre-bound to some keys but could not be bound to any other keys.
- Fixed the "show help" commands when listing unbound commands: unbound vi mode commands should not be listed in emacs mode because the vi mode commands are only meant to be used in vi mode, and are not meant to be bound to custom keys.
- Fixed memory leak in suggestions.

#### v1.2.50

- Added `rl.insertmode()` function to get or set whether insert mode is active.
- Added `clink.onaftercommand()` so scripts can registers a function to be called after every input command (key binding).
- Added additional failure logging during `clink inject`.

#### v1.2.49

- Added `cua-previous-screen-line` and `cua-next-screen-line`, bound to `Shift`+`Up` and `Shift`+`Down`, to extend the text selection up/down by one screen line.
- Updated match generator for `clink set autosuggest.strategy` to list the available suggestion generators.
- The `clink-show-help` and `clink-popup-show-help` commands can include commands that aren't bound to any key, when the numeric argument is 4 (e.g. `Alt`+`4` then `Alt`+`H`).
- The `rl.getkeybindings()` function takes an optional `mode` argument to control sorting and whether to include commands that aren't bound to any key.
- Generating suggestions skips generating match completions when the current word looks like a UNC path. This avoids pauses while typing that would otherwise occur when accessing networked drives.
- Fixed `Alt`+`Right` so it accepts the next word of the suggestion, just like `Ctrl`+`Right` does.
- Fixed the `clink-paste` command so it sets the mark to the cursor point prior to pasting.
- Fixed when `history.dupe_mode` is "erase_prev" and `history.shared` starts true but changes to false; subsequent commands were not added to the history properly anymore in that session (regression introduced in v1.1.0).
- Fixed #210; `clink-select-complete` drawing bug with RPROMPT.

#### v1.2.48

- `Ctrl`+`Right` now inserts the next word of the suggestion the same way it would move to the next word, and `Shift`+`Right` inserts the next full word of the suggestion up to a space.
- Keys like `Home`/`End`, `Shift`+`Left`/`Right`, and `Ctrl`+`Left`/`Right` work in VI mode.
- Fixed input line coloring glitch when color settings use the `sgr` syntax.

#### v1.2.47

- Added autosuggestions similar to the Fish shell.
  - Turn on by running `clink set autosuggest.enable true`. See the `autosuggest.enable` and `autosuggest.strategy` Clink settings for details.
  - Added `clink.suggester()` function to create new suggestion generators that can be used in the `autosuggest.strategy` setting.
- The `clink-diagnostics` command also lists match generators registered by `clink.generator()`.
- Fixed the color when the `horizontal-scroll-mode` config variable is `on`.
- Fixed the transient prompt when using Help commands.
- Fixed the `clink autorun` commands when paths contain Chinese characters and the system code page isn't UTF8.
- Fixed #209; `clink-popup-show-help` command fails.
- Fixed #208; orphaned symlinks are colored wrong.
- Fixed #203; unable to inject when Clink binary directory contains Chinese characters (regression introduced in v1.0.0).

#### v1.2.46

- Added a `magic-space` command that performs history expansion on the text before the cursor point and then inserts a space. Note: this is slightly different than one in bash, which performs history expansion on the whole line and can end up inserting the space in a wrong spot.
- Added `rl.getbinding()` and `rl.setbinding()` functions to query or override key bindings.
- Added a `clink.refilterprompt()` function to invoke prompt filtering on demand.
- The `clink-popup-directories` command is now bound by default to `Ctrl`+`Alt`+`PgUp`.
- The `clink-select-complete` command is now bound by default to `Ctrl`+`Space`.
- Fixed the `clink-popup-history` command so incremental search works again (regression introduced in v1.2.36).
- Fixed messages sometimes not being erased when finished, e.g. when using `Alt`+`digits` (regression introduced in v1.1.11).
- Fixed potential for prompt to redraw incorrectly after showing help when the `prompt.transient` setting is enabled.
- Fixed settings defined by Lua scripts so that the Lua scripts can reliably see the current values even while the Lua scripts are being loaded or reloaded.

#### v1.2.45

- Clarified description of the `match.wild` Clink setting.
- Fixed #196; installer checkboxes not working properly.

#### v1.2.44

- Fixed `clink.ondisplaymatches()` so it receives the right match strings (regression introduced in v1.2.39).
- Fixed #194; argmatcher not found when command name contains a dash (regression introduced in v1.1.5).
- Fixed #176; use current installation dir when upgrading clink. Now the installer remembers the chosen installation directory and defaults to the same place when installing an upgrade (all of the checkbox states are remembered, in fact).
- Fixed #171; have a way to override install directory. Now the installer has a checkbox whether to install to a versioned directory (recommended). Unchecking the box installs program files to a `bin` subdirectory, instead of the usual versioned subdirectory.

#### v1.2.43

- Fixed lingering issues with non-ASCII characters in path names in Clink (follows up on the preceding fixes for non-ASCII user name characters).

#### v1.2.42

- Fixed potential for history file to get corrupted during compacting, if multiple Clink instances are running concurrently.
- Fixed `clink inject` when the user account name contains non-ASCII characters (regression introduced in v1.0.0).
- Fixed #193; consider removing the 50K history limit: The `history.max_lines` Clink setting once again supports 0 to mean unlimited. Note that as the history file grows larger, it takes longer to load. If the size becomes a problem, you can use `clink history compact <n>` to prune the history file to N items as well as compacting it (removing deleted items).
- Fixed #192; completing `~` by itself does nothing: Completing `~` by itself now inserts the %USERPROFILE% directory. This is different than bash, because on Windows it doesn't make sense for ~ by itself to complete other user accounts. This is a convenient way to expand tilde into a path that Windows understands.
- Fixed #191; `cd /d -` isn't supported: The `cd -` feature now supports `cd /d -` as well. It also supports `cd -` even if there is a doskey macro defined for `cd`.

#### v1.2.41

- Fixed #187 differently: `doskey.enhanced` is `true` by default again, but if a macro contains `$*` or `$1`...`$9` tags within quotes then `|` and `&` symbols are part of the arguments, not command separators (and expansion stops after that macro).
- Fixed compatibility when `doskey.enhanced` is `false`; `alias|whatever` should not expand `alias` because there is no space after it.
- Fixed doskey expansion when `>&` redirection symbol is present; `command >& alias` should not attempt to expand `alias` because it's a redirection file name, not a command.

#### v1.2.40

- Fixed display quirks when an empty `display` or `description` string is provided by a match generator.
- Fixed #187; the `doskey.enhanced` setting interferes with some macros (regression introduced in v1.0.0). The setting is now `false` by default, because of the incompatibilities it can cause.

#### v1.2.39

- Fixed regression in match display filtering when listing possible completions (regression introduced in v1.2.38).
- Fixed display quirks in the `clink-select-complete` command when descriptions are at the bottom.

#### v1.2.38

- Enhancements for match descriptions (which are displayed when listing possible completions):
  - Argmatchers can provide description strings for flags and/or args (e.g. "Verbose output" for `-v`, or "Do nothing" for `-n`, etc).
  - Argmatchers can also provide argument info strings for flags and/or args. These are hint strings, and not part of the completion match itself. E.g. "linenum" for `--line`, which gets displayed as "--line linenum" when listing possible completions, but only "--line" is inserted.
  - Match generators can provide `display` and `description` strings when adding matches (`match_builder:addmatch()` and `match_builder:addmatches()`) -- it is no longer necessary to use `clink.ondisplaymatches()`.
  - The `clink-select-complete` command now shows match descriptions in a single line at the bottom (instead of in a second column) when there are more than 9 matches.
  - Added `color.arginfo` Clink setting for the arguments for a flag or argument when listing possible completions.
  - Added `color.description` Clink setting for the default match description color when listing possible completions.
  - Truncate descriptions when a line will wrap (or has wrapped) when listing possible completions.
- Command separators (`&`, `|`) and redirection symbols (`<`, `>`, `>&`) are colored in the input line, using colors from the new `color.cmdsep` and `color.cmdredir` Clink settings.
- Fixed `Backspace` in `clink-select-complete`; it had sometimes missed expanding the set of matches accordingly.
- Fixed the `clink-popup-history` command to respect the `search-ignore-case` setting.
- Fixed `:nofiles()` to dead-end an argmatcher (regression introduced in v1.0.0).
- Fixed `clink.ondisplaymatches()` and `clink.onfiltermatches()` when there's only 1 match.
- Fixed incremental find, find next, and find previous in console text popup lists.
- Fixed backward compatibility for the old matching filtering API.
- Fixed several other minor issues with match display filtering.
- Fixed intermittent incorrect match generation for `/flag:` or `/flag=` flags.
- Fixed duplicate removal with deprecated match generators.
- Fixed when nested deprecated argmatchers are exhausted (regression introduced in v1.2.36).
- Fixed deprecated match generators to not infer whether matches are filenames, to match the behavior of the v0.4.9 API.
- Fixed how `match.wild` works with deprecated match generators; e.g. arg completions for z.lua weren't working (regression introduced in v1.1.5).
- Fixed argmatcher for `clink --profile` so it produces directory matches.
- Fixed `%CLINK_RPROMPT%` alignment when `color.prompt` is set.

#### v1.2.37

- Fixed #180; `rl.collapsetilde()` behaves erratically.
- Fixed #179; incorrect handling for certain keys on some keyboard layouts.
- Fixed #178; OneDrive folders mistakenly show up as symlinks.
- Fixed #177; be silent about autorun injection into TCC.

#### v1.2.36

- Added `win-history-list` command bound to `F7` by default. This shows the history list, and executes the selected history entry.
- Changed all of the popup list commands to show popups using console text rather than GUI windows.
  - Added a `color.popup` Clink setting for the popup colors. If not set, the console's popup colors are used.
  - Added a `color.popup_desc` Clink setting for the popup colors for the description column(s). If not set, a color is chosen to complement the console's popup colors.
  - Added a `clink.gui_popups` Clink setting that can be set to use GUI popup windows as before (the `color.popup` settings have no effect on GUI popup windows).
- Key bindings now support `Enter` plus combinations of the `Ctrl`, `Shift`, or `Alt` modifier keys.
- Added more backward compatibility shims.
- Fixed the `clink-select-complete` command when `print-completions-horizontally` is on (and also minor issues when it is off).
- Fixed the `clink-select-complete` command when a Lua script has used `rl.setmatches()` to provide a custom list of matches.
- Fixed the `clink-menu-complete-numbers` family of commands (regression introduced in v1.2.32).
- Fixed a situation where the scrolling keys could stop working (regression introduced in v1.2.24).
- Fixed flags at the end of a linked parser, and fixed args at the end of two or more nested linked parsers (regression introduced in v1.0.0).
- Fixed #172; add a choice in the installer to not add Start menu shortcuts.
- Fixed #129; Bug completing files with - or _ characters (regression introduced in v1.0.0).

#### v1.2.35

- Added `rl_buffer:getanchor()` to get the text selection anchor (there is no set function; use `rl.invokecommand()` to invoke commands to set/extend the selection if needed).
- Reverted back to using IAT hooking (see issue #169).
- Fixed CUA selection commands invoked by `rl.invokecommand()`.
- Fixed #170; directory symlink completion is truncated when `mark-directories` is `off` in the .inputrc file.
- Fixed #169; incompatibility between AutoHotkey, AnsiCon, and Clink when all three are used in CMD's AutoRun regkey (regression introduced in v1.2.33).

#### v1.2.34

- Changed "luafunc:" macro functions to receive the `line_state` as a second argument.
- Fixed `Right` when `clink.default_bindings` is `windows`.
- Fixed `exec.files` setting so completion works when a path is specified (e.g. `subdir\foo`) (regression introduced in v1.2.33).
- Fixed #158; crash when a keyboard macro contains `\015` (regression introduced in v1.0.0).

#### v1.2.33

- Rewrote how Clink hooks APIs in CMD.EXE; it no longer uses any IAT hooking, and exclusively uses Detours.
- Added `clink.default_bindings` Clink setting to choose between `bash` or `windows` default key bindings. `bash` key bindings are still the default, for compatibility with existing Clink installations.
- Added `exec.aliases`, `exec.commands`, and `exec.files` Clink settings to further customize how matches are generated for the first word when the `exec.enable` Clink setting is enabled.
- Small performance optimization in the hooked `WriteConsoleW()` system API.
- Added logging for rare error case during inject.
- Added default key bindings for `F1` through `F9` that mimic the default Windows console function key inputs.
- Added `clink-selectall-conhost` command that mimics the default Windows console Select All command.
- Fixed `clink-select-complete` to remove duplicate matches if generators try to add duplicate matches.
- Fixed script error when `%PATH%` is not set and `exec.enable` and `exec.path` are both enabled.
- Fixed some quirks when using the `quoted-insert` command.

#### v1.2.32

- Added `rl_buffer:setargument()` function for a "luafunc:" macro to be able to set Readline's numeric argument.
- Added `os.getclipboardtext()` and `os.setclipboardtext()` functions.
- Added extra defense against antivirus interference (if it interferes when Clink inspects the target process, but permits Clink to inject into the target process).
- Fixed cooperation between "luafunc:" macros and CUA selection commands (e.g. `Shift`+`End`).
- Fixed `rl_buffer:getcursor()` and the return value from `rl_buffer:setcursor()`; both returned one less than the actual cursor position.
- Fixed #162; clink completion shows script error (regression introduced in v1.2.31).

#### v1.2.31

- Added `clink uninstallscripts --all` to clear all script paths installed by `clink installscripts`.
- Added `os.touch()` function to set the access and modified times for a file.
- Added more fields in `os.globdir()` and `os.globfiles()` when `extrainfo` is requested.
- Potential Breaking Change: Fixed `os.globdir()` and `os.globfiles()` to only return extra info when actually requested (regression introduced in v1.1.8).
  - This unfortunately changes the scheme and may break some scripts if they requested no extra info, but used the extra info anyway.
- Fixed crash in `clink-select-complete` when a match display filter returns nil.
- Fixed `ondisplaymatches()` which was receiving one fewer matches than it should (related to #124).
- Fixed `ondisplaymatches()` which was not using the word break info correctly (from generators' `:getwordbreakinfo()` functions).
- Fixed `word_classifications:applycolor()`; the input line didn't necessarily refresh correctly after a custom classifier applied custom colors.
- Fixed potential stray inaccurate colorations when coloring the input for `clink set color.something some_value`.
- Fixed #161; `clink installscripts` garbles previously-installed script paths when installing a new one.
- Fixed #155; `settings.set()` doesn't update the settings file.

#### v1.2.30

- Replaced the built-in Lua implementation of `os.clock()` so it doesn't stop working after the program has been running for more than 24 days (which caused asynchronous prompt filtering to stop working). As a side effect, the new `os.clock()` has microsecond precision instead of millisecond precision.
- Fixed coroutine throttling. It was meant to prevent running more than once per 5 seconds, but accidentally forced running every 5 seconds, even if the coroutine was registered to run less often.

#### v1.2.29

- Added `prompt.transient` Clink setting which can collapse prior prompts to a condensed form. The new `%CLINK_TRANSIENT_PROMPT%` and `%CLINK_TRANSIENT_RPROMPT%` environment variables supply the initial prompt strings, and prompt filters can define `:transientfilter()` and `:transientrightfilter()` functions to filter the transient prompt.
- Added `clink.logo` Clink setting to globally control what startup logo is shown (full copyright logo by default, or a short version logo, or no startup logo).
- Added `console.readinput()` function which waits for one key input, and returns the key sequence string for the key.
- Added `clink.reload()` function which reloads Lua scripts and the Readline config file at the next prompt.
- Added logging for more possible failure points while injecting Clink into the host process.
- Added default key bindings for `Ctrl`+`Up` and `Ctrl`+`Down` to scroll the screen one line, like conhost normally does.
- Now `clink set cl*` lists all settings that begin with `cl` (the star wildcard is only supported at the end of the string).
- Documentation includes a link to the new clink-flex-prompt.
- Fixed the Lua debugger to support printing UTF8 text, and to escape string variable contents to avoid escape code side effects.
- Fixed #154; crash when `settings.set("some_setting", false) is used.
- Fixed #153; ESC key problem. Clink migrated the old `esc_clears_line` setting backwards, causing `Esc` to behave opposite from what was expected.
- Fixed #152; LUA debugger breaks on the wrong line, and fails to execute expressions.

#### v1.2.28

- Added `rl.getpromptinfo()` function.
- Fixed loading .inputrc so that only one is loaded (regression introduced in v1.0.0a0 by the fix for mridgers #258). If similar behavior is still desired, consider using the `$include` directive in the Readline init file, to load additional files.
- Fixed `clink-select-complete` to respect when `mark-directories` in .inputrc file is `off`.
- Fixed crash in `console.findline()` when no attributes are passed. Callers using v1.2.27 and earlier can work around the crash by passing `{}` for attributes.
- Fixed an off-by-1 bug in `console.scroll("absolute", top)`. This will fix edge case malfunctions in some callers, but some callers could experience this as a breaking change.

#### v1.2.27

- The `cmd.get_errorlevel` Clink setting is now enabled by default.
- Clink now expands `$` codes in `%CLINK_RPROMPT%` before running prompt filters.
- Fixed parsing `2>&1` style redirection symbols, so the `&` doesn't get treated as a command separator.
- Fixed argmatchers to generate file matches for redirection arguments; `app.exe >` should generate file matches for the `>` symbol, not matches for the `app` argmatcher's first argument.

#### v1.2.26

- Fixed input line coloring for doskey aliases that don't have an argmatcher (regression introduced in v1.2.16).
- Fixed `Space` during `clink-select-complete` when there were already opening and closing quotes present.
- Fixed redrawing multiple lines of input after certain commands such as `clink-show-help` `Alt`+`H` (regression introduced in v1.1.20).
- Fixed the `completion-auto-query-items` config variable to account for multiple lines of input, if present.
- Fixed potential race condition if multiple Clink instances try to get the last errorlevel at the same time.

#### v1.2.25

- Added `cua-select-all` command to select the entire input line.
- Added `edit-and-execute-command` command to invoke an editor on the current input line and then execute the results (`Ctrl`+`X`,`Ctrl`+`E`). This attempts to invoke `%VISUAL%`, `%EDITOR%`, or `notepad.exe` as the editor, in that order.
- Added some new expansion commands:
  - `clink-expand-history` performs history expansion on the current input line (`Alt`+`^`).
  - `clink-expand-history-and-alias` performs history and doskey alias expansion on the current input line.
  - `clink-expand-line` performs history, doskey alias, and environment variable expansion on the current input line (`Ctrl`+`Alt`+`E`).
- Added some new completion commands:
  - `glob-complete-word` performs wildcard completion on the text before the cursor point, with a `*` implicitly appended (`Alt`+`G`).
  - `glob-expand-word` inserts all the wildcard completions that `glob-list-expansions` would list (`Ctrl`+`X`,`*`).
  - `glob-list-expansions` lists the possible wildcard completions of the text before the cursor point (`Ctrl`+`X`,`g`).
- Added some command name synonyms for increased .inputrc file portability with bash:
  - `alias-expand-line` is a synonym for `clink-expand-doskey-alias`.
  - `history-expand-line` is a synonym for `clink-expand-history`.
  - `history-and-alias-expand-line` is a synonym for `clink-expand-history-and-alias`.
  - `insert-last-argument` is a synonym for `yank-last-arg`.
  - `shell-expand-line` is a synonym for `clink-expand-line`.
- Added a `match.expand_envvars` Clink setting to expand environment variables in a word before performing completion (for mridgers #476).
- Changed the `match.wild` Clink setting to apply to all completion commands.
- Changed default key binding `Ctrl`+`Alt`+`E` to the `clink-expand-line` command (not the key binding expands everything, instead of only the env var at the cursor).
- Removed default key binding `Alt`+`Shift`+`H` for the `clink-show-help-raw` command (it has only niche usefulness).
- Removed unintended VI mode key binding `Alt`+`Ctrl`+`H`.
- Fixed `Ctrl`+`Shift`+`2` and `Ctrl`+`Shift`+`6` (regression introduced in v1.1.39).
- Fixed `More?` continuation prompt when pasting multiple lines.
- Fixed `/flag:` and `/flag=` handling quirks, especially when trying to complete an environment variable in `/flag:%env`.
- Fixed quirks about environment variable expansion in the `clink-expand-env-var` command and the `os.expandenv()` function.

#### v1.2.24

- Added support for `%CLINK_RPROMPT%` to show a right side prompt, and for prompt filters to define a `:rightfilter()` function to filter the right side prompt.
- Fixed `clink-select-complete` to not append a space after a flag that ends with `:` or `=` (e.g. `/x:`).

#### v1.2.23

- Fixed `PgUp` and `PgDn` in the `clink-select-complete` command, under certain conditions where they don't navigate in the intended manner.
- Cosmetic change: better key names for `Enter` vs `Ctrl`+`M`, and `Alt`+`Bkspc` vs `Alt`+`Ctrl`+`H`, depending on the `terminal.differentiate_keys` setting.

#### v1.2.22

- Added `clink-what-is` command bound by default to `Alt`+`?`, which shows the key binding for the next key sequence that is input.
- Added `rl.getargument()` function to get the accumulated Readline numeric argument, if any. For use in "luafunc:" macros.
- The `clink-show-help` command now categorizes key bindings and shows a description for the commands. Using a numeric argument can control whether categorization and descriptions are used.
- Fixed invoking `clink-select-complete` while it is already active, so that it doesn't lose quotes around the current match if it has quotes.
- Fixed `clink-show-help` to list "Enter" instead of "C-m" for the `Enter` key. Otherwise there's no way to differentiate between `Enter` and `Ctrl`+`M` when the `terminal.differentiate_keys` setting is enabled.
- Fixed the `insert-comment` command, which accidentally fell back to inserting `#` after the first prompt (that's what bash inserts, and shouldn't be used in Clink).
- Fixed the `dump-functions` command, which accidentally didn't list UTF8 key sequences correctly.

#### v1.2.21

- Fixed backwards exit codes from `clink autorun` commands.
- Fixed alert message text on startup when `debug.log_terminal` is set to true.
- Fixed #143; crash on start when `terminal.raw_esc` is true (regression introduced in v1.2.19).

#### v1.2.20

- Added `os.debugprint()` function to print debug text via the OS `OutputDebugString()` API.
- Enabled match completion coloring even when using match display filtering.
- Fixed input of slash and backslash in non-directory completions when using the `clink-select-complete` command.
- Fixed match display filtering in the `clink-select-complete` command.
- Fixed match display filtering in the `clink-popup-complete` command.
- Fixed quirk from Readline where it sometimes displays one fewer columns of matches than actually fit on the screen.

#### v1.2.19

- Added `clink-select-complete` command which shows an interactive list of possible completions.
- Added terminal emulation for CGI G, CSI s, and CSI u sequences.
- Fixed column alignment for match display filtering when some characters take more than one cell to display.

#### v1.2.18

- Added completions for `clink installscripts` and `clink uninstallscripts`.
- Added support for Readline's coloring and marking of symlinks.
- Fixed `clink installscripts --help`.
- Fixed `clink-popup-directories` for directories with spaces.

#### v1.2.17

- Added `clink-popup-show-help` command to show popup list with searchable list of key bindings and invoke the selected key binding.
- Added `clink.popuplist()` function to show a popup list. Only usable from inside a "luafunc:" key binding.
- Incremental search in the popup list window now centers the found item so items above and below it are visible.
- Fixed potential internal error when a doskey alias starts with `$` (regression introduced in v1.2.16).
- Fixed potential infinite loop when the `cmd.auto_answer` setting is enabled but an error occurs while retrieving a language string (might be related to #137).

#### v1.2.16

- Breaking Change: The `clink.onendedit()` Lua event has been split into two separate events:
  - `clink.onendedit()` registers a function to be called when the edit prompt ends.
  - `clink.onfilterinput()` registers a function to be called after the edit prompt ends (and after the onendedit event is sent), and the function can replace the input text.
- Added `rl.getkeybindings()` function to get a table containing key bindings. The bindings can be invoked via `rl.invokecommand()`. For example, a "luafunc:" macro could use this to get key bindings, show an interactive list, and then invoke the selected key binding.
- Fixed #134; `print()` can stop working. Issue #93 can potentially happen any time redirection is used, so the fix must be applied repeatedly (not just after Clink injection).
- Fixed #119; reuse registered parsers for doskey macros.

#### v1.2.15

- Fixed #132; multiline prompt gets overwritten when resizing the terminal width (regression introduced in v1.2.14).

#### v1.2.14

- Automatically runs `clink_start.cmd` from the binaries directory and/or the profile directory when Clink is injected.
- Clink is able to retrieve the last exit code for use by Lua scripts.
  - The new `cmd.get_errorlevel` setting is off by default, but when enabled it retrieves the last exit code from CMD before running Lua scripts.
  - The new `os.geterrorlevel()` function gets the last exit code (or 0 if the setting is off).
  - It works by running a hidden command line between each interactive prompt (as if you typed `echo %errorlevel%` yourself every second command you type). If you experience problems with this, turn it off.
- Improved refreshing the input line when resizing the terminal window. It's better than before, but there's no way to make it work perfectly because Windows can resize the terminal further while a program is already trying to respond to the terminal having been resized previously.
- Fixed #130; doskey alias completions stop working when there are many aliases.

#### v1.2.13

- Added support for linking a parser to flags ending with `:` or `=`; now completion works for the flag's argument.

#### v1.2.12

- Improved diagnostic output for coroutines (`Ctrl`-`X`,`Ctrl`+`Z`), plus more diagnostic info when the `lua.debug` setting is enabled.
- Fixed potential for a script error when a coroutine gets skipped due to a new prompt starting.

#### v1.2.11

- Added `clink.print()` function which behaves like `print()` but with support for ANSI escape codes (and terminal emulation), and also a `NONL` special argument that suppresses the usual newline at the end of the output.
- Expanded the sample code for async prompt filtering to clarify some things.
- Fixed #126; allow `Esc` to input literal escape character.
  - The new `terminal.raw_esc` setting controls how `Esc` input works.
  - Added migration for the old `esc_clears_line` setting.

#### v1.2.10

- Added asynchronous prompt filtering -- scripts can use this to do work in the background (e.g. `git status`) and refresh the prompt when finished.
  - Added `clink.promptcoroutine()` function to allow a prompt filter to do some work in the background.
  - Added `io.popenyield()` function to allow a coroutine to yield until the command's complete output is ready.
  - Added `prompt.async` setting that can disable asynchronous prompt filtering if preferred.
- Log error codes for failures during `clink inject`.
- Clarified help text for `clink autorun` (per #122).
- Documentation clarifications and reorganization.
- Fixed `clink` and `history` aliases getting lost after exiting a nested Clink instance.
- Fixed some input keys accidentally handled by the OS after certain Lua code is run.
- Fixed #124; `onfiltermatches()` receives one fewer matches than it should.
- Fixed #123; Failed to inject (Host validation failed).
- Fixed #117; Setup causes "System Error".

#### v1.2.9

- Added detection for possible antivirus interference when injecting Clink.
- Ignore duplicate scripts paths when loading scripts.
- Fixed #118; inputrc is not read from state directory (regression introduced in v1.0.0).

#### v1.2.8

- Fixed `...\` or `.../` to change directories (path separator after several dots).
- Fixed `/dirname/` to change directories (forward slashes when a directory is the only thing in the input line).
- Fixed #114; "Clink already loaded in process" error when autorun is installed for both Current User and All Users.
- Fixed #113; forward slash translation didn't work with the `cd` command.

#### v1.2.7

- Fixed #113; `clink.slash_translation()` had been removed (regression introduced in v1.0.0).
  - The new `match.translate_slashes` setting controls the default behavior for slash translation for completion matches.
  - The new `clink.translateslashes()` API can override slash translation for completion matches (and `clink.slash_translation()` is supported for backward compatibility).

#### v1.2.6

- Fixed tilde expansion for directory by itself; now `~\` can change the working directory to the `~` directory.
- Fixed pagination when displaying completions that take more than 1 line to display.
- Fixed inserting directory match completions when a Lua script didn't include a trailing path separator in the directory match.
- Fixed #111; `..` completion is different from bash (regression introduced in v1.0.0).

#### v1.2.5

- Added `os.expandenv()` function to expand environment variables in a string.
- Added `console.cellcount()` function to count the cells a string will use when displayed.
- Added `console.plaintext()` function to remove ANSI escape codes from a string.
- Clink now sets `%=clink.bin%` that points to the Clink binaries directory. This can be particularly useful for a portable installation of Clink so that scripts can find the Clink binaries directory and construct relative paths to other nearby files.
- Clean up column alignment in `--help` texts.
- Fixed `history.sticky_search` with anchored history search.
- Fixed `clink inject --profile` to use correct log file name while initially injecting.
- Fixed Clink autorun to be more compatible with Cmder (Cmder #2536).

#### v1.2.4

- Added support for `Shift`+`Arrows` to select text and typing to replace selected text.
- Added optional argument to `word_classifications:classifyword()` and `word_classifications:applycolor()` to allow only applying color where another color hasn't yet been applied.
- Fixed first `Up` after reusing a history line so that it gets the reused history line, rather than getting the previous history line.
- Fixed `add-history` command to not add blank lines to history.
- Fixed `rl.setmatches()` (regression introduced in v1.1.26).
- Fixed input coloring for `clink set` and any color setting name (regression introduced in v1.2).
- Fixed potential crash with `clink history --session`.
- Fixed `Ctrl`+`D` when `cmd.ctrld_exits` is disabled; it didn't exit, but it did still discard the input line and start a new prompt.
- Fixed #107; autorun reports inject failures (regression introduced in v1.2.3).
- Fixed #106; history missing `--bare` option (regression introduced in v1.2.3).

#### v1.2.3

- Added `history.sticky_search` setting: when enabled, reusing a history line does not add the reused line to the end of the history, and it leaves the history search position on the reused line so next/prev history can continue from there (e.g. replaying commands via `Up` several times then `Enter`, `Down`, `Enter`, etc).
- Added failure reporting and logging when `clink inject` fails.
- Added `--unique` flag for use with `clink history compact --unique` to remove duplicate entries from the history list.
- The `clink-popup-complete` command now matches wildcards.
- Restored the `Ctrl`+`Alt`+`U` key binding from v0.4.9 (moves the current working directory up one level).
- Fixed searching for inputrc files to also search in the profile directory (regression introduced in v1.0.0).
- Fixed incremental search in the History popup list to search in reverse order (bottom to top).
- Fixed `clink-popup-history` to set the history search position like other history search commands do, so that it plays well with the `history.sticky_search` setting.

#### v1.2.2

- Added `%CLINK_HISTORY_LABEL%` environment variable to use a different master history file (fixes #99).

#### v1.2.1

- Added Troubleshooting Tips section in the documentation.
- Added backward compatibility for `clink set` with v0.4.9. Old setting names and values are not documented, but are automatically mapped to the appropriate new setting(s). This was done so that suggestions in old web sites and posts can usually continue to work, to reduce confusion and support burden.
- Fixed #97; VS2017 error C2039: 'min': is not a member of 'std'.
- Fixed #96; wrong setting string (the name of a setting was accidentally truncated).
- Fixed some slightly inaccurate/incomplete migration from old settings to new settings.

#### v1.2

- First official release from chrisant996/clink fork.

#### v1.1.49

- Added `clink.classifier()` to enable coloring the input line independently from argmatchers.
- Added `word_classifications:applycolor()` to apply SGR escape codes anywhere in the input line.
- Removed `word_classifications:iswordclassified()`.
- Fixed the Product Version string in the binary file version resources.

#### v1.1.48

- Added `clink.getansihost()` function to get Clink's best guess who will process ANSI escape codes (can be useful for avoiding 256 bit and 24 bit color codes, for example).
- Added detection for being hosted in ConsoleZ.
- Fixed #20; `set /p VAR=""` shows the normal command prompt text instead of empty prompt text.

#### v1.1.47

- Added default key binding for `Ctrl`+`Space` to invoke `old-menu-complete`, which is the most similar to CMD's standard `Tab` behavior.
- Fixed `search-ignore-case` config variable to be on by default.

#### v1.1.46

- Added `rl.setvariable()` to temporarily override the value of a Readline config variable.
- The completion commands now also expand tilde by itself (`~`), in addition to tilde followed by a path separator (`~\etc`).
- Fixed #94; setting `history.save` to False also disables interactive history in subsequent sessions.

#### v1.1.45

- Fixed #93; stdout is sometimes broken by Cmder init.bat.

#### v1.1.44

- Added `clink.getsession()`.
- Added `%CLINK_NOAUTORUN%` which overrides automatic inject when Clink is installed for autorun.
- Fixed #92; `clink-popup-history` and similar commands not working with ConEmu and Cmder (regression introduced in v1.1.25).

#### v1.1.43

- Added `clink history --diag` flag that prints diagnostic information while performing history operations.
- Minor optimization in `clink history` when printing the full list of history items.
- Fixed `clink history compact` so it actually performs compaction.

#### v1.1.42

- Added `clink history --bare` flag to omit history item numbers.
- Added several Lua functions:
  - `io.popenrw()` is like `io.popen()`, but returns both a read file handle and a write file handle (see documentation for important usage warning).
  - `os.createtmpfile()` creates a unique named temporary file, with control over the prefix and suffix and path.
  - `os.getfullpathname()` to get the full path name for a file.
  - `os.getlongpathname()` to get the long path name for a file.
  - `os.getshortpathname()` to get the 8.3 short path name (if available) for a file.
- Improved argument validation for Clink's Lua APIs. This could expose bugs in existing scripts, so there is also a `lua.strict` setting that can be disabled to revert back to loose argument validation.
- Updated documentation.
- Fixed `clink history compact` so that it forces compaction as intended.
- Fixed completion for `clink set` so that filename completion works in string settings.
- Fixed backwards return value from `rl.invokecommand()`.
- Fixed console input/output modes across "luafunc:" key bindings, in case the Lua functions spawn a process that alters the console mode without restoring it.

#### v1.1.41

- Added `terminal.adjust_cursor_style` setting as a workaround to avoid interfering with the Windows 10 Cursor Shape console setting. There are several trade-offs, though.
- Added `rl_buffer:refreshline()` function to redraw the input line, e.g. in case something has written over it.
- Added `os.getpid()` function to get the process ID, intended mainly to help salt unique resource names.
- Added `clink.onfiltermatches()` so scripts can register a callback function to run after Clink generates matches and before it displays them.

#### v1.1.40

- Added a group of `clink-complete-numbers` commands that do completion for numbers from the console screen, bound to `Ctrl`+`Alt`+`N` by default.
- Added `rl.getlastcommand()` function that returns the name of the last command invoked by key bindings.
- Fixed sort order in `Alt`+`H` for the newly supported key bindings (that were added in v1.1.39).
- Fixed `Ctrl`+`Space` (regression introduced in v1.1.39).
- Fixed various `Ctrl`+`Shift`+`whatever` combinations (regression introduced in v1.1.39).
- Fixed `rl.setmatches()` when the input line is not empty and `clink.colorize_input` is enabled.

#### v1.1.39

- Added support for many more key bindings, such as `Ctrl`+`Shift`+Letter keys.
- Added `terminal.differentiate_keys` setting that when enabled allows binding `Ctrl` + `H` or `I` or `M` or `[` separately from `Backspace`, `Tab`, `Return`, or `Escape`.
- Removed `terminal.modify_other_keys` setting and made it always enabled.
- Changed `terminal.use_altgr_substitute` to be disabled by default so that `Ctrl`+`Alt` key bindings can work by default on keyboards with `AltGr`.
- Changed output from `clink echo` so it's directly usable in the inputrc files.
- Fixed `terminal.use_altgr_substitute` to only affect `AltGr` substitute key combinations (it had always broken the `RightAlt` key in general on other keyboard layouts).
- Fixed a benign issue with the console input mode in `clink echo`.

#### v1.1.38

- Fixed #84; added `terminal.use_altgr_substitute` setting.
- Fixed #80; clink.log is not deleted when Cmder injects Clink.

#### v1.1.37

- Fixed copy to clipboard (it never cleared the clipboard!).
- Fixed #82; added two new `clink.paste_crlf` modes: `ampersand` replaces newlines with ampersands, and `crlf` pastes newlines as-is and executes any commands ending in a newline.
- Fixed #69; space in the prompt disappears after enter echo: added support for CJK codepages.

#### v1.1.36

- Fixed #79; Issue with United States - international keyboard layout (regression introduced in v1.1.0).
- Fixed #78; crash when history file contains a line longer than 8192 characters (regression introduced in v1.1.2-alpha).

#### v1.1.35

- Fixed when the `mark-directories` inputrc variable is `off` (regression introduced in v1.1.1-alpha).
- Fixed Lua reading from stdin, especially in the Lua debugger (regression introduced in v1.1.25).
- Fixed exponential cost performance bug in Readline when removing duplicate matches.

#### v1.1.34

- Fixed copying to clipboard (CF_UNICODETEXT was put on the clipboard correctly, but CF_TEXT was empty and should have been omitted to let Windows automatically convert it from the Unicode text).

#### v1.1.33

- Make the "replacing arglink" warning message a little more informative, and write a lua traceback to the Clink log file.
- Fixed #77; with ConsoleZ scrolling does not always work.
- Fixed #76; cannot `cd` up multiple directories normally.

#### v1.1.32

- Added support for non-standard escape codes to set the window title or print environment variables. Depending on the `terminal.emulation` setting, the behavior is slightly different. When `emulate` Clink processes the escape codes. When `native` with ConEmu (and Clink) the escape codes are passed to ConEmu, except that Clink processes the environment variable codes in prompt strings. When `native` with other terminals, Clink preprocesses the title and environment variable escape codes in prompt strings, but passes the escape codes to the terminal outside of prompt strings.
- Fixed #67; AutoRun interferes with Cmder.

#### v1.1.31

- Fixed #74; clink gets confused by non-standard ConEmu escape codes.
- Fixed #73; `exec.space_prefix` and other settings defined in Lua scripts don't take effect until second input line (regression introduced in v1.1.4).

#### v1.1.30

- Fixed history compacting on x86 (regression introduced in v1.1.2-alpha).

#### v1.1.29

- Added `clink installscripts` and `clink uninstallscripts` to make it easy for package managers like Scoop to install/uninstall script packages for use with Clink. The installed script paths are stored in the registry for the current user.
- Fixed `bold` vs `bright` colors to more accurately follow generally accepted ANSI escape code conventions:
  - Renamed `dim` to `nobold` for clarity (though `dim` is still recognized for backward compatibility).
  - `bold` adds intensity to a non-intense color (e.g. `cyan` which is 36).
  - `nobold` removes intensity added by `bold` (e.g. `1;36` becomes `36`), but does not remove intensity from an explicit intense color (such as `bright cyan` which is `96`).
- Fixed support for `--file=` flags in argmatchers.
- Fixed match display filtering on the first try for a word (regression introduced in v1.1.19).
- Fixed the `clink --profile` flag (regression introduced in v1.1.10).
- Fixed `clink info` to accurately report the script dirs (it didn't account for the `clink.path` setting correctly).

#### v1.1.28

- Renamed the `log.rl_terminal` setting to `debug.log_terminal`; it has already been repeatedly very useful in multiple was since it was added, so it stays.
- Fixed #70; ctrl+c not working (regression introduced in v1.1.25).

#### v1.1.27

- Added `color.argmatcher` setting which, when set, is used to color a command name if it has an associated argmatcher (this supersedes `color.cmd`, `color.doskey`, and `color.input`). By default it's not set.
- Added `log.rl_terminal` setting which logs all terminal input and output for Readline (this setting may be renamed or removed in the future).

#### v1.1.26

- Added `rl.invokecommand()` which can invoke a Readline command from inside a "luafunc:" key binding.
- Added `rl.setmatches()` which can override match completions from inside a "luafunc:" key binding.
- Worked around UTF8 key binding problem with Readline which had been causing some meta key bindings (M-x, M-C-x, etc) to sometimes produce garbled key bindings and garbled entries in `clink-show-help` (`Alt`+`H`).
- Fixed crash if "luafunc:" key binding macro refers to a symbol that doesn't exist.

#### v1.1.25

- Added `clink-find-conhost` command that, when in a default (conhost) console window, is equivalent to picking "Find..." from the system menu.
- Added `clink-mark-conhost` command that, when in a default (conhost) console window, is equivalent to picking "Mark" from the system menu.
- `clink-copy-word` now copies the current word by default, but copies the nth word if a numeric argument is entered (see "Readline Arguments" in the Readline manual).
- Fixed match display filtering to not exceed the screen width (regression introduced in v1.1.12).
- Fixed multi-key sequences; in some cases it could get confused about whether an input key is part of a multi-key binding sequence (regression introduced in v1.1.1-alpha).
- Fixed stray input processing by conhost (holding `Ctrl`+`A` or `Ctrl`+`F` or etc could accidentally trigger conhost's shortcut keys).
- Fixed popup window location and size when using Windows Terminal.
- Fixed input coloring after `operate-and-get-next`; also fixes brief flicker of incorrect coloring whenever the input line is modified.

#### v1.1.24

- `auto` for `terminal.emulation` now uses native VT support on Windows 10 build 15063 and higher, unless the HKCU\Console\ForceV2 regkey is 0.
- Special quote handling now enables `"dir\"fi` to complete to `"dir\file"`. CMD simply strips quotes during completion, and now Clink behaves similarly.
- Breaking Change: `line:getword()` and `line:getendword()` now strip quotes from the word. This should generally automagically make existing match generators work even with embedded quotes, but there's a chance that some match generator might need to be updated. This seems like a reasonable compromise, given the general benefit purchased by this breaking change.
- `os:globdirs()` and `os:globfile()` strip quotes from the globpattern in order to behave more like CMD. Embedded quotes are nonsensical and the intended interpretation is clear, so the APIs now help out with that.
- Fixed #66; crash when injecting into 32 bit cmd (regression introduced in v1.1.21).
- Fixed #64; wrong cursor position when PROMPT contains BEL character.
- Fixed #62; argmatchers should color `-x:"foo"` as a flag if `-x:` is a flag.
- Fixed #61; argmatchers should not handle completion for text immediately following `-flag:`. Instead it always uses file completion. A custom generator can be used to override that behavior.
- Fixed #60; completion fails with multiple slashes.
- Fixed completion in some circumstances. Readline and Clink didn't always agree on where the word breaks were; now Clink always tells Readline where the word breaks are (so that completion, input colorization, and lua scripts can all work properly and consistently).
- Fixed 256 color ANSI codes.

#### v1.1.23

- Fixed #57; slashes not normalized in some cases.
- Fixed #45; interaction between `history.dupe_mode`=`erase_prev` and `history.shared`=`false`.
- Fixed `menu-complete-wraparound` when off and there's only 1 match.

#### v1.1.22

- Added `menu-complete-wraparound` (on by default) that controls whether completion commands wrap around when cycling past an end (affects popup windows as well).
- Fixed match completion getting stuck (regression introduced in v1.1.19).
- Fixed active mark region so it gets deactivated appropriately (it wasn't hooked up fully for Readline's callback mode, which is the mode Clink uses).
- Fixed `clink-show-help` (`Alt`+`H`) so it's able to list `C-@` bindings.
- Fixed inconsistent mark color.

#### v1.1.21

- Added `clink.oninject()` so scripts can register a callback function to run when Clink is injected into CMD.
- Added `console.linehascolor()` function that returns whether the specified line contains any of the specified colors.
- Added `console.findprevline()` and `console.findnextline()` functions that can search backwards or forwards for text and/or colors in the screen buffer. Regular expressions may be used.
- Fixed doskey alias parsing for match generators and input line coloring (Clink had been using slightly different parsing rules than CMD does).
- Fixed the "-- More --" prompt while listing key bindings; `Esc` didn't quit, and unexpected keys weren't ignored.

#### v1.1.20

- Now you can bind Lua functions to keys via "luafunc:" macros! Added new `rl_buffer` type that gets passed to the Lua function.
- Added a group of `console` Lua APIs intended mainly for use by Lua function key bindings (e.g. `console.scroll()`).
- Added `string.equalsi()` function that performs a case insensitive UTF8 comparison of two strings.
- Added `string.matchlen()` function that compares two UTF8 strings and returns how many characters match at the beginning, or -1 if the entire strings match. It respects the `match.ignore_case` and `match.ignore_accents` settings.
- Added `path.toparent()` function that adjust the input string by moving up one directory level.
- Added `clink.onendedit()` so scripts can register a callback function to run when editing finishes (e.g. `Enter` is pressed). If desired, the function can even change the input text. This is very powerful, and should be used carefully.
- Changed `os.getbatterystatus()` to return a table with the battery status details, rather than four separate return values.
- Fixed the `doskey.enhanced` setting to not expand doskey aliases when preceded by a space. However, a doskey alias after a `&` or `|` command separator needs to be preceded by two spaces to avoid expanding it. That's so `alias & alias` expands both, and `alias & alias` expands neither; while the rules are more complicated to explain, they make more sense visually.
- Fixed environment variable completion (regression introduced in v1.1.19).
- Fixed Cmder startup (regression introduced in v1.1.17). Cmder expects to be able to replace Clink v0.4.9's clink.lua file, but there is no such thing anymore in newer versions of Clink. To be properly backwardly compatible with Clink v0.4.9 requires loading clink.lua (if it exists) from the first script directory listed by `clink info`, and ignoring clink.lua files in all other script directories.

#### v1.1.19

- Improved responsiveness while typing: matches are collected only on demand, instead of always while typing. This makes it possible to always support match completion for UNC paths.
- Fixed #50; `Alt`+`H` could warn about likely mistakes in key bindings.

#### v1.1.18

- The input text now has context sensitive coloring based on the argmatchers. It's on by default and can be turned off with `clink set clink.colorize_input false`.
- Updated the Readline library to 8.1.
- Terminal emulation now supports the audible bell character.
- Fixed #48; `menu-complete` gets stuck.
- Fixed #47; `Alt`+`D` erases history instead of word.
- Fixed #46; typing `..` in subdirectory of root doesn't work.
- Fixed restoring color after pager when showing help.
- Fixed `clink set` match completions for color settings.

#### v1.1.17

- Added `os.getbatterystatus()` function that gets battery status information much faster than launching `wmic`.
- Fixed #44; Path completion doesn't work with `cd /d`.
- Fixed loading scripts to ignore loading clink.lua, so that loading scripts behaves like Clink v0.4.9.

#### v1.1.16

- Added `match.ignore_accent` setting (enabled by default) that ignores Latin alphabet diacriticals when completing matches (e.g. `ä` matches `a`, `ı` matches `i`, `ł` matches `l`, etc).
- Fixed #42; history lines are split on special characters.
- Fixed #41; Enable custom doskey handling of `..` and `-`.
- Fixed Readline bug inserting dir matches; `\win_ foo` (cursor at `_`) would become `\Windows\\_ foo`.
- Fixed the `quoted-insert` command to insert just `\x1b` when `ESC` is pressed.

#### v1.1.15

- Migrating settings now immediately writes a new settings file, instead of waiting until a setting is changed.
- Added support to detect when running in Windows Terminal and use native terminal support (which enables things like Xterm 256 and 24-bit color support).
- Added terminal emulation support for Xterm 256 and 24-bit color escape codes. Clink maps the specified color to the most similar color in the active 16 color palette (using the CIELAB color space). To get full support for 24-bit color, it's necessary to use ConEmu or Windows Terminal or a similar console host, or to set `terminal.emulation` to `native` (which isn't supported on some older Windows OS versions).
- Allow doskey macros named `..` or `-`, and also now doskey macros that resolve to `..` or `-` or a directory name will work (just like if the macro text had been typed at the Clink prompt).
- Fixed compatibility problem with various scripts getting the %HOME% environment variable. Now if it isn't set, then Clink synthesizes %HOME% from %HOMEDRIVE% and %HOMEPATH% or from %USERPROFILE%.
- Fixed saving color settings to behave like other settings: only write a setting's value to the setting file if it differs from the default value.
- Fixed the `clink.print()` Lua function so it also works during loading scripts and during prompt filtering.
- Fixed the Readline input text display getting garbled if the filtered prompt includes Xterm's OSC window title code (`\x1b]0;text\x07`). Clink doesn't support that escape code, but at no longer garbles the input text if that escape code is present.

#### v1.1.14

- Migrate settings and history from an old version of Clink, if present. This only happens if the new-version Clink settings or history files don't exist. (Deleting an existing new-version Clink settings or history file will cause migration to happen again.)
- Added `color.prompt` setting for backward compatibility with Clink v0.4.x.

#### v1.1.13

- Fixed `clink.arg.register_parser` backward compatibility.

#### v1.1.12

- Added `clink.ondisplaymatches()` as a replacement for the deprecated `clink.match_display_filter`. The new API is able to support popup list windows as well.
- Speculative possible fix for #35 Crash when clink on clink.bat.
- Fixed #33; Tab autocomplete, auto-quoting paths doesn't seem to work as in Clink 0.4.9.

#### v1.1.11

- Changed to load Lua scripts only once per session, unless forced to reload them. This enables backward compatibility for things like z.lua which has certain features that rely on Clink only loading scripts once per session.
- Added `clink.onbeginedit()` so scripts can register a callback function to run each time the edit prompt is activated.
- Added `lua.reload_scripts` setting to optionally force reloading Lua scripts each time the edit prompt is activated.
- Added `color.message` setting for the Readline message area color (e.g. the search prompt message or digit argument prompt message, etc).
- Fixed stray sticky `=` appended to completions after typing `set` and then typing a different command.

#### v1.1.10

- Fixed #32; hooking `ReadConsoleW` on Windows 7.

#### v1.1.9

- Added backward compatibility for `clink.match_display_filter`. The clink-completions/git.lua script uses it a lot, and that should all be working now.
- `settings.add` adds a color setting when the type is string and the name starts with "color.".
- `settings.get` now has an extra parameter to request the user friendly color name when getting a color setting.
- Added `clink.version_encoded` variable with the Clink version number as MMmmmpppp (e.g. v1.1.9 is `10010009`) to make it easy for scripts to check for feature availability.
- The `clink info` command now shows Lua script paths as well.
- Fixed backward compatibility for loading scripts from the profile directory (if `clink.path` isn't set, then load scripts from the DLL directory and the profile directory).
- Fixed some `color.input` bleed through to other things (introduced in v1.1.5).
- Fixed scroll commands (regression introduced by input line color in v1.1.5).
- Fixed horizontally sorted match display and re-enabled the performance fix from v1.1.4.
- Fixed wildcard evaluation with non-file and non-directory matches (e.g. a branch name `origin/master` accidentally didn't match `or` or `*ma` because of the `/`).
- Fixed sort order of `foo\` vs `foo.bar\` when displaying matches or using the `menu-complete` family of commands.
- Fixed potentially-missing trailing path separator when `menu-complete` completes a directory match (regression introduced by wildcard matching in v1.1.5).
- Other obscure minor fixes.

#### v1.1.8

- Fixed file match completions when an argmatcher only generates flag matches.
- Fixed automatic inferring whether Readline should use filename completion and/or display rules (regression introduced by backward compatibility in v1.1.3-alpha).
- Fixed backward compatibility for `clink.find_files()` and `clink.find_dirs()` (regression introduced by performance improvement in v1.1.7).
  - Ignore extra arguments after the first one (the performance improvement in v1.1.7 revealed that some scripts call `clink.find_files()` with extra invalid arguments; e.g. clink-completions/modules/matchers.lua).
  - Don't append a trailing path separator on directory names returned by these functions (the new `os.globfiles()` and `os.globdirs()` functions do, but the old `clink.find_files()` and `clink.find_dirs()` functions should not).
- Fixed backward compatibility for coloring matches (regression introduced by backward compatibility changes in v1.1.4).

#### v1.1.7

- Performance improvement when displaying matches: When enumerating files and dirs, the `os.globfiles` and `os.globdirs` functions have all the info about each file. Now they can return that info in a table. This frees the match display function from needing to do any further file system IO. The performance boost is noticeable.
- Rewrote the color settings: the .fg and .bg sub-settings are gone, and the main setting now uses a more natural syntax (e.g. `clink set color.input bright yellow` or `clink set color.modmark bright cyan on blue`).
- Added "cmd" match type for shell (CMD.EXE) command completions.
- Added VT emulation for the reverse video SGR parameters.
- Fixed tab completion for `clink set setting`, and also handle the new color setting syntax.
- Fixed confusing behavior if multiple scripts try to add settings with the same name (now the first one succeeds and the rest report errors).

#### v1.1.6

- Hooked up tilde completion in the `cd`, `md`, and `rd` command argmatchers.
- Hooked up tilde completion with the `exec.enable` setting ("~\pro" matches "C:\Users\myusername\program.exe").
- When `terminal.emulation` is `auto`, now it also detects ANSI{32|64}.DLL just like Clink 0.4.8 did.

#### v1.1.5

- The `menu-complete` family of commands now support matching `?` and `*` wildcards when the `match.wild` setting is enabled.
- Added `colour.input` and `colour.modmark` settings for coloring Readline's input line.
- Added `clink.upper()` Lua function, and both `clink.lower()` and `clink.upper()` are properly UTF8 aware now.
- Added `clink-copy-word` command that copies the word at the cursor to the clipboard.
- Added `clink.promptfilter` setting to control whether to filter the prompt with Lua scripts.
- Renamed `terminal.emulate` setting to `terminal.emulation`.
- Improved executable file extension logic to consistently use %PATHEXT% (and efficiently).
- Improved file extension logic (e.g. "file.foo bar" has no extension because of the space).
- Updated arg matcher for `clink` itself (was missing some flags).
- Changed `colour.hidden` setting to not be set by default.
- Fixed #28; Tab completion for "~" does not work.
- Fixed #25; Unicode surrogate pairs (and emoji) input isn't working -- Microsoft Terminal renders the text correctly, but ConEmu and the default conhost still don't (and that isn't a Clink issue).
- Fixed screen size bug in Readline on Windows.
- Fixed the backwards values in the `terminal.emulation` setting.
- Fixed `....` so it works properly again.
- Fixed case sensitive sorting of matches.
- Fixed script error when %PATHEXT% is empty.
- Fixed the `exec.cwd` Clink setting to default to true, so that the default behavior is consistent with how v0.4.x behaved.
- Fixed the `cd`, `md`, `rd`, etc argmatchers to only match one argument to be consistent with the actual command syntax.

#### v1.1.4

- Automatically detect when running inside ConEmu and disable Clink's Virtual Terminal emulation.
- Added `search-ignore-case` inputrc variable that makes the history search commands case insensitive.
- Suppress adding a space after completing a flag match that ends with `:` or `=` (e.g. `msbuild -maxCpuCount:`).
- Report any errors while loading Lua scripts.
- Report an error if a Lua script tries to add a flag string that begins with a letter.
- Fixed slow printing of possible matches. Readline is inefficient about emitting output, so Clink supplies a custom implementation.
- Fixed some bugs in auto detection of flag prefix characters.
- Fixed backward compatibility for flags, and for args when merging two parsers by calling `clink.arg.register_parser('foo')` multiple times for the same command string.
- Fixed truncated message when the last line of a prompt exceeds 128 characters.
- Fixed abort (`Ctrl`+`G` or `Esc`) in non-incremental history search mode.
- Fixed saved values for settings added by Lua scripts; now the saved value is available to the script immediately on adding the setting, and saved values are retained even if the setting isn't always added by the script.
- Fixed (and documented) shorthand form for defining an argmatcher.
- Fixed length of colored match prefix after a path separator.
- Fixed normalizing a slash by itself (`command /` mustn't become `command \` since that can interfere with completing flags).
- Fixed the `completion-auto-query-items` inputrc variable.
- Fixed the key binding list to correctly respect `completion-display-width`.
- No visible effect yet: internal change that parses the input line to identify colors to use for each word (command, argument, flag, etc), but the colors aren't yet applied to the input line.

#### v1.1.3-alpha

- Fixed argmatcher lookup to be more strict, like in Clink 0.4.9 (match exact names, or name plus an extension from %PATHEXT%).
- Backward compatibility:
  - Most things should work now.
  - Dropping the new Clink on top of the vendor\clink directory in Cmder seems to work -- but make a backup before you try this at home!
- API changes:
  - Added `log.info()` function.
  - Added Clink version numbers in `clink.version_major`, etc.
  - Added `_argmatcher:getwordbreakinfo()` callback; removed `_argmatcher:setprefixincluded()` (it was a mess, and it was new to v1.x, so there's no compatibility concern with removing it).
  - Deprecated `_argmatcher:setflagprefix()`; now it happens automagically when using `_argmatcher:addflags()`.
  - Introduced several deprecated functions to support backward compatibility.
- Improvements to Lua debugger:
  - Added `lua.traceback_on_error`, `lua.break_on_error`, and `lua.break_on_traceback` settings to make debugging script errors easier.
  - Made `pause()` consistent about pausing in the caller (rather than sometimes inside the pause command itself).
  - The debugger automatically shows the stack trace when entering debug mode, and on every pause.
  - Show 3 lines of source context by default.
  - The help list is sorted now.
  - Fixed the `set` command in the debugger to behave as documented.

#### v1.1.2-alpha

- Documentation is mostly updated; just the argmatcher Lua API and Clink command line options are left to be documented.
- Added `history.max_lines` setting that controls how many lines of command history to save (1 to 50000, default is 2500).
- Added `readline.hide_stderr` setting that can suppress stderr output from the Readline library.
- For backward compatibility with 0.4.8, `clink_inputrc` files are loaded as well.
- Lua script API changes:
  - `addmatch()` in Lua scripts takes an optional match type argument.
  - Removed `displayable`, `aux`, and `suffix` fields in matches.
  - Revert the change to disallow mixing file/directory/symlink with other match types (it broke the tests and certain completion scenarios).
- Fixed issues:
  - #18 alt+digit then alt+ctrl+y isn't working.
  - #17 arrow keys don't exit `reverse-search-history` like in bash.
  - #16 problems with $T in doskey macros.
  - #13 `clink history delete <n>` returns a CRT error.
- Other fixes:
  - There should be no more problems running on Windows Insider builds because Clink now uses Detours for hooking APIs.
  - Fixed crash in `insert-completions` due to heap failure (introduced by the performance changes for displaying matches).
  - Fixed `clink` and `history` built-in aliases (solve glitchy path problem).
  - Fixed scrolling to top of screen buffer.
  - Fixed env var and `set` completions.
  - Fixed `tilde-expand` for quoted text.
  - Fixed `Esc` in Readline's digit argument input mode (it doesn't try to cancel the mode, because that's not how Readline is documented to work).
  - Fixed exit code from some `clink` command line options.
- Set locale to UTF8 much earlier to avoid quirky behavior early in script processing.

#### v1.1.1-alpha

- Exclusively use Readline's completion implementation. This (with fixes and enhancements in Readline itself) makes the completion experience much nicer and more sophisticated, and removes a lot of code that was added in v1.0.0a0.
- Exclusively use Readline's key binding implementation. This makes it possible to have a single consistent way to set key bindings (inputrc) and for `clink-show-help` to list all key bindings, and removes a lot of code that was added in v1.0.0a0.
- Converted all of Clink's internal key behaviors to be implemented as commands that can be bound in the inputrc file.
- Rewrote and refactored the pagination routine to be used in multiple places.
- Fixed prompt filtering to correctly use the specified priority order.
- Readline library:
  - Updated the Readline library from v6.2 to v8.0. This picked up lots of bug fixes and new capabilities (for example colored completions).
  - Changed Readline to support backslash as a path separator.
  - The pager prompt in Readline is optionally colored, controlled by the `colour.interact` Clink setting.
  - Added `completion-auto-query-items` config variable (on by default) which asks whether to list possible matches when the number of lines listed will fill one screen page.
  - Added `history-point-at-end-of-anchored-search` config variable in inputrc to make the cursor point behave like 4Dos/4NT/TakeCommand when searching forward and backward through command history.
  - Fixed prev history at top of history.
  - Fixed to get the current values of environment variables when needed, rather than always getting the value from whenever Clink was started.
  - Fixed coloring directory completions.
  - Fixed `menu-complete` for `\dir` and `.` and `..`.
  - Fixed slow performance when displaying matches. Readline was calling stat() at least once per match (!!). A new match type field enables faster performance, coloring readonly and hidden file matches, applying filename completion rules only to filenames (vs branch names or other text strings), correct match de-duplication, and more. The Lua match APIs can supply the new match type.
  - Fixed inserting a completion to happen as a single undo group.
  - Fixed tilde to map to `%USERPROFILE%` instead of `%APPDATA%` on Windows.
- Typing a directory by itself uses `cd /d` to change to the directory:
  - Typing a directory with a trailing path separator changes to the directory.
  - Typing `..\` changes to the parent directory.
  - Typing `...` or `....` etc moves up an extra parent directory level for each extra dot (2 dots move up one parent, 3 dots moves up two parents, etc). A trailing path separator is optional when there are more than 2 dots.
  - Typing `-` or `cd -` or `chdir -` changes to the previous directory.
- Commands that are new, enhanced, or fixed:
  - Added `add-history` and `remove-history` commands (similar to 4Dos/4NT/TakeCommand).
  - Got the `menu-complete`, `menu-complete-backward`, and `old-menu-complete` commands working (they never worked properly before in Clink).
    - Also added a corresponding `old-menu-complete-backward` command for reverse order.
    - All of the `*-menu-complete-*` commands support wildcards (`*` and `?`).
  - Added `clink-show-help` command (`Alt`+`H`). The help now lists all key bindings, and it shows user-friendly key names (like `A-Up` or `C-x,C-r` or `C-S-PgUp` or `A-C-S-F3`).
  - Added `clink-popup-completions` command that shows a popup window listing possible completions. `Enter` inserts the highlighted completion.
  - Added `clink-popup-directories` command that shows a popup window listing recent directories. `Enter` changes to the highlighted directory, or `Shift`+`Enter` inserts the highlighted directory in the editing line (or `Ctrl`+`Enter`).
  - Added `clink-popup-history` command that shows a popup window listing command history. `Enter` executes the highlighted command, or `Shift`+`Enter` jumps to the highlighted command in the history (or `Ctrl`+`Enter`).
  - Added `clink-scroll-lineup`, `clink-scroll-linedown`, `clink-scroll-page-up`, `clink-scroll-page-down`, `clink-scroll-top`, and `clink-scroll-bottom` commands that do what it looks like they'd do and are bound to the keys it looks like they'd be.
  - Added `clink-expand-doskey` command (`Ctrl`+`Alt`+`f`) that expands the current line according to the current doskey aliases.
  - Added `clink-expand-env-var` command (`Ctrl`+`Alt`+`e`) that expands the environment variable at the cursor point.
  - Added `clink-exit` command (`Alt`+`F4`) that exits CMD.
- Fixed keyboard input issues:
  - `Esc` is a bindable key now (`\e[27;27~`).
  - Added more bindable key combinations (run `clink echo` then press keys to see the key sequence to use in the inputrc file).
  - `Ctrl`+`@` (NUL) didn't work.
  - `Ins` toggles insert/overwrite mode.
  - Unbound keys are ignored now, instead of inserting gibberish characters (part of the terminal internal key sequence).
  - Fixed input handling so the `quoted-insert` command can work properly.
  - Fixed `Esc` while searching.
  - Fixed vi mode (was working in v0.4.9, but not in v1.0.x).
- Fixed command history issues:
  - The `dont_add_to_history_cmds` Clink setting is a space-delimited list of commands to not add to history.
  - Fixed bleeding between history banks.
  - Fixed uninitialized variable that made history updates intermittently do nothing or corrupt the other history bank.
  - Fixed output from `clink history` to convert to UTF16 when writing to the console (but write UTF8 when output is redirected).
- Fixed terminal output issues:
  - Added `terminal.emulate` Clink setting that controls whether Clink does VT emulation or passes all ANSI escape codes directly to the console host. For example, this lets the prompt and completion coloring take advantage of more sophisticated ANSI escape codes such as XTerm 256 color and 16 bit color support.
  - Added back support for the `prefer-visible-bell` config variable.
  - Fixed underline support.
  - Fixed handling for UTF8 output from Readline.
  - Fixed invisible cursor point in Lua debugger.
- Completions:
  - Added `match.sort_dirs` Clink setting that specifies where to sort directories in the list of possible completions: before files, mixed in with files, or after files.
  - Don't attempt completing incomplete UNC paths: at least the `\\server\share\` path components are required (for anything shorter the OS APIs are guaranteed to fail, but will fail slowly).
  - Fixed sorting to use Unicode aware locale based sorting (like Windows does) instead of dumb UTF8 byte comparisons.
  - Fixed arbitrary limit on completions (had been limited to 64KB worth of completions).
  - Fixed quoting spaces in completions.
  - Fixed to use the same list as CMD for characters that require quoting.
  - Fixed normalizing UNC paths.
  - Fixed volume relative completions (e.g. `x:foo`).
  - Disallow mixing file/directory/symlink with other match types. This was to avoid a confusing/malfunctioning case in match display and prefix highlighting.
- Fixed UTF8 encoding in various Lua functions.
- Fixed printing stderr output from Readline, Lua, and Clink.
- Fixed crashes and other failures when starting Clink in 32 bit CMD.
- Fixed some memory leaks that accumulated with each new line of input.
- Fixed prompt filtering API to be backward compatible with v0.4.9 scripts.
- Fixed Lua errors from `clink set` (it neglected to fully initialize Clink's Lua integration before loading Lua scripts).
- Fixed UTF8 conversion bug that could truncate a string without fully converting it.
- Fixed serious rampant memory corruption bug in v1.0.x (not present in v0.4.9), which had been causing intermittent malfunctions and data corruption and crashes.
- Fixed multi-line doskey macros to show the prompt in between lines, like CMD does.
- Removed the 4096 byte limit on input.
- Renamed the Clink DLL back to what it was in v0.4.x, to fix compile time problems.
- Other fixed issues:
  - mridgers #544 Clink v1.0.0.a1 doesn't support cyrillic characters keyboard input on Windows 10 with console V2.
  - mridgers #543 Not compatible with Windows Insider Build 20150.
  - mridgers #537 Clink breaks the CMDS tool.
  - mridgers #520 Clink 1.0.0.a1 - `clink set history_io 1` Error.
  - mridgers #519 Clink v1.0.0.a1 - `-s|--scripts [path]` command line arg removed?
  - mridgers #516 Doskey $T not handled properly.
  - mridgers #512 Command history missing in .history.
  - mridgers #503 Keyboard shortcut for scrolling.
  - mridgers #501 `Ctrl`+`Backspace` works now.
  - mridgers #487 Clink breaks ConEmu-specific Escape codes.
  - mridgers #480 History never saved.
  - mridgers #465 Using LuaJIT (FFI).
  - mridgers #456 Clear-screen not working properly when PROMPT is two lines long.
  - mridgers #453 Wrong cursor position when a line contains non-printable characters.
  - mridgers #442 Unable to paste more than 1024 characters using `Ctrl`+`V`.
  - mridgers #422 Problem with filename modifiers.
  - mridgers #420 Use NtSuspendProcess instead of CreateToolhelp32Snapshot to freeze the threads.
  - mridgers #372 Provide a way to select a previous directory.
  - mridgers #365 history-search behavior.
  - mridgers #342 Clink_inputrc not being processed if it the clink_inputrc is a link (created via mklink).
- Fixed many other bugs.

### Releases from mridgers/clink original repo

#### v1.0.0a1 (alpha test release)

- Improve terminal integration with the Readline library.
- Internal improvements to the built-in ecma48 terminal emulator.
- Fixed use after free in Doskey emulation.
- Fixed dash-dash flag completion.
- Search ancestors for a compatible target process (for when cmd.exe starts another process that subsequently starts clink; especially useful during development).
- Use clink/terminal's wcwidth() implementation.
- screen_buffer::set_cursor() should be relative to the visible area.
- Try to adjust the cursor position better when resizing the terminal.
- Some internal Lua functions needed the unquoted clink exe path.
- The origin path now affects the hash in the dll cache, to guard against directory moves.
- More code reorganization.

#### v1.0.0a0 (alpha test release)

- Extensive code reorganization, refactoring, and rewriting -- multiple times -- almost everything was touched.
- OS integration:
  - Fixed Doskey macros on Win8, and on Win10.
  - Fixed `clink_x??.exe` startup stall on Windows 10.
  - Removed XP support. It doesn't load DLLs like Clink uses them.
  - Removed Powershell support.
- Readline integration:
  - Search for multiple places for [.|_]inputrc (fixes mridgers #258).
  - Disabled Readline's completion code, and only use the clink alternative code.
  - Removed redundant slash translation and shims to make it happen.
  - Removed control of Readline's suffix appending and disabled it.
- `clink` commands and flags:
  - Changed `--cfgdir` to `--profile`, it's no longer required, and added help about it.
  - Added a `--version` option to print Clink's version.
  - Added `clink info` to print information about Clink.
  - Added `clink echo` command to echo input key sequences to stdout.
  - Added `clink history` command (fixes mridgers #172).
  - Added `history` as an alias for `clink history`.
  - Added internal `--list` flag to `clink set` for match generation.
  - Removed `--scripts` argument (fixes mridgers #206).
  - Updated `clink autorun` command's help text.
- Lua scripts:
  - Prefer `userprofile` over other standard environment variables for where to look for lua scripts.
  - New API for argument style completion scripts.
  - Refactored prompt filtering, and introduced new prompt filtering API.
  - Refactored generating matches, and introduced new match generator API.
  - Removed built in completions scripts for git, go, hg, and p4. There's better ones.
  - Renamed many of clink's Lua functions.
  - Moved functions from `clink` to `os` in Lua.
  - Removed `clink.is_match()` in Lua; don't presume anything on anyone's behalf about matches.
  - Added some current dir functions in Lua.
  - Added some env/dir functions in Lua.
  - Exposed path manipulation functions to Lua.
  - Embed the core Lua scripts instead of loading them from files.
- Terminal IO:
  - Added a module for scrolling the screen.
  - Rewrote the terminal emulation module, and all Readline IO goes through it.
  - Use VT220-style control codes for special keys.
  - If `Alt` is pressed send ESC in the input stream rather than setting meta bit.
  - Replaced wcwidth() with a more complete and correct version.
- Settings:
  - Added `clink_path` setting for where to look for lua scripts.
  - Added `match.ignore_case` setting.
  - Added `files.unc_paths` setting for optional matching from UNC paths.
  - Added a setting to skip adding lines that start with `history`.
  - Removed `esc_clears_line` setting.
  - Pasting CRLFs doesn't really make sense.
  - Don't write out settings that are set to default.
- Make sure `Ctrl`-`C` doesn't modify history.
- Make a cached copy of Clink's DLL when injecting so as to not lock the master.
- Guard against Readline's writes to stderr.
- Remove `clink_inputrc_base` file and embed its content (fixes mridgers #257).
- Include more metadata in the Clink's executables.

#### v0.4.9

- Fixed broken Doskey on Win10 (#438, #451)

#### v0.4.8

- Environment variable `clink_profile` overrides Clink's profile path (#390).
- Load a clink_inputrc file from Clink's profile directory (fixes #406).
- Bug fixes;
  - Redraw issues when prompts end in OSC ANSI codes (#387, #384).
  - Fixed `clink autorun --help` crash.

#### v0.4.7

- Bug fixes;
  - Sometimes autorun tries to run clink.exe (#374).
  - Autorun would cause cmd.exe to return an error if it wasn't interactive (#373).

#### v0.4.6

- HOME is only set if it is currently unset.
- Readline can be initialised with .inputrc and _inputrc files too (#258).
- Bug fixes;
  - Executable completion;
    - Paths from PATH were checked twice.
    - Incorrect results were returned for words ending in `.` or `-`.
    - Directories . and .. were incorrectly displayed.
  - Fixed a crash if .bat script's stdout is redirected (#366).
  - Occasional crash when injecting Clink (#351).
  - Display errors;
    - When editing near the window's right-hand edge (#347).
    - Double display of multi-line prompts when resizing the terminal (#352).
    - Very rare wrap artefacts when making the terminal window larger.
  - Doskey emulation (#344).
  - Improved `clink autorun` help (#348).
  - Fixed launching Clink when clink.bat is renamed (#357).

#### v0.4.5

- Improved `clink autorun`. It now defaults to the Current User registry hive.
- `clink set` gives more details for enumeration-type settings.
- Tab completion for p4vc.
- New settings `history_expand_mode` to control history expansion in quotes (#317).
- Bug fixes;
  - Use full width of the terminal (#337).
  - Fixed MinGW compile error (#335).
  - Autorun now defaults to the current user's hive (#332).
  - Creating clink.html no longer needs Pandoc, plus it looks a bit better (#331).
  - Added settings to control history expansion (#326).
  - Correct fallback when `use_altgr_substitute` is off (#325).
  - Load history prior to saving it on shutdown (#318).
  - Added Shift-Tab documentation and menu completion example (#190).
  - Added shim for backwards menu completion (#190).
  - Input handling now outputs `\e`Z` for `Shift`-`Tab` (#190).
  - Updated Readme with current Premake info (#310).
  - Guard against there being no buffer to read from (#304).
  - Fixed artefacts when resizing conhost's buffer (#139).
  - Clear remaining characters if scroll window was too small (#301)
  - Escape % characters when expanding aliases (#280).
  - Fixed leaking exception filters.
  - Clearing the screen doesn't leave artefacts behind.

#### v0.4.4

- Completing .. behaves more like Bash (#277).
- Escape from yes/no question when `Ctrl`+`C` is pressed.
- Valid XP executables (#278, #289).
- Fixed n-th argument yank not working as expected (#254).
- Fixed prompt colours sometimes not working (#279, #286).
- Fixed `!0` causing Clink to crash.
- Save/restore cursor position in case Readline moves it.

#### v0.4.3

- Localised Y/N when auto-answering "terminate?" prompt.
- `$*` would early out if there was no arguments.
- Disable ANSI code support if third party provides it.
- Installer can now set %CLINK_DIR% to install location.
- Improved output from `clink set`.
- Support for Windows 10 Technical Preview.
- `Ctrl`-`L` now scrolls last line to the top of the window rather than clearing.
- New option to control how newline characters are pasted to the line.
- New options to control history;
  - `history_file_lines` - maximum lines saved to disk.
  - `history_ignore_space` - ignore lines prefixed with whitespace.
  - `history_dupe_mode` - how duplicate entries are handled.
  - `history_io` - load/save history from disk every line.
- Fixed nonfunctional numpad keys.
- Fixed missing WINCH signals if other processes resize the buffer.
- Support `Alt` codes sent from Conhost.

#### v0.4.2

- Prompt colouring no longer requires third party ANSI code utility.
- Override settings with environment variables prefixed with 'clink'.
- Ctrl-PgUp goes up a directory.
- Updated Go completions (by matrixik).
- Arguments to clink.arg.new_parser() now initialise parser's flags/args (from vladimir-kotikov).
- New clink.arg.add_flags() and clink.arg.add_arguments() functions.
- Removed footer and `Alt`-`H` tip for more succinct stdout output.
- Bug fixes;
  - Windows XP works again.
  - Fixed race condition in lua_execute().

#### v0.4.1

- Bug fixes;
  - Various Unicode fixes causing corrupt environment variables.
  - Fixed thread resume/suspend causing rare system-wide deadlock.
  - Fixed incorrect translation of suffixed slash when completing flags.
- Add `--nolog` argument to disable file logging. Fix #187 Fix #154
- Added missing escape sequences from doskey emulation.
- Reinstated unix-kill-line key binding.
- Mapped `PgUp`/`Down` to search history using line typed so far.
- Added documentation covering escape codes for special keys.
- Added support for Windows' `AltGr` substitute `Ctrl`-`Alt`.
- Support for Readline's 'menu' style completion (see docs).

#### v0.4

- New features;
  - Better `clink.arg` API. Easier, more intuitive, and more powerful.
  - Whitespace prefix skips exec matching.
  - Added a `set` verb to easily change settings from the command line.
  - Basic support for a shells other than cmd.exe.
  - Completion for Go (contributed by Dobroslaw Zybort).
  - Setting `exec_match_style` to -1 disables it entirely.
  - Make history persistence optional.
  - Alias/doskey completion.
  - Very basic support for Powershell.
  - View cmd.exe's autorun entry without needing admin rights.
- New key bindings;
  - `Ctrl`-`Alt`-`C` : Copy command line to the clipboard.
  - `Ctrl`-`Alt`-`E` : Expand environment variable under cursor.
  - `Ctrl`-`Alt`-`U` : "up directory" (formerly `Shift`-`Up`).
  - `Ctrl`-`U` : Adds `..\` to the command line.
  - `Alt`-`H` : Shows active keymap's key bindings.
- New Lua functions;
  - clink.execute().
  - clink.get_host_process().
  - clink.match_files().
  - clink.match_words().
  - clink.get_console_aliases().
- Lots of bug fixes, including;
  - Better command extraction.
  - Fixed cmd.exe command paging and `Ctrl`-`C`/`Ctrl`-`Break` handling.
  - Multiple locale fixes.
  - Use localised text for "Terminate batch job?" prompt.

#### v0.3

- Automatic answering of cmd.exe's "Terminate batch script?" prompt.
- Coloured prompts (requires ANSICON or ConEmu).
- Added Shift-Up keyboard shortcut to automatically execute `cd ..`
- Mapped `Ctrl`-`Z` to undo, Microsoft style.
- Improved integration of Readline;
  - New input handling code (`Ctrl`-`Alt` combos now work).
  - An implementation of the Termcap library.
  - Fully functional Vi-mode support.
  - Support for resizable consoles.
  - Line wrapping now works correctly (issue 50).
- Adjustable executable match style (issue 65).
- Improved environment variable completion.
- Added settings file to customise Clink.
- New Lua features and functions;
  - Matches can now be filtered in Lua before they are display.
  - clink.quote_split().
  - clink.arg.node_merge().
  - clink.get_screen_info() (issue 71).
  - clink.split() (for splitting strings).
  - clink.chdir().
  - clink.get_cwd().
  - Functions to query Clink's settings.
- New command line options;
  - `--profile dir` to override default profile directory.
  - `--nohostcheck` disables verification that host is cmd.exe.
  - `--pid` specifies the process to inject into.
- Update Mercurial completion (issue 73).
- Start menu shortcut starts in USERPROFILE, like cmd.exe
- Zip distribution is now portable.

#### v0.2.1

- The .history file now merges multiple sessions together.
- Fixed missing y/n, pause, and other prompts.
- Fixed segfault in loader executable.
- Better ConEmu compatibility.

#### v0.2

- Basic argument completion for `git`, `hg`, `svn`, and `p4`.
- Traditional Bash clear screen (`Ctrl`-`L`) and exit shortcuts (`Ctrl`-`D`).
- Scrollable command window using `PgUp`/`PgDown` keys.
- Doskey support.
- Automatic quoting of file names with spaces.
- Scriptable custom prompts.
- New argument framework to ease writing context-sensitive match generators.
- History and log file is now saved per-user rather than globally.
- Improved Clink's command line interface (`clink --help`).
- More reliable handling of cmd.exe's autorun entry.
- General improvements to executable and directory-command completion.
- Symbolic link support.
- Documentation.
- Windows 8 support.
- Improved hooking so Clink can be shared with other thirdparty utilities that also hook cmd.exe (ConEmu, ANSICon, etc.).

#### v0.1.1

- Fixed `AltGr`+`<key>` on international keyboards.
- Fixed broken completion when directories have a `-` in their name (Mark Hammond)
- The check for single match scenarios now correctly handles case-insensitivity.

#### v0.1

- Initial release.

# License

Clink is distributed under the terms of the GNU General Public License, version 3.

# Credits

### Clink

Clink was originally built by Martin Ridgers (https://github.com/mridgers/clink).
Copyright (c) 2012-2018 by Martin Ridgers.

Clink has been forked and renovated by Christopher Antos (https://github.com/chrisant996/clink).
Portions Copyright (c) 2020-2022 by Christopher Antos.

### Libraries

GNU Readline library version 8.1 (https://tiswww.case.edu/php/chet/readline/rltop.html).
GNU Readline is distributed under the terms of the GNU General Public License, version 3.

Lua 5.2 (https://www.lua.org).

getopt library.
Copyright (c) 1997 Gregory Pietsch, placed in the public domain.

Detours library version 4.0.1 (https://github.com/microsoft/detours).
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT license.

Match completion display uses column width calculations from GNU coreutils ls.c.
Licensed under the terms of the GNU General Public License, version 3.

Clink documentation embeds the highlight.js library (https://highlightjs.org).
Highlight.js is released under the BSD License.

Special thanks to Alexandra Barros and Matthew Wild for (https://code.matthewwild.co.uk/luatraverse).
Originally from (http://lua-users.org/lists/lua-l/2006-07/msg00110.html).
The script was very useful in tracking down dangling references.