Skip to content

zsh: expression after subscript flags is incorrectly parsed as arithmetic #1278

@LangLangBart

Description

@LangLangBart

When a subscript flag is present, shfmt seems to parse the expression after it
as an arithmetic expression instead of a pattern.

Reproduction

# (i) returns the index of the first double-dash/end of options operator
./shfmt -ln zsh <<<'array=(ls -ld -- "**/bar"); echo ${array[(i)--]}'
# <standard input>:1:45: `--` must be followed by a literal

# (I) returns the index of the last element matching the pattern '+'
./shfmt -ln zsh <<<'array=(foo + bar + baz); echo ${array[(I)+]}'
# <standard input>:1:42: `+` must be followed by an expression

# (R) returns the value of the last element matching the pattern '/*'
./shfmt -ln zsh <<<'array=(/usr/bin rel/path /etc ./local); echo ${array[(R)/*]}'
# <standard input>:1:57: `/` must follow an expression

# `%`, `^`, `<`, `>`, `|`, `&`, `=`, `:`, `,` also fail
./shfmt -ln zsh <<<'array=(5 "&" 6); echo ${array[(i)&]}'
# <standard input>:1:34: `&` must follow an expression

Note

The outer subscript containing a reverse subscript can still be
arithmetic. For example:

outer cmd_words[(i)--]-1] is arithmetic
inner (i) flag's argument -- is a pattern

# Returns the elements before the double-dash/end of options operator
cmd_words=(ls -a -- file.txt); echo ${cmd_words[1,cmd_words[(i)--]-1]}
# ls -a

zsh docs

https://zsh.sourceforge.io/Doc/Release/Parameters.html#Subscript-Flags

EDIT1: Delete redundant header

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions