Skip to content

x/term: support pluggable history #68780

Closed
@ldemailly

Description

@ldemailly

Proposal Details

--- Accepted proposal:

// A History provides a (possibly bounded) queue of input lines read by [ReadLine].
type History interface {
	// Add adds a new, most recent entry to the history.
	// It is allowed to drop any entry, including
	// the entry being added (e.g.,, if it's a whitespace-only entry),
	// the least-recent entry (e.g., to keep the history bounded),
	// or any other entry.
	Add(entry string)

	// Len returns the number of entries in the history.
	Len() int

	// At returns an entry from the history.
	// Index 0 is the most-recently added entry and
	// index Len()-1 is the least-recently added entry.
	// If index is < 0 or >= Len(), it panics.
	At(index int) string
}

type Terminal struct {
        ...

        // History records and retrieves lines of input read by [ReadLine].
        //
        // It is not safe to call ReadLine concurrently with any methods on History.
        // 
        // [NewTerminal] sets this to an implementation that records the last 100 lines of input.
        History History
}

copied from #68780 (comment)

--- Was "Interface" Proposal:

https://github.com/golang/term/pull/20/files

// The History interface provides a way to replace the default automatic
// 100 slots ringbuffer implementation.
type History interface {
	// Add will be called by Terminal to add a new line into the history.
	// An implementation may decide to not add every lines by ignoring calls
	// to this function (from Terminal.ReadLine) and to only add validated
	// entries out of band.
	Add(entry string)

	// At retrieves a line from history.
	// idx 0 should be the most recent entry.
	// return false when out of range.
	At(idx int) (string, bool)
}

// In terminal:

	// History allows to replace the default implementation of the history
	// which contains previously entered commands so that they can be
	// accessed with the up and down keys.
	// It's not safe to call ReadLine and methods on History concurrently.
	History History

And even earlier "direct" proposal for reference:

x/term is very nice, it includes a 100 slot history ring buffer, unfortunately entirely private

https://github.com/golang/term/blob/master/terminal.go#L89

it would be nice to let people

// History returns a slice of strings containing the history of entered commands so far.
func (t *Terminal) History() []string {

and

// AddToHistory populates history.
func (t *Terminal) AddToHistory(commands ...string) {

and resize

// NewHistory resets the history to one of a given capacity.
func (t *Terminal) NewHistory(capacity int) {

and allow replacement of last command in history (for instance to replace invalid by validated or canonical variant)

// ReplaceLatest replaces the most recent history entry with the given string.
// Enables to add invalid commands to the history for editing purpose and
// replace them with the corrected version. Returns the replaced entry.
func (t *Terminal) ReplaceLatest(entry string) string {

and control whether lines are automatically added to history (defaults remains true)

// AutoHistory sets whether lines are automatically added to the history
// before being returned by ReadLine() or not. Defaults to true.
func (t *Terminal) AutoHistory(onOff bool) {

if acceptable I'd be happy to make a PR edit: made a PR

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions