medit/moo/mooedit/syntax/sh.lang

830 lines
34 KiB
XML

<?xml version="1.0" encoding="UTF-8"?><!-- kate: space-indent on; indent-width 2 -->
<!DOCTYPE language SYSTEM "language.dtd"
[
<!ENTITY funcname "[A-Za-z_:][A-Za-z0-9_:#&#37;@-]*">
<!ENTITY varname "[A-Za-z_][A-Za-z0-9_]*">
<!ENTITY word "[^|&amp;;()&lt;&gt;\s]+"> <!-- see man bash -->
<!ENTITY eos "(?=($|\s))"> <!-- eol or space following -->
<!ENTITY noword "(?![\w$+-])"> <!-- no word, $, + or - following -->
]>
<language name="Bash" version="2.05" kateversion="2.4" section="Scripts"
extensions="*.sh;*.bash;*.ebuild;*.eclass" mimetypes="application/x-shellscript"
author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
<!-- (c) 2004 by Wilbert Berendsen, wilbert@kde.nl
Released under the LGPL, part of kdelibs/kate -->
<syntax>
<keyword-list name="keywords">
<keyword>else</keyword>
<keyword>for</keyword>
<keyword>function</keyword>
<keyword>in</keyword>
<keyword>select</keyword>
<keyword>until</keyword>
<keyword>while</keyword>
<keyword>.</keyword>
<keyword>elif</keyword>
<keyword>then</keyword>
<keyword>set</keyword>
</keyword-list>
<keyword-list name="builtins">
<keyword>:</keyword>
<keyword>.</keyword>
<keyword>source</keyword>
<keyword>alias</keyword>
<keyword>bg</keyword>
<keyword>bind</keyword>
<keyword>break</keyword>
<keyword>builtin</keyword>
<keyword>cd</keyword>
<keyword>command</keyword>
<keyword>compgen</keyword>
<keyword>complete</keyword>
<keyword>continue</keyword>
<keyword>dirs</keyword>
<keyword>disown</keyword>
<keyword>echo</keyword>
<keyword>enable</keyword>
<keyword>eval</keyword>
<keyword>exec</keyword>
<keyword>exit</keyword>
<keyword>fc</keyword>
<keyword>fg</keyword>
<keyword>getopts</keyword>
<keyword>hash</keyword>
<keyword>help</keyword>
<keyword>history</keyword>
<keyword>jobs</keyword>
<keyword>kill</keyword>
<keyword>let</keyword>
<keyword>logout</keyword>
<keyword>popd</keyword>
<keyword>printf</keyword>
<keyword>pushd</keyword>
<keyword>pwd</keyword>
<keyword>return</keyword>
<keyword>set</keyword>
<keyword>shift</keyword>
<keyword>shopt</keyword>
<keyword>suspend</keyword>
<keyword>test</keyword>
<keyword>times</keyword>
<keyword>trap</keyword>
<keyword>type</keyword>
<keyword>ulimit</keyword>
<keyword>umask</keyword>
<keyword>unalias</keyword>
<keyword>wait</keyword>
</keyword-list>
<keyword-list name="builtins_var">
<keyword>export</keyword>
<keyword>unset</keyword>
<keyword>declare</keyword>
<keyword>typeset</keyword>
<keyword>local</keyword>
<keyword>read</keyword>
<keyword>readonly</keyword>
</keyword-list>
<keyword-list name="unixcommands">
<!-- /bin -->
<keyword>arch</keyword>
<keyword>awk</keyword>
<keyword>bash</keyword>
<keyword>bunzip2</keyword>
<keyword>bzcat</keyword>
<keyword>bzcmp</keyword>
<keyword>bzdiff</keyword>
<keyword>bzegrep</keyword>
<keyword>bzfgrep</keyword>
<keyword>bzgrep</keyword>
<keyword>bzip2</keyword>
<keyword>bzip2recover</keyword>
<keyword>bzless</keyword>
<keyword>bzmore</keyword>
<keyword>cat</keyword>
<keyword>chattr</keyword>
<keyword>chgrp</keyword>
<keyword>chmod</keyword>
<keyword>chown</keyword>
<keyword>chvt</keyword>
<keyword>cp</keyword>
<keyword>date</keyword>
<keyword>dd</keyword>
<keyword>deallocvt</keyword>
<keyword>df</keyword>
<keyword>dir</keyword>
<keyword>dircolors</keyword>
<keyword>dmesg</keyword>
<keyword>dnsdomainname</keyword>
<keyword>domainname</keyword>
<keyword>du</keyword>
<keyword>dumpkeys</keyword>
<keyword>echo</keyword>
<keyword>ed</keyword>
<keyword>egrep</keyword>
<keyword>false</keyword>
<keyword>fgconsole</keyword>
<keyword>fgrep</keyword>
<keyword>fuser</keyword>
<keyword>gawk</keyword>
<keyword>getkeycodes</keyword>
<keyword>gocr</keyword>
<keyword>grep</keyword>
<keyword>groups</keyword>
<keyword>gunzip</keyword>
<keyword>gzexe</keyword>
<keyword>gzip</keyword>
<keyword>hostname</keyword>
<keyword>igawk</keyword>
<keyword>install</keyword>
<keyword>kbd_mode</keyword>
<keyword>kbdrate</keyword>
<keyword>killall</keyword>
<keyword>last</keyword>
<keyword>lastb</keyword>
<keyword>link</keyword>
<keyword>ln</keyword>
<keyword>loadkeys</keyword>
<keyword>loadunimap</keyword>
<keyword>login</keyword>
<keyword>ls</keyword>
<keyword>lsattr</keyword>
<keyword>lsmod</keyword>
<keyword>lsmod.old</keyword>
<keyword>mapscrn</keyword>
<keyword>mesg</keyword>
<keyword>mkdir</keyword>
<keyword>mkfifo</keyword>
<keyword>mknod</keyword>
<keyword>mktemp</keyword>
<keyword>more</keyword>
<keyword>mount</keyword>
<keyword>mv</keyword>
<keyword>nano</keyword>
<keyword>netstat</keyword>
<keyword>nisdomainname</keyword>
<keyword>openvt</keyword>
<keyword>pgawk</keyword>
<keyword>pidof</keyword>
<keyword>ping</keyword>
<keyword>ps</keyword>
<keyword>pstree</keyword>
<keyword>pwd</keyword>
<keyword>rbash</keyword>
<keyword>readlink</keyword>
<keyword>red</keyword>
<keyword>resizecons</keyword>
<keyword>rm</keyword>
<keyword>rmdir</keyword>
<keyword>run-parts</keyword>
<keyword>sash</keyword>
<keyword>sed</keyword>
<keyword>setfont</keyword>
<keyword>setkeycodes</keyword>
<keyword>setleds</keyword>
<keyword>setmetamode</keyword>
<keyword>setserial</keyword>
<keyword>sh</keyword>
<keyword>showkey</keyword>
<keyword>shred</keyword>
<keyword>sleep</keyword>
<keyword>ssed</keyword>
<keyword>stat</keyword>
<keyword>stty</keyword>
<keyword>su</keyword>
<keyword>sync</keyword>
<keyword>tar</keyword>
<keyword>tempfile</keyword>
<keyword>touch</keyword>
<keyword>true</keyword>
<keyword>umount</keyword>
<keyword>uname</keyword>
<keyword>unicode_start</keyword>
<keyword>unicode_stop</keyword>
<keyword>unlink</keyword>
<keyword>utmpdump</keyword>
<keyword>uuidgen</keyword>
<keyword>vdir</keyword>
<keyword>wall</keyword>
<keyword>wc</keyword>
<keyword>ypdomainname</keyword>
<keyword>zcat</keyword>
<keyword>zcmp</keyword>
<keyword>zdiff</keyword>
<keyword>zegrep</keyword>
<keyword>zfgrep</keyword>
<keyword>zforce</keyword>
<keyword>zgrep</keyword>
<keyword>zless</keyword>
<keyword>zmore</keyword>
<keyword>znew</keyword>
<keyword>zsh</keyword>
<!-- some from /usr/bin -->
<keyword>aclocal</keyword>
<keyword>aconnect</keyword>
<keyword>aplay</keyword>
<keyword>apm</keyword>
<keyword>apmsleep</keyword>
<keyword>apropos</keyword>
<keyword>ar</keyword>
<keyword>arecord</keyword>
<keyword>as</keyword>
<keyword>as86</keyword>
<keyword>autoconf</keyword>
<keyword>autoheader</keyword>
<keyword>automake</keyword>
<keyword>awk</keyword>
<keyword>basename</keyword>
<keyword>bc</keyword>
<keyword>bison</keyword>
<keyword>c++</keyword>
<keyword>cal</keyword>
<keyword>cat</keyword>
<keyword>cc</keyword>
<keyword>cdda2wav</keyword>
<keyword>cdparanoia</keyword>
<keyword>cdrdao</keyword>
<keyword>cd-read</keyword>
<keyword>cdrecord</keyword>
<keyword>chfn</keyword>
<keyword>chgrp</keyword>
<keyword>chmod</keyword>
<keyword>chown</keyword>
<keyword>chroot</keyword>
<keyword>chsh</keyword>
<keyword>clear</keyword>
<keyword>cmp</keyword>
<keyword>co</keyword>
<keyword>col</keyword>
<keyword>comm</keyword>
<keyword>cp</keyword>
<keyword>cpio</keyword>
<keyword>cpp</keyword>
<keyword>cut</keyword>
<keyword>dc</keyword>
<keyword>dd</keyword>
<keyword>df</keyword>
<keyword>diff</keyword>
<keyword>diff3</keyword>
<keyword>dir</keyword>
<keyword>dircolors</keyword>
<keyword>directomatic</keyword>
<keyword>dirname</keyword>
<keyword>du</keyword>
<keyword>env</keyword>
<keyword>expr</keyword>
<keyword>fbset</keyword>
<keyword>file</keyword>
<keyword>find</keyword>
<keyword>flex</keyword>
<keyword>flex++</keyword>
<keyword>fmt</keyword>
<keyword>free</keyword>
<keyword>ftp</keyword>
<keyword>funzip</keyword>
<keyword>fuser</keyword>
<keyword>g++</keyword>
<keyword>gawk</keyword>
<keyword>gc</keyword>
<keyword>gcc</keyword>
<keyword>gdb</keyword>
<keyword>getent</keyword>
<keyword>getopt</keyword>
<keyword>gettext</keyword>
<keyword>gettextize</keyword>
<keyword>gimp</keyword>
<keyword>gimp-remote</keyword>
<keyword>gimptool</keyword>
<keyword>gmake</keyword>
<keyword>gs</keyword>
<keyword>head</keyword>
<keyword>hexdump</keyword>
<keyword>id</keyword>
<keyword>install</keyword>
<keyword>join</keyword>
<keyword>kill</keyword>
<keyword>killall</keyword>
<keyword>ld</keyword>
<keyword>ld86</keyword>
<keyword>ldd</keyword>
<keyword>less</keyword>
<keyword>lex</keyword>
<keyword>ln</keyword>
<keyword>locate</keyword>
<keyword>lockfile</keyword>
<keyword>logname</keyword>
<keyword>lp</keyword>
<keyword>lpr</keyword>
<keyword>ls</keyword>
<keyword>lynx</keyword>
<keyword>m4</keyword>
<keyword>make</keyword>
<keyword>man</keyword>
<keyword>mkdir</keyword>
<keyword>mknod</keyword>
<keyword>msgfmt</keyword>
<keyword>mv</keyword>
<keyword>namei</keyword>
<keyword>nasm</keyword>
<keyword>nawk</keyword>
<keyword>nice</keyword>
<keyword>nl</keyword>
<keyword>nm</keyword>
<keyword>nm86</keyword>
<keyword>nmap</keyword>
<keyword>nohup</keyword>
<keyword>nop</keyword>
<keyword>od</keyword>
<keyword>passwd</keyword>
<keyword>patch</keyword>
<keyword>pcregrep</keyword>
<keyword>pcretest</keyword>
<keyword>perl</keyword>
<keyword>perror</keyword>
<keyword>pidof</keyword>
<keyword>pr</keyword>
<keyword>printf</keyword>
<keyword>procmail</keyword>
<keyword>prune</keyword>
<keyword>ps2ascii</keyword>
<keyword>ps2epsi</keyword>
<keyword>ps2frag</keyword>
<keyword>ps2pdf</keyword>
<keyword>ps2ps</keyword>
<keyword>psbook</keyword>
<keyword>psmerge</keyword>
<keyword>psnup</keyword>
<keyword>psresize</keyword>
<keyword>psselect</keyword>
<keyword>pstops</keyword>
<keyword>rcs</keyword>
<keyword>rev</keyword>
<keyword>rm</keyword>
<keyword>scp</keyword>
<keyword>sed</keyword>
<keyword>seq</keyword>
<keyword>setterm</keyword>
<keyword>shred</keyword>
<keyword>size</keyword>
<keyword>size86</keyword>
<keyword>skill</keyword>
<keyword>slogin</keyword>
<keyword>snice</keyword>
<keyword>sort</keyword>
<keyword>sox</keyword>
<keyword>split</keyword>
<keyword>ssh</keyword>
<keyword>ssh-add</keyword>
<keyword>ssh-agent</keyword>
<keyword>ssh-keygen</keyword>
<keyword>ssh-keyscan</keyword>
<keyword>stat</keyword>
<keyword>strings</keyword>
<keyword>strip</keyword>
<keyword>sudo</keyword>
<keyword>suidperl</keyword>
<keyword>sum</keyword>
<keyword>tac</keyword>
<keyword>tail</keyword>
<keyword>tee</keyword>
<keyword>test</keyword>
<keyword>tr</keyword>
<keyword>uniq</keyword>
<keyword>unlink</keyword>
<keyword>unzip</keyword>
<keyword>updatedb</keyword>
<keyword>updmap</keyword>
<keyword>uptime</keyword>
<keyword>users</keyword>
<keyword>vmstat</keyword>
<keyword>w</keyword>
<keyword>wc</keyword>
<keyword>wget</keyword>
<keyword>whatis</keyword>
<keyword>whereis</keyword>
<keyword>which</keyword>
<keyword>who</keyword>
<keyword>whoami</keyword>
<keyword>write</keyword>
<keyword>xargs</keyword>
<keyword>yacc</keyword>
<keyword>yes</keyword>
<keyword>zip</keyword>
<keyword>zsoelim</keyword>
<!-- others -->
<keyword>dcop</keyword>
<keyword>kdialog</keyword>
<keyword>kfile</keyword>
<keyword>xhost</keyword>
<keyword>xmodmap</keyword>
<keyword>xset</keyword>
</keyword-list>
<context style="Normal Text" eol-context="#stay" name="Start">
<IncludeRules from="FindAll" />
</context>
<!-- ====== The following rulessets are meant to be included ======== -->
<!-- FindAll tries to interpret everything -->
<context style="Normal Text" eol-context="#stay" name="FindAll">
<IncludeRules from="FindComments" />
<IncludeRules from="FindCommands" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- FindMost tries to interpret anything except commands -->
<context style="Normal Text" eol-context="#stay" name="FindMost">
<IncludeRules from="FindComments" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- FindComments consumes shell comments till EOL -->
<context style="Normal Text" eol-context="#pop" name="FindComments">
<Char style="Comment" context="Comment" char="#" first-non-blank-only="true"/>
<Regex style="Normal Text" context="Comment" pattern="[\s;](?=#)" />
</context>
<context style="Comment" eol-context="#pop" name="Comment">
<IncludeRules from="##Misc##AlertRules"/>
</context>
<!-- FindCommentsParen consumes shell comments till EOL or a closing parenthese -->
<context style="Normal Text" eol-context="#pop" name="FindCommentsParen">
<Char style="Comment" context="CommentParen" char="#" first-non-blank-only="true"/>
<Regex style="Normal Text" context="CommentParen" pattern="[\s;](?=#)" />
</context>
<context style="Comment" eol-context="#pop" name="CommentParen">
<Regex style="Comment" context="#pop" pattern="[^)](?=\))" />
<IncludeRules from="##Misc##AlertRules"/>
</context>
<!-- FindCommentsBackq consumes shell comments till EOL or a backquote -->
<context style="Normal Text" eol-context="#pop" name="FindCommentsBackq">
<Char style="Comment" context="CommentBackq" char="#" first-non-blank-only="true"/>
<Regex style="Normal Text" context="CommentBackq" pattern="[\s;](?=#)" />
</context>
<context style="Comment" eol-context="#pop" name="CommentBackq">
<Regex style="Comment" context="#pop" pattern="[^`](?=`)" />
<IncludeRules from="##Misc##AlertRules"/>
</context>
<!-- FindCommands matches many items that can be expected outside strings, substitutions etc. -->
<context style="Normal Text" eol-context="#stay" name="FindCommands">
<!-- start expression in double parentheses -->
<TwoChars style="Keyword" context="ExprDblParen" char1="(" char2="(" beginRegion="expression" />
<!-- start expression in double brackets -->
<Regex style="Keyword" context="ExprDblBracket" pattern="\[\[&eos;" beginRegion="expression" bol-only="TRUE"/>
<Regex style="Keyword" context="ExprDblBracket" pattern="\s\[\[&eos;" beginRegion="expression" />
<!-- start expression in single brackets -->
<Regex style="Builtin" context="ExprBracket" pattern="\[&eos;" beginRegion="expression" bol-only="TRUE"/>
<Regex style="Builtin" context="ExprBracket" pattern="\s\[&eos;" beginRegion="expression" />
<!-- start a group command with { -->
<Regex style="Keyword" context="Group" pattern="\{&eos;" beginRegion="group" />
<!-- start a subshell -->
<Char style="Keyword" context="SubShell" char="(" beginRegion="subshell" />
<!-- match do and if blocks -->
<Regex style="Keyword" context="#stay" pattern="\bdo&noword;" beginRegion="do" />
<Regex style="Keyword" context="#stay" pattern="\bdone&noword;" endRegion="do" />
<Regex style="Keyword" context="#stay" pattern="\bif&noword;" beginRegion="if" />
<Regex style="Keyword" context="#stay" pattern="\bfi&noword;" endRegion="if" />
<!-- handle case as a special case -->
<Regex style="Keyword" context="Case" pattern="\bcase&noword;" beginRegion="case" />
<!-- handle command line options -->
<Regex style="Option" context="#stay" pattern="-[A-Za-z0-9]+" />
<Regex style="Option" context="#stay" pattern="--[a-z][A-Za-z0-9_-]*" />
<!-- handle variable assignments -->
<Regex style="Variable" context="Assign" pattern="\b&varname;=" />
<Regex style="Variable" context="AssignSubscr" pattern="\b&varname;(?=\[[^]]+\]=)" />
<!-- handle functions with function keyword before keywords -->
<String style="Function" context="#stay" string=":()" />
<Regex style="Keyword" context="FunctionDef" pattern="\bfunction\b" />
<!-- handle keywords -->
<Keyword style="Keyword" context="#stay" keyword="keywords" />
<Keyword style="Builtin" context="#stay" keyword="builtins" />
<Keyword style="Command" context="#stay" keyword="unixcommands" />
<!-- handle commands that have variable names as argument -->
<Keyword style="Builtin" context="VarName" keyword="builtins_var" />
<!-- handle here-string -->
<String style="Redirection" context="#stay" string="&lt;&lt;&lt;" />
<!-- handle here document -->
<!-- <String style="Redirection" context="HereDoc" string="&lt;&lt;" include-into-next="true" /> -->
<!-- handle process subst -->
<Regex style="Redirection" context="ProcessSubst" pattern="[&lt;&gt;]\(" />
<!-- handle redirection -->
<Regex style="Redirection" context="#stay" pattern="([0-9]*(&gt;{1,2}|&lt;)(&amp;[0-9]+-?)?|&amp;&gt;|&gt;&amp;|[0-9]*&lt;&gt;)" />
<!-- handle &, &&, | and || -->
<Regex style="Control" context="#stay" pattern="([|&amp;])\1?" />
<!-- mark function definitions without function keyword -->
<Regex style="Function" context="#stay" pattern="&funcname;\s*\(\)" />
</context>
<!-- FindOthers contains various rules to mark different shell input -->
<context style="Normal Text" eol-context="#stay" name="FindOthers">
<Regex style="Escape" context="#stay" pattern="\\[][;&quot;\\'$`{}()|&amp;&lt;&gt;* ]" />
<Regex style="Keyword" context="#stay" pattern="\\$" />
<Regex style="Escape" context="#stay" pattern="\{(?!(\s|$))\S*\}" />
<Regex style="Path" context="#stay" pattern="\.?/[\w_@.+-]+(?=([\s/):]|$))" />
<!-- TODO: shell globs -->
</context>
<!-- FindStrings looks for single and double quoted strings, also with $-prefix -->
<context style="Normal Text" eol-context="#stay" name="FindStrings">
<Char style="String SingleQ" context="StringSQ" char="'" />
<Char style="String DoubleQ" context="StringDQ" char="&quot;" />
<TwoChars style="String SingleQ" context="StringEsc" char1="$" char2="'" />
<TwoChars style="String Transl." context="StringDQ" char1="$" char2="&quot;" />
</context>
<!-- FindSubstitutions goes after anything starting with $ and ` and their escapes -->
<context style="Normal Text" eol-context="#stay" name="FindSubstitutions">
<Regex style="Variable" context="#stay" pattern="\$[*@#?$!_0-9-]" />
<Regex style="Variable" context="Subscript" pattern="\$&varname;\[" />
<Regex style="Variable" context="#stay" pattern="\$&varname;" />
<Regex style="Variable" context="#stay" pattern="\$\{[*@#?$!_0-9-]\}" />
<Regex style="Variable" context="#stay" pattern="\$\{#&varname;\}" />
<Regex style="Variable" context="#stay" pattern="\$\{!&varname;\*?\}" />
<Regex style="Variable" context="VarBrace" pattern="\$\{&varname;" />
<Regex style="Variable" context="VarBrace" pattern="\$\{[*@#?$!_0-9-](?=[:#%/])" />
<String style="Variable" context="ExprDblParenSubst" string="$((" beginRegion="expression" />
<String style="Redirection" context="SubstFile" string="$(&lt;" />
<String style="Variable" context="SubstCommand" string="$(" />
<Char style="Backquote" context="SubstBackq" char="`" />
<Regex style="Escape" context="#stay" pattern="\\[`$\\]" />
</context>
<!-- ====== These are the contexts that can be branched to ======= -->
<!-- ExprDblParen consumes an expression started in command mode till )) -->
<context style="Normal Text" eol-context="#stay" name="ExprDblParen">
<TwoChars style="Keyword" context="#pop" char1=")" char2=")" endRegion="expression" />
<Char style="Normal Text" context="ExprSubParen" char="(" />
<IncludeRules from="FindMost" />
</context>
<!-- ExprDblParenSubst like ExprDblParen but matches )) as Variable -->
<context style="Normal Text" eol-context="#stay" name="ExprDblParenSubst">
<TwoChars style="Variable" context="#pop" char1=")" char2=")" endRegion="expression" />
<Char style="Normal Text" context="ExprSubParen" char="(" />
<IncludeRules from="FindMost" />
</context>
<!-- ExprSubParen consumes an expression till ) -->
<context style="Normal Text" eol-context="#stay" name="ExprSubParen">
<Char style="Normal Text" context="#pop" char=")" />
<Char style="Normal Text" context="ExprSubParen" char="(" />
<IncludeRules from="FindMost" />
</context>
<!-- ExprBracket consumes an expression till ] -->
<context style="Normal Text" eol-context="#stay" name="ExprBracket">
<Regex style="Builtin" context="#pop" pattern="\s\](?=($|[\s;|&amp;]))" endRegion="expression" />
<Regex style="Builtin" context="#pop" pattern="\](?=($|[\s;|&amp;]))" endRegion="expression" bol-only="TRUE"/>
<Char style="Normal Text" context="ExprSubParen" char="(" />
<IncludeRules from="FindMost" />
</context>
<!-- ExprDblBracket consumes an expression till ]] -->
<context style="Normal Text" eol-context="#stay" name="ExprDblBracket">
<Regex style="Keyword" context="#pop" pattern="\s\]\](?=($|[\s;|&amp;]))" endRegion="expression" />
<Regex style="Keyword" context="#pop" pattern="\]\](?=($|[\s;|&amp;]))" endRegion="expression" bol-only="TRUE"/>
<Char style="Normal Text" context="ExprSubParen" char="(" />
<IncludeRules from="FindMost" />
</context>
<!-- Group consumes shell input till } -->
<context style="Normal Text" eol-context="#stay" name="Group">
<Char style="Keyword" context="#pop" char="}" endRegion="group" />
<IncludeRules from="FindAll" />
</context>
<!-- SubShell consumes shell input till ) -->
<context style="Normal Text" eol-context="#stay" name="SubShell">
<Char style="Keyword" context="#pop" char=")" endRegion="subshell" />
<IncludeRules from="FindAll" />
</context>
<!-- Assign consumes an expression till EOL or whitespace -->
<context style="Normal Text" eol-context="#pop" name="Assign">
<Char style="Variable" context="AssignArray" char="(" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
<Regex style="Normal Text" context="#stay" pattern="[\w:,+_./-]+" />
</context>
<!-- AssignArray consumes everything till ), marking assignments -->
<context style="Normal Text" eol-context="#pop" name="AssignArray">
<Char style="Variable" context="#pop" char=")" />
<Char style="Variable" context="Subscript" char="[" />
<Char style="Variable" context="Assign" char="=" />
<IncludeRules from="FindMost" />
</context>
<!-- AssignSubscr first expects a [ then parses subscript and continues with '=value' -->
<context style="Normal Text" eol-context="#pop" name="AssignSubscr">
<Char style="Variable" context="Subscript" char="[" />
<Char style="Variable" context="Assign" char="=" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- Subscript consumes anything till ], marks as Variable -->
<context style="Variable" eol-context="#stay" name="Subscript">
<Char style="Variable" context="#pop" char="]" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- FunctionDef consumes a name, possibly with (), marks as Function -->
<context style="Function" eol-context="#pop" name="FunctionDef">
<Regex style="Function" context="#pop" pattern="\s+&funcname;(\s*\(\))?" />
</context>
<!-- VarName consumes spare variable names and assignments -->
<context style="Normal Text" eol-context="#pop" name="VarName">
<!-- handle command line options -->
<Regex style="Option" context="#stay" pattern="-[A-Za-z0-9]+" />
<Regex style="Option" context="#stay" pattern="--[a-z][A-Za-z0-9_-]*" />
<Regex style="Variable" context="#stay" pattern="\b&varname;" />
<Char style="Variable" context="Subscript" char="[" />
<Char style="Variable" context="Assign" char="=" />
<IncludeRules from="FindMost"/>
<!-- stay here in spaces and other safe characters -->
<Regex style="Normal Text" context="#stay" pattern="[^]})|;`&amp;&gt;&lt;]" />
</context>
<!-- ProcessSubst handles <(command) and >(command) -->
<context style="Normal Text" eol-context="#stay" name="ProcessSubst">
<Char style="Redirection" context="#pop" char=")" />
<IncludeRules from="FindCommentsParen" />
<IncludeRules from="FindCommands" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- StringSQ consumes anything till ' -->
<context style="String SingleQ" eol-context="#stay" name="StringSQ">
<Char style="String SingleQ" context="#pop" char="'" />
</context>
<!-- StringDQ consumes anything till ", substitutes vars and expressions -->
<context style="String DoubleQ" eol-context="#stay" name="StringDQ">
<Char style="String DoubleQ" context="#pop" char="&quot;" />
<Regex style="String Escape" context="#stay" pattern="\\[`&quot;\\$\n]" />
<IncludeRules from="FindSubstitutions" />
</context>
<!-- StringEsc eats till ', but escaping many characters -->
<context style="String SingleQ" eol-context="#stay" name="StringEsc">
<Char style="String SingleQ" context="#pop" char="'" />
<Regex style="String Escape" context="#stay" pattern="\\[abefnrtv\\']" />
<Regex style="String Escape" context="#stay" pattern="\\([0-7]{1,3}|x[A-Fa-f0-9]{1,2}|c.)" />
</context>
<!-- VarBrace is called as soon as ${xxx is encoutered -->
<context style="Variable" eol-context="#stay" name="VarBrace">
<Char style="Variable" context="#pop" char="}" />
<Char style="Variable" context="Subscript" char="[" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<!-- TODO: highlight various special parameter expansions } -->
</context>
<!-- SubstFile is called after a <( or >( is encoutered -->
<context style="Normal Text" eol-context="#stay" name="SubstFile">
<Char style="Redirection" context="#pop" char=")" />
<IncludeRules from="FindCommentsParen" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- SubstCommand is called after a $( is encountered -->
<context style="Normal Text" eol-context="#stay" name="SubstCommand">
<Char style="Variable" context="#pop" char=")" />
<IncludeRules from="FindCommentsParen" />
<IncludeRules from="FindCommands" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- SubstBackq is called when a backquote is encountered -->
<context style="Normal Text" eol-context="#stay" name="SubstBackq">
<Char style="Keyword" context="#pop" char="`" />
<IncludeRules from="FindCommentsBackq" />
<IncludeRules from="FindCommands" />
<IncludeRules from="FindStrings" />
<IncludeRules from="FindSubstitutions" />
<IncludeRules from="FindOthers" />
</context>
<!-- Case is called after the case keyword is encoutered. We handle this because of
the lonely closing parentheses that would otherwise disturb the expr matching -->
<context style="Normal Text" eol-context="#stay" name="Case">
<Regex style="Keyword" context="CaseIn" pattern="\sin\b" />
<IncludeRules from="FindMost" />
</context>
<!-- CaseIn is called when the construct 'case ... in' has been found. -->
<context style="Normal Text" eol-context="#stay" name="CaseIn">
<Regex style="Keyword" context="#pop#pop" pattern="\besac(?=$|[\s;)])" endRegion="case" />
<Char style="Keyword" context="CaseExpr" char=")" beginRegion="caseexpr" />
<AnyChar style="Keyword" context="#stay" chars="(|" />
<IncludeRules from="FindMost" />
</context>
<!-- CaseExpr eats shell input till ;; -->
<context style="Normal Text" eol-context="#stay" name="CaseExpr">
<TwoChars style="Keyword" context="#pop" char1=";" char2=";" endRegion="caseexpr" />
<IncludeRules from="FindAll" />
</context>
<!-- HereDoc consumes Here-documents. It is called at the beginning of the "<<" construct. -->
<!-- <context style="Normal Text" eol-context="#stay" name="HereDoc"> -->
<!-- <Regex style="Redirection" context="HereDocQ" pattern="(&lt;&lt;\s*&quot;(&word;)&quot;)" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocQ" pattern="(&lt;&lt;\s*'(&word;)')" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocQ" pattern="(&lt;&lt;\s*\\(&word;))" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocNQ" pattern="(&lt;&lt;\s*(&word;))" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocIQ" pattern="(&lt;&lt;-\s*&quot;(&word;)&quot;)" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocIQ" pattern="(&lt;&lt;-\s*'(&word;)')" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocIQ" pattern="(&lt;&lt;-\s*\\(&word;))" include-into-next="true" /> -->
<!-- <Regex style="Redirection" context="HereDocINQ" pattern="(&lt;&lt;-\s*(&word;))" include-into-next="true" /> -->
<!--<String style="Redirection" context="#pop" string="&lt;&lt;" />--> <!-- always met -->
<!-- </context> -->
<!-- <context style="Normal Text" eol-context="#pop" name="HereDocRemainder"> -->
<!-- <IncludeRules from="FindAll" /> -->
<!-- </context> -->
<!-- <context style="Normal Text" eol-context="#stay" name="HereDocQ" dynamic="true">
<Regex style="Redirection" context="HereDocRemainder" pattern="%1" dynamic="true" />
<Regex style="Redirection" context="#pop#pop" pattern="%2[\s;]*$" dynamic="true" bol-only="TRUE"/>
</context>-->
<!-- <context style="Normal Text" eol-context="#stay" name="HereDocNQ" dynamic="true">
<Regex style="Redirection" context="HereDocRemainder" pattern="%1" dynamic="true" />
<Regex style="Redirection" context="#pop#pop" pattern="%2[\s;]*$" dynamic="true" bol-only="TRUE"/>
<IncludeRules from="FindSubstitutions" />
</context>-->
<!-- <context style="Normal Text" eol-context="#stay" name="HereDocIQ" dynamic="true">
<Regex style="Redirection" context="HereDocRemainder" pattern="%1" dynamic="true" />
<Regex style="Redirection" context="#pop#pop" pattern="\s*%2[\s;]*$" dynamic="true" bol-only="TRUE"/>
</context>-->
<!-- <context style="Normal Text" eol-context="#stay" name="HereDocINQ" dynamic="true">
<Regex style="Redirection" context="HereDocRemainder" pattern="%1" dynamic="true" />
<Regex style="Redirection" context="#pop#pop" pattern="\s*%2[\s;]*$" dynamic="true" bol-only="TRUE"/>
<IncludeRules from="FindSubstitutions" />
</context>-->
</syntax>
<styles>
<style name="Normal Text" default-style="Normal"/>
<style name="Comment" default-style="Comment"/>
<style name="Keyword" default-style="Keyword"/>
<style name="Control" default-style="Keyword"/>
<style name="Builtin" default-style="Keyword" foreground="#808"/>
<style name="Command" default-style="Keyword" foreground="#c0c"/>
<style name="Redirection" default-style="Keyword" foreground="#238"/>
<style name="Escape" default-style="DataType"/>
<style name="String SingleQ" default-style="String"/>
<style name="String DoubleQ" default-style="String"/>
<style name="Backquote" default-style="Keyword"/>
<style name="String Transl." default-style="String"/>
<style name="String Escape" default-style="DataType"/>
<style name="Variable" default-style="Others"/>
<style name="Expression" default-style="Others"/>
<style name="Function" default-style="Char" bold="1"/>
<style name="Path" default-style="Normal"/>
<style name="Option" default-style="Normal"/>
</styles>
<general>
<comments>
<single-line start="#"/>
</comments>
<!-- <keywords casesensitive="1" weakDeliminator="^%#[]$._{}:-" additionalDeliminator="`"/> -->
</general>
</language>