Top Related Projects
Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.
Readline is a pure go(golang) implementation for GNU-Readline kind library
A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
Interactive prompt for command-line applications
Pure Go line editor with history, inspired by linenoise
Quick Overview
abiosoft/ishell is a Go library for creating interactive CLI applications with custom commands and subcommands. It provides a simple and flexible way to build shell-like interfaces, complete with command history, tab completion, and nested subcommands.
Pros
- Easy to use and integrate into existing Go projects
- Supports nested subcommands and custom command completion
- Provides built-in command history and readline-like functionality
- Allows for flexible input/output handling
Cons
- Limited documentation and examples
- May be overkill for simple CLI applications
- Lacks some advanced features found in more comprehensive CLI frameworks
- Not actively maintained (last commit was in 2021)
Code Examples
Creating a basic shell:
package main
import (
"github.com/abiosoft/ishell/v2"
)
func main() {
shell := ishell.New()
shell.Println("Welcome to my interactive shell!")
shell.Run()
}
Adding a custom command:
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "greet <name>",
Func: func(c *ishell.Context) {
if len(c.Args) == 0 {
c.Println("Please provide a name")
return
}
c.Printf("Hello, %s!\n", c.Args[0])
},
})
Using subcommands:
shell.AddCmd(&ishell.Cmd{
Name: "math",
Help: "perform math operations",
Func: nil,
Subcommands: []*ishell.Cmd{
{
Name: "add",
Help: "add <num1> <num2>",
Func: func(c *ishell.Context) {
if len(c.Args) != 2 {
c.Println("Please provide two numbers")
return
}
num1, _ := strconv.Atoi(c.Args[0])
num2, _ := strconv.Atoi(c.Args[1])
c.Printf("%d + %d = %d\n", num1, num2, num1+num2)
},
},
},
})
Getting Started
To use abiosoft/ishell in your Go project, follow these steps:
-
Install the library:
go get github.com/abiosoft/ishell/v2
-
Import it in your Go file:
import "github.com/abiosoft/ishell/v2"
-
Create a new shell instance and add commands:
shell := ishell.New() shell.AddCmd(&ishell.Cmd{ Name: "hello", Help: "say hello", Func: func(c *ishell.Context) { c.Println("Hello, World!") }, }) shell.Run()
This will create a basic interactive shell with a "hello" command. You can expand on this by adding more commands, subcommands, and customizing the shell's behavior.
Competitor Comparisons
Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.
Pros of go-prompt
- More advanced auto-completion features, including fuzzy matching
- Better support for multi-line input and editing
- Provides a more polished and responsive user interface
Cons of go-prompt
- Less flexible in terms of customization compared to ishell
- Steeper learning curve for developers
- Limited built-in command handling functionality
Code Comparison
ishell example:
shell := ishell.New()
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "greet user",
Func: func(c *ishell.Context) {
c.Println("Hello", c.Args[0])
},
})
shell.Run()
go-prompt example:
p := prompt.New(
executor,
completer,
prompt.OptionPrefix(">>> "),
prompt.OptionTitle("My REPL"),
)
p.Run()
Both libraries provide ways to create interactive command-line interfaces in Go, but they differ in their approach and feature set. ishell focuses on simplicity and ease of use, making it quick to set up basic shell-like interfaces. go-prompt, on the other hand, offers more advanced features like sophisticated auto-completion and multi-line editing, at the cost of increased complexity.
The choice between the two depends on the specific requirements of your project. If you need a simple shell-like interface with basic command handling, ishell might be the better choice. For more complex interactive prompts with advanced features, go-prompt could be more suitable.
Readline is a pure go(golang) implementation for GNU-Readline kind library
Pros of readline
- Lower-level library providing more control over input handling
- Supports advanced features like custom key bindings and completion
- Widely used and battle-tested in production environments
Cons of readline
- Requires more setup and configuration for basic functionality
- Less user-friendly for creating simple interactive shells
- Limited built-in support for command history management
Code Comparison
readline:
rl, err := readline.New("> ")
if err != nil {
panic(err)
}
defer rl.Close()
ishell:
shell := ishell.New()
shell.Println("Welcome to Interactive Shell")
shell.Run()
Summary
readline is a lower-level library offering more control and advanced features, while ishell provides a higher-level abstraction for creating interactive shells with less setup. readline requires more configuration but offers greater flexibility, whereas ishell is more user-friendly for simple use cases. The choice between the two depends on the specific requirements of your project and the level of control you need over input handling.
A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
Pros of survey
- Focused on creating interactive prompts and surveys
- Supports a wide range of question types (input, confirm, select, multiselect)
- Easy to use API for creating complex surveys
Cons of survey
- Limited to command-line input/output interactions
- Lacks features for building full interactive shell applications
- May require additional libraries for more advanced CLI functionality
Code comparison
survey:
prompt := &survey.Input{
Message: "Enter your name:",
}
survey.AskOne(prompt, &name)
ishell:
shell := ishell.New()
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "Greets user",
Func: func(c *ishell.Context) {
c.Println("Hello!")
},
})
shell.Run()
Summary
survey is ideal for creating interactive prompts and surveys in Go applications, offering a variety of question types and an easy-to-use API. However, it's limited to input/output interactions and may not be suitable for building full-fledged interactive shell applications.
ishell, on the other hand, provides a more comprehensive framework for creating interactive command-line applications with features like command registration, auto-completion, and persistent history. It's better suited for building complex CLI tools but may be overkill for simple survey-style interactions.
Choose survey for quick and easy interactive prompts, and ishell for more advanced interactive shell applications.
Interactive prompt for command-line applications
Pros of promptui
- Focused on creating interactive prompts and user input validation
- Provides pre-built templates for common input types (e.g., select, confirm)
- Offers customizable styling options for prompts
Cons of promptui
- Limited to command-line prompts and input handling
- Lacks built-in shell functionality and command execution
- May require additional libraries for more complex CLI applications
Code Comparison
promptui:
prompt := promptui.Select{
Label: "Select Day",
Items: []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"},
}
_, result, err := prompt.Run()
ishell:
shell := ishell.New()
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "greet user",
Func: func(c *ishell.Context) {
c.Println("Hello, world!")
},
})
Summary
promptui is specialized for creating interactive prompts and handling user input, offering pre-built templates and customizable styling. It's ideal for applications that require user input validation and selection.
ishell, on the other hand, provides a more comprehensive framework for building interactive shell applications. It includes features like command registration, argument parsing, and shell-like behavior.
Choose promptui for focused input handling and promptui for full-fledged interactive CLI applications.
Pure Go line editor with history, inspired by linenoise
Pros of liner
- Simpler and more lightweight, focusing primarily on line editing functionality
- Better suited for projects requiring basic readline-like features without full shell capabilities
- More actively maintained with recent updates and contributions
Cons of liner
- Limited functionality compared to ishell's full-featured interactive shell capabilities
- Lacks built-in command parsing and execution features
- Doesn't provide a complete framework for building interactive CLI applications
Code Comparison
liner example:
line, err := liner.NewLiner()
defer line.Close()
line.SetCtrlCAborts(true)
for {
if input, err := line.Prompt("> "); err == nil {
fmt.Println("You entered:", input)
} else if err == liner.ErrPromptAborted {
break
}
}
ishell example:
shell := ishell.New()
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "greet user",
Func: func(c *ishell.Context) {
c.Println("Hello", c.Args[0])
},
})
shell.Run()
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
ishell
ishell is an interactive shell library for creating interactive cli applications.
Usage
import "strings"
import "github.com/abiosoft/ishell/v2"
func main(){
// create new shell.
// by default, new shell includes 'exit', 'help' and 'clear' commands.
shell := ishell.New()
// display welcome info.
shell.Println("Sample Interactive Shell")
// register a function for "greet" command.
shell.AddCmd(&ishell.Cmd{
Name: "greet",
Help: "greet user",
Func: func(c *ishell.Context) {
c.Println("Hello", strings.Join(c.Args, " "))
},
})
// run shell
shell.Run()
}
Execution
Sample Interactive Shell
>>> help
Commands:
clear clear the screen
greet greet user
exit exit the program
help display help
>>> greet Someone Somewhere
Hello Someone Somewhere
>>> exit
$
Reading input
// simulate an authentication
shell.AddCmd(&ishell.Cmd{
Name: "login",
Help: "simulate a login",
Func: func(c *ishell.Context) {
// disable the '>>>' for cleaner same line input.
c.ShowPrompt(false)
defer c.ShowPrompt(true) // yes, revert after login.
// get username
c.Print("Username: ")
username := c.ReadLine()
// get password.
c.Print("Password: ")
password := c.ReadPassword()
... // do something with username and password
c.Println("Authentication Successful.")
},
})
Execution
>>> login
Username: someusername
Password:
Authentication Successful.
Multiline input
Builtin support for multiple lines.
>>> This is \
... multi line
>>> Cool that << EOF
... everything here goes
... as a single argument.
... EOF
User defined
shell.AddCmd(&ishell.Cmd{
Name: "multi",
Help: "input in multiple lines",
Func: func(c *ishell.Context) {
c.Println("Input multiple lines and end with semicolon ';'.")
lines := c.ReadMultiLines(";")
c.Println("Done reading. You wrote:")
c.Println(lines)
},
})
Execution
>>> multi
Input multiple lines and end with semicolon ';'.
>>> this is user defined
... multiline input;
You wrote:
this is user defined
multiline input;
Keyboard interrupt
Builtin interrupt handler.
>>> ^C
Input Ctrl-C once more to exit
>>> ^C
Interrupted
exit status 1
Custom
shell.Interrupt(func(count int, c *ishell.Context) { ... })
Multiple Choice
func(c *ishell.Context) {
choice := c.MultiChoice([]string{
"Golangers",
"Go programmers",
"Gophers",
"Goers",
}, "What are Go programmers called ?")
if choice == 2 {
c.Println("You got it!")
} else {
c.Println("Sorry, you're wrong.")
}
},
Output
What are Go programmers called ?
Golangers
Go programmers
> Gophers
Goers
You got it!
Checklist
func(c *ishell.Context) {
languages := []string{"Python", "Go", "Haskell", "Rust"}
choices := c.Checklist(languages,
"What are your favourite programming languages ?", nil)
out := func() []string { ... } // convert index to language
c.Println("Your choices are", strings.Join(out(), ", "))
}
Output
What are your favourite programming languages ?
Python
â Go
Haskell
>â Rust
Your choices are Go, Rust
Progress Bar
Determinate
func(c *ishell.Context) {
c.ProgressBar().Start()
for i := 0; i < 101; i++ {
c.ProgressBar().Suffix(fmt.Sprint(" ", i, "%"))
c.ProgressBar().Progress(i)
... // some background computation
}
c.ProgressBar().Stop()
}
Output
[==========> ] 50%
Indeterminate
func(c *ishell.Context) {
c.ProgressBar().Indeterminate(true)
c.ProgressBar().Start()
... // some background computation
c.ProgressBar().Stop()
}
Output
[ ==== ]
Custom display using briandowns/spinner.
display := ishell.ProgressDisplayCharSet(spinner.CharSets[11])
func(c *Context) { c.ProgressBar().Display(display) ... }
// or set it globally
ishell.ProgressBar().Display(display)
Durable history
// Read and write history to $HOME/.ishell_history
shell.SetHomeHistoryPath(".ishell_history")
Non-interactive execution
In some situations it is desired to exit the program directly after executing a single command.
// when started with "exit" as first argument, assume non-interactive execution
if len(os.Args) > 1 && os.Args[1] == "exit" {
shell.Process(os.Args[2:]...)
} else {
// start shell
shell.Run()
}
# Run normally - interactive mode:
$ go run main.go
>>> |
# Run non-interactivelly
$ go run main.go exit greet Someusername
Hello Someusername
Output with Color
You can use fatih/color.
func(c *ishell.Context) {
yellow := color.New(color.FgYellow).SprintFunc()
c.Println(yellow("This line is yellow"))
}
Execution
>>> color
This line is yellow
Example
Available here.
go run example/main.go
Supported Platforms
- Linux
- OSX
- Windows [Not tested but should work]
Note
ishell is in active development and can still change significantly.
Roadmap (in no particular order)
- Multiline inputs
- Command history
- Customizable tab completion
- Handle ^C interrupts
- Subcommands and help texts
- Scrollable paged output
- Progress bar
- Multiple choice prompt
- Checklist prompt
- Support for command aliases
- Multiple line progress bars
- Testing, testing, testing
Contribution
- Create an issue to discuss it.
- Send in Pull Request.
License
MIT
Credits
Library | Use |
---|---|
github.com/flynn-archive/go-shlex | splitting input into command and args. |
github.com/chzyer/readline | readline capabilities. |
Donate
bitcoin: 1GTHYEDiy2C7RzXn5nY4wVRaEN2GvLjwZN
paypal: a@abiosoft.com
Top Related Projects
Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.
Readline is a pure go(golang) implementation for GNU-Readline kind library
A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
Interactive prompt for command-line applications
Pure Go line editor with history, inspired by linenoise
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot