1" Vim syntax file
2" Language:		tcsh scripts
3" Maintainer:		Doug Kearns <dougkearns@gmail.com>
4" Previous Maintainer:	Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail (Original Author)
5" Last Change:		2021 Oct 15
6
7" Description: We break up each statement into a "command" and an "end" part.
8" All groups are either a "command" or part of the "end" of a statement (ie
9" everything after the "command"). This is because blindly highlighting tcsh
10" statements as keywords caused way too many false positives. Eg:
11"
12" 	set history=200
13"
14" causes history to come up as a keyword, which we want to avoid.
15
16" Quit when a syntax file was already loaded
17if exists('b:current_syntax')
18  finish
19endif
20
21let s:oldcpo = &cpo
22set cpo&vim " Line continuation is used
23
24syn iskeyword @,48-57,_,192-255,-
25
26syn case match
27
28" ----- Clusters ----- {{{1
29syn cluster tcshModifiers	contains=tcshModifier,tcshModifierError
30syn cluster tcshQuoteList	contains=tcshDQuote,tcshSQuote,tcshBQuote
31syn cluster tcshStatementEnds	contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArgument
32syn cluster tcshStatements	contains=tcshBuiltin,tcshCommands,tcshIf,tcshWhile
33syn cluster tcshVarList		contains=tcshUsrVar,tcshArgv,tcshSubst
34syn cluster tcshConditions	contains=tcshCmdSubst,tcshParenExpr,tcshOperator,tcshNumber,@tcshVarList
35
36" ----- Errors ----- {{{1
37" Define first, so can be easily overridden.
38syn match tcshError contained '\v\S.+'
39
40" ----- Statements ----- {{{1
41" Tcsh commands: Any filename / modifiable variable (must be first!)
42syn match tcshCommands	'\v[a-zA-Z0-9\\./_$:-]+' contains=tcshSpecial,tcshUsrVar,tcshArgv,tcshVarError nextgroup=tcshStatementEnd
43
44" Builtin commands except those treated specially. Currently (un)set(env),
45" (un)alias, if, while, else, bindkey
46syn keyword tcshBuiltin nextgroup=tcshStatementEnd alloc bg break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc termname time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
47
48" StatementEnd is anything after a built-in / command till the lexical end of a
49" statement (;, |, ||, |&, && or end of line)
50syn region tcshStatementEnd	transparent contained matchgroup=tcshBuiltin start='' end='\v\\@<!(;|\|[|&]?|\&\&|$)' contains=@tcshStatementEnds
51
52" set expressions (Contains shell variables)
53syn keyword tcshShellVar contained addsuffix afsuser ampm anyerror argv autocorrect autoexpand autolist autologout autorehash backslash_quote catalog cdpath cdtohome color colorcat command compat_expr complete continue continue_args correct csubstnonl cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit editors ellipsis euid euser fignore filec gid globdot globstar group highlight histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd padhour parseoctal path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version vimode visiblebell watch who wordchars
54syn keyword tcshBuiltin	nextgroup=tcshSetEnd set unset
55syn region  tcshSetEnd	contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$\|;' contains=tcshShellVar,@tcshStatementEnds
56
57" setenv expressions (Contains environment variables)
58syn keyword tcshEnvVar contained AFSUSER COLUMNS DISPLAY EDITOR GROUP HOME HOST HOSTTYPE HPATH LANG LC_CTYPE LINES LS_COLORS MACHTYPE NOREBIND OSTYPE PATH PWD REMOTEHOST SHLVL SYSTYPE TERM TERMCAP USER VENDOR VISUAL
59syn keyword tcshBuiltin	nextgroup=tcshEnvEnd setenv unsetenv
60syn region  tcshEnvEnd	contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$\|;' contains=tcshEnvVar,@tcshStatementEnds
61
62" alias and unalias (contains special aliases)
63syn keyword tcshAliases contained beepcmd cwdcmd jobcmd helpcommand periodic precmd postcmd shell
64syn keyword tcshBuiltin	nextgroup=tcshAliCmd skipwhite alias unalias
65syn match   tcshAliCmd	contained nextgroup=tcshAliEnd skipwhite '\v(\w|-)+' contains=tcshAliases
66syn region  tcshAliEnd	contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$\|;' contains=@tcshStatementEnds
67
68" if statements
69syn keyword tcshIf	nextgroup=tcshIfEnd skipwhite if
70syn region  tcshIfEnd	contained start='\S' skip='\\$' matchgroup=tcshBuiltin end='\v<then>|$' contains=@tcshConditions,tcshSpecial,@tcshStatementEnds
71syn region  tcshIfEnd	contained matchgroup=tcshBuiltin contains=@tcshConditions,tcshSpecial start='(' end='\v\)%(\s+then>)?' skipwhite nextgroup=@tcshStatementEnds
72syn region  tcshIfEnd	contained matchgroup=tcshBuiltin contains=tcshCommands,tcshSpecial start='\v\{\s+' end='\v\s+\}%(\s+then>)?' skipwhite nextgroup=@tcshStatementEnds keepend
73
74" else statements
75syn keyword tcshBuiltin	nextgroup=tcshIf skipwhite else
76
77" while statements (contains expressions / operators)
78syn keyword tcshBuiltin	nextgroup=@tcshConditions,tcshSpecial skipwhite while
79
80" Conditions (for if and while)
81syn region tcshParenExpr contained contains=@tcshConditions,tcshSpecial matchgroup=tcshBuiltin start='(' end=')'
82syn region tcshCmdSubst  contained contains=tcshCommands matchgroup=tcshBuiltin start='\v\{\s+' end='\v\s+\}' keepend
83
84" Bindkey. Internal editor functions
85syn keyword tcshBindkeyFuncs contained backward-char backward-delete-char
86	    \ backward-delete-word backward-kill-line backward-word
87	    \ beginning-of-line capitalize-word change-case
88	    \ change-till-end-of-line clear-screen complete-word
89	    \ complete-word-fwd complete-word-back complete-word-raw
90	    \ copy-prev-word copy-region-as-kill dabbrev-expand delete-char
91	    \ delete-char-or-eof delete-char-or-list
92	    \ delete-char-or-list-or-eof delete-word digit digit-argument
93	    \ down-history downcase-word end-of-file end-of-line
94	    \ exchange-point-and-mark expand-glob expand-history expand-line
95	    \ expand-variables forward-char forward-word
96	    \ gosmacs-transpose-chars history-search-backward
97	    \ history-search-forward insert-last-word i-search-fwd
98	    \ i-search-back keyboard-quit kill-line kill-region
99	    \ kill-whole-line list-choices list-choices-raw list-glob
100	    \ list-or-eof load-average magic-space newline newline-and-hold
101	    \ newline-and-down-history normalize-path normalize-command
102	    \ overwrite-mode prefix-meta quoted-insert redisplay
103	    \ run-fg-editor run-help self-insert-command sequence-lead-in
104	    \ set-mark-command spell-word spell-line stuff-char
105	    \ toggle-literal-history transpose-chars transpose-gosling
106	    \ tty-dsusp tty-flush-output tty-sigintr tty-sigquit tty-sigtsusp
107	    \ tty-start-output tty-stop-output undefined-key
108	    \ universal-argument up-history upcase-word
109	    \ vi-beginning-of-next-word vi-add vi-add-at-eol vi-chg-case
110	    \ vi-chg-meta vi-chg-to-eol vi-cmd-mode vi-cmd-mode-complete
111	    \ vi-delprev vi-delmeta vi-endword vi-eword vi-char-back
112	    \ vi-char-fwd vi-charto-back vi-charto-fwd vi-insert
113	    \ vi-insert-at-bol vi-repeat-char-fwd vi-repeat-char-back
114	    \ vi-repeat-search-fwd vi-repeat-search-back vi-replace-char
115	    \ vi-replace-mode vi-search-back vi-search-fwd vi-substitute-char
116	    \ vi-substitute-line vi-word-back vi-word-fwd vi-undo vi-zero
117	    \ which-command yank yank-pop e_copy_to_clipboard
118	    \ e_paste_from_clipboard e_dosify_next e_dosify_prev e_page_up
119	    \ e_page_down
120syn keyword tcshBuiltin nextgroup=tcshBindkeyEnd bindkey
121syn region tcshBindkeyEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$' contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshMeta,tcshSpecial,tcshArgument,tcshBindkeyFuncs
122
123" Expressions start with @.
124syn match tcshExprStart '\v\@\s+' nextgroup=tcshExprVar
125syn match tcshExprVar	contained '\v\h\w*%(\[\d+\])?' contains=tcshShellVar,tcshEnvVar nextgroup=tcshExprOp
126syn match tcshExprOp	contained '++\|--'
127syn match tcshExprOp	contained '\v\s*\=' nextgroup=tcshExprEnd
128syn match tcshExprEnd	contained '\v.*$'hs=e+1 contains=@tcshConditions
129syn match tcshExprEnd	contained '\v.{-};'hs=e	contains=@tcshConditions
130
131" ----- Comments: ----- {{{1
132syn match tcshComment	'#\s.*' contains=tcshTodo,tcshCommentTi,@Spell
133syn match tcshComment	'\v#($|\S.*)' contains=tcshTodo,tcshCommentTi
134syn match tcshSharpBang '^#! .*$'
135syn match tcshCommentTi contained '\v#\s*\u\w*(\s+\u\w*)*:'hs=s+1 contains=tcshTodo
136syn match tcshTodo	contained '\v\c<todo>'
137
138" ----- Strings ----- {{{1
139" Tcsh does not allow \" in strings unless the "backslash_quote" shell
140" variable is set. Set the vim variable "tcsh_backslash_quote" to 0 if you
141" want VIM to assume that no backslash quote constructs exist.
142
143" Backquotes are treated as commands, and are not contained in anything
144if exists('tcsh_backslash_quote') && tcsh_backslash_quote == 0
145    syn region tcshSQuote	keepend contained start="\v\\@<!'" end="'"
146    syn region tcshDQuote	keepend contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
147    syn region tcshBQuote	keepend start='\v\\@<!`' end='`' contains=@tcshStatements
148else
149    syn region tcshSQuote	contained start="\v\\@<!'" skip="\v\\\\|\\'" end="'"
150    syn region tcshDQuote	contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
151    syn region tcshBQuote	keepend matchgroup=tcshBQuoteGrp start='\v\\@<!`' skip='\v\\\\|\\`' end='`' contains=@tcshStatements
152endif
153
154" ----- Variables ----- {{{1
155" Variable Errors. Must come first! \$ constructs will be flagged by
156" tcshSpecial, so we don't consider them here.
157syn match tcshVarError	'\v\$\S*'	contained
158
159" Modifiable Variables without {}.
160syn match tcshUsrVar contained '\v\$\h\w*%(\[\d+%(-\d+)?\])?' nextgroup=@tcshModifiers contains=tcshShellVar,tcshEnvVar
161syn match tcshArgv   contained '\v\$%(\d+|\*)' nextgroup=@tcshModifiers
162
163" Modifiable Variables with {}.
164syn match tcshUsrVar contained '\v\$\{\h\w*%(\[\d+%(-\d+)?\])?%(:\S*)?\}' contains=@tcshModifiers,tcshShellVar,tcshEnvVar
165syn match tcshArgv   contained '\v\$\{%(\d+|\*)%(:\S*)?\}' contains=@tcshModifiers
166
167" Un-modifiable Substitutions. Order is important here.
168syn match tcshSubst contained	'\v\$[?#$!_<]' nextgroup=tcshModifierError
169syn match tcshSubst contained	'\v\$[%#?]%(\h\w*|\d+)' nextgroup=tcshModifierError contains=tcshShellVar,tcshEnvVar
170syn match tcshSubst contained	'\v\$\{[%#?]%(\h\w*|\d+)%(:\S*)?\}' contains=tcshModifierError contains=tcshShellVar,tcshEnvVar
171
172" Variable Name Expansion Modifiers (order important)
173syn match tcshModifierError	contained '\v:\S*'
174syn match tcshModifier		contained '\v:[ag]?[htreuls&qx]' nextgroup=@tcshModifiers
175
176" ----- Operators / Specials ----- {{{1
177" Standard redirects (except <<) [<, >, >>, >>&, >>!, >>&!]
178syn match tcshRedir contained	'\v\<|\>\>?\&?!?'
179
180" Meta-chars
181syn match tcshMeta  contained	'\v[]{}*?[]'
182
183" Here documents (<<)
184syn region tcshHereDoc contained matchgroup=tcshShellVar start='\v\<\<\s*\z(\h\w*)' end='^\z1$' contains=@tcshVarList,tcshSpecial
185syn region tcshHereDoc contained matchgroup=tcshShellVar start="\v\<\<\s*'\z(\h\w*)'" start='\v\<\<\s*"\z(\h\w*)"$' start='\v\<\<\s*\\\z(\h\w*)$' end='^\z1$'
186
187" Operators
188syn match tcshOperator	contained '&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|\~\|||\|!\|%\|&\|+\|-\|/\|<\|>\||'
189"syn match tcshOperator	contained '[(){}]'
190
191" Numbers
192syn match tcshNumber	contained '\v<-?\d+>'
193
194" Arguments
195syn match tcshArgument	contained '\v\s@<=-(\w|-)*'
196
197" Special characters. \xxx, or backslashed characters.
198"syn match tcshSpecial	contained '\v\\@<!\\(\d{3}|.)'
199syn match tcshSpecial	contained '\v\\%([0-7]{3}|.)'
200
201" ----- Synchronising ----- {{{1
202if exists('tcsh_minlines')
203    if tcsh_minlines == 'fromstart'
204	syn sync fromstart
205    else
206	exec 'syn sync minlines=' . tcsh_minlines
207    endif
208else
209    syn sync minlines=100	" Some completions can be quite long
210endif
211
212" ----- Highlighting ----- {{{1
213" Define highlighting of syntax groups
214hi def link tcshError		Error
215hi def link tcshBuiltin		Statement
216hi def link tcshShellVar	Preproc
217hi def link tcshEnvVar		tcshShellVar
218hi def link tcshAliases		tcshShellVar
219hi def link tcshAliCmd		Identifier
220hi def link tcshCommands	Identifier
221hi def link tcshIf		tcshBuiltin
222hi def link tcshWhile		tcshBuiltin
223hi def link tcshBindkeyFuncs	Function
224hi def link tcshExprStart	tcshBuiltin
225hi def link tcshExprVar		tcshUsrVar
226hi def link tcshExprOp		tcshOperator
227hi def link tcshExprEnd		tcshOperator
228hi def link tcshComment		Comment
229hi def link tcshCommentTi	Preproc
230hi def link tcshSharpBang	tcshCommentTi
231hi def link tcshTodo		Todo
232hi def link tcshSQuote		Constant
233hi def link tcshDQuote		tcshSQuote
234hi def link tcshBQuoteGrp	Include
235hi def link tcshVarError	Error
236hi def link tcshUsrVar		Type
237hi def link tcshArgv		tcshUsrVar
238hi def link tcshSubst		tcshUsrVar
239hi def link tcshModifier	tcshArgument
240hi def link tcshModifierError	tcshVarError
241hi def link tcshMeta		tcshSubst
242hi def link tcshRedir		tcshOperator
243hi def link tcshHereDoc		tcshSQuote
244hi def link tcshOperator	Operator
245hi def link tcshNumber		Number
246hi def link tcshArgument	Special
247hi def link tcshSpecial		SpecialChar
248" }}}
249
250let &cpo = s:oldcpo
251unlet s:oldcpo
252
253let b:current_syntax = 'tcsh'
254
255" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
256