Convert Figma logo to code with AI

abiosoft logoishell

Library for creating interactive cli applications.

1,676
195
1,676
58

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

4,089

A golang library for building interactive and accessible prompts with full support for windows and posix terminals.

Interactive prompt for command-line applications

1,043

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:

  1. Install the library:

    go get github.com/abiosoft/ishell/v2
    
  2. Import it in your Go file:

    import "github.com/abiosoft/ishell/v2"
    
  3. 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.

4,089

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.

1,043

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

ishell

ishell is an interactive shell library for creating interactive cli applications.

Go Reference Go Report Card

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

  1. Create an issue to discuss it.
  2. Send in Pull Request.

License

MIT

Credits

LibraryUse
github.com/flynn-archive/go-shlexsplitting input into command and args.
github.com/chzyer/readlinereadline capabilities.

Donate

bitcoin: 1GTHYEDiy2C7RzXn5nY4wVRaEN2GvLjwZN
paypal: a@abiosoft.com