Skip to content

Configuration File

maxlandon edited this page May 13, 2023 · 15 revisions

Loading configurations

At startup, any program using readline will read the user ~/.inputrc file, or if not found the system one, /etc/inputrc. It is however possible for developers to access the loaded configuration from the shell API, and to modify it freely (even replacing it altogether, although this is neither really practical nor recommended).

To access the configuration:

shell := readline.NewShell()
config := shell.Config

Developers will want to use readline for an application, which will have a name. The library thus enables them to pass this name when creating the shell instance, so that any app-specific binds/options will be parsed/setup accordingly:

appName := "teleport"

// Creating the shell with this name
shell := readline.NewShell(inputrc.WithName(appname)...)

// Or adding it later and re-reading the inputrc file (not recommended)
shell.Opts = append(shell.Options, inputrc.WithName(appname))
shell.Config.ReadFile("~/.inputrc")

Global options

Inputrc options are used to setup the global behavior, display and input/output settings of the shell. They can be accessed, queried and set like the following:

// Access the map of all options
allOptions := config.Vars

// Querying option values
editingMode := config.GetString("editing-mode")         // Either "vi" or "emacs"
autocomplete := config.GetBool("autocomplete")          // directly as boolean (on/off)
viPromptMode := config.GetString("vi-ins-mode-string")  // Some options are string values
keyTimeout := config.GetInt("keyseq-timeout")           // Others are integers

// Modifying the option values
config.Set("editing-mode", "vi")            
config.Set("autocomplete", true)
config.Set("keyseq-timeout", 100)

Key bindings

The second part of the .inputrc file is used to declare custom keybindings, either for commands or macros. As well, it's possible to add, delete or overwrite all or some keybindings, per keymap, through the code.

To access each keymap and its binds:

// Get all keymaps and their binds
binds := config.Binds

// Emacs
emacs := binds["emacs"]              // Access all binds for the Emacs keymap
emacsCtrlX := binds["emacs-ctrlx"]   // All binds of the Emacs Ctrl-X (subset of emacs)
emacsMeta := binds["emacs-meta"]     // All binds of the Emacs Ctrl-Meta (subset of emacs)

// Vim
viCommand := binds["vi"]             // You can also query vi/vi-move/vi-cmd for this keymap
viInsert := binds["vi-insert"]       // Insertion keymap
viOpp := binds["vi-opp"]             // The vi-operator pending keymap is a special one.

// Completion & incremental search
menuSelect := binds["menu-select"]  // The keymap used when selecting completions.
isearch := binds["isearch"]         // Incremental-search (empty by default, see doc for why)

To override, add or delete binds in a given keymap, you can proceed in several ways:

// Using the provided configuration method to add a bind
config.Bind("vi", "K", "vi-kill-eol", false)            // Bind a command
config.Bind("vi", `\C-K`, "K", true)                    // Bind a macro (doing what the line above does)

// Or adding directly to the map
viCommand["K"] = inputrc.Bind{"vi-kill-eol", false}     // Bind a command.
viCommand[`\C-K`] = inputrc.Bind{"K", true}             // Bind a macro.

// Deleting is as simple
delete(viCommand, "K")
delete(viCommand, `\C-K`)
Clone this wiki locally