blob: 74b45c252a29abf64040599f28722315916a7db2 [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>
Bram Moolenaarf1568ec2011-12-14 21:17:39 +01004" Maintainer: GI <a@b.c>, where a='gi1242+vim', b='gmail', c='com'
GI36e2c0f2024-01-23 19:46:30 +01005" Last Change: Thu 18 Jan 2024 06:34:38 PM EST
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
Bram Moolenaarb8ff1fb2012-02-04 21:59:01 +010012let s:cpo_save = &cpo
13set cpo&vim
14
GI36e2c0f2024-01-23 19:46:30 +010015syn spell toplevel
16
Bram Moolenaar071d4272004-06-13 20:20:40 +000017" The mail header is recognized starting with a "keyword:" line and ending
18" with an empty line or other line that can't be in the header. All lines of
19" the header are highlighted. Headers of quoted messages (quoted with >) are
20" also highlighted.
21
22" Syntax clusters
23syn cluster mailHeaderFields contains=mailHeaderKey,mailSubject,mailHeaderEmail,@mailLinks
24syn cluster mailLinks contains=mailURL,mailEmail
25syn cluster mailQuoteExps contains=mailQuoteExp1,mailQuoteExp2,mailQuoteExp3,mailQuoteExp4,mailQuoteExp5,mailQuoteExp6
26
27syn case match
28" For "From " matching case is required. The "From " is not matched in quoted
29" emails
Bram Moolenaarc81e5e72007-05-05 18:24:42 +000030" According to RFC 2822 any printable ASCII character can appear in a field
31" name, except ':'.
Bram Moolenaar5c736222010-01-06 20:54:52 +010032syn region mailHeader contains=@mailHeaderFields,@NoSpell start="^From .*\d\d\d\d$" skip="^\s" end="\v^[!-9;-~]*([^!-~]|$)"me=s-1 fold
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +000033syn match mailHeaderKey contained contains=mailEmail,@NoSpell "^From\s.*\d\d\d\d$"
Bram Moolenaar5c736222010-01-06 20:54:52 +010034
35" Nothing else depends on case.
36syn case ignore
37
38" Headers in properly quoted (with "> " or ">") emails are matched
39syn 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
40
Bram Moolenaarc1a11ed2008-06-24 22:09:24 +000041" Usenet headers
42syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(Newsgroups|Followup-To|Message-ID|Supersedes|Control):.*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +000043
Bram Moolenaar071d4272004-06-13 20:20:40 +000044
Bram Moolenaar6bb68362005-03-22 23:03:44 +000045syn region mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@mailQuoteExps,@NoSpell start="\v(^(\> ?)*)@<=(to|b?cc):" skip=",$" end="$"
Bram Moolenaar5c736222010-01-06 20:54:52 +010046syn match mailHeaderKey contained contains=mailHeaderEmail,mailEmail,@NoSpell "\v(^(\> ?)*)@<=(from|reply-to):.*$" fold
Bram Moolenaar75c50c42005-06-04 22:06:24 +000047syn match mailHeaderKey contained contains=@NoSpell "\v(^(\> ?)*)@<=date:"
Bram Moolenaarb8ff1fb2012-02-04 21:59:01 +010048syn match mailSubject contained "\v^subject:.*$" fold
Bram Moolenaar75c50c42005-06-04 22:06:24 +000049syn match mailSubject contained contains=@NoSpell "\v(^(\> ?)+)@<=subject:.*$"
Bram Moolenaar071d4272004-06-13 20:20:40 +000050
51" Anything in the header between < and > is an email address
Bram Moolenaar75c50c42005-06-04 22:06:24 +000052syn match mailHeaderEmail contained contains=@NoSpell "<.\{-}>"
Bram Moolenaar071d4272004-06-13 20:20:40 +000053
Bram Moolenaar4399ef42005-02-12 14:29:27 +000054" Mail Signatures. (Begin with "-- ", end with change in quote level)
Bram Moolenaar5c736222010-01-06 20:54:52 +010055syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps start="^--\s$" end="^$" end="^\(> \?\)\+"me=s-1 fold
56syn region mailSignature keepend contains=@mailLinks,@mailQuoteExps,@NoSpell start="^\z(\(> \?\)\+\)--\s$" end="^\z1$" end="^\z1\@!"me=s-1 end="^\z1\(> \?\)\+"me=s-1 fold
57
58" Treat verbatim Text special.
59syn region mailVerbatim contains=@NoSpell keepend start="^#v+$" end="^#v-$" fold
Bram Moolenaar7cba6c02013-09-05 22:13:31 +020060syn region mailVerbatim contains=@mailQuoteExps,@NoSpell keepend start="^\z(\(> \?\)\+\)#v+$" end="\z1#v-$" fold
Bram Moolenaar071d4272004-06-13 20:20:40 +000061
62" URLs start with a known protocol or www,web,w3.
Bram Moolenaar75c50c42005-06-04 22:06:24 +000063syn match mailURL contains=@NoSpell `\v<(((https?|ftp|gopher)://|(mailto|file|news):)[^' <>"]+|(www|web|w3)[a-z0-9_-]*\.[a-z0-9._-]+\.[^' <>"]+)[a-z0-9/]`
64syn match mailEmail contains=@NoSpell "\v[_=a-z\./+0-9-]+\@[a-z0-9._-]+\a{2}"
Bram Moolenaar071d4272004-06-13 20:20:40 +000065
GI36e2c0f2024-01-23 19:46:30 +010066" Don't spell emojis
67syn match mailEmoji contains=@NoSpell "\v[\U1f300-\U1f64f\U1f900-\U1f9ff]"
68
Bram Moolenaar071d4272004-06-13 20:20:40 +000069" Make sure quote markers in regions (header / signature) have correct color
70syn match mailQuoteExp1 contained "\v^(\> ?)"
71syn match mailQuoteExp2 contained "\v^(\> ?){2}"
72syn match mailQuoteExp3 contained "\v^(\> ?){3}"
73syn match mailQuoteExp4 contained "\v^(\> ?){4}"
74syn match mailQuoteExp5 contained "\v^(\> ?){5}"
75syn match mailQuoteExp6 contained "\v^(\> ?){6}"
76
Bram Moolenaar5c736222010-01-06 20:54:52 +010077" Even and odd quoted lines. Order is important here!
78syn region mailQuoted6 keepend contains=mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{5}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold
79syn region mailQuoted5 keepend contains=mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{4}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold
80syn region mailQuoted4 keepend contains=mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{3}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold
81syn region mailQuoted3 keepend contains=mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{2}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold
82syn region mailQuoted2 keepend contains=mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z(\(\([a-z]\+>\|[]|}>]\)[ \t]*\)\{1}\([a-z]\+>\|[]|}>]\)\)" end="^\z1\@!" fold
83syn region mailQuoted1 keepend contains=mailQuoted2,mailQuoted3,mailQuoted4,mailQuoted5,mailQuoted6,mailVerbatim,mailHeader,@mailLinks,mailSignature,@NoSpell start="^\z([a-z]\+>\|[]|}>]\)" end="^\z1\@!" fold
Bram Moolenaar071d4272004-06-13 20:20:40 +000084
85" Need to sync on the header. Assume we can do that within 100 lines
86if exists("mail_minlines")
87 exec "syn sync minlines=" . mail_minlines
88else
89 syn sync minlines=100
90endif
91
92" Define the default highlighting.
Bram Moolenaar5c736222010-01-06 20:54:52 +010093hi def link mailVerbatim Special
GI36e2c0f2024-01-23 19:46:30 +010094hi def link mailHeader PreProc
Bram Moolenaar071d4272004-06-13 20:20:40 +000095hi def link mailHeaderKey Type
GI36e2c0f2024-01-23 19:46:30 +010096hi def link mailSignature Comment
Bram Moolenaar071d4272004-06-13 20:20:40 +000097hi def link mailHeaderEmail mailEmail
GI36e2c0f2024-01-23 19:46:30 +010098hi def link mailEmail String
99hi def link mailURL Constant
100hi def link mailSubject Statement
101hi def link mailQuoted1 Function
Bram Moolenaar071d4272004-06-13 20:20:40 +0000102hi def link mailQuoted3 mailQuoted1
103hi def link mailQuoted5 mailQuoted1
104hi def link mailQuoted2 Identifier
105hi def link mailQuoted4 mailQuoted2
106hi def link mailQuoted6 mailQuoted2
107hi def link mailQuoteExp1 mailQuoted1
108hi def link mailQuoteExp2 mailQuoted2
109hi def link mailQuoteExp3 mailQuoted3
110hi def link mailQuoteExp4 mailQuoted4
111hi def link mailQuoteExp5 mailQuoted5
112hi def link mailQuoteExp6 mailQuoted6
113
114let b:current_syntax = "mail"
Bram Moolenaarb8ff1fb2012-02-04 21:59:01 +0100115
116let &cpo = s:cpo_save
117unlet s:cpo_save