1071d4279SBram Moolenaar" Vim syntax file 2071d4279SBram Moolenaar" Language: Mail file 3071d4279SBram Moolenaar" Previous Maintainer: Felix von Leitner <[email protected]> 4f1568ecaSBram Moolenaar" Maintainer: GI <[email protected]>, where a='gi1242+vim', b='gmail', c='com' 5*7cba6c06SBram Moolenaar" Last Change: Wed 14 Aug 2013 08:24:52 AM PDT 6071d4279SBram Moolenaar 7071d4279SBram Moolenaar" Quit when a syntax file was already loaded 8071d4279SBram Moolenaarif exists("b:current_syntax") 9071d4279SBram Moolenaar finish 10071d4279SBram Moolenaarendif 11071d4279SBram Moolenaar 12b8ff1fb5SBram Moolenaarlet s:cpo_save = &cpo 13b8ff1fb5SBram Moolenaarset cpo&vim 14b8ff1fb5SBram Moolenaar 15071d4279SBram Moolenaar" The mail header is recognized starting with a "keyword:" line and ending 16071d4279SBram Moolenaar" with an empty line or other line that can't be in the header. All lines of 17071d4279SBram Moolenaar" the header are highlighted. Headers of quoted messages (quoted with >) are 18071d4279SBram Moolenaar" also highlighted. 19071d4279SBram Moolenaar 20071d4279SBram Moolenaar" Syntax clusters 21071d4279SBram Moolenaarsyn cluster mailHeaderFields contains=mailHeaderKey,mailSubject,mailHeaderEmail,@mailLinks 22071d4279SBram Moolenaarsyn cluster mailLinks contains=mailURL,mailEmail 23071d4279SBram Moolenaarsyn cluster mailQuoteExps contains=mailQuoteExp1,mailQuoteExp2,mailQuoteExp3,mailQuoteExp4,mailQuoteExp5,mailQuoteExp6 24071d4279SBram Moolenaar 25071d4279SBram Moolenaarsyn case match 26071d4279SBram Moolenaar" For "From " matching case is required. The "From " is not matched in quoted 27071d4279SBram Moolenaar" emails 28c81e5e79SBram Moolenaar" According to RFC 2822 any printable ASCII character can appear in a field 29c81e5e79SBram Moolenaar" name, except ':'. 305c73622aSBram Moolenaarsyn region mailHeader contains=@mailHeaderFields,@NoSpell start="^From .*\d\d\d\d$" skip="^\s" end="\v^[!-9;-~]*([^!-~]|$)"me=s-1 fold 31c1a11ed5SBram Moolenaarsyn match mailHeaderKey contained contains=mailEmail,@NoSpell "^From\s.*\d\d\d\d$" 325c73622aSBram Moolenaar 335c73622aSBram Moolenaar" Nothing else depends on case. 345c73622aSBram Moolenaarsyn case ignore 355c73622aSBram Moolenaar 365c73622aSBram Moolenaar" Headers in properly quoted (with "> " or ">") emails are matched 375c73622aSBram Moolenaarsyn 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 385c73622aSBram Moolenaar 39c1a11ed5SBram Moolenaar" Usenet headers 40c1a11ed5SBram Moolenaarsyn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(Newsgroups|Followup-To|Message-ID|Supersedes|Control):.*$" 41071d4279SBram Moolenaar 42071d4279SBram Moolenaar 436bb68366SBram Moolenaarsyn region mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$" 445c73622aSBram Moolenaarsyn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$" fold 4575c50c46SBram Moolenaarsyn match mailHeaderKey contained contains=@NoSpell "\v(^(\> ?)*)@<=date:" 46b8ff1fb5SBram Moolenaarsyn match mailSubject contained "\v^subject:.*$" fold 4775c50c46SBram Moolenaarsyn match mailSubject contained contains=@NoSpell "\v(^(\> ?)+)@<=subject:.*$" 48071d4279SBram Moolenaar 49071d4279SBram Moolenaar" Anything in the header between < and > is an email address 5075c50c46SBram Moolenaarsyn match mailHeaderEmail contained contains=@NoSpell "<.\{-}>" 51071d4279SBram Moolenaar 52071d4279SBram Moolenaar" Mail Signatures. (Begin with "-- ", end with change in quote level) 535c73622aSBram Moolenaarsyn region mailSignature keepend contains=@mailLinks,@mailQuoteExps start="^--\s$" end="^$" end="^\(> \?\)\+"me=s-1 fold 545c73622aSBram Moolenaarsyn region mailSignature keepend contains=@mailLinks,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)--\s$" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1 fold 555c73622aSBram Moolenaar 565c73622aSBram Moolenaar" Treat verbatim Text special. 575c73622aSBram Moolenaarsyn region mailVerbatim contains=@NoSpell keepend start="^#v+$" end="^#v-$" fold 58*7cba6c06SBram Moolenaarsyn region mailVerbatim contains=@mailQuoteExps,@NoSpell keepend start="^\z(\(> \?\)\+\)#v+$" end="\z1#v-$" fold 59071d4279SBram Moolenaar 60071d4279SBram Moolenaar" URLs start with a known protocol or www,web,w3. 6175c50c46SBram Moolenaarsyn match mailURL contains=@NoSpell `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' <>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' <>"]+)[a-z0-9/]` 6275c50c46SBram Moolenaarsyn match mailEmail contains=@NoSpell "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}" 63071d4279SBram Moolenaar 64071d4279SBram Moolenaar" Make sure quote markers in regions (header / signature) have correct color 65071d4279SBram Moolenaarsyn match mailQuoteExp1 contained "\v^(\> ?)" 66071d4279SBram Moolenaarsyn match mailQuoteExp2 contained "\v^(\> ?){2}" 67071d4279SBram Moolenaarsyn match mailQuoteExp3 contained "\v^(\> ?){3}" 68071d4279SBram Moolenaarsyn match mailQuoteExp4 contained "\v^(\> ?){4}" 69071d4279SBram Moolenaarsyn match mailQuoteExp5 contained "\v^(\> ?){5}" 70071d4279SBram Moolenaarsyn match mailQuoteExp6 contained "\v^(\> ?){6}" 71071d4279SBram Moolenaar 725c73622aSBram Moolenaar" Even and odd quoted lines. Order is important here! 735c73622aSBram Moolenaarsyn region mailQuoted6 keepend contains=mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 745c73622aSBram Moolenaarsyn region mailQuoted5 keepend contains=mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 755c73622aSBram Moolenaarsyn region mailQuoted4 keepend contains=mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 765c73622aSBram Moolenaarsyn region mailQuoted3 keepend contains=mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 775c73622aSBram Moolenaarsyn region mailQuoted2 keepend contains=mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{1}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold 785c73622aSBram Moolenaarsyn region mailQuoted1 keepend contains=mailQuoted2,mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z([a-z]\+>\|[]|}>]\)" end="^\z1\@!" fold 79071d4279SBram Moolenaar 80071d4279SBram Moolenaar" Need to sync on the header. Assume we can do that within 100 lines 81071d4279SBram Moolenaarif exists("mail_minlines") 82071d4279SBram Moolenaar exec "syn sync minlines=" . mail_minlines 83071d4279SBram Moolenaarelse 84071d4279SBram Moolenaar syn sync minlines=100 85071d4279SBram Moolenaarendif 86071d4279SBram Moolenaar 87071d4279SBram Moolenaar" Define the default highlighting. 885c73622aSBram Moolenaarhi def link mailVerbatim Special 89071d4279SBram Moolenaarhi def link mailHeader Statement 90071d4279SBram Moolenaarhi def link mailHeaderKey Type 91071d4279SBram Moolenaarhi def link mailSignature PreProc 92071d4279SBram Moolenaarhi def link mailHeaderEmail mailEmail 93071d4279SBram Moolenaarhi def link mailEmail Special 94071d4279SBram Moolenaarhi def link mailURL String 95f1568ecaSBram Moolenaarhi def link mailSubject Title 96071d4279SBram Moolenaarhi def link mailQuoted1 Comment 97071d4279SBram Moolenaarhi def link mailQuoted3 mailQuoted1 98071d4279SBram Moolenaarhi def link mailQuoted5 mailQuoted1 99071d4279SBram Moolenaarhi def link mailQuoted2 Identifier 100071d4279SBram Moolenaarhi def link mailQuoted4 mailQuoted2 101071d4279SBram Moolenaarhi def link mailQuoted6 mailQuoted2 102071d4279SBram Moolenaarhi def link mailQuoteExp1 mailQuoted1 103071d4279SBram Moolenaarhi def link mailQuoteExp2 mailQuoted2 104071d4279SBram Moolenaarhi def link mailQuoteExp3 mailQuoted3 105071d4279SBram Moolenaarhi def link mailQuoteExp4 mailQuoted4 106071d4279SBram Moolenaarhi def link mailQuoteExp5 mailQuoted5 107071d4279SBram Moolenaarhi def link mailQuoteExp6 mailQuoted6 108071d4279SBram Moolenaar 109071d4279SBram Moolenaarlet b:current_syntax = "mail" 110b8ff1fb5SBram Moolenaar 111b8ff1fb5SBram Moolenaarlet &cpo = s:cpo_save 112b8ff1fb5SBram Moolenaarunlet s:cpo_save 113