1" Vim syntax file
2" Language:	sed
3" Maintainer:	Haakon Riiser <hakonrk@fys.uio.no>
4" URL:		http://folk.uio.no/hakonrk/vim/syntax/sed.vim
5" Last Change:	2010 May 29
6
7" quit when a syntax file was already loaded
8if exists("b:current_syntax")
9    finish
10endif
11
12syn match sedError	"\S"
13
14syn match sedWhitespace "\s\+" contained
15syn match sedSemicolon	";"
16syn match sedAddress	"[[:digit:]$]"
17syn match sedAddress	"\d\+\~\d\+"
18syn region sedAddress   matchgroup=Special start="[{,;]\s*/\(\\/\)\="lc=1 skip="[^\\]\(\\\\\)*\\/" end="/I\=" contains=sedTab,sedRegexpMeta
19syn region sedAddress   matchgroup=Special start="^\s*/\(\\/\)\=" skip="[^\\]\(\\\\\)*\\/" end="/I\=" contains=sedTab,sedRegexpMeta
20syn match sedComment	"^\s*#.*$"
21syn match sedFunction	"[dDgGhHlnNpPqQx=]\s*\($\|;\)" contains=sedSemicolon,sedWhitespace
22syn match sedLabel	":[^;]*"
23syn match sedLineCont	"^\(\\\\\)*\\$" contained
24syn match sedLineCont	"[^\\]\(\\\\\)*\\$"ms=e contained
25syn match sedSpecial	"[{},!]"
26if exists("highlight_sedtabs")
27    syn match sedTab	"\t" contained
28endif
29
30" Append/Change/Insert
31syn region sedACI	matchgroup=sedFunction start="[aci]\\$" matchgroup=NONE end="^.*$" contains=sedLineCont,sedTab
32
33syn region sedBranch	matchgroup=sedFunction start="[bt]" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace
34syn region sedRW	matchgroup=sedFunction start="[rw]" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace
35
36" Substitution/transform with various delimiters
37syn region sedFlagwrite	    matchgroup=sedFlag start="w" matchgroup=sedSemicolon end=";\|$" contains=sedWhitespace contained
38syn match sedFlag	    "[[:digit:]gpI]*w\=" contains=sedFlagwrite contained
39syn match sedRegexpMeta	    "[.*^$]" contained
40syn match sedRegexpMeta	    "\\." contains=sedTab contained
41syn match sedRegexpMeta	    "\[.\{-}\]" contains=sedTab contained
42syn match sedRegexpMeta	    "\\{\d\*,\d*\\}" contained
43syn match sedRegexpMeta	    "\\(.\{-}\\)" contains=sedTab contained
44syn match sedReplaceMeta    "&\|\\\($\|.\)" contains=sedTab contained
45
46" Metacharacters: $ * . \ ^ [ ~
47" @ is used as delimiter and treated on its own below
48let __at = char2nr("@")
49let __sed_i = char2nr(" ") " ASCII: 32, EBCDIC: 64
50if has("ebcdic")
51    let __sed_last = 255
52else
53    let __sed_last = 126
54endif
55let __sed_metacharacters = '$*.\^[~'
56while __sed_i <= __sed_last
57    let __sed_delimiter = escape(nr2char(__sed_i), __sed_metacharacters)
58	if __sed_i != __at
59	    exe 'syn region sedAddress matchgroup=Special start=@\\'.__sed_delimiter.'\(\\'.__sed_delimiter.'\)\=@ skip=@[^\\]\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'I\=@ contains=sedTab'
60	    exe 'syn region sedRegexp'.__sed_i  'matchgroup=Special start=@'.__sed_delimiter.'\(\\\\\|\\'.__sed_delimiter.'\)*@ skip=@[^\\'.__sed_delimiter.']\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'@me=e-1 contains=sedTab,sedRegexpMeta keepend contained nextgroup=sedReplacement'.__sed_i
61	    exe 'syn region sedReplacement'.__sed_i 'matchgroup=Special start=@'.__sed_delimiter.'\(\\\\\|\\'.__sed_delimiter.'\)*@ skip=@[^\\'.__sed_delimiter.']\(\\\\\)*\\'.__sed_delimiter.'@ end=@'.__sed_delimiter.'@ contains=sedTab,sedReplaceMeta keepend contained nextgroup=sedFlag'
62	endif
63    let __sed_i = __sed_i + 1
64endwhile
65syn region sedAddress matchgroup=Special start=+\\@\(\\@\)\=+ skip=+[^\\]\(\\\\\)*\\@+ end=+@I\=+ contains=sedTab,sedRegexpMeta
66syn region sedRegexp64 matchgroup=Special start=+@\(\\\\\|\\@\)*+ skip=+[^\\@]\(\\\\\)*\\@+ end=+@+me=e-1 contains=sedTab,sedRegexpMeta keepend contained nextgroup=sedReplacement64
67syn region sedReplacement64 matchgroup=Special start=+@\(\\\\\|\\@\)*+ skip=+[^\\@]\(\\\\\)*\\@+ end=+@+ contains=sedTab,sedReplaceMeta keepend contained nextgroup=sedFlag
68
69" Since the syntax for the substituion command is very similar to the
70" syntax for the transform command, I use the same pattern matching
71" for both commands.  There is one problem -- the transform command
72" (y) does not allow any flags.  To save memory, I ignore this problem.
73syn match sedST	"[sy]" nextgroup=sedRegexp\d\+
74
75
76hi def link sedAddress		Macro
77hi def link sedACI		NONE
78hi def link sedBranch		Label
79hi def link sedComment		Comment
80hi def link sedDelete		Function
81hi def link sedError		Error
82hi def link sedFlag		Type
83hi def link sedFlagwrite		Constant
84hi def link sedFunction		Function
85hi def link sedLabel		Label
86hi def link sedLineCont		Special
87hi def link sedPutHoldspc	Function
88hi def link sedReplaceMeta	Special
89hi def link sedRegexpMeta	Special
90hi def link sedRW		Constant
91hi def link sedSemicolon		Special
92hi def link sedST		Function
93hi def link sedSpecial		Special
94hi def link sedWhitespace	NONE
95if exists("highlight_sedtabs")
96hi def link sedTab		Todo
97endif
98let __sed_i = char2nr(" ") " ASCII: 32, EBCDIC: 64
99while __sed_i <= __sed_last
100exe "hi def link sedRegexp".__sed_i		"Macro"
101exe "hi def link sedReplacement".__sed_i	"NONE"
102let __sed_i = __sed_i + 1
103endwhile
104
105
106unlet __sed_i __sed_last __sed_delimiter __sed_metacharacters
107
108let b:current_syntax = "sed"
109
110" vim: sts=4 sw=4 ts=8
111