1<?xml version="1.0" encoding="UTF-8"?>
2<!--
3
4 This file is part of GtkSourceView
5
6 Author: Silian Della Ragione <silian87@gechi.it>
7 Copyright (C) 2005 Silian Della Ragione <silian87@gechi.it>
8 Copyright (C) 2008 Steve Frécinaux <code@istique.net>
9
10 GtkSourceView is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14
15 GtkSourceView is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with this library; if not, see <http://www.gnu.org/licenses/>.
22
23-->
24<language id="sh" name="sh" version="2.0" _section="Script">
25  <metadata>
26    <property name="mimetypes">text/x-shellscript;application/x-shellscript;text/x-sh</property>
27    <property name="globs">*.sh;*bashrc;.profile;.bash_profile</property>
28    <property name="line-comment-start">#</property>
29  </metadata>
30
31  <styles>
32    <style id="comment"             name="Comment"             map-to="def:comment"/>
33    <style id="function"            name="Function"            map-to="def:function"/>
34    <style id="string"              name="String"              map-to="def:string"/>
35    <style id="keyword"             name="Keyword"             map-to="def:keyword"/>
36    <style id="variable"            name="Variable"            map-to="def:type"/> <!-- FIXME: need to sort out proper styles for variables -->
37    <style id="variable-definition" name="Variable Definition" map-to="sh:variable"/>
38    <style id="others"              name="Others"              map-to="def:keyword"/>
39    <style id="common-command"      name="Common Commands"     map-to="def:keyword"/>
40    <style id="here-doc-bound"      name="Heredoc Bound"       map-to="def:keyword"/>
41    <style id="subshell"            name="Subshell"            map-to="def:preprocessor"/>
42  </styles>
43
44  <definitions>
45
46    <!-- we cannot use def:shell-like-comment, because
47         m4.lang needs to replace this context -->
48    <context id="line-comment" style-ref="comment" end-at-line-end="true" class="comment" class-disabled="no-spell-check">
49      <start>(?&lt;!\S)#</start>
50      <include>
51        <context ref="def:in-comment"/>
52      </include>
53    </context>
54
55    <context id="double-quoted-string" style-ref="string" class="string" class-disabled="no-spell-check">
56      <start>"</start>
57      <end>"</end>
58      <include>
59        <!-- highlight escaped chars -->
60        <context style-ref="def:special-char">
61            <match>\\[$`"\\]</match>
62        </context>
63        <!-- skip backslash where it's not an escaping char -->
64        <context>
65            <match>\\</match>
66        </context>
67        <context ref="def:line-continue"/>
68        <context ref="variable"/>
69        <context ref="backtick-subshell"/>
70      </include>
71    </context>
72
73    <context id="single-quoted-string" style-ref="string" class="string" class-disabled="no-spell-check">
74      <start>'</start>
75      <end>'</end>
76    </context>
77
78    <context id="subshell">
79      <start>\(</start>
80      <end>\)</end>
81      <include>
82        <context sub-pattern="0" where="start" style-ref="keyword"/>
83        <context sub-pattern="0" where="end" style-ref="keyword"/>
84        <context ref="sh"/>
85      </include>
86    </context>
87
88    <context id="backtick-subshell" style-ref="subshell">
89      <start>`</start>
90      <end>`</end>
91      <include>
92        <context ref="def:escape"/>
93        <context ref="def:line-continue"/>
94        <context ref="variable"/>
95        <context ref="built-in-command"/>
96        <context ref="common-command"/>
97        <context ref="single-quoted-string"/>
98        <context ref="double-quoted-string"/>
99      </include>
100    </context>
101
102    <context id="punctuator" style-ref="others">
103      <match>[;\|&amp;/]</match>
104    </context>
105
106    <context id="function" style-ref="function">
107      <match>\b[a-zA-Z_][a-zA-Z0-9_]+[ \t]*\(\)</match>
108    </context>
109
110    <context id="redirection" style-ref="others">
111      <keyword>&gt;&amp;+[0-9]</keyword>
112      <keyword>\b[0-9]+&gt;&amp;</keyword>
113      <keyword>\b[0-9]+&gt;&amp;+[0-9]</keyword>
114      <keyword>\b[0-9]+&gt;</keyword>
115      <keyword>&gt;&gt;</keyword>
116      <keyword>\b[0-9]+&gt;&gt;</keyword>
117      <keyword>&lt;&amp;[0-9]</keyword>
118      <keyword>\b[0-9]+&lt;&amp;</keyword>
119      <keyword>\b[0-9]+&lt;&amp;[0-9]</keyword>
120      <keyword>\b[0-9]+&lt;</keyword>
121      <keyword>&lt;&lt;+[0-9]</keyword>
122      <keyword>\b[0-9]+&lt;&lt;</keyword>
123    </context>
124
125    <context id="here-doc">
126      <start extended="true" dupnames="true">
127        # (?&lt;!&lt;) and [^\s&lt;] are for not matching
128        # here-word (&lt;&lt;&lt;)
129        (?&lt;!&lt;)
130        &lt;&lt;-?\s*\\?(
131          \"(?P&lt;HDB&gt;[^\s&lt;]+)\" | # "EOF"
132          \'(?P&lt;HDB&gt;[^\s&lt;]+)\' | # 'EOF'
133          (?P&lt;HDB&gt;[^\s&lt;]+)       # EOF
134        )$
135      </start>
136      <end>^\t*\%{HDB@start}$</end>
137      <include>
138        <context sub-pattern="0" where="start" style-ref="here-doc-bound"/>
139        <context sub-pattern="0" where="end" style-ref="here-doc-bound"/>
140      </include>
141    </context>
142
143    <context id="operator" style-ref="function">
144      <keyword>\-a\b</keyword>
145      <keyword>\-b\b</keyword>
146      <keyword>\-c\b</keyword>
147      <keyword>\-d\b</keyword>
148      <keyword>\-e\b</keyword>
149      <keyword>\-f\b</keyword>
150      <keyword>\-g\b</keyword>
151      <keyword>\-h\b</keyword>
152      <keyword>\-k\b</keyword>
153      <keyword>\-p\b</keyword>
154      <keyword>\-r\b</keyword>
155      <keyword>\-s\b</keyword>
156      <keyword>\-t\b</keyword>
157      <keyword>\-u\b</keyword>
158      <keyword>\-w\b</keyword>
159      <keyword>\-x\b</keyword>
160      <keyword>\-O\b</keyword>
161      <keyword>\-G\b</keyword>
162      <keyword>\-L\b</keyword>
163      <keyword>\-S\b</keyword>
164      <keyword>\-N\b</keyword>
165      <keyword>\-nt\b</keyword>
166      <keyword>\-ot\b</keyword>
167      <keyword>\-ef\b</keyword>
168      <keyword>\-o\b</keyword>
169      <keyword>\-z\b</keyword>
170      <keyword>\-n\b</keyword>
171      <keyword>&lt;</keyword>
172      <keyword>&gt;</keyword>
173      <keyword>\!=</keyword>
174      <keyword>\-eq\b</keyword>
175      <keyword>\-ne\b</keyword>
176      <keyword>\-lt\b</keyword>
177      <keyword>\-le\b</keyword>
178      <keyword>\-gt\b</keyword>
179      <keyword>\-ge\b</keyword>
180    </context>
181
182    <context id="short-parameter-expansion" style-ref="variable">
183      <match>\$([!@?*#\$0-9]|[a-zA-Z0-9_]+)</match>
184    </context>
185
186    <context id="parameter-expansion" style-ref="variable">
187      <start>\$\{</start>
188      <end>\}</end>
189      <include>
190        <context ref="single-quoted-string"/>
191        <context ref="double-quoted-string"/>
192        <context ref="variable"/>
193        <context ref="backtick-subshell"/>
194      </include>
195    </context>
196
197    <context id="variable">
198      <include>
199        <context ref="short-parameter-expansion"/>
200        <context ref="parameter-expansion"/>
201      </include>
202    </context>
203
204    <context id="variable-definition">
205      <match>(^\s*|(?&lt;=then|else|do|export)\s+)([a-zA-Z_][a-zA-Z0-9_]*)\=</match>
206      <include>
207        <context sub-pattern="2" style-ref="variable-definition"/>
208      </include>
209    </context>
210
211    <context id="built-in-command-1" style-ref="keyword">
212      <prefix></prefix>
213      <suffix></suffix>
214      <keyword>\!</keyword>
215      <keyword>\{</keyword>
216      <keyword>\}</keyword>
217      <keyword>\:</keyword>
218      <keyword>(?&lt;=\s)\.(?=\s)</keyword>
219    </context>
220
221    <context id="for-command">
222      <start>\bfor\b</start>
223      <end>\b(in|do)\b</end>
224      <include>
225        <context sub-pattern="0" where="start" style-ref="keyword"/>
226        <context sub-pattern="0" where="end" style-ref="keyword"/>
227        <context style-ref="variable-definition" once-only="true">
228          <match>\w+</match>
229        </context>
230      </include>
231    </context>
232
233    <context id="built-in-command-2" style-ref="keyword">
234      <prefix>(?&lt;![^\s;\(\)\`])</prefix>
235      <suffix>(?![^\s;\(\)\`])</suffix>
236      <keyword>do</keyword>
237      <keyword>done</keyword>
238      <keyword>elif</keyword>
239      <keyword>else</keyword>
240      <keyword>fi</keyword>
241      <keyword>for</keyword>
242      <keyword>function</keyword>
243      <keyword>if</keyword>
244      <keyword>in</keyword>
245      <keyword>select</keyword>
246      <keyword>then</keyword>
247      <keyword>until</keyword>
248      <keyword>while</keyword>
249      <keyword>alias</keyword>
250      <keyword>bg</keyword>
251      <keyword>bind</keyword>
252      <keyword>break</keyword>
253      <keyword>builtin</keyword>
254      <keyword>cd</keyword>
255      <keyword>command</keyword>
256      <keyword>compgen</keyword>
257      <keyword>complete</keyword>
258      <keyword>continue</keyword>
259      <keyword>declare</keyword>
260      <keyword>dirs</keyword>
261      <keyword>disown</keyword>
262      <keyword>echo</keyword>
263      <keyword>enable</keyword>
264      <keyword>eval</keyword>
265      <keyword>exec</keyword>
266      <keyword>exit</keyword>
267      <keyword>export</keyword>
268      <keyword>fc</keyword>
269      <keyword>fg</keyword>
270      <keyword>getopts</keyword>
271      <keyword>hash</keyword>
272      <keyword>help</keyword>
273      <keyword>history</keyword>
274      <keyword>jobs</keyword>
275      <keyword>let</keyword>
276      <keyword>local</keyword>
277      <keyword>logout</keyword>
278      <keyword>popd</keyword>
279      <keyword>printf</keyword>
280      <keyword>pushd</keyword>
281      <keyword>read</keyword>
282      <keyword>readonly</keyword>
283      <keyword>return</keyword>
284      <keyword>set</keyword>
285      <keyword>shift</keyword>
286      <keyword>shopt</keyword>
287      <keyword>source</keyword>
288      <keyword>suspend</keyword>
289      <keyword>test</keyword>
290      <keyword>times</keyword>
291      <keyword>trap</keyword>
292      <keyword>type</keyword>
293      <keyword>typeset</keyword>
294      <keyword>ulimit</keyword>
295      <keyword>umask</keyword>
296      <keyword>unalias</keyword>
297      <keyword>unset</keyword>
298      <keyword>wait</keyword>
299    </context>
300
301    <context id="built-in-command">
302      <include>
303        <context ref="built-in-command-1"/>
304        <context ref="for-command"/>
305        <context ref="built-in-command-2"/>
306      </include>
307    </context>
308
309    <context id="common-command" style-ref="common-command">
310      <prefix>(?&lt;![\w\-\.])</prefix>
311      <suffix>(?![\w\-\.])</suffix>
312      <keyword>ar</keyword>
313      <keyword>awk</keyword>
314      <keyword>basename</keyword>
315      <keyword>bash</keyword>
316      <keyword>beep</keyword>
317      <keyword>bunzip2</keyword>
318      <keyword>bzcat</keyword>
319      <keyword>bzcmp</keyword>
320      <keyword>bzdiff</keyword>
321      <keyword>bzegrep</keyword>
322      <keyword>bzfgrep</keyword>
323      <keyword>bzgrep</keyword>
324      <keyword>bzip2recover</keyword>
325      <keyword>bzip2</keyword>
326      <keyword>bzless</keyword>
327      <keyword>bzmore</keyword>
328      <keyword>cc</keyword>
329      <keyword>cat</keyword>
330      <keyword>chattr</keyword>
331      <keyword>chgrp</keyword>
332      <keyword>chmod</keyword>
333      <keyword>chown</keyword>
334      <keyword>chroot</keyword>
335      <keyword>clear</keyword>
336      <keyword>cmp</keyword>
337      <keyword>cpp</keyword>
338      <keyword>cp</keyword>
339      <keyword>cut</keyword>
340      <keyword>date</keyword>
341      <keyword>dd</keyword>
342      <keyword>df</keyword>
343      <keyword>dialog</keyword>
344      <keyword>diff3</keyword>
345      <keyword>diff</keyword>
346      <keyword>dirname</keyword>
347      <keyword>dir</keyword>
348      <keyword>du</keyword>
349      <keyword>egrep</keyword>
350      <keyword>eject</keyword>
351      <keyword>env</keyword>
352      <keyword>expr</keyword>
353      <keyword>false</keyword>
354      <keyword>fgrep</keyword>
355      <keyword>file</keyword>
356      <keyword>find</keyword>
357      <keyword>fmt</keyword>
358      <keyword>free</keyword>
359      <keyword>ftp</keyword>
360      <keyword>funzip</keyword>
361      <keyword>fuser</keyword>
362      <keyword>gawk</keyword>
363      <keyword>gcc</keyword>
364      <keyword>getent</keyword>
365      <keyword>getopt</keyword>
366      <keyword>grep</keyword>
367      <keyword>groups</keyword>
368      <keyword>gunzip</keyword>
369      <keyword>gzip</keyword>
370      <keyword>head</keyword>
371      <keyword>hostname</keyword>
372      <keyword>id</keyword>
373      <keyword>ifconfig</keyword>
374      <keyword>info</keyword>
375      <keyword>insmod</keyword>
376      <keyword>install</keyword>
377      <keyword>join</keyword>
378      <keyword>killall</keyword>
379      <keyword>kill</keyword>
380      <keyword>lastb</keyword>
381      <keyword>last</keyword>
382      <keyword>ld</keyword>
383      <keyword>less</keyword>
384      <keyword>ln</keyword>
385      <keyword>locate</keyword>
386      <keyword>lockfile</keyword>
387      <keyword>login</keyword>
388      <keyword>logname</keyword>
389      <keyword>lp</keyword>
390      <keyword>lpr</keyword>
391      <keyword>lsattr</keyword>
392      <keyword>ls</keyword>
393      <keyword>lsmod</keyword>
394      <keyword>make</keyword>
395      <keyword>man</keyword>
396      <keyword>mkdir</keyword>
397      <keyword>mkfifo</keyword>
398      <keyword>mknod</keyword>
399      <keyword>mktemp</keyword>
400      <keyword>modprobe</keyword>
401      <keyword>more</keyword>
402      <keyword>mount</keyword>
403      <keyword>mv</keyword>
404      <keyword>namei</keyword>
405      <keyword>nawk</keyword>
406      <keyword>nice</keyword>
407      <keyword>nl</keyword>
408      <keyword>passwd</keyword>
409      <keyword>patch</keyword>
410      <keyword>perl</keyword>
411      <keyword>pgawk</keyword>
412      <keyword>pidof</keyword>
413      <keyword>ping</keyword>
414      <keyword>pkg-config</keyword>
415      <keyword>pr</keyword>
416      <keyword>ps</keyword>
417      <keyword>pwd</keyword>
418      <keyword>readlink</keyword>
419      <keyword>renice</keyword>
420      <keyword>rmdir</keyword>
421      <keyword>rm</keyword>
422      <keyword>scp</keyword>
423      <keyword>sed</keyword>
424      <keyword>seq</keyword>
425      <keyword>sh</keyword>
426      <keyword>sleep</keyword>
427      <keyword>sort</keyword>
428      <keyword>split</keyword>
429      <keyword>ssh-add</keyword>
430      <keyword>ssh-agent</keyword>
431      <keyword>ssh-keygen</keyword>
432      <keyword>ssh-keyscan</keyword>
433      <keyword>ssh</keyword>
434      <keyword>stat</keyword>
435      <keyword>sudo</keyword>
436      <keyword>sum</keyword>
437      <keyword>su</keyword>
438      <keyword>sync</keyword>
439      <keyword>tac</keyword>
440      <keyword>tail</keyword>
441      <keyword>tar</keyword>
442      <keyword>tee</keyword>
443      <keyword>tempfile</keyword>
444      <keyword>touch</keyword>
445      <keyword>true</keyword>
446      <keyword>tr</keyword>
447      <keyword>umount</keyword>
448      <keyword>uname</keyword>
449      <keyword>uniq</keyword>
450      <keyword>unlink</keyword>
451      <keyword>unzip</keyword>
452      <keyword>uptime</keyword>
453      <keyword>wall</keyword>
454      <keyword>wc</keyword>
455      <keyword>wget</keyword>
456      <keyword>whereis</keyword>
457      <keyword>which</keyword>
458      <keyword>whoami</keyword>
459      <keyword>who</keyword>
460      <keyword>write</keyword>
461      <keyword>w</keyword>
462      <keyword>xargs</keyword>
463      <keyword>xdialog</keyword>
464      <keyword>zcat</keyword>
465      <keyword>zcmp</keyword>
466      <keyword>zdiff</keyword>
467      <keyword>zegrep</keyword>
468      <keyword>zenity</keyword>
469      <keyword>zfgrep</keyword>
470      <keyword>zforce</keyword>
471      <keyword>zgrep</keyword>
472      <keyword>zip</keyword>
473      <keyword>zless</keyword>
474      <keyword>zmore</keyword>
475      <keyword>znew</keyword>
476    </context>
477
478    <context id="case">
479      <start>\bcase\b</start>
480      <end>\besac\b</end>
481      <include>
482        <context sub-pattern="0" where="start" style-ref="keyword"/>
483        <context sub-pattern="0" where="end" style-ref="keyword"/>
484        <context ref="double-quoted-string"/>
485        <context ref="single-quoted-string"/>
486        <context style-ref="others">
487          <match>[^\)\s]+\s*\)|;;</match>
488        </context>
489        <context ref="sh"/>
490      </include>
491    </context>
492
493    <context id="sh" class="no-spell-check">
494      <include>
495        <context ref="def:shebang"/>
496        <context ref="line-comment"/>
497        <context ref="def:escape"/>
498        <context ref="single-quoted-string"/>
499        <context ref="double-quoted-string"/>
500        <context ref="subshell"/>
501        <context ref="backtick-subshell"/>
502        <context ref="case"/>
503        <context ref="punctuator"/>
504        <context ref="function"/>
505        <context ref="here-doc"/>
506        <context ref="redirection"/>
507        <context ref="operator"/>
508        <context ref="variable"/>
509        <context ref="variable-definition"/>
510        <context ref="built-in-command"/>
511        <context ref="common-command"/>
512      </include>
513    </context>
514
515  </definitions>
516</language>
517