Repository: rsteube/carapace
Pull request #945 (2023-12-02 20:53:46)

bash: fix compline patching
related #944


Patch:
diff --git a/complete.go b/complete.go
index cad9e54..b13ed44 100644
--- a/complete.go
+++ b/complete.go
@@ -1,6 +1,8 @@
 package carapace
 
 import (
+	"os"
+
 	"github.com/rsteube/carapace/internal/config"
 	"github.com/rsteube/carapace/internal/shell/bash"
 	"github.com/rsteube/carapace/internal/shell/nushell"
@@ -22,6 +24,8 @@ func complete(cmd *cobra.Command, args []string) (string, error) {
 			args = nushell.Patch(args) // handle open quotes
 			LOG.Printf("patching args to %#v", args)
 		case "bash": // TODO what about oil and such?
+			LOG.Printf("COMP_LINE is %#v", os.Getenv("COMP_LINE"))
+			LOG.Printf("COMP_POINT is %#v", os.Getenv("COMP_POINT"))
 			var err error
 			args, err = bash.Patch(args) // handle redirects
 			LOG.Printf("patching args to %#v", args)
diff --git a/internal/shell/bash/patch.go b/internal/shell/bash/patch.go
index a115300..c7511e2 100644
--- a/internal/shell/bash/patch.go
+++ b/internal/shell/bash/patch.go
@@ -2,6 +2,7 @@ package bash
 
 import (
 	"os"
+	"strconv"
 
 	shlex "github.com/rsteube/carapace-shlex"
 )
@@ -17,6 +18,25 @@ func (r RedirectError) Error() string {
 // introduces state and hides what is happening but works for now
 var wordbreakPrefix string = ""
 
+func CompLine() (string, bool) {
+	line, ok := os.LookupEnv("COMP_LINE")
+	if !ok {
+		return "", false
+	}
+
+	point, ok := os.LookupEnv("COMP_POINT")
+	if !ok {
+		return "", false
+	}
+
+	pointI, err := strconv.Atoi(point)
+	if err != nil || len(line) < pointI {
+		return "", false
+	}
+
+	return line[:pointI], true
+}
+
 // Patch patches args if `COMP_LINE` environment variable is set.
 //
 // Bash passes redirects to the completion function so these need to be filtered out.
@@ -25,7 +45,7 @@ var wordbreakPrefix string = ""
 //	["example", "action", ">", "/tmp/stdout.txt", "--values", "2", ">", "/tmp/stderr.txt", "fi"]
 //	["example", "action", "--values", "fi"]
 func Patch(args []string) ([]string, error) { // TODO document and fix wordbreak splitting (e.g. `:`)
-	compline, ok := os.LookupEnv("COMP_LINE")
+	compline, ok := CompLine()
 	if !ok {
 		return args, nil
 	}
diff --git a/internal/shell/bash/snippet.go b/internal/shell/bash/snippet.go
index 806ec2f..1663ddf 100644
--- a/internal/shell/bash/snippet.go
+++ b/internal/shell/bash/snippet.go
@@ -14,6 +14,7 @@ func Snippet(cmd *cobra.Command) string {
 _%v_completion() {
   export COMP_WORDBREAKS
   export COMP_LINE
+  export COMP_POINT
 
   local nospace data compline="${COMP_LINE:0:${COMP_POINT}}"
 


Test patch:
diff --git a/example/cmd/_test/bash-ble.sh b/example/cmd/_test/bash-ble.sh
index ba7c57b..ea4fa69 100644
--- a/example/cmd/_test/bash-ble.sh
+++ b/example/cmd/_test/bash-ble.sh
@@ -2,6 +2,7 @@
 _example_completion() {
   export COMP_WORDBREAKS
   export COMP_LINE
+  export COMP_POINT
 
   local nospace data compline="${COMP_LINE:0:${COMP_POINT}}"
 
diff --git a/example/cmd/_test/bash.sh b/example/cmd/_test/bash.sh
index 9591d72..f4ed518 100644
--- a/example/cmd/_test/bash.sh
+++ b/example/cmd/_test/bash.sh
@@ -2,6 +2,7 @@
 _example_completion() {
   export COMP_WORDBREAKS
   export COMP_LINE
+  export COMP_POINT
 
   local nospace data compline="${COMP_LINE:0:${COMP_POINT}}"