summaryrefslogtreecommitdiffstats
path: root/runtime/syntax/rst.vim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--runtime/syntax/rst.vim278
1 files changed, 278 insertions, 0 deletions
diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim
new file mode 100644
index 0000000..c865cf6
--- /dev/null
+++ b/runtime/syntax/rst.vim
@@ -0,0 +1,278 @@
+" Vim syntax file
+" Language: reStructuredText documentation format
+" Maintainer: Marshall Ward <marshall.ward@gmail.com>
+" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
+" Website: https://github.com/marshallward/vim-restructuredtext
+" Latest Revision: 2018-12-29
+
+if exists("b:current_syntax")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn case ignore
+
+syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/
+
+syn cluster rstCruft contains=rstEmphasis,rstStrongEmphasis,
+ \ rstInterpretedText,rstInlineLiteral,rstSubstitutionReference,
+ \ rstInlineInternalTargets,rstFootnoteReference,rstHyperlinkReference
+
+syn region rstLiteralBlock matchgroup=rstDelimiter
+ \ start='::\_s*\n\ze\z(\s\+\)' skip='^$' end='^\z1\@!'
+ \ contains=@NoSpell
+
+syn region rstQuotedLiteralBlock matchgroup=rstDelimiter
+ \ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)"
+ \ end='^\z1\@!' contains=@NoSpell
+
+syn region rstDoctestBlock oneline display matchgroup=rstDelimiter
+ \ start='^>>>\s' end='^$'
+
+syn region rstTable transparent start='^\n\s*+[-=+]\+' end='^$'
+ \ contains=rstTableLines,@rstCruft
+syn match rstTableLines contained display '|\|+\%(=\+\|-\+\)\='
+
+syn region rstSimpleTable transparent
+ \ start='^\n\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+ \ end='^$'
+ \ contains=rstSimpleTableLines,@rstCruft
+syn match rstSimpleTableLines contained display
+ \ '^\%(\s*\)\@>\%(\%(=\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(=\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+syn match rstSimpleTableLines contained display
+ \ '^\%(\s*\)\@>\%(\%(-\+\)\@>\%(\s\+\)\@>\)\%(\%(\%(-\+\)\@>\%(\s*\)\@>\)\+\)\@>$'
+
+syn cluster rstDirectives contains=rstFootnote,rstCitation,
+ \ rstHyperlinkTarget,rstExDirective
+
+syn match rstExplicitMarkup '^\s*\.\.\_s'
+ \ nextgroup=@rstDirectives,rstComment,rstSubstitutionDefinition
+
+" "Simple reference names are single words consisting of alphanumerics plus
+" isolated (no two adjacent) internal hyphens, underscores, periods, colons
+" and plus signs."
+let s:ReferenceName = '[[:alnum:]]\%([-_.:+]\?[[:alnum:]]\+\)*'
+
+syn keyword rstTodo contained FIXME TODO XXX NOTE
+
+execute 'syn region rstComment contained' .
+ \ ' start=/.*/'
+ \ ' skip=+^$+' .
+ \ ' end=/^\s\@!/ contains=rstTodo'
+
+execute 'syn region rstFootnote contained matchgroup=rstDirective' .
+ \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' .
+ \ ' skip=+^$+' .
+ \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
+
+execute 'syn region rstCitation contained matchgroup=rstDirective' .
+ \ ' start=+\[' . s:ReferenceName . '\]\_s+' .
+ \ ' skip=+^$+' .
+ \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell'
+
+syn region rstHyperlinkTarget contained matchgroup=rstDirective
+ \ start='_\%(_\|[^:\\]*\%(\\.[^:\\]*\)*\):\_s' skip=+^$+ end=+^\s\@!+
+
+syn region rstHyperlinkTarget contained matchgroup=rstDirective
+ \ start='_`[^`\\]*\%(\\.[^`\\]*\)*`:\_s' skip=+^$+ end=+^\s\@!+
+
+syn region rstHyperlinkTarget matchgroup=rstDirective
+ \ start=+^__\_s+ skip=+^$+ end=+^\s\@!+
+
+execute 'syn region rstExDirective contained matchgroup=rstDirective' .
+ \ ' start=+' . s:ReferenceName . '::\_s+' .
+ \ ' skip=+^$+' .
+ \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock'
+
+execute 'syn match rstSubstitutionDefinition contained' .
+ \ ' /|.*|\_s\+/ nextgroup=@rstDirectives'
+
+function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
+ execute 'syn region rst' . a:name .
+ \ ' start=+' . a:char_left . '\zs' . a:start .
+ \ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
+ \ a:middle .
+ \ ' end=+\S' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+'
+endfunction
+
+function! s:DefineInlineMarkup(name, start, middle, end)
+ let middle = a:middle != "" ?
+ \ (' skip=+\\\\\|\\' . a:middle . '+') :
+ \ ""
+
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '"', '"')
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '(', ')')
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\[', '\]')
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '{', '}')
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '<', '>')
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '’', '’')
+ " TODO: Additional Unicode Pd, Po, Pi, Pf, Ps characters
+
+ call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '')
+
+ execute 'syn match rst' . a:name .
+ \ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start .
+ \ '[^[:space:]' . a:start[strlen(a:start) - 1] . ']'
+ \ a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
+
+ execute 'hi def link rst' . a:name . 'Delimiter' . ' rst' . a:name
+endfunction
+
+call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*')
+call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*')
+call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}')
+call s:DefineInlineMarkup('InlineLiteral', '``', "", '``')
+call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
+call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
+
+" Sections are identified through their titles, which are marked up with
+" adornment: "underlines" below the title text, or underlines and matching
+" "overlines" above the title. An underline/overline is a single repeated
+" punctuation character that begins in column 1 and forms a line extending at
+" least as far as the right edge of the title text.
+"
+" It is difficult to count characters in a regex, but we at least special-case
+" the case where the title has at least three characters to require the
+" adornment to have at least three characters as well, in order to handle
+" properly the case of a literal block:
+"
+" this is the end of a paragraph
+" ::
+" this is a literal block
+syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1+\n)?.{1,2}\n([=`:.'"~^_*+#-])\2+$"
+ \ contains=@Spell
+syn match rstSections "\v^%(([=`:.'"~^_*+#-])\1{2,}\n)?.{3,}\n([=`:.'"~^_*+#-])\2{2,}$"
+ \ contains=@Spell
+
+" TODO: Can’t remember why these two can’t be defined like the ones above.
+execute 'syn match rstFootnoteReference contains=@NoSpell' .
+ \ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+'
+
+execute 'syn match rstCitationReference contains=@NoSpell' .
+ \ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
+
+execute 'syn match rstHyperlinkReference' .
+ \ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/'
+
+syn match rstStandaloneHyperlink contains=@NoSpell
+ \ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]"
+
+syn region rstCodeBlock contained matchgroup=rstDirective
+ \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s\+.*\_s*\n\ze\z(\s\+\)+
+ \ skip=+^$+
+ \ end=+^\z1\@!+
+ \ contains=@NoSpell
+syn cluster rstDirectives add=rstCodeBlock
+
+if !exists('g:rst_syntax_code_list')
+ " A mapping from a Vim filetype to a list of alias patterns (pattern
+ " branches to be specific, see ':help /pattern'). E.g. given:
+ "
+ " let g:rst_syntax_code_list = {
+ " \ 'cpp': ['cpp', 'c++'],
+ " \ }
+ "
+ " then the respective contents of the following two rST directives:
+ "
+ " .. code:: cpp
+ "
+ " auto i = 42;
+ "
+ " .. code:: C++
+ "
+ " auto i = 42;
+ "
+ " will both be highlighted as C++ code. As shown by the latter block
+ " pattern matching will be case-insensitive.
+ let g:rst_syntax_code_list = {
+ \ 'vim': ['vim'],
+ \ 'java': ['java'],
+ \ 'cpp': ['cpp', 'c++'],
+ \ 'lisp': ['lisp'],
+ \ 'php': ['php'],
+ \ 'python': ['python'],
+ \ 'perl': ['perl'],
+ \ 'sh': ['sh'],
+ \ }
+elseif type(g:rst_syntax_code_list) == type([])
+ " backward compatibility with former list format
+ let s:old_spec = g:rst_syntax_code_list
+ let g:rst_syntax_code_list = {}
+ for s:elem in s:old_spec
+ let g:rst_syntax_code_list[s:elem] = [s:elem]
+ endfor
+endif
+
+for s:filetype in keys(g:rst_syntax_code_list)
+ unlet! b:current_syntax
+ " guard against setting 'isk' option which might cause problems (issue #108)
+ let prior_isk = &l:iskeyword
+ let s:alias_pattern = ''
+ \.'\%('
+ \.join(g:rst_syntax_code_list[s:filetype], '\|')
+ \.'\)'
+
+ exe 'syn include @rst'.s:filetype.' syntax/'.s:filetype.'.vim'
+ exe 'syn region rstDirective'.s:filetype
+ \.' matchgroup=rstDirective fold'
+ \.' start="\c\%(sourcecode\|code\%(-block\)\=\)::\s\+'.s:alias_pattern.'\_s*\n\ze\z(\s\+\)"'
+ \.' skip=#^$#'
+ \.' end=#^\z1\@!#'
+ \.' contains=@NoSpell,@rst'.s:filetype
+ exe 'syn cluster rstDirectives add=rstDirective'.s:filetype
+
+ " reset 'isk' setting, if it has been changed
+ if &l:iskeyword !=# prior_isk
+ let &l:iskeyword = prior_isk
+ endif
+ unlet! prior_isk
+endfor
+
+" Enable top level spell checking
+syntax spell toplevel
+
+" TODO: Use better syncing.
+syn sync minlines=50 linebreaks=2
+
+hi def link rstTodo Todo
+hi def link rstComment Comment
+hi def link rstSections Title
+hi def link rstTransition rstSections
+hi def link rstLiteralBlock String
+hi def link rstQuotedLiteralBlock String
+hi def link rstDoctestBlock PreProc
+hi def link rstTableLines rstDelimiter
+hi def link rstSimpleTableLines rstTableLines
+hi def link rstExplicitMarkup rstDirective
+hi def link rstDirective Keyword
+hi def link rstFootnote String
+hi def link rstCitation String
+hi def link rstHyperlinkTarget String
+hi def link rstExDirective String
+hi def link rstSubstitutionDefinition rstDirective
+hi def link rstDelimiter Delimiter
+hi def link rstInterpretedTextOrHyperlinkReference Identifier
+hi def link rstInlineLiteral String
+hi def link rstSubstitutionReference PreProc
+hi def link rstInlineInternalTargets Identifier
+hi def link rstFootnoteReference Identifier
+hi def link rstCitationReference Identifier
+hi def link rstHyperLinkReference Identifier
+hi def link rstStandaloneHyperlink Identifier
+hi def link rstCodeBlock String
+if exists('g:rst_use_emphasis_colors')
+ " TODO: Less arbitrary color selection
+ hi def rstEmphasis ctermfg=13 term=italic cterm=italic gui=italic
+ hi def rstStrongEmphasis ctermfg=1 term=bold cterm=bold gui=bold
+else
+ hi def rstEmphasis term=italic cterm=italic gui=italic
+ hi def rstStrongEmphasis term=bold cterm=bold gui=bold
+endif
+
+let b:current_syntax = "rst"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save