class TermBuf::Editor

Overview

Keys, bound to what they do to a LineBuffer.

Bindings are data. Action names the vocabulary and Keymap maps keys to it, so an application rebinds by replacing entries rather than by subclassing, and the enum is what documents what a field can be asked to do.

Anything not in the map that carries no modifier but shift is text and gets inserted. That rule is what keeps the map small.

Defined in:

termbuf/widgets/editor.cr

Constant Summary

DEFAULT_KEYMAP = begin map = Keymap.new {Key::Name::Left => Action::MoveLeft, Key::Name::Right => Action::MoveRight, Key::Name::Home => Action::MoveHome, Key::Name::End => Action::MoveEnd, Key::Name::Backspace => Action::DeleteBackward, Key::Name::Delete => Action::DeleteForward, Key::Name::Up => Action::HistoryPrevious, Key::Name::Down => Action::HistoryNext, Key::Name::Tab => Action::Complete, Key::Name::Enter => Action::Accept, Key::Name::Escape => Action::Cancel}.each do |name, action| map[Key.named(name)] = action end {Key::Name::Left => Action::SelectLeft, Key::Name::Right => Action::SelectRight, Key::Name::Home => Action::SelectHome, Key::Name::End => Action::SelectEnd}.each do |name, action| map[Key.named(name, Modifiers::Shift)] = action end {Key::Name::Left => Action::MoveWordLeft, Key::Name::Right => Action::MoveWordRight}.each do |name, action| map[Key.named(name, Modifiers::Ctrl)] = action end {'a' => Action::MoveHome, 'e' => Action::MoveEnd, 'b' => Action::MoveLeft, 'f' => Action::MoveRight, 'k' => Action::KillToEnd, 'u' => Action::KillToStart, 'w' => Action::DeleteWordBackward, 'y' => Action::Yank, 't' => Action::Transpose, 'p' => Action::HistoryPrevious, 'n' => Action::HistoryNext, 'l' => Action::Clear, 'c' => Action::Cancel, 'd' => Action::EndOfInput, 'h' => Action::DeleteBackward}.each do |char, action| map[Key.character(char, Modifiers::Ctrl)] = action end {'b' => Action::MoveWordLeft, 'f' => Action::MoveWordRight, 'd' => Action::DeleteWordForward}.each do |char, action| map[Key.character(char, Modifiers::Alt)] = action end map end

The readline bindings, because that is what fingers in a terminal expect.

Constructors

Instance Method Summary

Constructor Detail

def self.new(buffer : LineBuffer = LineBuffer.new, keymap : Keymap | Nil = nil, history : History | Nil = nil, completions : Completion::Hook | Nil = nil, multiline : Bool = false) #

[View source]

Instance Method Detail

def accepted : String #

The line the last Accepted outcome handed over.


[View source]
def buffer : LineBuffer #

The text being edited.


[View source]
def candidates : Array(String) #

Candidates the last completion offered when there was more than one, for a field to list. Emptied by anything else.


[View source]
def completions : Completion::Hook | Nil #

What to ask when someone presses the completion key, or nil for a field that does not complete.


[View source]
def completions=(completions : Completion::Hook | Nil) #

What to ask when someone presses the completion key, or nil for a field that does not complete.


[View source]
def handle(key : Key) : Outcome #

Does whatever key is bound to, or inserts it when it is bound to nothing and carries a character.


[View source]
def history : History | Nil #

Lines entered earlier, or nil for a field that does not remember.


[View source]
def history=(history : History | Nil) #

Lines entered earlier, or nil for a field that does not remember.


[View source]
def keymap : Keymap #

Which key does what. DEFAULT_KEYMAP duplicated unless one was given.


[View source]
def keymap=(keymap : Keymap) #

Which key does what. DEFAULT_KEYMAP duplicated unless one was given.


[View source]
def listing? : Bool #

Whether the candidates are worth showing, which they are only once the completion key has been pressed twice with nothing chosen in between.


[View source]
def multiline=(multiline : Bool) #

Whether Newline inserts a break rather than being ignored.


[View source]
def multiline? : Bool #

Whether Newline inserts a break rather than being ignored.


[View source]
def paste(text : String) : Outcome #

Pasted text goes in as text, whatever it contains. A field with no room for a line break flattens them rather than dropping the rest.


[View source]
def text : String #

The line as it stands.


[View source]
def text=(value : String) : String #

Replaces the line and forgets where the history walk had got to.


[View source]
def word_range : Range(Int32, Int32) #

The word under the cursor, by the buffer's own idea of what a word is.


[View source]