liner

package module
v0.0.0-...-df01d1e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2024 License: MIT Imports: 18 Imported by: 0

README

Liner

This fork adds minimal support for vi editing to Liner. Projects that make use of Liner have users that may be looking for vi editing functionality. The modifications in this repository offer basic vi editing behavior.

code statistics
===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 Go                     17         3211         2666          272          273
 Markdown                1           87            0           75           12
===============================================================================
 Total                  18         3298         2666          347          285
===============================================================================

We implement basic, single-action, vi editing functions. At present, we do not support number keys to execute multiple operations, a repeat key, or undo actions.

Users may expect a method to visually discern between vi normal and insert modes. Though we do not support changing cursor behavior, however, we can send terminal escape codes change the appearance of text in the terminal.

Vi Keys Supported

key function
r replace character under cursor
i enter insert mode
I enter insert mode at beginning of line
a enter insert mode one character to the right
A enter insert mode at end of line
^ H move cursor to the beginning of line
$ L move cursor to the end of line
h move cursor one character to the left
l move cursor one character to the right
w move cursor to the next word
W move cursor to the next Word
e move cursor to the end of next word
E move cursor to the end of next Word
b move cursor to the previous word
x delete the character under cursor
X delete the character before cursor
d delete the next word
D delete from cursor to end of line
C change text from cursor to end of line
j next matching history
k previous matching history
p paste from yank buffer
~ change character case
default keys supported
key function
Ctrl-A, Home move cursor to the beginning of line
Ctrl-E, End move cursor to the end of line
Ctrl-B, Left move cursor one character to the left
Ctrl-F, Right move cursor one character to the right
Ctrl-Left, Alt-B move cursor to the previous word
Ctrl-Right, Alt-F move cursor to the next word
Ctrl-D, Del delete character under cursor if line is not empty
Ctrl-D end of file/exit if line is empty
Ctrl-C abort input
Ctrl-L clear screen
Ctrl-T transpose previous character with current character
Ctrl-H, BackSpace delete character before cursor
Ctrl-W, Alt-BackSpace delete word leading up to cursor
Alt-D delete word following cursor
Ctrl-K delete from cursor to end of line
Ctrl-U delete from start of line to cursor
Ctrl-P, Up previous match from history
Ctrl-N, Down next match from history
Ctrl-R reverse search history (Ctrl-S forward, Ctrl-G cancel)
Ctrl-Y paste from yank buffer (Alt-Y to paste next yank instead)
Tab next completion
Shift-Tab (after Tab) previous completion

Vi Functions

EnableViMode(bool)      // enable or disable vi editing functionality
EnableViPrompt(bool)    // allow liner prompt to change based on current vi mode
SetViMode(vimode)       // explicitly se the vi mode (normal, insert, replace)
SetViNormalStyle(style) // style used when in vi normal mode
SetViInsertStyle(style) // style used when in vi insert mode

Documentation

Overview

Package liner implements a simple command line editor, inspired by linenoise (https://github.com/antirez/linenoise/). This package supports WIN32 in addition to the xterm codes supported by everything else.

Index

Constants

View Source
const (
	ViNormal vimode = iota
	ViInsert
	ViReplace
)
View Source
const (
	Default style = iota
	Bold
	Dim
	Italic
	Under
	Blink
	Reverse
	Invisible
	Strikethrough
)
View Source
const HistoryLimit = 1000

HistoryLimit is the maximum number of entries saved in the scrollback history.

View Source
const KillRingMax = 60

KillRingMax is the max number of elements to save on the killring.

Variables

View Source
var ErrInternal = errors.New("liner: internal error")

ErrInternal is returned when liner experiences an error that it cannot handle. For example, if the number of colums becomes zero during an active call to Prompt

View Source
var ErrInvalidPrompt = errors.New("invalid prompt")

ErrInvalidPrompt is returned from Prompt or PasswordPrompt if the prompt contains any unprintable runes (including substrings that could be colour codes on some platforms).

View Source
var ErrNotTerminalOutput = errors.New("standard output is not a terminal")

ErrNotTerminalOutput is returned from Prompt or PasswordPrompt if the platform is normally supported, but stdout has been redirected

View Source
var ErrPromptAborted = errors.New("prompt aborted")

ErrPromptAborted is returned from Prompt or PasswordPrompt when the user presses Ctrl-C if SetCtrlCAborts(true) has been called on the State

Functions

func TerminalSupported

func TerminalSupported() bool

TerminalSupported returns true if the current terminal supports line editing features, and false if liner will use the 'dumb' fallback for input. Note that TerminalSupported does not check all factors that may cause liner to not fully support the terminal (such as stdin redirection)

Types

type Completer

type Completer func(line string) []string

Completer takes the currently edited line content at the left of the cursor and returns a list of completion candidates. If the line is "Hello, wo!!!" and the cursor is before the first '!', "Hello, wo" is passed to the completer which may return {"Hello, world", "Hello, Word"} to have "Hello, world!!!".

type ModeApplier

type ModeApplier interface {
	ApplyMode() error
}

ModeApplier is the interface that wraps a representation of the terminal mode. ApplyMode sets the terminal to this mode.

func TerminalMode

func TerminalMode() (ModeApplier, error)

TerminalMode returns the current terminal input mode as an InputModeSetter.

This function is provided for convenience, and should not be necessary for most users of liner.

type ShouldRestart

type ShouldRestart func(err error) bool

ShouldRestart is passed the error generated by readNext and returns true if the the read should be restarted or false if the error should be returned.

type State

type State struct {
	// contains filtered or unexported fields
}

State represents an open terminal

func NewLiner

func NewLiner() *State

NewLiner initializes a new *State, and sets the terminal into raw mode. To restore the terminal to its previous state, call State.Close().

func (*State) AppendHistory

func (s *State) AppendHistory(item string)

AppendHistory appends an entry to the scrollback history. AppendHistory should be called iff Prompt returns a valid command.

func (*State) ClearHistory

func (s *State) ClearHistory()

ClearHistory clears the scrollback history.

func (*State) Close

func (s *State) Close() error

Close returns the terminal to its previous mode

func (*State) EnableViMode

func (s *State) EnableViMode(state bool)

enable or disable vi keybindings

func (*State) EnableViPrompt

func (s *State) EnableViPrompt(state bool)

allow prompt to change visually based on current viMode

func (*State) InitializeLogger

func (s *State) InitializeLogger(state bool) error

enable or disable the debug log for vi functions

func (*State) PasswordPrompt

func (s *State) PasswordPrompt(prompt string) (string, error)

PasswordPrompt displays p, and then waits for user input. The input typed by the user is not displayed in the terminal.

func (*State) Prompt

func (s *State) Prompt(prompt string) (string, error)

Prompt displays p and returns a line of user input, not including a trailing newline character. An io.EOF error is returned if the user signals end-of-file by pressing Ctrl-D. Prompt allows line editing if the terminal supports it.

func (*State) PromptWithSuggestion

func (s *State) PromptWithSuggestion(prompt string, text string, pos int) (string, error)

PromptWithSuggestion displays prompt and an editable text with cursor at given position. The cursor will be set to the end of the line if given position is negative or greater than length of text (in runes). Returns a line of user input, not including a trailing newline character. An io.EOF error is returned if the user signals end-of-file by pressing Ctrl-D.

func (*State) ReadHistory

func (s *State) ReadHistory(r io.Reader) (num int, err error)

ReadHistory reads scrollback history from r. Returns the number of lines read, and any read error (except io.EOF).

func (*State) SetBeep

func (s *State) SetBeep(beep bool)

SetBeep sets whether liner should beep the terminal at various times (output ASCII BEL, 0x07). Default is true (will beep).

func (*State) SetCompleter

func (s *State) SetCompleter(f Completer)

SetCompleter sets the completion function that Liner will call to fetch completion candidates when the user presses tab.

func (*State) SetCtrlCAborts

func (s *State) SetCtrlCAborts(aborts bool)

SetCtrlCAborts sets whether Prompt on a supported terminal will return an ErrPromptAborted when Ctrl-C is pressed. The default is false (will not return when Ctrl-C is pressed). Unsupported terminals typically raise SIGINT (and Prompt does not return) regardless of the value passed to SetCtrlCAborts.

func (*State) SetMultiLineMode

func (s *State) SetMultiLineMode(mlmode bool)

SetMultiLineMode sets whether line is auto-wrapped. The default is false (single line).

func (*State) SetShouldRestart

func (s *State) SetShouldRestart(f ShouldRestart)

SetShouldRestart sets the restart function that Liner will call to determine whether to retry the call to, or return the error returned by, readNext.

func (*State) SetTabCompletionStyle

func (s *State) SetTabCompletionStyle(tabStyle TabStyle)

SetTabCompletionStyle sets the behvavior when the Tab key is pressed for auto-completion. TabCircular is the default behavior and cycles through the list of candidates at the prompt. TabPrints will print the available completion candidates to the screen similar to BASH and GNU Readline

func (*State) SetViInsertStyle

func (s *State) SetViInsertStyle(style style)

style used when in vi insert mode

func (*State) SetViMode

func (s *State) SetViMode(state vimode)

explicitly set the vi mode (normal, insert, replace)

func (*State) SetViNormalStyle

func (s *State) SetViNormalStyle(style style)

style used when in vi normal mode

func (*State) SetWordCompleter

func (s *State) SetWordCompleter(f WordCompleter)

SetWordCompleter sets the completion function that Liner will call to fetch completion candidates when the user presses tab.

func (*State) WriteHistory

func (s *State) WriteHistory(w io.Writer) (num int, err error)

WriteHistory writes scrollback history to w. Returns the number of lines successfully written, and any write error.

Unlike the rest of liner's API, WriteHistory is safe to call from another goroutine while Prompt is in progress. This exception is to facilitate the saving of the history buffer during an unexpected exit (for example, due to Ctrl-C being invoked)

type TabStyle

type TabStyle int

TabStyle is used to select how tab completions are displayed.

const (
	TabCircular TabStyle = iota
	TabPrints
)

Two tab styles are currently available:

TabCircular cycles through each completion item and displays it directly on the prompt

TabPrints prints the list of completion items to the screen after a second tab key is pressed. This behaves similar to GNU readline and BASH (which uses readline)

type WordCompleter

type WordCompleter func(line string, pos int) (head string, completions []string, tail string)

WordCompleter takes the currently edited line with the cursor position and returns the completion candidates for the partial word to be completed. If the line is "Hello, wo!!!" and the cursor is before the first '!', ("Hello, wo!!!", 9) is passed to the completer which may returns ("Hello, ", {"world", "Word"}, "!!!") to have "Hello, world!!!".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL