midterm

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2023 License: MIT Imports: 14 Imported by: 5

README

midterm GoDoc

a pretty mid terminal library

Midterm is a virtual terminal emulator. There is no GUI, but it has conveniences for rendering back to a terminal or to HTML.

Some examples:

  • Progrock uses it for displaying progress logs.
  • Dagger uses it for interactive shells, also rendered via Progrock.
  • Bass uses it for rendering terminal output in its docs. (And also uses Progrock.)
Project goals
  • Compatibility with everyday tools like htop and vim.
  • Good enough performance, though optimizations haven't been sought out yet so there's probably some low hanging fruit.
  • Composability/versatility, e.g. forwarding OSC requests/responses between an outer terminal and a remote shell in a container.
  • Anything you'd expect for interactive shells: full mouse support, 256 colors, copy/paste, etc. - though there's no GUI so this really just amounts to forwarding ANSI sequences between local/remote shells.
What's it for?

This is not a GUI terminal emulator intended for everyday use. It's all in-memory. If you want to wrap it in a GUI, feel free!

Right now it's used for rendering terminals embedded in other TUIs (Progrock), and for rendering terminal output in documentation.

What's with the name?

It used to be called vt100, but then I added support for things beyond vt100 like scroll regions, and I don't want to keep renaming it.

I went with midterm because this library often sits in between a local and remote terminal (e.g. dagger shell), so it's a middle terminal. 🤷♂

Credit

Based on tonistiigi/vt100 which was was based on jaguilar/vt100.

Documentation

Overview

package midterm implements an in-memory terminal emulator, designed to be used as a component within a larger application for displaying logs, running interactive shells, or rendering terminal output.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Command

type Command interface {
	// contains filtered or unexported methods
}

Command is a type of object that the terminal can process to perform an update.

func Decode

func Decode(s io.RuneScanner) (Command, []rune, error)

Decode decodes one ANSI terminal command from s.

s should be connected to a client program that expects an ANSI terminal on the other end. It will push bytes to us that we are meant to intepret as terminal control codes, or text to place onto the terminal.

This Command alone does not actually update the terminal. You need to pass it to VT100.Process().

You should not share s with any other reader, because it could leave the stream in an invalid state.

type Cursor

type Cursor struct {
	// Y and X are the coordinates.
	Y, X int

	// F is the format that will be displayed.
	F Format
}

Cursor represents both the position and text type of the cursor.

type Format

type Format struct {
	// Reset inidcates that the format should be reset prior to applying any of
	// the other fields.
	Reset bool
	// Fg is the foreground color.
	Fg termenv.Color
	// Bg is the background color.
	Bg termenv.Color
	// Intensity is the text intensity (bright, normal, dim).
	Intensity Intensity
	// Various text properties.
	Italic, Underline, Blink, Reverse, Conceal, CrossOut, Overline bool
}

Format represents the display format of text on a terminal.

func (Format) Render

func (f Format) Render() string

type Intensity

type Intensity int
const (
	Normal Intensity = 0
	Bold   Intensity = 1
	Faint  Intensity = 2
)

type OnResizeFunc

type OnResizeFunc func(rows, cols int)

type Screen added in v0.1.4

type Screen struct {
	// Height and Width are the dimensions of the terminal.
	Height, Width int

	// Content is the text in the terminal.
	Content [][]rune

	// Format is the display properties of each cell.
	Format [][]Format

	// Cursor is the current state of the cursor.
	Cursor Cursor

	// ScrollRegion is the region of the terminal that is scrollable. If it is
	// nil, the entire terminal is scrollable.
	//
	// This value is set by the CSI ; Ps ; Ps r command.
	ScrollRegion *ScrollRegion

	// CursorVisible indicates whether the cursor is visible.
	//
	// This value is set by CSI ? 25 h and unset by CSI ? 25 l.
	CursorVisible bool

	// CursorBlinking indicates whether the cursor is blinking, and the start of
	// the blinking interval.
	CursorBlinkEpoch *time.Time

	// SavedCursor is the state of the cursor last time save() was called.
	SavedCursor Cursor

	// MaxY is the maximum vertical offset that a character has been printed.
	MaxY int
}

type ScrollRegion

type ScrollRegion struct {
	Start, End int
}

ScrollRegion represents a region of the terminal that is scrollable.

type Terminal

type Terminal struct {
	// Screen is the current screen, embedded so that Terminal is a pass-through.
	*Screen

	// Alt is either the alternate screen (if !IsAlt) or the main screen (if
	// IsAlt).
	Alt *Screen

	// IsAlt indicates whether the alt screen is active.
	IsAlt bool

	// AutoResizeY indicates whether the terminal should automatically resize
	// when the content exceeds its maximum height.
	AutoResizeY bool

	// AutoResizeX indicates whether the terminal should automatically resize
	// when the content exceeds its maximum width.
	AutoResizeX bool

	// ForwardRequests is the writer to which we send requests to forward
	// to the terminal.
	ForwardRequests io.Writer

	// ForwardResponses is the writer to which we send responses to CSI/OSC queries.
	ForwardResponses io.Writer
	// contains filtered or unexported fields
}

Terminal represents a raw terminal capable of handling VT100 and VT102 ANSI escape sequences, some of which are handled by forwarding them to a local or remote session (e.g. OSC52 copy/paste).

func NewAutoResizingTerminal added in v0.1.1

func NewAutoResizingTerminal() *Terminal

NewAutoResizingTerminal creates a new Terminal object with small initial dimensions, configured to automatically resize width and height as needed.

This may be useful for applications that want to display dynamically sized content.

func NewTerminal

func NewTerminal(rows, cols int) *Terminal

NewTerminal creates a new Terminal object with the specified dimensions. y and x must both be greater than zero.

Each cell is set to contain a ' ' rune, and all formats are left as the default.

func (*Terminal) HTML

func (v *Terminal) HTML() string

HTML renders v as an HTML fragment. One idea for how to use this is to debug the current state of the screen reader.

func (*Terminal) OnResize

func (v *Terminal) OnResize(f OnResizeFunc)

func (*Terminal) Process

func (v *Terminal) Process(c Command) error

Process handles a single ANSI terminal command, updating the terminal appropriately.

One special kind of error that this can return is an UnsupportedError. It's probably best to check for these and skip, because they are likely recoverable.

func (*Terminal) Render

func (vt *Terminal) Render(w io.Writer) error

func (*Terminal) RenderLine

func (vt *Terminal) RenderLine(w io.Writer, row int) error

func (*Terminal) Reset

func (v *Terminal) Reset()

func (*Terminal) Resize

func (v *Terminal) Resize(rows, cols int)

Resize sets the terminal height and width to rows and cols and disables auto-resizing on both axes.

func (*Terminal) ResizeX added in v0.1.3

func (v *Terminal) ResizeX(cols int)

Resize sets the terminal width to cols and disables auto-resizing width.

func (*Terminal) ResizeY added in v0.1.3

func (v *Terminal) ResizeY(rows int)

Resize sets the terminal height to rows rows and disables auto-resizing height.

func (*Terminal) UsedHeight

func (v *Terminal) UsedHeight() int

func (*Terminal) Write

func (v *Terminal) Write(dt []byte) (n int, rerr error)

type UnsupportedError

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

UnsupportedError indicates that we parsed an operation that this terminal does not implement. Such errors indicate that the client program asked us to perform an action that we don't know how to. It MAY be safe to continue trying to do additional operations. This is a distinct category of errors from things we do know how to do, but are badly encoded, or errors from the underlying io.RuneScanner that we're reading commands from.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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