• Stars
    star
    1,671
  • Rank 27,970 (Top 0.6 %)
  • Language
    Go
  • License
    MIT License
  • Created over 9 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Library for creating interactive cli applications.

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

Library Use
github.com/flynn-archive/go-shlex splitting input into command and args.
github.com/chzyer/readline readline capabilities.

Donate

bitcoin: 1GTHYEDiy2C7RzXn5nY4wVRaEN2GvLjwZN
paypal: [email protected]

More Repositories

1

colima

Container runtimes on macOS (and Linux) with minimal setup
Go
18,415
star
2

caddy-docker

Docker container for Caddy
Shell
768
star
3

caddy-git

git middleware for Caddy
Go
205
star
4

dockward

Port forwarding tool for Docker containers
Go
137
star
5

caddy-json-schema

JSON schema generator for Caddy v2
Go
130
star
6

caddy-exec

Caddy v2 module for running one-off commands
Go
102
star
7

DevReload

Auto reload for ASP.NET core development
C#
61
star
8

autoplank

automatically move Plank to the active monitor
Go
51
star
9

semaphore

Wrapping sync.Mutex for familiar semaphore api
Go
44
star
10

runcmd

Wrapper for cli apps. Write less commands.
Go
43
star
11

caddyplug

Experimental Caddy plugin manager using Go plugins
Go
40
star
12

river

River is a simple and lightweight REST server
Go
37
star
13

gocalc

Simple Go Calculator
Go
34
star
14

dotfiles

dotfiles. zsh, neovim, tmux, i3 e.t.c.
Vim Script
33
star
15

caddy-yaml

Alternative Caddy YAML config adapter with extra features
Go
27
star
16

crostini-docker

Docker for Crostini with fixed binariest that work
Shell
25
star
17

caddy-json-parse

Caddy v2 module for parsing json request
Go
18
star
18

parent

A minimal process wrapper
Go
15
star
19

caddy-named-routes

named routes support for Caddy v2
Go
14
star
20

lineprefix

io.Writer wrapper with line prefix and color customizations.
Go
13
star
21

launchar

minimal GTK application launcher
Vala
11
star
22

hello-elementary

quick start elementary OS application
Vala
10
star
23

caddy-hmac

Caddy v2 hmac signature validation middleware
Go
8
star
24

cmdplay

Prototype shell session recorder and player
Go
5
star
25

bgrun

Run processes in background
Python
5
star
26

hello-caddy

Sample external middleware for Caddy
Go
4
star
27

colima-core

Dependencies for Colima
Shell
4
star
28

caddyserver.com

Source of the Caddy website
HTML
4
star
29

forloopui2017

Code used for forloop UI 2017 talk
Go
3
star
30

webtest

Basically web repo to test servers
HTML
3
star
31

atom-go-imports

Auto import Go packages via the goimports tool
CoffeeScript
3
star
32

errs

convenience wrapper for chaining multiple error returning functions.
Go
3
star
33

injekt

Pluggable service injector
Go
3
star
34

hcl2json

HCL to JSON converter
Go
3
star
35

servefile

File Server for any directory or file
Go
2
star
36

buildsrv

The Caddy build server
Go
2
star
37

gistdl

Download github gists as files
Python
2
star
38

ghrelease

A tool to download latest release archive for a GitHub project using GitHub API.
Go
2
star
39

node-graceful

Gracefully shutdown your node app. Graceful interrupts SIGTERM and SIGINT signals.
JavaScript
2
star
40

codementorhannah

Mentorship codes
Go
1
star
41

lexicon

CSC 332 Assignment
JavaScript
1
star
42

gopages-sample

Sample blog using gopages and mgo
1
star
43

structures

CSC 341 assignment
Go
1
star
44

stack

Simple Stack
Go
1
star
45

goutils

A set of utilities for Go
Go
1
star