From c93dbdcad5d885e1a1d11044c66c3bf1525e3270 Mon Sep 17 00:00:00 2001 From: maxlandon Date: Mon, 18 Dec 2023 12:11:17 +0000 Subject: [PATCH 1/3] Fixes and merges before release (#44) * Use mvdan/sh for parsing and removing comments * Update readline dep * Update carapace dependency library * Update readline dependency * Ensure the completion function is initialized * Update completer.go * Update carapace to latest --- completer.go | 2 +- go.mod | 2 -- go.sum | 6 ------ 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/completer.go b/completer.go index d5ca4cc..5d1df57 100644 --- a/completer.go +++ b/completer.go @@ -10,7 +10,7 @@ import ( "unicode" "unicode/utf8" - "github.com/rsteube/carapace" + "github.com/rsteube/carapace" "github.com/rsteube/carapace/pkg/style" completer "github.com/rsteube/carapace/pkg/x" "github.com/rsteube/carapace/pkg/xdg" diff --git a/go.mod b/go.mod index 00ee8f9..2460ed4 100644 --- a/go.mod +++ b/go.mod @@ -21,5 +21,3 @@ require ( gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -// replace github.com/rsteube/carapace v0.45.0 => github.com/reeflective/carapace v0.25.2-0.20230816093630-a30f5184fa0d diff --git a/go.sum b/go.sum index 3ff8498..2add551 100644 --- a/go.sum +++ b/go.sum @@ -14,16 +14,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/reeflective/readline v1.0.12 h1:QPhnlGCqWXR4iZvApU5RJ5Bo3vIaVAW6ICBJ8F8QZII= -github.com/reeflective/readline v1.0.12/go.mod h1:3iOe/qyb2jEy0KqLrNlb/CojBVqxga9ACqz/VU22H6A= github.com/reeflective/readline v1.0.13 h1:TeJmYw9B7VRPZWfNExr9QHxL1m0iSicyqBSQIRn39Ss= github.com/reeflective/readline v1.0.13/go.mod h1:3iOe/qyb2jEy0KqLrNlb/CojBVqxga9ACqz/VU22H6A= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY= github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rsteube/carapace v0.46.3-0.20231209231049-19872eee702a h1:DotkLg9BRx7a9/QEICipXFFKxwWISkW8e0HhloIPwno= -github.com/rsteube/carapace v0.46.3-0.20231209231049-19872eee702a/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o= github.com/rsteube/carapace v0.46.3-0.20231214181515-27e49f3c3b69 h1:ctOUuKn5PO6VtwtaS7unNrm6u20YXESPtnKEie/u304= github.com/rsteube/carapace v0.46.3-0.20231214181515-27e49f3c3b69/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o= github.com/rsteube/carapace-shlex v0.1.1 h1:fRQEBBKyYKm4TXUabm4tzH904iFWSmXJl3UZhMfQNYU= @@ -33,8 +29,6 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= -golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= From e608d6823bd7560921be444ba2fb1ae54ec9d577 Mon Sep 17 00:00:00 2001 From: Pygrum <119087231+pygrum@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:54:00 +0100 Subject: [PATCH 2/3] feat: newline when empty flag (#49) * no large gaps between prompts on empty input due to NewlineBefore and NewlineAfter * removed lastLine placeholder * don't print lastLine * check firstRead in newlineAfter * set lastLine every iteration --- console.go | 13 +++++++++++++ line.go | 11 +++++++++++ run.go | 33 ++++++++++++++++++++++++++++----- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/console.go b/console.go index 795363a..764b57b 100644 --- a/console.go +++ b/console.go @@ -33,6 +33,17 @@ type Console struct { // know how to handle it in all situations. NewlineAfter bool + // Leave empty lines with NewlineBefore and NewlineAfter, even if the provided input was empty. + // Empty characters are defined as any number of spaces and tabs. The 'empty' character set + // can be changed by modifying Console.EmptyChars + // This field is false by default. + NewlineWhenEmpty bool + + // Characters that are used to determine whether an input line was empty. If a line is not entirely + // made up by any of these characters, then it is not considered empty. The default characters + // are ' ' and '\t'. + EmptyChars []rune + // PreReadlineHooks - All the functions in this list will be executed, // in their respective orders, before the console starts reading // any user input (ie, before redrawing the prompt). @@ -89,6 +100,8 @@ func New(app string) *Console { console.shell.Completer = console.complete console.defaultStyleConfig() + // Defaults + console.EmptyChars = []rune{' ', '\t'} return console } diff --git a/line.go b/line.go index d33ce06..9be30eb 100644 --- a/line.go +++ b/line.go @@ -267,3 +267,14 @@ func trimSpacesMatch(remain []string) (trimmed []string) { return } + +func (c *Console) lineEmpty(line string) bool { + empty := true + for _, r := range line { + if !strings.ContainsRune(string(c.EmptyChars), r) { + empty = false + break + } + } + return empty +} diff --git a/run.go b/run.go index 29c6821..29b379b 100644 --- a/run.go +++ b/run.go @@ -23,11 +23,24 @@ func (c *Console) Start() error { c.printLogo(c) } - for { + lastLine := "" // used to check if last read line is empty. + + for i := 0; ; i++ { // Identical to printing it at the end of the loop, and // leaves some space between the logo and the first prompt. + + // If NewlineAfter is set but NewlineWhenEmpty is not set, we do a check to see + // if the last line was empty. If it wasn't, then we can print. + //fmt.Println(lastLine, len(lastLine)) if c.NewlineAfter { - fmt.Println() + if !c.NewlineWhenEmpty && i != 0 { + // Print on the condition that the last input wasn't empty. + if !c.lineEmpty(lastLine) { + fmt.Println() + } + } else { + fmt.Println() + } } // Always ensure we work with the active menu, with freshly @@ -44,13 +57,19 @@ func (c *Console) Start() error { // Block and read user input. line, err := c.shell.Readline() - if c.NewlineBefore { - fmt.Println() + if !c.NewlineWhenEmpty { + if !c.lineEmpty(line) { + fmt.Println() + } + } else { + fmt.Println() + } } if err != nil { menu.handleInterrupt(err) + lastLine = line continue } @@ -63,10 +82,12 @@ func (c *Console) Start() error { args, err := c.parse(line) if err != nil { fmt.Printf("Parsing error: %s\n", err.Error()) + lastLine = line continue } if len(args) == 0 { + lastLine = line continue } @@ -75,6 +96,7 @@ func (c *Console) Start() error { args, err = c.runLineHooks(args) if err != nil { fmt.Printf("Line error: %s\n", err.Error()) + lastLine = line continue } @@ -83,9 +105,10 @@ func (c *Console) Start() error { // the library user is responsible for setting // the cobra behavior. // If it's an interrupt, we take care of it. - if err := c.execute(menu, args, false); err != nil { + if err = c.execute(menu, args, false); err != nil { fmt.Println(err) } + lastLine = line } } From af61a0f3601ddeaf90b3ad3aa748b71e388f4dbb Mon Sep 17 00:00:00 2001 From: Pygrum <119087231+pygrum@users.noreply.github.com> Date: Wed, 10 Jul 2024 21:35:54 +0100 Subject: [PATCH 3/3] feat: custom shell highlight (#50) * no large gaps between prompts on empty input due to NewlineBefore and NewlineAfter * removed lastLine placeholder * don't print lastLine * check firstRead in newlineAfter * set lastLine every iteration * custom ansi code for flag and command highlight color * docstring --- console.go | 20 ++++++++++++-------- highlighter.go | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/console.go b/console.go index 764b57b..390e6f3 100644 --- a/console.go +++ b/console.go @@ -12,14 +12,16 @@ import ( // Console is an integrated console application instance. type Console struct { // Application - name string // Used in the prompt, and for readline `.inputrc` application-specific settings. - shell *readline.Shell // Provides readline functionality (inputs, completions, hints, history) - printLogo func(c *Console) // Simple logo printer. - menus map[string]*Menu // Different command trees, prompt engines, etc. - filters []string // Hide commands based on their attributes and current context. - isExecuting bool // Used by log functions, which need to adapt behavior (print the prompt, , etc) - printed bool // Used to adjust asynchronous messages too. - mutex *sync.RWMutex // Concurrency management. + name string // Used in the prompt, and for readline `.inputrc` application-specific settings. + shell *readline.Shell // Provides readline functionality (inputs, completions, hints, history) + printLogo func(c *Console) // Simple logo printer. + cmdHighlight string // Ansi code for highlighting of command in default highlighter. Green by default. + flagHighlight string // Ansi code for highlighting of flag in default highlighter. Grey by default. + menus map[string]*Menu // Different command trees, prompt engines, etc. + filters []string // Hide commands based on their attributes and current context. + isExecuting bool // Used by log functions, which need to adapt behavior (print the prompt, etc.) + printed bool // Used to adjust asynchronous messages too. + mutex *sync.RWMutex // Concurrency management. // Execution @@ -93,6 +95,8 @@ func New(app string) *Console { } // Syntax highlighting, multiline callbacks, etc. + console.cmdHighlight = seqFgGreen + console.flagHighlight = seqBrightWigth console.shell.AcceptMultiline = console.acceptMultiline console.shell.SyntaxHighlighter = console.highlightSyntax diff --git a/highlighter.go b/highlighter.go index 436b7c0..48f53a6 100644 --- a/highlighter.go +++ b/highlighter.go @@ -31,6 +31,22 @@ var ( reverseReset = "\x1b[27m" ) +// SetDefaultCommandHighlight allows the user to change the highlight color for a command in the default syntax +// highlighter using an ansi code. +// This action has no effect if a custom syntax highlighter for the shell is set. +// By default, the highlight code is green ("\x1b[32m"). +func (c *Console) SetDefaultCommandHighlight(seq string) { + c.cmdHighlight = seq +} + +// SetDefaultFlagHighlight allows the user to change the highlight color for a flag in the default syntax +// highlighter using an ansi color code. +// This action has no effect if a custom syntax highlighter for the shell is set. +// By default, the highlight code is grey ("\x1b[38;05;244m"). +func (c *Console) SetDefaultFlagHighlight(seq string) { + c.flagHighlight = seq +} + // highlightSyntax - Entrypoint to all input syntax highlighting in the Wiregost console. func (c *Console) highlightSyntax(input []rune) (line string) { // Split the line as shellwords @@ -82,7 +98,7 @@ func (c *Console) highlightCommand(done, args []string, _ *cobra.Command) ([]str } if cmdFound { - highlighted = append(highlighted, bold+seqFgGreen+args[0]+seqFgReset+boldReset) + highlighted = append(highlighted, bold+c.cmdHighlight+args[0]+seqFgReset+boldReset) rest = args[1:] return append(done, highlighted...), rest @@ -102,7 +118,7 @@ func (c *Console) highlightCommandFlags(done, args []string, _ *cobra.Command) ( for _, arg := range args { if strings.HasPrefix(arg, "-") || strings.HasPrefix(arg, "--") { - highlighted = append(highlighted, bold+seqBrightWigth+arg+seqFgReset+boldReset) + highlighted = append(highlighted, bold+c.flagHighlight+arg+seqFgReset+boldReset) } else { highlighted = append(highlighted, arg) }