Skip to content

Commit

Permalink
removed MultipartsContext
Browse files Browse the repository at this point in the history
- moved Parts to Context for simplicity
- this is only set during an ActionMultiParts
  • Loading branch information
rsteube committed Feb 28, 2021
1 parent 9768772 commit 23e2f9a
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 51 deletions.
34 changes: 14 additions & 20 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ func (a ActionMap) shell(shell string, c Context) map[string]string {
}

type Context struct {
// CallbackValue contains the (partial) value (or part of it during an ActionMultiParts) currently being completed
CallbackValue string
Args []string
}

type MultipartsContext struct {
Context
// Args contains the positional arguments of current (sub)command (exclusive the one currently being completed)
Args []string
// Parts contains the splitted CallbackValue during an ActionMultiParts (exclusive the part currently being completed)
Parts []string
}

Expand Down Expand Up @@ -148,15 +147,15 @@ func (a InvokedAction) ToA() Action {
}

func (a InvokedAction) ToMultiPartsA(divider string) Action {
return ActionMultiParts(divider, func(mc MultipartsContext) Action {
return ActionMultiParts(divider, func(c Context) Action {
uniqueVals := make(map[string]string)
for _, val := range a.rawValues {
if strings.HasPrefix(val.Value, strings.Join(mc.Parts, divider)) {
if splitted := strings.Split(val.Value, divider); len(splitted) > len(mc.Parts) {
if len(splitted) == len(mc.Parts)+1 {
uniqueVals[splitted[len(mc.Parts)]] = val.Description
if strings.HasPrefix(val.Value, strings.Join(c.Parts, divider)) {
if splitted := strings.Split(val.Value, divider); len(splitted) > len(c.Parts) {
if len(splitted) == len(c.Parts)+1 {
uniqueVals[splitted[len(c.Parts)]] = val.Description
} else {
uniqueVals[splitted[len(mc.Parts)]+divider] = ""
uniqueVals[splitted[len(c.Parts)]+divider] = ""
}
}
}
Expand Down Expand Up @@ -327,29 +326,24 @@ func ActionMessage(msg string) Action {
})
}

// CallbackValue is set to the currently completed flag/positional value during callback (note that this is updated during ActionMultiParts)
//var CallbackValue string // TODO remove

// ActionMultiParts completes multiple parts of words separately where each part is separated by some char (CallbackValue is set to the currently completed part during invocation)
func ActionMultiParts(divider string, callback func(mc MultipartsContext) Action) Action {
func ActionMultiParts(divider string, callback func(c Context) Action) Action {
return ActionCallback(func(c Context) Action {
mc := MultipartsContext{Context: c}

index := strings.LastIndex(c.CallbackValue, string(divider))
prefix := ""
if len(divider) == 0 {
prefix = c.CallbackValue
} else if index != -1 {
prefix = c.CallbackValue[0 : index+len(divider)]
mc.CallbackValue = c.CallbackValue[index+len(divider):] // update CallbackValue to only contain the currently completed part
c.CallbackValue = c.CallbackValue[index+len(divider):] // update CallbackValue to only contain the currently completed part
}
parts := strings.Split(prefix, string(divider))
if len(parts) > 0 {
parts = parts[0 : len(parts)-1]
}
mc.Parts = parts
c.Parts = parts

return callback(mc).Invoke(mc.Context).Prefix(prefix).ToA()
return callback(c).Invoke(c).Prefix(prefix).ToA()
})
}

Expand Down
18 changes: 9 additions & 9 deletions docs/src/carapace/action/actionMultiParts.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
[`ActionMultiParts`] is a [callback action](./actionCallback.md) where parts of an argument can be completed separately (e.g. `user:group` from chown). Divider can be empty as well, but note that bash and fish will add the space suffix for anything other than `/=@:.,` (it still works, but after each selection backspace is needed to continue the completion).

```go
carapace.ActionMultiParts(":", func(mc carapace.MultipartsContext) carapace.Action {
carapace.ActionMultiParts(":", func(c carapace.Context) carapace.Action {
switch len(parts) {
case 0:
return ActionUsers().Invoke(mc.Args).Suffix(":").ToA()
return ActionUsers().Invoke(c.Args).Suffix(":").ToA()
case 1:
return ActionGroups()
default:
Expand All @@ -25,17 +25,17 @@ carapace.ActionMultiParts(":", func(mc carapace.MultipartsContext) carapace.Acti
[`ActionMultiParts`] can be nested as well, e.g. completing multiple `KEY=VALUE` pairs separated by `,`.

```go
carapace.ActionMultiParts(",", func(mcEntries carapace.MultipartsContext) carapace.Action {
return carapace.ActionMultiParts("=", func(mc carapace.MultipartsContext) carapace.Action {
switch len(mc.Parts) {
carapace.ActionMultiParts(",", func(cEntries carapace.Context) carapace.Action {
return carapace.ActionMultiParts("=", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
keys := make([]string, len(mcEntries.Parts))
for index, entry := range mcEntries.Parts {
keys := make([]string, len(cEntries.Parts))
for index, entry := range cEntries.Parts {
keys[index] = strings.Split(entry, "=")[0]
}
return carapace.ActionValues("FILE", "DIRECTORY", "VALUE").Invoke(mc.Context).Filter(keys).Suffix("=").ToA()
return carapace.ActionValues("FILE", "DIRECTORY", "VALUE").Invoke(c).Filter(keys).Suffix("=").ToA()
case 1:
switch mc.Parts[0] {
switch c.Parts[0] {
case "FILE":
return carapace.ActionFiles("")
case "DIRECTORY":
Expand Down
4 changes: 2 additions & 2 deletions docs/src/carapace/invokedAction/filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
E.g. completing a unique list of values in an [ActionMultiParts](../action/actionMultiParts.md):

```go
carapace.ActionMultiParts(",", func(mc carapace.MultipartsContext) carapace.Action {
return carapace.ActionValues("one", "two", "three").Invoke(mc.Context).Filter(c.Parts).ToA()
carapace.ActionMultiParts(",", func(c carapace.Context) carapace.Action {
return carapace.ActionValues("one", "two", "three").Invoke(c).Filter(c.Parts).ToA()
}
```
6 changes: 3 additions & 3 deletions example/cmd/action/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ func ActionUsers() carapace.Action {
}

func ActionUserGroup() carapace.Action {
return carapace.ActionMultiParts(":", func(mc carapace.MultipartsContext) carapace.Action {
switch len(mc.Parts) {
return carapace.ActionMultiParts(":", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
return ActionUsers().Invoke(mc.Context).Suffix(":").ToA()
return ActionUsers().Invoke(c).Suffix(":").ToA()
case 1:
return ActionGroups()
default:
Expand Down
6 changes: 3 additions & 3 deletions example/cmd/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ func init() {
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
return carapace.ActionValues("callback1", "callback2")
}).Cache(30*time.Second),
carapace.ActionMultiParts("=", func(mc carapace.MultipartsContext) carapace.Action {
switch len(mc.Parts) {
carapace.ActionMultiParts("=", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
return carapace.ActionValues("alpha=", "beta=", "gamma")
case 1:
switch mc.Parts[0] {
switch c.Parts[0] {
case "alpha":
return carapace.ActionValues("one", "two", "three")
case "beta":
Expand Down
28 changes: 14 additions & 14 deletions example/cmd/multiparts.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ func init() {
"dotdotdot": ActionMultipartsTest("..."),
"equals": ActionMultipartsTest("="),
"slash": ActionMultipartsTest("/"),
"none": carapace.ActionMultiParts("", func(mc carapace.MultipartsContext) carapace.Action {
return carapace.ActionValuesDescribed("a", "first", "b", "second", "c", "third", "d", "fourth").Invoke(mc.Context).Filter(strings.Split(mc.CallbackValue, "")).ToA()
"none": carapace.ActionMultiParts("", func(c carapace.Context) carapace.Action {
return carapace.ActionValuesDescribed("a", "first", "b", "second", "c", "third", "d", "fourth").Invoke(c).Filter(strings.Split(c.CallbackValue, "")).ToA()
}),
})

carapace.Gen(multipartsCmd).PositionalCompletion(
carapace.ActionMultiParts(",", func(mcEntries carapace.MultipartsContext) carapace.Action {
return carapace.ActionMultiParts("=", func(mc carapace.MultipartsContext) carapace.Action {
switch len(mc.Parts) {
carapace.ActionMultiParts(",", func(cEntries carapace.Context) carapace.Action {
return carapace.ActionMultiParts("=", func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
keys := make([]string, len(mcEntries.Parts))
for index, entry := range mcEntries.Parts {
keys := make([]string, len(cEntries.Parts))
for index, entry := range cEntries.Parts {
keys[index] = strings.Split(entry, "=")[0]
}
return carapace.ActionValues("FILE", "DIRECTORY", "VALUE").Invoke(mc.Context).Filter(keys).Suffix("=").ToA()
return carapace.ActionValues("FILE", "DIRECTORY", "VALUE").Invoke(c).Filter(keys).Suffix("=").ToA()
case 1:
switch mc.Parts[0] {
switch c.Parts[0] {
case "FILE":
return carapace.ActionFiles("")
case "DIRECTORY":
Expand All @@ -68,14 +68,14 @@ func init() {
}

func ActionMultipartsTest(divider string) carapace.Action {
return carapace.ActionMultiParts(divider, func(mc carapace.MultipartsContext) carapace.Action {
switch len(mc.Parts) {
return carapace.ActionMultiParts(divider, func(c carapace.Context) carapace.Action {
switch len(c.Parts) {
case 0:
return ActionTestValues().Invoke(mc.Context).Suffix(divider).ToA()
return ActionTestValues().Invoke(c).Suffix(divider).ToA()
case 1:
return ActionTestValues().Invoke(mc.Context).Filter(mc.Parts).Suffix(divider).ToA()
return ActionTestValues().Invoke(c).Filter(c.Parts).Suffix(divider).ToA()
case 2:
return ActionTestValues().Invoke(mc.Context).Filter(mc.Parts).ToA()
return ActionTestValues().Invoke(c).Filter(c.Parts).ToA()
default:
return carapace.ActionValues()
}
Expand Down

0 comments on commit 23e2f9a

Please sign in to comment.