Skip to content

Commit

Permalink
Merge pull request #1095 from carapace-sh/zsh-fix-quotingstate
Browse files Browse the repository at this point in the history
zsh: fix quoting state
  • Loading branch information
rsteube authored Jan 19, 2025
2 parents c9cfc31 + 9e384b6 commit 518ea54
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@


────────────────────────────────────────────────────────────────────────────────
> example action embeddedP1 "embeddedP2\ with\ space
> example action embeddedP1 "embeddedP2\ with\ space"






────────────────────────────────────────────────────────────────────────────────
> example action embeddedP1 "embeddedP2\ with\ space
> example action embeddedP1 "embeddedP2\ with\ space"



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@


────────────────────────────────────────────────────────────────────────────────
> example action embeddedP1 'embeddedP2\ with\ space
> example action embeddedP1 'embeddedP2\ with\ space'






────────────────────────────────────────────────────────────────────────────────
> example action embeddedP1 'embeddedP2\ with\ space
> example action embeddedP1 'embeddedP2\ with\ space'



Expand Down
4 changes: 2 additions & 2 deletions example/cmd/_test/zsh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ function _example_completion {
if echo ${words}"''" | xargs echo 2>/dev/null > /dev/null; then
local lines="$(echo ${words}"''" | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs example _carapace zsh )"
elif echo ${words} | sed "s/\$/'/" | xargs echo 2>/dev/null > /dev/null; then
local lines="$(echo ${words} | sed "s/\$/'/" | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs example _carapace zsh)"
local lines="$(echo ${words} | sed "s/\$/'/" | CARAPACE_STATE=QUOTING_STATE CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs example _carapace zsh)"
else
local lines="$(echo ${words} | sed 's/$/"/' | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs example _carapace zsh)"
local lines="$(echo ${words} | sed 's/$/"/' | CARAPACE_STATE=QUOTING_ESCAPING_STATE CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs example _carapace zsh)"
fi

local zstyle message data
Expand Down
13 changes: 13 additions & 0 deletions internal/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"strings"

shlex "github.com/carapace-sh/carapace-shlex"
"github.com/carapace-sh/carapace/internal/common"
)

Expand All @@ -18,6 +19,7 @@ const (
CARAPACE_MATCH = "CARAPACE_MATCH" // match case insensitive
CARAPACE_NOSPACE = "CARAPACE_NOSPACE" // nospace suffixes
CARAPACE_SANDBOX = "CARAPACE_SANDBOX" // mock context for sandbox tests
CARAPACE_STATE = "CARAPACE_STATE" // current word state
CARAPACE_TOOLTIP = "CARAPACE_TOOLTIP" // enable tooltip style
CARAPACE_ZSH_HASH_DIRS = "CARAPACE_ZSH_HASH_DIRS" // zsh hash directories
CLICOLOR = "CLICOLOR" // disable color
Expand Down Expand Up @@ -76,6 +78,17 @@ func Tooltip() bool {
return getBool(CARAPACE_TOOLTIP)
}

func State() shlex.LexerState {
switch os.Getenv(CARAPACE_STATE) {
case "QUOTING_STATE":
return shlex.QUOTING_STATE
case "QUOTING_ESCAPING_STATE":
return shlex.QUOTING_ESCAPING_STATE
default:
return shlex.START_STATE
}
}

func getBool(s string) bool {
switch os.Getenv(s) {
case "true", "1":
Expand Down
12 changes: 12 additions & 0 deletions internal/shell/zsh/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"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(
Expand Down Expand Up @@ -63,6 +65,16 @@ func ActionRawValues(currentWord string, meta common.Meta, values common.RawValu
val.Value = quoteValue(val.Value)
val.Value = strings.ReplaceAll(val.Value, `\`, `\\`) // TODO find out why `_describe` needs another backslash
val.Value = strings.ReplaceAll(val.Value, `:`, `\:`) // TODO find out why `_describe` needs another backslash

switch env.State() {
// TODO depending on state value needs to be formatted differently
// TODO backspace strings are currently an issue
case shlex.QUOTING_STATE:
val.Value = val.Value + `'`
case shlex.QUOTING_ESCAPING_STATE:
val.Value = val.Value + `"`
}

if !meta.Nospace.Matches(val.Value) {
val.Value = val.Value + " "
}
Expand Down
4 changes: 2 additions & 2 deletions internal/shell/zsh/snippet.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ function _%v_completion {
if echo ${words}"''" | xargs echo 2>/dev/null > /dev/null; then
local lines="$(echo ${words}"''" | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs %v _carapace zsh )"
elif echo ${words} | sed "s/\$/'/" | xargs echo 2>/dev/null > /dev/null; then
local lines="$(echo ${words} | sed "s/\$/'/" | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs %v _carapace zsh)"
local lines="$(echo ${words} | sed "s/\$/'/" | CARAPACE_STATE=QUOTING_STATE CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs %v _carapace zsh)"
else
local lines="$(echo ${words} | sed 's/$/"/' | CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs %v _carapace zsh)"
local lines="$(echo ${words} | sed 's/$/"/' | CARAPACE_STATE=QUOTING_ESCAPING_STATE CARAPACE_ZSH_HASH_DIRS="$(hash -d)" xargs %v _carapace zsh)"
fi
local zstyle message data
Expand Down

0 comments on commit 518ea54

Please sign in to comment.