blob: a45eb61ce67dc6cf56db7d6bf58ba0ffd7717f79 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim syntax file
2" Language: Mail file
3" Previous Maintainer: Felix von Leitner <leitner@math.fu-berlin.de>
4" Maintainer: Gautam Iyer <gautam@math.uchicago.edu>
Bram Moolenaar68b76a62005-03-25 21:53:48 +00005" Last Change: 2005 Mar 23
Bram Moolenaar071d4272004-06-13 20:20:40 +00006
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
25syn region mailHeader contains=@mailHeaderFields start="^From " skip="^\s" end="\v^[-A-Za-z0-9]*([^-A-Za-z0-9:]|$)"me=s-1
Bram Moolenaar6bb68362005-03-22 23:03:44 +000026syn match mailHeaderKey contained contains=mailEmail,@NoSpell "^From\s.*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +000027
28syn case ignore
29" Nothing else depends on case. Headers in properly quoted (with "> " or ">")
30" emails are matched
Bram Moolenaar6bb68362005-03-22 23:03:44 +000031syn region mailHeader keepend contains=@mailHeaderFields,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)*\)\v(newsgroups|from|((in-)?reply-)?to|b?cc|subject|return-path|received|date|replied):" skip="^\z1\s" end="\v^\z1[-a-z0-9]*([^-a-z0-9:]|$)"me=s-1 end="\v^\z1@!"me=s-1 end="\v^\z1(\> ?)+"me=s-1
Bram Moolenaar071d4272004-06-13 20:20:40 +000032
Bram Moolenaar6bb68362005-03-22 23:03:44 +000033syn region mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$"
34syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +000035syn match mailHeaderKey contained "\v(^(\> ?)*)@<=date:"
Bram Moolenaar6bb68362005-03-22 23:03:44 +000036syn match mailSubject contained "\v(^(\> ?)*)@<=subject:.*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +000037
38" Anything in the header between < and > is an email address
Bram Moolenaar68b76a62005-03-25 21:53:48 +000039syn match mailHeaderEmail contained "<.\{-}>" contains=@NoSpell
Bram Moolenaar071d4272004-06-13 20:20:40 +000040
Bram Moolenaar4399ef42005-02-12 14:29:27 +000041" Mail Signatures. (Begin with "-- ", end with change in quote level)
42syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps start="^\z(\(> \?\)*\)-- $" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1
Bram Moolenaar071d4272004-06-13 20:20:40 +000043
44" URLs start with a known protocol or www,web,w3.
Bram Moolenaar68b76a62005-03-25 21:53:48 +000045syn match mailURL `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' <>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' <>"]+)[a-z0-9/]` contains=@NoSpell
46syn match mailEmail "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}" contains=@NoSpell
Bram Moolenaar071d4272004-06-13 20:20:40 +000047
48" Make sure quote markers in regions (header / signature) have correct color
49syn match mailQuoteExp1 contained "\v^(\> ?)"
50syn match mailQuoteExp2 contained "\v^(\> ?){2}"
51syn match mailQuoteExp3 contained "\v^(\> ?){3}"
52syn match mailQuoteExp4 contained "\v^(\> ?){4}"
53syn match mailQuoteExp5 contained "\v^(\> ?){5}"
54syn match mailQuoteExp6 contained "\v^(\> ?){6}"
55
56" Even and odd quoted lines. order is imporant here!
57syn match mailQuoted1 contains=mailHeader,@mailLinks,mailSignature "^\([a-z]\+>\|[]|}>]\).*$"
58syn match mailQuoted2 contains=mailHeader,@mailLinks,mailSignature "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}.*$"
59syn match mailQuoted3 contains=mailHeader,@mailLinks,mailSignature "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}.*$"
60syn match mailQuoted4 contains=mailHeader,@mailLinks,mailSignature "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}.*$"
61syn match mailQuoted5 contains=mailHeader,@mailLinks,mailSignature "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}.*$"
62syn match mailQuoted6 contains=mailHeader,@mailLinks,mailSignature "^\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{6}.*$"
63
64" Need to sync on the header. Assume we can do that within 100 lines
65if exists("mail_minlines")
66 exec "syn sync minlines=" . mail_minlines
67else
68 syn sync minlines=100
69endif
70
71" Define the default highlighting.
72hi def link mailHeader Statement
73hi def link mailHeaderKey Type
74hi def link mailSignature PreProc
75hi def link mailHeaderEmail mailEmail
76hi def link mailEmail Special
77hi def link mailURL String
78hi def link mailSubject LineNR
79hi def link mailQuoted1 Comment
80hi def link mailQuoted3 mailQuoted1
81hi def link mailQuoted5 mailQuoted1
82hi def link mailQuoted2 Identifier
83hi def link mailQuoted4 mailQuoted2
84hi def link mailQuoted6 mailQuoted2
85hi def link mailQuoteExp1 mailQuoted1
86hi def link mailQuoteExp2 mailQuoted2
87hi def link mailQuoteExp3 mailQuoted3
88hi def link mailQuoteExp4 mailQuoted4
89hi def link mailQuoteExp5 mailQuoted5
90hi def link mailQuoteExp6 mailQuoted6
91
92let b:current_syntax = "mail"