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 17 Jan 2008 11:25:44 AM 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 28syn match mailHeaderKey contained contains=mailEmail,@NoSpell "^From\s.*\d\d\d\d$" 29" Usenet headers 30syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(Newsgroups|Followup-To|Message-ID|Supersedes|Control):.*$" 31 32syn case ignore 33" Nothing else depends on case. Headers in properly quoted (with "> " or ">") 34" emails are matched 35syn 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 36 37syn region mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$" 38syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$" 39syn match mailHeaderKey contained contains=@NoSpell "\v(^(\> ?)*)@<=date:" 40syn match mailSubject contained "\v^subject:.*$" 41syn match mailSubject contained contains=@NoSpell "\v(^(\> ?)+)@<=subject:.*$" 42 43" Anything in the header between < and > is an email address 44syn match mailHeaderEmail contained contains=@NoSpell "<.\{-}>" 45 46" Mail Signatures. (Begin with "-- ", end with change in quote level) 47syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps start="^--\s$" end="^$" end="^\(> \?\)\+"me=s-1 48syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)--\s$" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1 49 50" URLs start with a known protocol or www,web,w3. 51syn match mailURL contains=@NoSpell `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' <>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' <>"]+)[a-z0-9/]` 52syn match mailEmail contains=@NoSpell "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}" 53 54" Make sure quote markers in regions (header / signature) have correct color 55syn match mailQuoteExp1 contained "\v^(\> ?)" 56syn match mailQuoteExp2 contained "\v^(\> ?){2}" 57syn match mailQuoteExp3 contained "\v^(\> ?){3}" 58syn match mailQuoteExp4 contained "\v^(\> ?){4}" 59syn match mailQuoteExp5 contained "\v^(\> ?){5}" 60syn match mailQuoteExp6 contained "\v^(\> ?){6}" 61 62" Even and odd quoted lines. order is imporant here! 63syn match mailQuoted1 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\([a-z]\+>\|[]|}>]\).*$" 64syn match mailQuoted2 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}.*$" 65syn match mailQuoted3 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}.*$" 66syn match mailQuoted4 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}.*$" 67syn match mailQuoted5 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}.*$" 68syn match mailQuoted6 contains=mailHeader,@mailLinks,mailSignature,@NoSpell "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{6}.*$" 69 70" Need to sync on the header. Assume we can do that within 100 lines 71if exists("mail_minlines") 72 exec "syn sync minlines=" . mail_minlines 73else 74 syn sync minlines=100 75endif 76 77" Define the default highlighting. 78hi def link mailHeader Statement 79hi def link mailHeaderKey Type 80hi def link mailSignature PreProc 81hi def link mailHeaderEmail mailEmail 82hi def link mailEmail Special 83hi def link mailURL String 84hi def link mailSubject LineNR 85hi def link mailQuoted1 Comment 86hi def link mailQuoted3 mailQuoted1 87hi def link mailQuoted5 mailQuoted1 88hi def link mailQuoted2 Identifier 89hi def link mailQuoted4 mailQuoted2 90hi def link mailQuoted6 mailQuoted2 91hi def link mailQuoteExp1 mailQuoted1 92hi def link mailQuoteExp2 mailQuoted2 93hi def link mailQuoteExp3 mailQuoted3 94hi def link mailQuoteExp4 mailQuoted4 95hi def link mailQuoteExp5 mailQuoted5 96hi def link mailQuoteExp6 mailQuoted6 97 98let b:current_syntax = "mail" 99