vim-patch:11bde1f: runtime(sh): refactored sh.vim syntax script (#35895)

- unified bashStatement, kshStatement and shStatement as much as
  possible
- separated builtin commands from external programs
- cleaned up kornshell flavor logic
- fixed alias syntax highlighting
- added test for bash alias syntax highlighting
- removed daemon keyword

closes: vim/vim#18355

11bde1f169

Co-authored-by: Bjoern Foersterling <bjoern.foersterling@gmail.com>
This commit is contained in:
zeertzjq
2025-09-24 08:28:38 +08:00
committed by GitHub
parent dd630e7f84
commit 409122e5ae

View File

@@ -4,20 +4,21 @@
" Previous Maintainers: Charles E. Campbell " Previous Maintainers: Charles E. Campbell
" Lennart Schultz <Lennart.Schultz@ecmwf.int> " Lennart Schultz <Lennart.Schultz@ecmwf.int>
" Last Change: 2024 Mar 04 by Vim Project {{{1 " Last Change: 2024 Mar 04 by Vim Project {{{1
" 2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> (improved bracket expressions, #15941) " 2024 Nov 03 by Aliaksei Budavei <0x000c70 AT gmail DOT com> improved bracket expressions, #15941
" 2025 Jan 06 add $PS0 to bashSpecialVariables (#16394) " 2025 Jan 06 add $PS0 to bashSpecialVariables #16394
" 2025 Jan 18 add bash coproc, remove duplicate syn keywords (#16467) " 2025 Jan 18 add bash coproc, remove duplicate syn keywords #16467
" 2025 Mar 21 update shell capability detection (#16939) " 2025 Mar 21 update shell capability detection #16939
" 2025 Apr 03 command substitution opening paren at EOL (#17026) " 2025 Apr 03 command substitution opening paren at EOL #17026
" 2025 Apr 10 improve shell detection (#17084) " 2025 Apr 10 improve shell detection #17084
" 2025 Apr 29 match escaped chars in test operands (#17221) " 2025 Apr 29 match escaped chars in test operands #17221
" 2025 May 06 improve single-quote string matching in parameter expansions " 2025 May 06 improve single-quote string matching in parameter expansions
" 2025 May 06 match KornShell compound arrays " 2025 May 06 match KornShell compound arrays
" 2025 May 10 improve wildcard character class lists " 2025 May 10 improve wildcard character class lists
" 2025 May 21 improve supported KornShell features " 2025 May 21 improve supported KornShell features
" 2025 Jun 16 change how sh_fold_enabled is reset (#17557) " 2025 Jun 16 change how sh_fold_enabled is reset #17557
" 2025 Jul 18 properly delete :commands (#17785) " 2025 Jul 18 properly delete :commands #17785
" 2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} (#18084) " 2025 Aug 23 bash: add support for ${ cmd;} and ${|cmd;} #18084
" 2025 Sep 23 simplify ksh logic, update sh statements #18355
" }}} " }}}
" Version: 208 " Version: 208
" Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH " Former URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
@@ -318,8 +319,6 @@ if exists("b:is_kornshell") || exists("b:is_bash") || exists("b:is_posix")
syn match shStatement "\<alias\>" syn match shStatement "\<alias\>"
syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@=" skip="\\$" end="\>\|`" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*\)\@=" skip="\\$" end="\>\|`"
syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\\$" end="=" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]*=\)\@=" skip="\\$" end="="
" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+\)\@=" skip="\\$" end="\>\|`"
" syn region shAlias matchgroup=shStatement start="\<alias\>\s\+\(\h[-._[:alnum:]]\+=\)\@=" skip="\\$" end="="
" Touch: {{{1 " Touch: {{{1
" ===== " =====
@@ -449,12 +448,7 @@ endif
"====== "======
syn match shWrapLineOperator "\\$" syn match shWrapLineOperator "\\$"
syn region shCommandSubBQ start="`" skip="\\\\\|\\." end="`" contains=shBQComment,@shCommandSubList syn region shCommandSubBQ start="`" skip="\\\\\|\\." end="`" contains=shBQComment,@shCommandSubList
"COMBAK: see ksh13:50
"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shSingleQuote,shDoubleQuote,shComment
"COMBAK: see sh11:27
syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shComment syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shComment
"COMBAK: see ksh13:53
"syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.'
" $() and $(()): {{{1 " $() and $(()): {{{1
" $(..) is not supported by sh (Bourne shell). However, apparently " $(..) is not supported by sh (Bourne shell). However, apparently
@@ -492,45 +486,45 @@ if exists("b:is_bash")
syn cluster shCommandSubList add=bashSpecialVariables,bashStatement syn cluster shCommandSubList add=bashSpecialVariables,bashStatement
syn cluster shCaseList add=bashAdminStatement,bashStatement syn cluster shCaseList add=bashAdminStatement,bashStatement
syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING BASH_LINENO BASHOPTS BASHPID BASH_REMATCH BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION BASH_XTRACEFD CDPATH COLUMNS COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS COPROC COPROC_PID DIRSTACK EMACS ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNEST GLOBIGNORE GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LINENO LINES MACHTYPE MAIL MAILCHECK MAILPATH MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS POSIXLY_CORRECT PPID PROMPT_COMMAND PS0 PS1 PS2 PS3 PS4 PWD RANDOM READLINE_LINE READLINE_POINT REPLY SECONDS SHELL SHELLOPTS SHLVL TIMEFORMAT TIMEOUT TMPDIR UID syn keyword bashSpecialVariables contained auto_resume BASH BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_ENV BASH_EXECUTION_STRING BASH_LINENO BASHOPTS BASHPID BASH_REMATCH BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION BASH_XTRACEFD CDPATH COLUMNS COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS COPROC COPROC_PID DIRSTACK EMACS ENV EUID FCEDIT FIGNORE FUNCNAME FUNCNEST GLOBIGNORE GROUPS histchars HISTCMD HISTCONTROL HISTFILE HISTFILESIZE HISTIGNORE HISTSIZE HISTTIMEFORMAT HOME HOSTFILE HOSTNAME HOSTTYPE IFS IGNOREEOF INPUTRC LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LINENO LINES MACHTYPE MAIL MAILCHECK MAILPATH MAPFILE OLDPWD OPTARG OPTERR OPTIND OSTYPE PATH PIPESTATUS POSIXLY_CORRECT PPID PROMPT_COMMAND PS0 PS1 PS2 PS3 PS4 PWD RANDOM READLINE_LINE READLINE_POINT REPLY SECONDS SHELL SHELLOPTS SHLVL TIMEFORMAT TIMEOUT TMPDIR UID
syn keyword bashStatement basename cat chgrp chmod chown cksum clear cmp comm command compgen complete cp cut date dirname du egrep expr fgrep find fmt fold getconf gnufind gnugrep grep head iconv id join less ln logname ls md5sum mkdir mkfifo mknod mktemp mv od paste pathchk readlink realpath rev rm rmdir rpm sed sha1sum sha224sum sha256sum sha384sum sha512sum sleep sort strip stty sum sync tail tee tr tty uname uniq wc which xargs xgrep syn keyword bashStatement bind builtin caller compgen complete compopt declare dirs disown enable fg help history let logout mapfile popd pushd readarray shopt source suspend time
syn keyword bashAdminStatement daemon killall killproc nice reload restart start status stop syn keyword bashStatement typeset nextgroup=shSetOption
syn keyword bashAdminStatement reload restart start status stop
endif endif
if exists("b:is_kornshell") || exists("b:is_posix") " for all kornshells
syn cluster shCommandSubList add=kshSpecialVariables,kshStatement if exists("b:is_kornshell")
syn cluster shCaseList add=kshStatement syn cluster shCaseList add=kshStatement
syn cluster shCommandSubList add=kshSpecialVariables,kshStatement
syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV FCEDIT FIGNORE FPATH HISTCMD HISTEDIT HISTFILE HISTSIZE HOME IFS JOBMAX KSH_VERSION LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL SHLVL TMOUT VISUAL syn keyword kshSpecialVariables contained CDPATH COLUMNS EDITOR ENV FCEDIT FIGNORE FPATH HISTCMD HISTEDIT HISTFILE HISTSIZE HOME IFS JOBMAX KSH_VERSION LANG LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME LINENO LINES MAIL MAILCHECK MAILPATH OLDPWD OPTARG OPTIND PATH PPID PS1 PS2 PS3 PS4 PWD RANDOM REPLY SECONDS SHELL SHLVL TMOUT VISUAL
syn keyword kshStatement basename cat chgrp chmod chown cksum clear cmp comm command cp cut date dirname du egrep expr fgrep find fmt fold grep head iconv id join killall less ln logname ls md5sum mkdir mknod mkfifo mktemp mv nice od paste pathchk printenv readlink realpath rev rm rmdir sed setgroups setsenv sha1sum sha224sum sha256sum sha384sum sha512sum sort strip stty sum sync tail tee tput tr tty uname uniq wc which xargs xgrep syn keyword kshStatement autoload builtin compound disown enum fg float functions hist history integer let nameref r redirect source stop suspend time whence xgrep
if exists("b:is_ksh88") syn keyword shStatement typeset skipwhite nextgroup=shSetOption
syn keyword kshSpecialVariables contained ERRNO endif
elseif exists("b:is_mksh")
syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID " kornshell flavors
syn keyword kshStatement bind rename if exists("b:generic_korn")
elseif exists("b:is_ksh93v") || exists("b:is_ksh2020") syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME ERRNO EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE VPATH SRANDOM CSWIDTH
syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE syn keyword kshStatement alarm bind compgen complete eloop fds mkservice pids poll sha2sum vmstate
syn keyword kshStatement compgen complete elseif exists("b:is_ksh88")
if exists("b:is_ksh93v") syn keyword kshSpecialVariables bind contained ERRNO
syn keyword kshSpecialVariables contained VPATH CSWIDTH elseif exists("b:is_ksh93")
syn keyword kshStatement vmstate alarm fds pids poll sha2sum syn keyword kshSpecialVariables contained BASHPID COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMPREPLY COMP_TYPE COMP_WORDBREAKS COMP_WORDS CSWIDTH EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS SH_OPTIONS SRANDOM TMPDIR USER_ID VPATH
endif syn keyword kshStatement alarm bind compgen complete eloop fds mkservice pids poll sha2sum vmstate
elseif exists("b:is_ksh93u") elseif exists("b:is_ksh93v")
" ksh93u+ syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE CSWIDTH VPATH
syn keyword kshStatement alarm compgen complete fds pids poll sha2sum vmstate
elseif exists("b:is_ksh93u")
syn keyword kshSpecialVariables contained VPATH CSWIDTH syn keyword kshSpecialVariables contained VPATH CSWIDTH
syn keyword kshStatement alarm fds pids vmstate syn keyword kshStatement alarm fds pids vmstate
else elseif exists("b:is_ksh2020")
" 'ksh' is ambiguous; include everything syn keyword kshSpecialVariables contained SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE
syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID SH_OPTIONS COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS COMP_KEY COMPREPLY COMP_WORDBREAKS COMP_TYPE VPATH SRANDOM CSWIDTH syn keyword kshStatement compgen complete
if !exists("b:is_ksh93") elseif exists("b:is_mksh")
syn keyword kshSpecialVariables contained ERRNO syn keyword kshSpecialVariables contained BASHPID EPOCHREALTIME EXECSHELL KSHEGID KSHGID KSHUID KSH_MATCH PATHSEP PGRP PIPESTATUS TMPDIR USER_ID
endif syn keyword kshStatement bind
syn keyword kshStatement vmstate alarm fds pids poll sha2sum alarm eloop fds mkservice pids compgen complete bind rename
endif
endif endif
syn match shSource "^\.\s" syn match shSource "^\.\s"
syn match shSource "\s\.\s" syn match shSource "\s\.\s"
"syn region shColon start="^\s*:" end="$" end="\s#"me=e-2 contains=@shColonList
"syn region shColon start="^\s*\zs:" end="$" end="\s#"me=e-2
if exists("b:is_kornshell") || exists("b:is_posix") if exists("b:is_kornshell") || exists("b:is_posix")
syn match shColon '^\s*\zs:' syn match shColon '^\s*\zs:'
endif endif
@@ -559,8 +553,6 @@ syn match shSpecialStart "\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBks
syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]" syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecialNoZS contained "\%(\\\\\)*\\[\\"'`$()#]" syn match shSpecialNoZS contained "\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecialNxt contained "\\[\\"'`$()#]" syn match shSpecialNxt contained "\\[\\"'`$()#]"
"syn region shBkslshSnglQuote contained matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart
"syn region shBkslshDblQuote contained matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
" Comments: {{{1 " Comments: {{{1
"========== "==========
@@ -635,6 +627,7 @@ elseif exists("b:is_kornshell") || exists("b:is_posix")
syn match shSet "^\s*set\ze\s\+$" syn match shSet "^\s*set\ze\s\+$"
if exists("b:is_dash") if exists("b:is_dash")
syn region shSetList oneline matchgroup=shSet start="\<\%(local\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList syn region shSetList oneline matchgroup=shSet start="\<\%(local\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
syn keyword shStatement chdir
endif endif
syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList syn region shSetList oneline matchgroup=shSet start="\<\(export\)\>\ze[/]\@!" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList nextgroup=shComment syn region shSetList oneline matchgroup=shSet start="\<\%(set\|unset\>\)\ze[/a-zA-Z_]\@!" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList nextgroup=shComment
@@ -667,8 +660,6 @@ endif
" Parameter Dereferencing: {{{1 " Parameter Dereferencing: {{{1
" ======================== " ========================
" Note: sh04 failure with following line
"if !exists("g:sh_no_error") && !(exists("b:is_bash") || exists("b:is_kornshell") || exists("b:is_posix"))
if !exists("g:sh_no_error") if !exists("g:sh_no_error")
syn match shDerefWordError "[^}$[~]" contained syn match shDerefWordError "[^}$[~]" contained
endif endif
@@ -797,35 +788,15 @@ syn region shParen matchgroup=shArithRegion start='\$\@!(\%(\ze[^(]\|$\)' end=')
" Additional sh Keywords: {{{1 " Additional sh Keywords: {{{1
" =================== " ===================
syn keyword shStatement break cd chdir continue eval exec exit kill newgrp pwd read readonly return shift test trap ulimit umask wait " builtins:
syn keyword shStatement bg break cd continue command eval exec exit export fc getopts hash jobs local printf read readonly return shift times trap type ulimit umask unalias wait
" external programs:
syn keyword shStatement basename cat chgrp chmod chown cksum clear cmp comm cp cut date dirname du egrep expr false fgrep find fmt fold getconf grep head iconv id join kill killall less ln login logname ls md5sum mkdir mkfifo mknod mktemp mv newgrp nice nohup od paste pathchk printenv pwd readlink realpath rename rev rm rmdir sed sha1sum sha224sum sha256sum sha384sum sha512sum sleep sort strip stty sum sync tail tee test tput tr true tty uname uniq wc which xargs
syn keyword shConditional contained elif else then syn keyword shConditional contained elif else then
if !exists("g:sh_no_error") if !exists("g:sh_no_error")
syn keyword shCondError elif else then syn keyword shCondError elif else then
endif endif
" Additional ksh Keywords and Aliases: {{{1
" ===================================
if exists("b:is_kornshell") || exists("b:is_posix")
syn keyword shStatement bg builtin disown enum export false fg getconf getopts hist jobs let printf sleep true unalias whence
syn keyword shStatement typeset skipwhite nextgroup=shSetOption
syn keyword shStatement autoload compound fc float functions hash history integer nameref nohup r redirect source stop suspend times type
if exists("b:is_posix")
syn keyword shStatement command
else
syn keyword shStatement time
endif
" Additional bash Keywords: {{{1
" =====================
elseif exists("b:is_bash")
syn keyword shStatement bg builtin disown export false fg getopts jobs let printf true unalias
syn keyword shStatement typeset nextgroup=shSetOption
syn keyword shStatement fc hash history source suspend times type
syn keyword shStatement bind caller compopt declare dirs enable help logout local mapfile popd pushd readarray shopt typeset
else
syn keyword shStatement login newgrp
endif
" Synchronization: {{{1 " Synchronization: {{{1
" ================ " ================
if !exists("g:sh_minlines") if !exists("g:sh_minlines")