-
Notifications
You must be signed in to change notification settings - Fork 6
Prompts
The console makes use of oh-my-posh prompt engines for each menu. This allows users to have a cross-platform, versatile and customizable prompt system. Courtesy of @JanDeDobbeleer and its amazing maintenance and code, users now can:
- Write custom prompt segments, specific to their application logic and/or to a console menu.
- Use those segments in a prompt configuration file loaded by default (or not) in their applicaiton.
- Make use of all the builtin prompt segments offered by Oh-My-Posh.
A prompt segment writer is any type satisfying the following interface:
import (
"github.com/jandedobbeleer/oh-my-posh/src/platform"
"github.com/jandedobbeleer/oh-my-posh/src/properties"
)
type SegmentWriter interface {
Enabled() bool
Template() string
Init(props properties.Properties, env platform.Environment) {
}
This interface is quite simple, but also very powerful. It allows library users to declare an arbitrary
structure, and to use its various fields in a template string in order to provide a prompt segment. The
following is a very simple example, where we just alias a string, and where we just return the value of
it. You could as well return a full template in the Template() string
method.
The following is maybe the simplest segment one can write, from the example console:
type Module struct {
Type string
Path string
}
func (m Module) Enabled() bool {
return string(m.Path) != ""
}
func (m Module) Template() string {
return string(m.Path)
}
func (m Module) Init(props properties.Properties, env platform.Environment) {
}
var module = Module{"scan", "protocol/tcp"}
You can then directly register this segment to the oh-my-posh
library, without going through the console:
import (
"github.com/jandedobbeleer/oh-my-posh/src/engine"
)
func main() {
engine.Segments[engine.SegmentType("module")] = func() engine.SegmentWriter { return module }
}
Note: It is not mandatory to register a custom segment before loading a configuration making use of it. You could as well go the next section of this page, and add this code hereafter. The prompt engine would still work as intended.
The following is an extracted snippet of the example application prompt configuration:
"blocks": [
{
"alignment": "left",
"newline": true,
"segments": [
{
"style": "plain",
"template": " using (<#df2e1c>{{ .Segment }}</>) ",
"type": "module"
}
... other segments
Now that we have our custom segment, we need to load a custom prompt configuration should we want to, for a given menu. Please see [here] for a complete documentation on how to write this configuration.
One of the big advantages of being able to use the oh-my-posh
prompt engine, is that we can now use
our module
segment in pretty much any block of the prompt (primary/secondary/RPROMPT/tooltip, etc).
Coming back to our newly created menu:
func createMenu(c *console.Console) {
clientMenu := c.NewMenu("client")
prompt := clientMenu.Prompt()
// Add custom segments to the prompt library.
// (again, can be used by all menu engines)
engine.Segments[engine.SegmentType("module")] = func() engine.SegmentWriter { return module }
// Load a configuration file on the system,
// where we actually use our new prompt segment.
prompt.LoadConfig("prompt.omp.json")
}