Skip to content

Commit

Permalink
added Action.Split
Browse files Browse the repository at this point in the history
  • Loading branch information
rsteube committed Jul 26, 2023
1 parent 22fc1c6 commit f4ae688
Show file tree
Hide file tree
Showing 12 changed files with 1,124 additions and 0 deletions.
30 changes: 30 additions & 0 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/rsteube/carapace/internal/cache"
"github.com/rsteube/carapace/internal/common"
"github.com/rsteube/carapace/internal/lexer"
pkgcache "github.com/rsteube/carapace/pkg/cache"
"github.com/rsteube/carapace/pkg/style"
)
Expand Down Expand Up @@ -294,3 +295,32 @@ func (a Action) UsageF(f func() string) Action {
return a
})
}

// Split splits `Context.Value` using a shell lexer.
func (a Action) Split() Action {
return ActionCallback(func(c Context) Action {
tokenset, err := lexer.Split(c.Value)
if err != nil {
return ActionMessage(err.Error())
}

c.Args = tokenset.Tokens[:len(tokenset.Tokens)-1]
c.Parts = []string{}
c.Value = tokenset.Tokens[len(tokenset.Tokens)-1]
invoked := a.Invoke(c)
for index, value := range invoked.rawValues {
if !invoked.meta.Nospace.Matches(value.Value) {
switch tokenset.State {
case lexer.OPEN_DOUBLE:
invoked.rawValues[index].Value = fmt.Sprintf(`"%v" `, strings.Replace(value.Value, `"`, `\"`, -1))
case lexer.OPEN_SINGLE:
invoked.rawValues[index].Value = fmt.Sprintf(`'%v' `, strings.Replace(value.Value, `'`, `'"'"'`, -1))
default:
invoked.rawValues[index].Value = strings.Replace(value.Value, ` `, `\ `, -1) + ` `
}
}
}
invoked.Prefix(tokenset.Prefix)
return invoked.ToA().NoSpace()
})
}
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [Prefix](./carapace/action/prefix.md)
- [Retain](./carapace/action/retain.md)
- [Shift](./carapace/action/shift.md)
- [Split](./carapace/action/split.md)
- [Style](./carapace/action/style.md)
- [StyleF](./carapace/action/styleF.md)
- [StyleR](./carapace/action/styleR.md)
Expand Down
86 changes: 86 additions & 0 deletions docs/src/carapace/action/split.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{"version": 2, "width": 108, "height": 24, "timestamp": 1690392077, "env": {"SHELL": "elvish", "TERM": "tmux-256color"}}
[0.078465, "o", "\u001b[?7h\u001b[7m⏎\u001b[m \r \r\u001b[?7l\u001b[?2004h"]
[0.079091, "o", "\u001b[?25l\r???> ???> \r\u001b[5C\u001b[?25h\u001b[?25l\r\u001b[5C\u001b[K\r\u001b[5C\u001b[?25h"]
[0.091788, "o", "\u001b[?25l\r\r\u001b[5C\u001b[?25h\u001b[?25l\r\r\u001b[5C\u001b[?25h"]
[0.091933, "o", "\u001b[?25l\r\u001b[K\r\n\u001b[0;1;36mcarapace/example\u001b[0;m on \u001b[0;1;35m add-action-split\u001b[0;m \u001b[0;1;31m[$!?]\u001b[0;m via \u001b[0;1;36m🐹 v1.20.6 \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \r\u001b[6C\u001b[?25h"]
[0.766098, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;31me\u001b[0;m\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.766287, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.784573, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.952355, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[7C\u001b[0;31mx\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[1.115515, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexa\u001b[0;m\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[1.230336, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mexam\u001b[0;m\r\u001b[10C\u001b[?25h"]
[1.230421, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[1.31764, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[10C\u001b[0;31mp\u001b[0;m\r\u001b[11C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[11C\u001b[?25h"]
[1.396956, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[11C\u001b[0;31ml\u001b[0;m\r\u001b[12C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[12C\u001b[?25h"]
[1.497506, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexample\u001b[0;m\r\u001b[13C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[13C\u001b[?25h"]
[1.556128, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[13C \r\u001b[14C\u001b[?25h"]
[1.556218, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[14C\u001b[?25h"]
[1.734389, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[14Cm\r\u001b[15C\u001b[?25h"]
[1.734499, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[15C\u001b[?25h"]
[1.805083, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[15Co\r\u001b[16C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[16C\u001b[?25h"]
[1.955922, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[16Cdifier \r\u001b[23C\u001b[?25h"]
[2.2755, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[23C-\r\u001b[24C\u001b[?25h"]
[2.435598, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[24C-\r\u001b[25C\u001b[?25h"]
[2.435702, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[25C\u001b[?25h"]
[2.507351, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[25Cs\r\u001b[26C\u001b[?25h"]
[2.507573, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[26C\u001b[?25h"]
[2.656398, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[26Cp\r\u001b[27C\u001b[?25h"]
[2.656504, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[27C\u001b[?25h"]
[2.914668, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[27Clit \r\u001b[31C\u001b[?25h"]
[3.591351, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[0;33m'pos\u001b[0;m\r\u001b[35C\u001b[?25h"]
[4.000959, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7mpos1\u001b[0;m positional1\u001b[1A\r\u001b[22C\u001b[?25h"]
[4.629769, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[38C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[38C\u001b[?25h"]
[4.841815, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[38C-\r\u001b[39C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[39C\u001b[?25h"]
[5.013282, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 --bool '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7m--bool\u001b[0;2;7m (bool flag)\u001b[0;m \u001b[0;34m--string\u001b[0;2m (string flag)\u001b[0;m -b\u001b[0;2m (bool flag)\u001b[0;m \u001b[0;34m-s\u001b[0;2m (string flag)\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[6.298726, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[39C\u001b[K\u001b[0;4;33mstring '\r\n\r\n\u001b[0;m\u001b[K--bool\u001b[0;2m (bool flag)\u001b[0;m \u001b[0;7;34m--string\u001b[0;2;7m (string flag)\u001b[0;m -b\u001b[0;2m (bool flag)\u001b[0;m \u001b[0;34m-s\u001b[0;2m (string flag)\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[7.242436, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 --string '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[47C\u001b[?25h"]
[7.242548, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[47C\u001b[?25h"]
[7.37394, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 --string one '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7mone\u001b[0;m three two\u001b[1A\r\u001b[22C\u001b[?25h"]
[7.864491, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[46C\u001b[K\u001b[0;4;33mthree '\r\n\r\n\u001b[0;m\u001b[Kone \u001b[0;7mthree\u001b[0;m two\u001b[1A\r\u001b[22C\u001b[?25h"]
[8.021653, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[47C\u001b[K\u001b[0;4;33mwo '\r\n\r\n\u001b[5C\u001b[0;m\u001b[Kthree \u001b[0;7mtwo\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[8.292493, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 --string two '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[51C\u001b[?25h"]
[8.293454, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.294475, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.294789, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.295564, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.29635, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.296527, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.296633, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[51C\u001b[?25h"]
[8.972497, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[51C-\r\u001b[52C\u001b[?25h"]
[9.14571, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[52C-\r\u001b[53C\u001b[?25h"]
[9.145817, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[53C\u001b[?25h"]
[9.295241, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 --string two --bool '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7m--bool\u001b[0;2;7m (bool flag)\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[9.875059, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 --string two --bool '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[58C\u001b[?25h"]
[9.875183, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[58C\u001b[?25h"]
[10.056459, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[57C\u001b[K\r\u001b[57C\u001b[?25h"]
[10.236407, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[56C\u001b[K\r\u001b[56C\u001b[?25h"]
[10.307922, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[56C\u001b[0;33m=\u001b[0;m\r\u001b[57C\u001b[?25h"]
[10.307993, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[57C\u001b[?25h"]
[10.429317, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 --string two --bool=false '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;31mfalse\u001b[0;m \u001b[0;32mtrue\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[11.242227, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[57C\u001b[K\u001b[0;4;33mtrue '\r\n\r\n\u001b[0;m\u001b[K\u001b[0;31mfalse\u001b[0;m \u001b[0;7;32mtrue\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[11.819496, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 --string two --bool=true '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[63C\u001b[?25h"]
[11.819604, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[63C\u001b[?25h"]
[13.270469, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[63C\u001b[0;33m\"\u001b[0;m\r\u001b[64C\u001b[?25h"]
[13.270956, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[64C\u001b[?25h"]
[13.586174, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[63C\u001b[K\r\u001b[63C\u001b[?25h"]
[13.586272, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[63C\u001b[?25h"]
[13.692969, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[62C\u001b[K\r\u001b[62C\u001b[?25h"]
[13.894107, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[62C\u001b[0;33m\"\u001b[0;m\r\u001b[63C\u001b[?25h"]
[13.894197, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[63C\u001b[?25h"]
[14.083592, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[63C\u001b[0;33mpos\u001b[0;m\r\u001b[66C\u001b[?25h"]
[14.595357, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;4;33m'pos1 --string two --bool=true \"pos2\" '\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7mpos2\u001b[0;m positional2\u001b[1A\r\u001b[22C\u001b[?25h"]
[15.655501, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[66C\u001b[K\u001b[0;4;33mitional2\" '\r\n\r\n\u001b[0;m\u001b[Kpos2 \u001b[0;7mpositional2\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[16.240866, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[31C\u001b[K\u001b[0;33m'pos1 --string two --bool=true \"positional2\" '\u001b[0;m\r\n\u001b[J\u001b[A\r\u001b[77C\u001b[?25h"]
[16.240978, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[77C\u001b[?25h"]
[19.377509, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\r\u001b[6C\u001b[?25h"]
[19.37868, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[19.396225, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[19.39648, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[19.396618, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[19.621854, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;31me\u001b[0;m\r\u001b[7C\u001b[?25h"]
[19.84434, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[7C\u001b[0;31mx\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[19.948184, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[8C\u001b[0;31mi\u001b[0;m\r\u001b[9C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[20.109817, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexit\u001b[0;m\r\u001b[10C\u001b[?25h"]
[20.109903, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[20.23343, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\r\u001b[?25h"]
[20.233512, "o", "\u001b[?7h\u001b[?2004l\r"]
27 changes: 27 additions & 0 deletions docs/src/carapace/action/split.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Split

[`Split`] splits `Context.Value` using a shell lexer.

```go
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
cmd := &cobra.Command{}
carapace.Gen(cmd).Standalone()
cmd.Flags().BoolP("bool", "b", false, "bool flag")
cmd.Flags().StringP("string", "s", "", "string flag")

carapace.Gen(cmd).FlagCompletion(carapace.ActionMap{
"string": carapace.ActionValues("one", "two", "three"),
})

carapace.Gen(cmd).PositionalCompletion(
carapace.ActionValues("pos1", "positional1"),
carapace.ActionValues("pos2", "positional2"),
)

return carapace.ActionExecute(cmd)
}).Split()
```

![](./split.cast)

[`Split`]: https://pkg.go.dev/github.com/rsteube/carapace#Action.Split
18 changes: 18 additions & 0 deletions example/cmd/modifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func init() {
modifierCmd.Flags().String("prefix", "", "Prefix()")
modifierCmd.Flags().String("retain", "", "Retain()")
modifierCmd.Flags().String("shift", "", "Shift()")
modifierCmd.Flags().String("split", "", "Split()")
modifierCmd.Flags().String("style", "", "Style()")
modifierCmd.Flags().String("stylef", "", "StyleF()")
modifierCmd.Flags().String("styler", "", "StyleR()")
Expand Down Expand Up @@ -123,6 +124,23 @@ func init() {
"shift": carapace.ActionCallback(func(c carapace.Context) carapace.Action {
return carapace.ActionMessage("%#v", c.Args)
}).Shift(1),
"split": carapace.ActionCallback(func(c carapace.Context) carapace.Action {
cmd := &cobra.Command{}
carapace.Gen(cmd).Standalone()
cmd.Flags().BoolP("bool", "b", false, "bool flag")
cmd.Flags().StringP("string", "s", "", "string flag")

carapace.Gen(cmd).FlagCompletion(carapace.ActionMap{
"string": carapace.ActionValues("one", "two", "three"),
})

carapace.Gen(cmd).PositionalCompletion(
carapace.ActionValues("pos1", "positional1"),
carapace.ActionFiles(),
)

return carapace.ActionExecute(cmd)
}).Split(),
"style": carapace.ActionValues(
"one",
"two",
Expand Down
81 changes: 81 additions & 0 deletions example/cmd/modifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,84 @@ func TestPrefix(t *testing.T) {
Tag("files"))
})
}

func TestSplit(t *testing.T) {
os.Unsetenv("LS_COLORS")
sandbox.Package(t, "github.com/rsteube/carapace/example")(func(s *sandbox.Sandbox) {
s.Files("subdir/file1.txt", "")

s.Run("modifier", "--split", "").
Expect(carapace.ActionValues(
"pos1",
"positional1",
).NoSpace('*').
Suffix(" ").
Usage("Split()"))

s.Run("modifier", "--split", "pos1 ").
Expect(carapace.ActionValues(
"subdir/",
).StyleF(style.ForPathExt).
Prefix("pos1 ").
NoSpace('*').
Usage("Split()").
Tag("files"))

s.Run("modifier", "--split", "pos1 \"").
Expect(carapace.ActionValues(
"subdir/",
).StyleF(style.ForPathExt).
Prefix("pos1 ").
Suffix("\"").
NoSpace('*').
Usage("Split()").
Tag("files"))

s.Run("modifier", "--split", "pos1 '").
Expect(carapace.ActionValues(
"subdir/",
).StyleF(style.ForPathExt).
Prefix("pos1 ").
Suffix("'").
NoSpace('*').
Usage("Split()").
Tag("files"))

s.Run("modifier", "--split", "pos1 --").
Expect(carapace.ActionStyledValuesDescribed(
"--bool", "bool flag", style.Default,
"--string", "string flag", style.Blue,
).Prefix("pos1 ").
Suffix(" ").
NoSpace('*').
Usage("Split()").
Tag("flags"))

s.Run("modifier", "--split", "pos1 --bool=").
Expect(carapace.ActionStyledValues(
"true", style.Green,
"false", style.Red,
).Prefix("pos1 --bool=").
Suffix(" ").
NoSpace('*').
Usage("bool flag"))

s.Run("modifier", "--split", "pos1 \"--bool=").
Expect(carapace.ActionStyledValues(
"true", style.Green,
"false", style.Red,
).Prefix("pos1 \"--bool=").
Suffix("\" ").
NoSpace('*').
Usage("bool flag"))

s.Run("modifier", "--split", "pos1 '--bool=").
Expect(carapace.ActionStyledValues(
"true", style.Green,
"false", style.Red,
).Prefix("pos1 '--bool=").
Suffix("' ").
NoSpace('*').
Usage("bool flag"))
})
}
62 changes: 62 additions & 0 deletions internal/lexer/lexer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package lexer

import (
"strings"

"github.com/rsteube/carapace/third_party/github.com/google/shlex"
)

type State int

const (
UNQUOTED = iota
OPEN_DOUBLE
OPEN_SINGLE
)

type Tokenset struct {
Tokens []string
Prefix string
State State
}

func Split(s string) (*Tokenset, error) {
tokenset, err := split(s)
if err != nil && err.Error() == "EOF found when expecting closing quote" {
tokenset, err = split(s + `_"`)
if err == nil {
last := tokenset.Tokens[len(tokenset.Tokens)-1]
tokenset.Tokens[len(tokenset.Tokens)-1] = last[:len(last)-1]
tokenset.Prefix = tokenset.Prefix[:len(tokenset.Prefix)-1]
tokenset.State = OPEN_DOUBLE
}
}
if err != nil && err.Error() == "EOF found when expecting closing quote" {
tokenset, err = split(s + `_'`)
if err == nil {
last := tokenset.Tokens[len(tokenset.Tokens)-1]
tokenset.Tokens[len(tokenset.Tokens)-1] = last[:len(last)-1]
tokenset.Prefix = tokenset.Prefix[:len(tokenset.Prefix)-1]
tokenset.State = OPEN_SINGLE
}
}
return tokenset, err
}

func split(s string) (*Tokenset, error) {
splitted, err := shlex.Split(s)
if strings.HasSuffix(s, " ") {
splitted = append(splitted, "")
}
if err != nil {
return nil, err
}

if len(splitted) == 0 {
splitted = []string{""}
}
return &Tokenset{
Tokens: splitted,
Prefix: s[:strings.LastIndex(s, splitted[len(splitted)-1])],
}, nil
}
Loading

0 comments on commit f4ae688

Please sign in to comment.