[vim/vim] runtime(sh): treat 'name=()' as array assignment, not a function (PR #20184)

2 views
Skip to first unread message

ChrisJr404

unread,
May 10, 2026, 5:24:25 PM (19 hours ago) May 10
to vim/vim, Subscribed

Fixes the case from #20183 where the second of two consecutive empty-array assignments was highlighted as if it were a function definition:

#!/bin/bash
array_a=()
array_b=()
if :; then :; fi

array_a=() highlights as shVariable+shVarAssign+shShellVariables but array_b=() was matched by shFunctionCmdOne because the line array_b=()\nif :; then :; fi satisfies the bash function-command head pattern: a candidate name, optional whitespace, (), then \_s* followed by one of for|case|select|if|while|until|[[|((.

The candidate-name alternation is \%(\<\k\+\|[^()<>|&\$;\t ]\+\)\+. The negated class allows =, so array_b= is accepted as a function-name run, () follows, and the next line starts with if. The first row escapes only because the next non-blank token there is array_b, which is not in the lookahead set.

The bisect referenced in the issue (12f6f205521) wrapped these patterns in \%(...\)\@> and pinned the old engine. The candidate-name class itself dates back further; the regression-tagged commit changed visible group attribution which made the symptom obvious.

Fix

Exclude = from the negated character class in the six bash patterns (shFunctionCmdOne/Two, shFunctionOne/Two/Three/Four). bash function names cannot contain = anyway, since the parser would otherwise split the token into name and =value for an assignment.

Verification

Before:

3:1 a  shFunctionCmdOne
3:2 r  shFunctionCmdOne
...
3:9 (  shFunctionCmdOne
3:10 ) shFunctionCmdOne

After:

3:1 a  shVariable
3:2 r  shVariable
...
3:8 =  shVarAssign
3:9 (  shShellVariables
3:10 ) shShellVariables

Both array_a=() and array_b=() now highlight identically.

Tested manually against:

  • the reporter's exact reproducer
  • regular function definitions: my_fn() { ... } (still shFunctionOne)
  • weird names: weird-name() { ... } (still shFunctionOne)
  • command-head bodies: my_cmd_fn() if true; then echo a; fi (still shFunctionCmdOne)
  • multiple consecutive name=() lines preceding if/case/while (all now shVariable)

runtime/syntax/testdir/input/sh_functions_bash.sh does not currently cover empty-array assignments. Happy to add a case with regenerated screendumps if preferred, or leave it for a follow-up.

Closes #20183


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/20184

Commit Summary

  • 64e0167 runtime(sh): treat 'name=()' as array assignment, not a function

File Changes

(1 file)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20184@github.com>

Reply all
Reply to author
Forward
0 new messages