package keymapimport ()// Engine is used to manage the main and local keymaps for the shell.typeEnginestruct { local Mode main Mode prefixed inputrc.Bind active inputrc.Bind pending []inputrc.Bind skip bool isCaller bool nonIncSearch bool keys *core.Keys iterations *core.Iterations config *inputrc.Config commands map[string]func()}// NewEngine is a required constructor for the keymap modes manager.// It initializes the keymaps to their defaults or configured values.func ( *core.Keys, *core.Iterations, ...inputrc.Option) (*Engine, *inputrc.Config) { := &Engine{main: Emacs,keys: ,iterations: ,config: inputrc.NewDefaultConfig(),commands: make(map[string]func()), }// Load the inputrc configurations and set up related things. .ReloadConfig(...)return , .config}// Register adds command functions to the list of available commands.// Each key of the map should be a unique name, not yet used by any// other builtin/user command, in order not to "overload" the builtins.func ( *Engine) ( map[string]func()) {for , := range { .commands[] = }}// SetMain sets the main keymap of the shell.// Valid builtin keymaps are:// - emacs, emacs-meta, emacs-ctlx, emacs-standard.// - vi, vi-insert, vi-command, vi-move.func ( *Engine) ( string) { .main = Mode() .UpdateCursor()}// Main returns the local keymap.func ( *Engine) () Mode {return .main}// SetLocal sets the local keymap of the shell.// Valid builtin keymaps are:// - vi-opp, vi-visual. (used in commands like yank, change, delete, etc.)// - isearch, menu-select (used in search and completion).func ( *Engine) ( string) { .local = Mode() .UpdateCursor()}// Local returns the local keymap.func ( *Engine) () Mode {return .local}// ResetLocal deactivates the local keymap of the shell.func ( *Engine) () { .local = "" .UpdateCursor()}// UpdateCursor reprints the cursor corresponding to the current keymaps.func ( *Engine) () {switch .local {caseViOpp: .PrintCursor(ViOpp)returncaseVisual: .PrintCursor(Visual)return }// But if not, we check for the global keymapswitch .main {caseEmacs, EmacsStandard, EmacsMeta, EmacsCtrlX: .PrintCursor(Emacs)caseViInsert: .PrintCursor(ViInsert)caseViCommand, ViMove, Vi: .PrintCursor(ViCommand) }}// PendingCursor changes the cursor to pending mode,// and returns a function to call once done with it.func ( *Engine) () ( func()) { .PrintCursor(ViOpp)returnfunc() { .UpdateCursor() }}// IsEmacs returns true if the main keymap is one of the emacs modes.func ( *Engine) () bool {switch .main {caseEmacs, EmacsStandard, EmacsMeta, EmacsCtrlX:returntruedefault:returnfalse }}// PrintBinds displays a list of currently bound commands (and their sequences)// to the screen. If inputrcFormat is true, it displays it formatted such that// the output can be reused in an .inputrc file.func ( *Engine) ( string, bool) {var []stringfor := range .commands { = append(, ) }sort.Strings() := .config.Binds[]if == nil {return }// Make a list of all sequences bound to each command. := make(map[string][]string)for , := range {for , := range {if .Action != {continue } := [] = append(, inputrc.Escape()) [] = } }if {printBindsInputrc(, ) } else {printBindsReadable(, ) }}// InputIsTerminator returns true when current input keys are one of// the configured or builtin "terminators", which can be configured// in .inputrc with the isearch-terminators variable.func ( *Engine) () bool { := []string{inputrc.Unescape(`\C-G`),inputrc.Unescape(`\C-]`), } := make(map[string]inputrc.Bind)for , := range { [] = inputrc.Bind{Action: "abort", Macro: false} } , , , := .dispatchKeys()return .Action == "abort"}// Commands returns the map of all command functions available to the shell.// This includes the builtin commands (emacs/Vim/history/completion/etc), as// well as any functions added by the user through Keymap.Register().// The keys of this map are the names of each corresponding command function.func ( *Engine) () map[string]func() {return .commands}// ActiveCommand returns the sequence/command currently being ran.func ( *Engine) () inputrc.Bind {return .active}// NonIncrementalSearchStart is used to notify the keymap dispatchers// that are using a minibuffer, and that the set of valid commands// should be restrained to a few ones (self-insert/abort/rubout...).func ( *Engine) () { .nonIncSearch = true}// NonIncrementalSearchStop notifies the keymap dispatchers// that we stopped editing a non-incremental search minibuffer.func ( *Engine) () { .nonIncSearch = false}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.