package zsh
import (
"fmt"
"regexp"
"strings"
shlex "github.com/carapace-sh/carapace-shlex"
"github.com/carapace-sh/carapace/internal/common"
"github.com/carapace-sh/carapace/internal/env"
)
var sanitizer = strings .NewReplacer (
"\n" , `` ,
"\r" , `` ,
"\t" , `` ,
)
var quotingReplacer = strings .NewReplacer (
`'` , `'\''` ,
)
var quotingEscapingReplacer = strings .NewReplacer (
`\` , `\\` ,
`"` , `\"` ,
`$` , `\$` ,
"`" , "\\`" ,
)
var defaultReplacer = strings .NewReplacer (
`\` , `\\` ,
`&` , `\&` ,
`<` , `\<` ,
`>` , `\>` ,
"`" , "\\`" ,
`'` , `\'` ,
`"` , `\"` ,
`{` , `\{` ,
`}` , `\}` ,
`$` , `\$` ,
`#` , `\#` ,
`|` , `\|` ,
`?` , `\?` ,
`(` , `\(` ,
`)` , `\)` ,
`;` , `\;` ,
` ` , `\ ` ,
`[` , `\[` ,
`]` , `\]` ,
`*` , `\*` ,
`~` , `\~` ,
)
var describeReplacer = strings .NewReplacer (
`\` , `\\` ,
`:` , `\:` ,
)
func quoteValue(s string ) string {
if strings .HasPrefix (s , "~/" ) || NamedDirectories .Matches (s ) {
return "~" + defaultReplacer .Replace (strings .TrimPrefix (s , "~" ))
}
return defaultReplacer .Replace (s )
}
type state int
const (
DEFAULT_STATE state = iota
QUOTING_ESCAPING_STATE
QUOTING_STATE
FULL_QUOTING_ESCAPING_STATE
FULL_QUOTING_STATE
)
func ActionRawValues (currentWord string , meta common .Meta , values common .RawValues ) string {
splitted , err := shlex .Split (env .Compline ())
state := DEFAULT_STATE
if err == nil {
rawValue := splitted .CurrentToken ().RawValue
switch {
case regexp .MustCompile (`^'$|^'.*[^']$` ).MatchString (rawValue ):
state = QUOTING_STATE
case regexp .MustCompile (`^"$|^".*[^"]$` ).MatchString (rawValue ):
state = QUOTING_ESCAPING_STATE
case regexp .MustCompile (`^".*"$` ).MatchString (rawValue ):
state = FULL_QUOTING_ESCAPING_STATE
case regexp .MustCompile (`^'.*'$` ).MatchString (rawValue ):
state = FULL_QUOTING_STATE
}
}
for index , value := range values {
switch value .Tag {
case "shorthand flags" , "longhand flags" :
values [index ].Tag = "flags"
}
}
tagGroup := make ([]string , 0 )
values .EachTag (func (tag string , values common .RawValues ) {
vals := make ([]string , len (values ))
displays := make ([]string , len (values ))
for index , val := range values {
value := sanitizer .Replace (val .Value )
switch state {
case QUOTING_ESCAPING_STATE :
value = quotingEscapingReplacer .Replace (value )
value = describeReplacer .Replace (value )
value = value + `"`
case QUOTING_STATE :
value = quotingReplacer .Replace (value )
value = describeReplacer .Replace (value )
value = value + `'`
case FULL_QUOTING_ESCAPING_STATE :
value = quotingEscapingReplacer .Replace (value )
value = describeReplacer .Replace (value )
case FULL_QUOTING_STATE :
value = quotingReplacer .Replace (value )
value = describeReplacer .Replace (value )
default :
value = quoteValue (value )
value = describeReplacer .Replace (value )
}
if !meta .Nospace .Matches (val .Value ) {
switch state {
case FULL_QUOTING_ESCAPING_STATE , FULL_QUOTING_STATE :
default :
value += " "
}
}
display := sanitizer .Replace (val .Display )
display = describeReplacer .Replace (display )
description := sanitizer .Replace (val .Description )
vals [index ] = value
if strings .TrimSpace (description ) == "" {
displays [index ] = display
} else {
displays [index ] = fmt .Sprintf ("%v:%v" , display , description )
}
}
tagGroup = append (tagGroup , strings .Join ([]string {tag , strings .Join (displays , "\n" ), strings .Join (vals , "\n" )}, "\003" ))
})
return fmt .Sprintf ("%v\001%v\001%v\001" , zstyles {values }.Format (), message {meta }.Format (), strings .Join (tagGroup , "\002" )+"\002" )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .