1" Vim syntax file 2" Language: Mail file 3" Previous Maintainer: Felix von Leitner <[email protected]> 4" Maintainer: Gautam Iyer <[email protected]> 5" Last Change: Thu 06 Nov 2008 10:10:55 PM PST 6 7" Quit when a syntax file was already loaded 8if exists("b:current_syntax") 9 finish 10endif 11 12" The mail header is recognized starting with a "keyword:" line and ending 13" with an empty line or other line that can't be in the header. All lines of 14" the header are highlighted. Headers of quoted messages (quoted with >) are 15" also highlighted. 16 17" Syntax clusters 18syn cluster mailHeaderFields contains=mailHeaderKey,mailSubject,mailHeaderEmail,@mailLinks 19syn cluster mailLinks contains=mailURL,mailEmail 20syn cluster mailQuoteExps contains=mailQuoteExp1,mailQuoteExp2,mailQuoteExp3,mailQuoteExp4,mailQuoteExp5,mailQuoteExp6 21 22syn case match 23" For "From " matching case is required. The "From " is not matched in quoted 24" emails 25" According to RFC 2822 any printable ASCII character can appear in a field 26" name, except ':'. 27syn region mailHeader contains=@mailHeaderFields,@NoSpell start="^From .*\d\d\d\d$" skip="^\s" end="\v^[!-9;-~]*([^!-~]|$)"me=s-1 fold 28syn match mailHeaderKey contained contains=mailEmail,@NoSpell "^From\s.*\d\d\d\d$" 29 30" Nothing else depends on case. 31syn case ignore 32 33" Headers in properly quoted (with "> " or ">") emails are matched 34syn region mailHeader keepend contains=@mailHeaderFields,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)*\)\v(newsgroups|x-([a-z\-])*|path|xref|message-id|from|((in-)?reply-)?to|b?cc|subject|return-path|received|date|replied):" skip="^\z1\s" end="\v^\z1[!-9;-~]*([^!-~]|$)"me=s-1 end="\v^\z1@!"me=s-1 end="\v^\z1(\> ?)+"me=s-1 fold 35 36" Usenet headers 37syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(Newsgroups|Followup-To|Message-ID|Supersedes|Control):.*$" 38 39 40syn region mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$" 41syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$" fold 42syn match mailHeaderKey contained contains=@NoSpell "\v(^(\> ?)*)@<=date:" 43syn match mailSubject contained "\v^subject:.*$" fold 44syn match mailSubject contained contains=@NoSpell "\v(^(\> ?)+)@<=subject:.*$" 45 46" Anything in the header between < and > is an email address 47syn match mailHeaderEmail contained contains=@NoSpell "<.\{-}>" 48 49" Mail Signatures. (Begin with "-- ", end with change in quote level) 50syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps start="^--\s$" end="^$" end="^\(> \?\)\+"me=s-1 fold 51syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)--\s$" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1 fold 52 53" Treat verbatim Text special. 54syn region mailVerbatim contains=@NoSpell keepend start="^#v+$" end="^#v-$" fold 55syn region mailVerbatim contains=@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)#v+$" end="\z1#v-$" fold 56 57" URLs start with a known protocol or www,web,w3. 58syn match mailURL contains=@NoSpell `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' <>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' <>"]+)[a-z0-9/]` 59syn match mailEmail contains=@NoSpell "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}" 60 61" Make sure quote markers in regions (header / signature) have correct color 62syn match mailQuoteExp1 contained "\v^(\> ?)" 63syn match mailQuoteExp2 contained "\v^(\> ?){2}" 64syn match mailQuoteExp3 contained "\v^(\> ?){3}" 65syn match mailQuoteExp4 contained "\v^(\> ?){4}" 66syn match mailQuoteExp5 contained "\v^(\> ?){5}" 67syn match mailQuoteExp6 contained "\v^(\> ?){6}" 68 69" Even and odd quoted lines. Order is important here! 70syn region mailQuoted6 keepend contains=mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 71syn region mailQuoted5 keepend contains=mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 72syn region mailQuoted4 keepend contains=mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 73syn region mailQuoted3 keepend contains=mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 74syn region mailQuoted2 keepend contains=mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{1}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 75syn region mailQuoted1 keepend contains=mailQuoted2,mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z([a-z]\+>\|[]|}>]\)" end="^\z1\@!" fold 76 77" Need to sync on the header. Assume we can do that within 100 lines 78if exists("mail_minlines") 79 exec "syn sync minlines=" . mail_minlines 80else 81 syn sync minlines=100 82endif 83 84" Define the default highlighting. 85hi def link mailVerbatim Special 86hi def link mailHeader Statement 87hi def link mailHeaderKey Type 88hi def link mailSignature PreProc 89hi def link mailHeaderEmail mailEmail 90hi def link mailEmail Special 91hi def link mailURL String 92hi def link mailSubject LineNR 93hi def link mailQuoted1 Comment 94hi def link mailQuoted3 mailQuoted1 95hi def link mailQuoted5 mailQuoted1 96hi def link mailQuoted2 Identifier 97hi def link mailQuoted4 mailQuoted2 98hi def link mailQuoted6 mailQuoted2 99hi def link mailQuoteExp1 mailQuoted1 100hi def link mailQuoteExp2 mailQuoted2 101hi def link mailQuoteExp3 mailQuoted3 102hi def link mailQuoteExp4 mailQuoted4 103hi def link mailQuoteExp5 mailQuoted5 104hi def link mailQuoteExp6 mailQuoted6 105 106let b:current_syntax = "mail" 107