Files
org-vim/runtime/syntax/rst.vim

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

317 lines
12 KiB
VimL
Raw Normal View History

2020-04-10 22:10:56 +02:00
" Vim reST syntax file
2014-10-15 22:51:52 +02:00
" Language: reStructuredText documentation format
" Maintainer: Marshall Ward <marshall.ward@gmail.com>
2014-08-23 15:31:19 +02:00
" Previous Maintainer: Nikolai Weibull <now@bitwi.se>
" Reference: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
2016-08-18 22:54:46 +02:00
" Website: https://github.com/marshallward/vim-restructuredtext
" Latest Revision: 2025-10-13
2005-06-29 22:40:58 +00:00
if exists("b:current_syntax")
2004-06-13 20:20:40 +00:00
finish
endif
2005-06-29 22:40:58 +00:00
let s:cpo_save = &cpo
set cpo&vim
" reStructuredText is case-insensitive
syntax case ignore
2004-06-13 20:20:40 +00:00
2010-01-06 20:54:52 +01:00
syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/
2004-06-13 20:20:40 +00:00
2006-04-10 14:55:34 +00:00
syn cluster rstCruft contains=rstEmphasis,rstStrongEmphasis,
\ rstInterpretedTextOrHyperlinkReference,rstInlineLiteral,
\ rstSubstitutionReference,rstInlineInternalTargets,rstFootnoteReference,
\ rstHyperlinkReference
2004-06-13 20:20:40 +00:00
2006-04-10 14:55:34 +00:00
syn region rstLiteralBlock matchgroup=rstDelimiter
2020-04-10 22:10:56 +02:00
\ start='\(^\z(\s*\).*\)\@<=::\n\s*\n' skip='^\s*$' end='^\(\z1\s\+\)\@!'
2006-04-10 14:55:34 +00:00
\ contains=@NoSpell
2005-06-29 22:40:58 +00:00
2006-04-10 14:55:34 +00:00
syn region rstQuotedLiteralBlock matchgroup=rstDelimiter
\ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)"
\ end='^\z1\@!' contains=@NoSpell
2005-06-29 22:40:58 +00:00
syn region rstDoctestBlock matchgroup=rstDoctestBlockPrompt
2006-04-10 14:55:34 +00:00
\ start='^>>>\s' end='^$'
\ contains=rstDoctestBlockPrompt
syn match rstDoctestBlockPrompt contained '^>>>\s'
2005-06-29 22:40:58 +00:00
2006-04-10 14:55:34 +00:00
syn region rstTable transparent start='^\n\s*+[-=+]\+' end='^$'
\ contains=rstTableLines,@rstCruft
syn match rstTableLines contained display '|\|+\%(=\+\|-\+\)\='
2005-06-29 22:40:58 +00:00
2006-04-10 14:55:34 +00:00
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*\)\@>\)\+\)\@>$'
2005-06-29 22:40:58 +00:00
2006-04-10 14:55:34 +00:00
syn cluster rstDirectives contains=rstFootnote,rstCitation,
\ rstHyperlinkTarget,rstExDirective
2005-06-29 22:40:58 +00:00
2014-08-23 15:31:19 +02:00
syn match rstExplicitMarkup '^\s*\.\.\_s'
\ nextgroup=@rstDirectives,rstSubstitutionDefinition
\ contains=rstComment
2005-06-29 22:40:58 +00:00
2018-07-29 15:07:52 +02:00
" "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:]]\+\)*'
2005-06-29 22:40:58 +00:00
2006-04-10 14:55:34 +00:00
syn keyword rstTodo contained FIXME TODO XXX NOTE
2004-06-13 20:20:40 +00:00
syn region rstComment
\ start='\v^\z(\s*)\.\.(\_s+[\[|_]|\_s+.*::)@!' skip=+^$+ end=/^\(\z1 \)\@!/
\ contains=@Spell,rstTodo
" Note: Order matters for rstCitation and rstFootnote as the regex for
" citations also matches numeric only patterns, e.g. [1], which are footnotes.
" Since we define rstFootnote after rstCitation, it takes precedence, see
" |:syn-define|.
execute 'syn region rstCitation contained matchgroup=rstDirective' .
\ ' start=+\[' . s:ReferenceName . '\]\_s+' .
\ ' skip=+^$+' .
\ ' end=+^\s\@!+ contains=@Spell,@rstCruft'
2006-04-10 14:55:34 +00:00
execute 'syn region rstFootnote contained matchgroup=rstDirective' .
\ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' .
\ ' skip=+^$+' .
\ ' end=+^\s\@!+ contains=@Spell,@rstCruft'
2006-04-10 14:55:34 +00:00
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=@Spell,@rstCruft,rstLiteralBlock,rstExplicitMarkup'
2006-04-10 14:55:34 +00:00
execute 'syn match rstSubstitutionDefinition contained' .
2018-07-29 15:07:52 +02:00
\ ' /|.*|\_s\+/ nextgroup=@rstDirectives'
2006-04-10 14:55:34 +00:00
"" Inline Markup ""
2006-04-10 14:55:34 +00:00
function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right)
2020-04-10 22:10:56 +02:00
" Only escape the first char of a multichar delimiter (e.g. \* inside **)
if a:start[0] == '\'
let first = a:start[0:1]
else
let first = a:start[0]
endif
if a:start != '``'
let rst_contains=' contains=@Spell,rstEscape' . a:name
execute 'syn match rstEscape'.a:name.' +\\\\\|\\'.first.'+'.' contained'
else
let rst_contains=' contains=@Spell'
endif
2020-04-10 22:10:56 +02:00
2006-04-10 14:55:34 +00:00
execute 'syn region rst' . a:name .
\ ' start=+' . a:char_left . '\zs' . a:start .
2007-05-10 19:06:20 +00:00
\ '\ze[^[:space:]' . a:char_right . a:start[strlen(a:start) - 1] . ']+' .
2006-04-10 14:55:34 +00:00
\ a:middle .
2020-04-10 22:10:56 +02:00
\ ' end=+' . a:end . '\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+' .
\ rst_contains
2020-04-10 22:10:56 +02:00
if a:start != '``'
execute 'hi def link rstEscape'.a:name.' Special'
endif
2006-04-10 14:55:34 +00:00
endfunction
function! s:DefineInlineMarkup(name, start, middle, end)
if a:middle == '`'
let middle = ' skip=+\s'.a:middle.'+'
else
let middle = ' skip=+\\\\\|\\' . a:middle . '\|\s' . a:middle . '+'
endif
2006-04-10 14:55:34 +00:00
" Some characters may precede or follow an inline token
2006-04-10 14:55:34 +00:00
call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, "'", "'")
2014-08-23 15:31:19 +02:00
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, '<', '>')
2016-08-18 22:54:46 +02:00
call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '', '')
2006-04-10 14:55:34 +00:00
" TODO: Additional whitespace Unicode characters: Pd, Po, Pi, Pf, Ps
2018-07-29 15:07:52 +02:00
call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '')
2006-04-10 14:55:34 +00:00
execute 'syn match rst' . a:name .
2018-07-29 15:07:52 +02:00
\ ' +\%(^\|\s\|\%ua0\|[''"([{</:]\)\zs' . a:start .
2006-04-10 14:55:34 +00:00
\ '[^[: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', '``', '`', '``')
2006-04-10 14:55:34 +00:00
call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}')
call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`')
2018-07-29 15:07:52 +02:00
" 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
2016-01-15 20:57:49 +01:00
2006-04-10 14:55:34 +00:00
" TODO: Cant remember why these two cant be defined like the ones above.
execute 'syn match rstFootnoteReference contains=@NoSpell' .
2018-07-29 15:07:52 +02:00
\ ' +\%(\s\|^\)\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]_+'
2006-04-10 14:55:34 +00:00
execute 'syn match rstCitationReference contains=@NoSpell' .
2018-07-29 15:07:52 +02:00
\ ' +\%(\s\|^\)\[' . s:ReferenceName . '\]_\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)+'
2006-04-10 14:55:34 +00:00
execute 'syn match rstHyperlinkReference' .
2007-05-10 19:06:20 +00:00
\ ' /\<' . s:ReferenceName . '__\=\ze\%($\|\s\|[''")\]}>/:.,;!?\\-]\)/'
2006-04-10 14:55:34 +00:00
syn match rstStandaloneHyperlink contains=@NoSpell
\ "\<\%(\%(\%(https\=\|file\|ftp\|gopher\)://\|\%(mailto\|news\):\)[^[:space:]'\"<>]\+\|www[[:alnum:]_-]*\.[[:alnum:]_-]\+\.[^[:space:]'\"<>]\+\)[[:alnum:]/]"
" `code` is the standard reST directive for source code.
" `code-block` and `sourcecode` are nearly identical directives in Sphinx.
2012-11-15 21:28:22 +01:00
syn region rstCodeBlock contained matchgroup=rstDirective
2020-04-10 22:10:56 +02:00
\ start=+\%(sourcecode\|code\%(-block\)\=\)::\s*\(\S*\)\?\s*\n\%(\s*:.*:\s*.*\s*\n\)*\n\ze\z(\s\+\)+
2012-11-15 21:28:22 +01:00
\ skip=+^$+
2014-08-23 15:31:19 +02:00
\ end=+^\z1\@!+
2012-11-15 21:28:22 +01:00
\ contains=@NoSpell
syn cluster rstDirectives add=rstCodeBlock
if !exists('g:rst_syntax_code_list')
2018-07-29 15:07:52 +02:00
" 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
2012-11-15 21:28:22 +01:00
endif
2018-07-29 15:07:52 +02:00
for s:filetype in keys(g:rst_syntax_code_list)
2012-11-15 21:28:22 +01:00
unlet! b:current_syntax
2014-10-15 22:51:52 +02:00
" guard against setting 'isk' option which might cause problems (issue #108)
let prior_isk = &l:iskeyword
2018-07-29 15:07:52 +02:00
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\+\)"'
2016-06-17 12:48:11 +02:00
\.' skip=#^$#'
\.' end=#^\z1\@!#'
2018-07-29 15:07:52 +02:00
\.' contains=@NoSpell,@rst'.s:filetype
exe 'syn cluster rstDirectives add=rstDirective'.s:filetype
2014-10-15 22:51:52 +02:00
" reset 'isk' setting, if it has been changed
if &l:iskeyword !=# prior_isk
let &l:iskeyword = prior_isk
endif
unlet! prior_isk
2012-11-15 21:28:22 +01:00
endfor
2018-07-29 15:07:52 +02:00
" Enable top level spell checking
syntax spell toplevel
exe "syn sync minlines=" . get(g:, 'rst_minlines', 50) . " linebreaks=2"
2013-06-06 21:36:40 +02:00
2006-04-10 14:55:34 +00:00
hi def link rstTodo Todo
hi def link rstComment Comment
2012-08-15 17:43:31 +02:00
hi def link rstSections Title
hi def link rstTransition rstSections
2006-04-10 14:55:34 +00:00
hi def link rstLiteralBlock String
hi def link rstQuotedLiteralBlock String
hi def link rstDoctestBlock PreProc
hi def link rstDoctestBlockPrompt rstDelimiter
2006-04-10 14:55:34 +00:00
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
2012-11-15 21:28:22 +01:00
hi def link rstCodeBlock String
2018-07-29 15:07:52 +02:00
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
2004-06-13 20:20:40 +00:00
let b:current_syntax = "rst"
2005-06-29 22:40:58 +00:00
let &cpo = s:cpo_save
unlet s:cpo_save