-
Notifications
You must be signed in to change notification settings - Fork 6
Getting Started
The following snippet shows how to create a new console instance with the following defaults:
- A readline shell with a default configuration (Emacs mode).
- A default -main- menu, with an empty command tree.
- Bound to this menu, an in-memory history source.
package main
func main() {
// Instantiate a new app, with a single, default menu.
// All defaults are set, and nothing is needed to make it work.
//
// The call requires an application name (which can be left empty), which will be used
// by the underlying readline shell to load per-application options and command binds.
// See below.
app := console.New("ApplicationName")
// ... We will include code in here as we go through the documentation...
// And will run the console application.
app.Start()
}
To begin with, we setup a few global options, applying to all menus and contexts:
// Surround command output, asynchronous logs and interrupt handlers with a newline.
app.NewlineBefore = true
app.NewlineAfter = true
// Set the logo function
app.SetPrintLogo(func(_ *console.Console) {
fmt.Print(`
_____ __ _ _ _ _____ _
| __ \ / _| | | | (_) / ____| | |
| |__) |___ ___| |_| | ___ ___| |_ ___ _____ | | ___ _ __ ___ ___ | | ___
| _ // _ \/ _ \ _| |/ _ \/ __| __| \ \ / / _ \ | | / _ \| '_ \/ __|/ _ \| |/ _ \
| | \ \ __/ __/ | | | __/ (__| |_| |\ V / __/ | |___| (_) | | | \__ \ (_) | | __/
|_| \_\___|\___|_| |_|\___|\___|\__|_| \_/ \___| \_____\___/|_| |_|___/\___/|_|\___|
`)
})
The underlying readline shell used by the console is highly configurable.
However, for most intents and purposes, its defaults are powerful enough, and most of
the customization is made through user-side inputrc
files.
The shell configuration and documentation can be found here.
Of interest for developers using this console
application is the fact that the shell
inputrc
supports that each application using readline
can declare itself so that
per-application user bindings and options apply, like in the legacy GNU readline library.
Therefore, it is highly recommanded to use a unique name for your console application.
An extract of such per-application settings in a user inputrc
file is the following:
# github.com/reeflective/readline Go readline library
$if ApplicationName
set autocomplete on
set usage-hint-always on
set history-autosuggest off
set autopairs on
set prompt-transient off
# Other per-application command bindings/macros/etc.
$endif
Some more specialized options can be passed to the readline
shell if you want to reload
the user configuration, although this is very likely not needed:
import "github.com/reeflective/readline/inputrc"
var opts []inputrc.Option
opts = append(opts, inputrc.WithName("/path/to/app_config.inputrc")) // Force a specific configuration file.
opts = append(opts, inputrc.WithMode("xterm-256colors")) // Force a specific terminal
// Set the shell options and/or reload the configuration.
app.Shell().Opts = opts // If assigned, those will be used on each user-triggered reload
app.Shell().Keymap.ReloadConfig(opts) // If only reloaded through this call, will apply only once.
Developers can write and bind a custom callback which will apply highlighting to the input buffer, before readline adds its own overlays when it needs to. The callback is the following:
// SyntaxHighlighter is a helper function to provide syntax highlighting.
// Once enabled, set to nil to disable again.
SyntaxHighlighter func(line []rune) string
The console application is created with a default simple syntax highlighter, which support for command,
flag and strings highlighting. Should you need a more complex (or maybe more reliable) syntax highligther,
you might use the famous chroma
library:
import "github.com/alecthomas/chroma/quick"
// highlighter uses chroma to highlight the line in an SQL dialect.
func highlighter(line []rune) string {
var highlighted strings.Builder
err := quick.Highlight(&highlighter, string(input), "sql", "terminal16m", "xcode-dark")
if err != nil {
return string(line)
}
return highlighted.String()
}
// Binding the syntax highlighter
app := console.New("App") // The default highlighter is bound in this call.
app.Shell().SyntaxHighlighter = highlighter // And is overridden like this.
By default, the console application comes with classic sh-style input line word splitter, slightly
modify to add support for multiline, the latter being triggered on several conditions (and upon Return
keypress, or the keybinding assigned to one of the shell's accept-line
command variants):
- If the current quote is not closed.
- If the last character of the input line is backslash.
You can override this default behavior by overriding the AcceptMultiline()
callback of the app.Shell()
.