shell

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

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

Go to latest
Published: Aug 24, 2023 License: MIT Imports: 20 Imported by: 0

README

Bubble Shell

This library provides you with a interactive shell powered by bubbletea by executing cobra, allowing you to build powerful interactive terminal based shell applications.

Usage

Create a root command as you would normally with cobra, attaching your various commands to it. Then pass it to the shell.New function to create a new shell.

package main

import (
	tea "github.com/charmbracelet/bubbletea"
    "github.com/DomBlack/bubble-shell"
    "github.com/spf13/cobra"
)

func main() {
	// Create the root command which we can attach everything to
    rootCmd := &cobra.Command{}
	
	// Create a command to add to the root command
	myCmd := &cobra.Command{
		Use: "hi",
        RunE: func(cmd *cobra.Command, args []string) error {
			cmd.OutOrStdout().Write([]byte("Hello World\n"))
			return nil
        },
	}
	rootCmd.AddCommand(myCmd)
    
	// Create the shell
	shell := shell.New(rootCmd)
	
	// Run the shell
	p := tea.NewProgram(shell)
	if _, err := p.Run(); err != nil {
		panic(err)
	}
}

In this example, a user will be given an interactive shell with a single command hi which will print Hello World when run.

Options

The shell.New function takes a number of options to configure the shell, which are detailed below. Full documentaton for them can be seen in options.go.

shell.WithHistoryFile / shell.WithNoHistory

By default the shell will save the history of commands to .bubble-shell-history in the user's home directory, however using these two options you can change this behaviour, either providing your own filename or disabling history entirely.

shell.WithKeyMap

You can use this option to customise the key bindings used by the shell. The default key bindings are located in the keymap package.

shell.WithStyles

You can use this option to customise the styles used by the shell. The default styles are located in the styles package.

shell.WithStackTraceFilters / shell.WithAdditionalStackTraceFilters

By default the shell will filter out stack traces from the github.com/DomBlack/bubble-shell package and other related packages when rendering the stack traces of errors to the user. You can use these options to customise this behaviour, either by providing your own list of packages to filter out, or by adding to the default list.

Guidelines for building commands
  1. The shell supports autocompletion of commands and arguments, so ideally implement a ValidArgsFunction function or ValidArgs property on your command.
  2. If you implement your commands using RunE rather than Run you can then return an error to bubble-shell which will be displayed to the user. If the error carries a stack trace, it will be displayed to the user. (I recommend using cockroachdb/errors to create errors with stack traces by default).
  3. If you need a context use cmd.Context() rather than creating your own. This is because the shell will cancel the context when the user presses Ctrl+C.
  4. If you want to display a message to the user, use cmd.OutOrStdout() rather than fmt.Println("Hello World"). While both will be captured and returned to the user, the former will be streamed to the user as it is written, while the os.Stdout and os.Stderr streams are buffered and only displayed when the command completes.

Example Apps

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(rootCmd *cobra.Command, options ...Option) tea.Model

Types

type AutoCompleteMode

type AutoCompleteMode struct{}

func (*AutoCompleteMode) AcceptOption

func (a *AutoCompleteMode) AcceptOption(m Model) (Model, tea.Cmd)

func (*AutoCompleteMode) AdditionalView

func (a *AutoCompleteMode) AdditionalView(m Model) string

func (*AutoCompleteMode) Enter

func (a *AutoCompleteMode) Enter(m Model) (Model, tea.Cmd)

func (*AutoCompleteMode) FullHelp

func (a *AutoCompleteMode) FullHelp(m Model, keyMap KeyMap) [][]key.Binding

func (*AutoCompleteMode) Leave

func (a *AutoCompleteMode) Leave(m Model) (Model, tea.Cmd)

func (*AutoCompleteMode) ShortHelp

func (a *AutoCompleteMode) ShortHelp(m Model, keyMap KeyMap) []key.Binding

func (*AutoCompleteMode) Update

func (a *AutoCompleteMode) Update(m Model, msg tea.Msg) (Model, tea.Cmd)

type CommandEntryMode

type CommandEntryMode struct{ KeepInputContent bool }

func (*CommandEntryMode) AdditionalView

func (c *CommandEntryMode) AdditionalView(m Model) string

func (*CommandEntryMode) Enter

func (c *CommandEntryMode) Enter(m Model) (Model, tea.Cmd)

func (*CommandEntryMode) FullHelp

func (c *CommandEntryMode) FullHelp(m Model, keyMap KeyMap) [][]key.Binding

func (*CommandEntryMode) Leave

func (c *CommandEntryMode) Leave(m Model) (Model, tea.Cmd)

func (*CommandEntryMode) ShortHelp

func (c *CommandEntryMode) ShortHelp(m Model, keyMap KeyMap) []key.Binding

func (*CommandEntryMode) Update

func (c *CommandEntryMode) Update(m Model, msg tea.Msg) (Model, tea.Cmd)

type CommandRunningMode

type CommandRunningMode struct{ KeepInputContent bool }

func (*CommandRunningMode) AdditionalView

func (c *CommandRunningMode) AdditionalView(m Model) string

func (*CommandRunningMode) Enter

func (c *CommandRunningMode) Enter(m Model) (Model, tea.Cmd)

func (*CommandRunningMode) FullHelp

func (c *CommandRunningMode) FullHelp(m Model, keyMap KeyMap) [][]key.Binding

func (*CommandRunningMode) Leave

func (c *CommandRunningMode) Leave(m Model) (Model, tea.Cmd)

func (*CommandRunningMode) ShortHelp

func (c *CommandRunningMode) ShortHelp(m Model, keyMap KeyMap) []key.Binding

func (*CommandRunningMode) Update

func (c *CommandRunningMode) Update(m Model, msg tea.Msg) (Model, tea.Cmd)

type HistoryLookbackMode

type HistoryLookbackMode struct {
	TriggerMsg tea.Msg
}

func (*HistoryLookbackMode) AdditionalView

func (h *HistoryLookbackMode) AdditionalView(m Model) string

func (*HistoryLookbackMode) Enter

func (h *HistoryLookbackMode) Enter(m Model) (Model, tea.Cmd)

func (*HistoryLookbackMode) FullHelp

func (h *HistoryLookbackMode) FullHelp(m Model, keyMap KeyMap) [][]key.Binding

func (*HistoryLookbackMode) Leave

func (h *HistoryLookbackMode) Leave(m Model) (Model, tea.Cmd)

func (*HistoryLookbackMode) ShortHelp

func (h *HistoryLookbackMode) ShortHelp(m Model, keyMap KeyMap) []key.Binding

func (*HistoryLookbackMode) Update

func (h *HistoryLookbackMode) Update(m Model, msg tea.Msg) (Model, tea.Cmd)

type HistorySearchMode

type HistorySearchMode struct{}

func (*HistorySearchMode) AdditionalView

func (h *HistorySearchMode) AdditionalView(m Model) string

func (*HistorySearchMode) Enter

func (h *HistorySearchMode) Enter(m Model) (Model, tea.Cmd)

func (*HistorySearchMode) FullHelp

func (h *HistorySearchMode) FullHelp(m Model, keyMap KeyMap) [][]key.Binding

func (*HistorySearchMode) Leave

func (h *HistorySearchMode) Leave(m Model) (Model, tea.Cmd)

func (*HistorySearchMode) ShortHelp

func (h *HistorySearchMode) ShortHelp(m Model, keyMap KeyMap) []key.Binding

func (*HistorySearchMode) Update

func (h *HistorySearchMode) Update(m Model, msg tea.Msg) (Model, tea.Cmd)

type KeyMap

type KeyMap = keymap.KeyMap

KeyMap is a collection of all the key bindings used by the shell

A default is provided and will be used by the shell if no other KeyMap is provided when creating a new shell.

type Mode

type Mode interface {
	// Enter is called when the mode is entered
	Enter(m Model) (Model, tea.Cmd)

	// Leave is called when the mode is left, before the next mode is entered
	Leave(m Model) (Model, tea.Cmd)

	// Update is called when a message is received for the mode
	Update(m Model, msg tea.Msg) (Model, tea.Cmd)

	// AdditionalView is called to render additional output
	// at the bottom of the screen
	AdditionalView(m Model) string

	// ShortHelp returns a list of key bindings and their descriptions
	ShortHelp(m Model, keyMap KeyMap) []key.Binding

	// FullHelp returns a list of key bindings and their descriptions
	FullHelp(m Model, keyMap KeyMap) [][]key.Binding
}

Mode is an interface which represents an input mode the shell can be in and is used to handle input

type Model

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

Model is the main shell model

func (Model) Enter

func (m Model) Enter(mode Mode) tea.Cmd

Enter tells the mode to enter the given mode leaving the old mode

func (Model) ExecuteCommand

func (m Model) ExecuteCommand(cmd history.Item) tea.Cmd

func (Model) FullHelp

func (m Model) FullHelp() [][]key.Binding

func (Model) Init

func (m Model) Init() tea.Cmd

func (Model) ShortHelp

func (m Model) ShortHelp() []key.Binding

func (Model) Shutdown

func (m Model) Shutdown() tea.Msg

Shutdown is a tea.Cmd to shutdown the shell cleanly

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

func (Model) View

func (m Model) View() string

type Option

type Option func(*config.Config)

Option is a function that configures the shell.

func WithAdditionalStackTraceFilters

func WithAdditionalStackTraceFilters(packages ...string) Option

WithAdditionalStackTraceFilters adds additional packages to filter from the stack traces of errors when rendered to the user.

func WithBaseContext

func WithBaseContext(ctx context.Context) Option

WithBaseContext sets the context that commands will be run with when they are executed by users.

By default context.Background will be used

func WithHistoryFile

func WithHistoryFile(fileName string) Option

WithHistoryFile sets the history file to be used by the shell if not absolute will be relative to $HOME

func WithInlineShell

func WithInlineShell() Option

WithInlineShell sets the shell to be inline rather than trying to render full screen

This means that recovered history will not be shown, however your terminals own render will be incharge of scrolling.

func WithKeyMap

func WithKeyMap(keyMap KeyMap) Option

WithKeyMap sets the keymap to be used by the shell

func WithMaxStackFrames

func WithMaxStackFrames(frames int) Option

WithMaxStackFrames sets the maximum number of stack frames to show in errors when rendered to the user.

The shell defaults to 8 frames.

func WithNoHistory

func WithNoHistory() Option

WithNoHistory disables history for the shell

func WithPromptFunc

func WithPromptFunc(promptFunc func() string) Option

WithPromptFunc sets the function for rendering the prompt

By default a function will be provided that returns "> "

func WithStackTraceFilters

func WithStackTraceFilters(packages ...string) Option

WithStackTraceFilters sets the packages to filter from the stack traces of errors when rendered to the user.

By default the shell will filter out packages related to running the shell itself, if you want to keep these filters, then use WithAdditionalStackTraceFilters.

If you want no filtering to be done, then call this with no packages listed.

func WithStyles

func WithStyles(styles Styles) Option

WithStyles sets the styles to be used by the shell

type ShutdownMsg

type ShutdownMsg struct {
	ID modelid.ID
}

ShutdownMsg is sent by the shell when it wants to shutdown the application.

It is used to allow for one render cycle to occur before the tea.Quit is sent, allowing us to remove the prompt

func (ShutdownMsg) ForModelID

func (msg ShutdownMsg) ForModelID() modelid.ID

type Styles

type Styles = styles.Styles

Styles is the set of styles which will be used to render the shell.

A default is provided and will be used by the shell if no other Styles is provided when creating a new shell.

Directories

Path Synopsis
examples
internal
pkg
modelid
Package modelid provides a way to identify a specific model instance by providing a global counter that is incremented each time a new model is created.
Package modelid provides a way to identify a specific model instance by providing a global counter that is incremented each time a new model is created.

Jump to

Keyboard shortcuts

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