From 7455c5ce88c4c3ee7ddd3ea8975fafec310d5a9b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:41:51 +0800 Subject: [PATCH 01/10] vim-patch:0940465: runtime(rst): Fix doctest block syntax A doctest block usually spans multiple lines, e.g. >>> print('this is a Doctest block') this is a Doctest block Remove ``oneline`` argument to syntax region as this requirement is not met. Consequently, also remove ``display`` as the prerequisite (the syntax region is on a single line) is no longer met. ---- Recognise '>>>' inside doctest blocks Recognise subsequent '>>>' prompts in doctest blocks, e.g. >>> print('this is a Doctest block') this is a Doctest block >>> print('this is a second Doctest block') this is a second Doctest block A doctest block usually spans multiple lines, e.g. >>> print('this is a Doctest block') this is a Doctest block related: vim/vim#18566 https://github.com/vim/vim/commit/0940465866486db47baa1fe85ebefb6e6fe54612 Co-authored-by: Kirk Roemer <91125534+kirk-roemer@users.noreply.github.com> --- runtime/syntax/rst.vim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index a90c90be21..c43bda5892 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -28,8 +28,11 @@ syn region rstQuotedLiteralBlock matchgroup=rstDelimiter \ start="::\_s*\n\ze\z([!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]\)" \ end='^\z1\@!' contains=@NoSpell -syn region rstDoctestBlock oneline display matchgroup=rstDelimiter +syn region rstDoctestBlock matchgroup=rstDoctestBlockPrompt \ start='^>>>\s' end='^$' + \ contains=rstDoctestBlockPrompt + +syn match rstDoctestBlockPrompt contained '^>>>\s' syn region rstTable transparent start='^\n\s*+[-=+]\+' end='^$' \ contains=rstTableLines,@rstCruft @@ -256,6 +259,7 @@ hi def link rstTransition rstSections hi def link rstLiteralBlock String hi def link rstQuotedLiteralBlock String hi def link rstDoctestBlock PreProc +hi def link rstDoctestBlockPrompt rstDelimiter hi def link rstTableLines rstDelimiter hi def link rstSimpleTableLines rstTableLines hi def link rstExplicitMarkup rstDirective From dbddd5989acf55a30d3ff8fa4243bf2560238ca3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:42:03 +0800 Subject: [PATCH 02/10] vim-patch:310082f: runtime(rst): Add support for rst_minlines Following the approach used in other syntax definitions, add support for defining the "syntax sync minlines=..." values for rst files in the users' ~/.vimrc files, to allow the users to adjust that value in case syntax highlighting stops working for some of the files they edit. related: vim/vim#18566 https://github.com/vim/vim/commit/310082f3cfab92a28a635b0dc2a972c7f1fa5b92 Co-authored-by: Dragan Simic --- runtime/doc/syntax.txt | 3 +++ runtime/syntax/rst.vim | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 8fba2bc032..baafd8c00a 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2892,6 +2892,9 @@ To enable folding of sections: > Note that folding can cause performance issues on some platforms. +The minimum line syntax sync is set to 50. To modify this number: > + let rst_minlines = 100 + REXX *ft-rexx-syntax* diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index c43bda5892..34e43932b6 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -246,11 +246,11 @@ for s:filetype in keys(g:rst_syntax_code_list) unlet! prior_isk endfor + " Enable top level spell checking syntax spell toplevel -" TODO: Use better syncing. -syn sync minlines=50 linebreaks=2 +exe "syn sync minlines=" . get(g:, 'rst_minlines', 50) . " linebreaks=2" hi def link rstTodo Todo hi def link rstComment Comment From 6b006a03c4053c09e4aa00d8cd4b6e2e63a7ae90 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:43:06 +0800 Subject: [PATCH 03/10] vim-patch:47949b4: runtime(rst): Fix highlights nested in directive body The leading two dots of a RST directive gets matched by rstExplicitMarkup group first, and then the directive name and directive body will be matched by the groups contained in rstDirectives cluster in order. The rstExDirective group in rstDiretives matches any RST directives other than footnote, citation and hyperlink target, therefore admonition and code block will be matched by rstExDirective. This fix has rstExDirective contain rstExplicitMarkup so as to enable recursive RST directives match. The interpreted texts enclosed in quotes are not highlighted within a RST directive body, because the rstCruft cluster contains a non-existing rstInterpretedText group.It should be renamed to rstInterpretedTextOrHyperlinkReference which is defined in a DefineInlineMarkup function call. related: vim/vim#18566 https://github.com/vim/vim/commit/47949b4b46965fdabbbe84cbe14027890d4ed3b8 Co-authored-by: Minjie Xu --- runtime/syntax/rst.vim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 34e43932b6..4b9379f5e6 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -17,8 +17,9 @@ syn case ignore syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/ syn cluster rstCruft contains=rstEmphasis,rstStrongEmphasis, - \ rstInterpretedText,rstInlineLiteral,rstSubstitutionReference, - \ rstInlineInternalTargets,rstFootnoteReference,rstHyperlinkReference + \ rstInterpretedTextOrHyperlinkReference,rstInlineLiteral, + \ rstSubstitutionReference,rstInlineInternalTargets,rstFootnoteReference, + \ rstHyperlinkReference syn region rstLiteralBlock matchgroup=rstDelimiter \ start='\(^\z(\s*\).*\)\@<=::\n\s*\n' skip='^\s*$' end='^\(\z1\s\+\)\@!' @@ -87,7 +88,7 @@ syn region rstHyperlinkTarget matchgroup=rstDirective execute 'syn region rstExDirective contained matchgroup=rstDirective' . \ ' start=+' . s:ReferenceName . '::\_s+' . \ ' skip=+^$+' . - \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock' + \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock,rstExplicitMarkup' execute 'syn match rstSubstitutionDefinition contained' . \ ' /|.*|\_s\+/ nextgroup=@rstDirectives' From 2b2a297bf16880c67b8652ac2cdf0a244d436ca0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:43:45 +0800 Subject: [PATCH 04/10] vim-patch:4e9f16d: runtime(rst): Correctly end nested comments Previously, a comment in a directive block would incorrectly mark all subsequent lines in the directive block as comment, because the syn-region did not check the leading indent. related: vim/vim#18566 https://github.com/vim/vim/commit/4e9f16dd1ef8b48d4a37fde479adde1758796871 Co-authored-by: Antony Lee --- runtime/syntax/rst.vim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 4b9379f5e6..8094d8771b 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -52,7 +52,8 @@ syn cluster rstDirectives contains=rstFootnote,rstCitation, \ rstHyperlinkTarget,rstExDirective syn match rstExplicitMarkup '^\s*\.\.\_s' - \ nextgroup=@rstDirectives,rstComment,rstSubstitutionDefinition + \ nextgroup=@rstDirectives,rstSubstitutionDefinition + \ contains=rstComment " "Simple reference names are single words consisting of alphanumerics plus " isolated (no two adjacent) internal hyphens, underscores, periods, colons @@ -61,10 +62,10 @@ let s:ReferenceName = '[[:alnum:]]\%([-_.:+]\?[[:alnum:]]\+\)*' syn keyword rstTodo contained FIXME TODO XXX NOTE -execute 'syn region rstComment contained' . - \ ' start=/.*/' - \ ' skip=+^$+' . - \ ' end=/^\s\@!/ contains=rstTodo' +syn region rstComment + \ start='\v^\z(\s*)\.\.(\_s+[\[|_]|\_s+.*::)@!' skip=+^$+ end=/^\(\z1 \)\@!/ + \ contains=@Spell,rstTodo + execute 'syn region rstFootnote contained matchgroup=rstDirective' . \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' . From 08e29ec4a148aece61a857c41d2f244b18122743 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:06 +0800 Subject: [PATCH 05/10] vim-patch:5485827: runtime(rst): Recognise numeric footnotes [1] correctly The markup for footonotes [1] and citations [2] are almost identical. The difference is that footnotes allow numeric values but citations allow every valid reference name except numeric values. The regex for matching citations currently only checks for valid reference names but does not exclude number-only labels, thus also matches numeric footnotes. To match such footnotes, e.g. ``[1]`` define the syntax rule for footnotes after the syntax rule for citations so it gets higher precedence and matches first. [1] https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#footnotes [2] https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#citations related: vim/vim#18566 https://github.com/vim/vim/commit/5485827c5f872884dab83607e89562c8db4899c4 Co-authored-by: Kirk Roemer <91125534+kirk-roemer@users.noreply.github.com> --- runtime/syntax/rst.vim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 8094d8771b..308ae5d68f 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -66,17 +66,20 @@ 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' 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\@!+ From 263d0f86b4604bd5ca325cfd1004f0f06a872074 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:17 +0800 Subject: [PATCH 06/10] vim-patch:d7fb4cd: runtime(rst): Inline literal escape support Escape character support was disabled for inline literals, which are handled separately from standard inline highlights, in that escape characters are unsupported. related: vim/vim#18566 https://github.com/vim/vim/commit/d7fb4cd2f8349670920ce15c28a1920b9f94d79a Co-authored-by: Marshall Ward --- runtime/syntax/rst.vim | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 308ae5d68f..9fab02839a 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -105,23 +105,33 @@ function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_righ let first = a:start[0] endif - execute 'syn match rstEscape'.a:name.' +\\\\\|\\'.first.'+'.' contained' + if a:start != '``' + let rst_contains=' contains=rstEscape' . a:name + execute 'syn match rstEscape'.a:name.' +\\\\\|\\'.first.'+'.' contained' + else + let rst_contains='' + endif 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=+' . a:end . '\ze\%($\|\s\|[''"’)\]}>/:.,;!?\\-]\)+' . - \ ' contains=rstEscape' . a:name + \ rst_contains - execute 'hi def link rstEscape'.a:name.' Special' + if a:start != '``' + execute 'hi def link rstEscape'.a:name.' Special' + endif endfunction function! s:DefineInlineMarkup(name, start, middle, end) - let middle = a:middle != "" ? - \ (' skip=+\\\\\|\\' . a:middle . '\|\s' . a:middle . '+') : - \ "" + if a:middle == '`' + let middle = ' skip=+\s'.a:middle.'+' + else + let middle = ' skip=+\\\\\|\\' . a:middle . '\|\s' . a:middle . '+' + endif + " Some characters may precede or follow an inline token 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, '(', ')') @@ -129,8 +139,8 @@ function! s:DefineInlineMarkup(name, start, middle, 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 + " TODO: Additional whitespace Unicode characters: Pd, Po, Pi, Pf, Ps call s:DefineOneInlineMarkup(a:name, a:start, middle, a:end, '\%(^\|\s\|\%ua0\|[/:]\)', '') execute 'syn match rst' . a:name . @@ -144,7 +154,7 @@ endfunction call s:DefineInlineMarkup('Emphasis', '\*', '\*', '\*') call s:DefineInlineMarkup('StrongEmphasis', '\*\*', '\*', '\*\*') call s:DefineInlineMarkup('InterpretedTextOrHyperlinkReference', '`', '`', '`_\{0,2}') -call s:DefineInlineMarkup('InlineLiteral', '``', "", '``') +call s:DefineInlineMarkup('InlineLiteral', '``', '`', '``') call s:DefineInlineMarkup('SubstitutionReference', '|', '|', '|_\{0,2}') call s:DefineInlineMarkup('InlineInternalTargets', '_`', '`', '`') From d6a9679b46043df01f5798232b28afac24ed5746 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:26 +0800 Subject: [PATCH 07/10] vim-patch:a70f346: runtime(rst): Enable spell checking for more syntax constructs Enable spell checking for more recognised constructs: * comments * footnotes * citations * directives * inline markup (*text*, **text**, ...) related: vim/vim#18566 https://github.com/vim/vim/commit/a70f3467069eaf40a037ad74aa4f1ccb44565271 Co-authored-by: Kirk Roemer <91125534+kirk-roemer@users.noreply.github.com> --- runtime/syntax/rst.vim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index 9fab02839a..bb9a0b3a46 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -78,7 +78,7 @@ execute 'syn region rstCitation contained matchgroup=rstDirective' . execute 'syn region rstFootnote contained matchgroup=rstDirective' . \ ' start=+\[\%(\d\+\|#\%(' . s:ReferenceName . '\)\=\|\*\)\]\_s+' . \ ' skip=+^$+' . - \ ' end=+^\s\@!+ contains=@rstCruft,@NoSpell' + \ ' end=+^\s\@!+ contains=@Spell,@rstCruft' syn region rstHyperlinkTarget contained matchgroup=rstDirective \ start='_\%(_\|[^:\\]*\%(\\.[^:\\]*\)*\):\_s' skip=+^$+ end=+^\s\@!+ @@ -92,7 +92,7 @@ syn region rstHyperlinkTarget matchgroup=rstDirective execute 'syn region rstExDirective contained matchgroup=rstDirective' . \ ' start=+' . s:ReferenceName . '::\_s+' . \ ' skip=+^$+' . - \ ' end=+^\s\@!+ contains=@rstCruft,rstLiteralBlock,rstExplicitMarkup' + \ ' end=+^\s\@!+ contains=@Spell,@rstCruft,rstLiteralBlock,rstExplicitMarkup' execute 'syn match rstSubstitutionDefinition contained' . \ ' /|.*|\_s\+/ nextgroup=@rstDirectives' @@ -106,10 +106,10 @@ function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_righ endif if a:start != '``' - let rst_contains=' contains=rstEscape' . a:name + let rst_contains=' contains=@Spell,rstEscape' . a:name execute 'syn match rstEscape'.a:name.' +\\\\\|\\'.first.'+'.' contained' else - let rst_contains='' + let rst_contains=' contains=@Spell' endif execute 'syn region rst' . a:name . From 6a6ba5c567e0928668a3b2bc0774a82f665c02ae Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:35 +0800 Subject: [PATCH 08/10] vim-patch:46d8697: runtime(rst): Style update Minor style and whitespace changes to the reST syntax file, to sync with the development branch. related: vim/vim#18566 https://github.com/vim/vim/commit/46d86979a9208e0842e1d8cfc0341737efc95e75 Co-authored-by: Marshall Ward --- runtime/syntax/rst.vim | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/runtime/syntax/rst.vim b/runtime/syntax/rst.vim index bb9a0b3a46..9584947df5 100644 --- a/runtime/syntax/rst.vim +++ b/runtime/syntax/rst.vim @@ -2,8 +2,9 @@ " Language: reStructuredText documentation format " Maintainer: Marshall Ward " Previous Maintainer: Nikolai Weibull +" Reference: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html " Website: https://github.com/marshallward/vim-restructuredtext -" Latest Revision: 2020-03-31 +" Latest Revision: 2025-10-13 if exists("b:current_syntax") finish @@ -12,7 +13,8 @@ endif let s:cpo_save = &cpo set cpo&vim -syn case ignore +" reStructuredText is case-insensitive +syntax case ignore syn match rstTransition /^[=`:.'"~^_*+#-]\{4,}\s*$/ @@ -97,6 +99,9 @@ execute 'syn region rstExDirective contained matchgroup=rstDirective' . execute 'syn match rstSubstitutionDefinition contained' . \ ' /|.*|\_s\+/ nextgroup=@rstDirectives' + +"" Inline Markup "" + function! s:DefineOneInlineMarkup(name, start, middle, end, char_left, char_right) " Only escape the first char of a multichar delimiter (e.g. \* inside **) if a:start[0] == '\' @@ -190,6 +195,8 @@ execute 'syn match rstHyperlinkReference' . 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. syn region rstCodeBlock contained matchgroup=rstDirective \ start=+\%(sourcecode\|code\%(-block\)\=\)::\s*\(\S*\)\?\s*\n\%(\s*:.*:\s*.*\s*\n\)*\n\ze\z(\s\+\)+ \ skip=+^$+ From 1ccbaa6c251b6dffa945b4a08043c0626572f6b0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:45 +0800 Subject: [PATCH 09/10] vim-patch:5ffb23c: runtime(rst): Update b:undo_ftplugin variable The value of this variable is evaluated when the 'filetype' option is changed and should be a command string that will undo any configuration changes that the plugin has made. See :help undo_indent for details related: vim/vim#18566 https://github.com/vim/vim/commit/5ffb23c967189585b74bb9a031caf3b6ef7cce9c Co-authored-by: Doug Kearns --- runtime/ftplugin/rst.vim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/runtime/ftplugin/rst.vim b/runtime/ftplugin/rst.vim index c88e8f2580..887f64bb4c 100644 --- a/runtime/ftplugin/rst.vim +++ b/runtime/ftplugin/rst.vim @@ -4,6 +4,7 @@ " Original Maintainer: Nikolai Weibull " Website: https://github.com/marshallward/vim-restructuredtext " Latest Revision: 2020-03-31 +" 2025 Oct 13 by Vim project: update b:undo_ftplugin #18566 if exists("b:did_ftplugin") finish @@ -18,7 +19,7 @@ if !exists('g:rst_fold_enabled') let g:rst_fold_enabled = 0 endif -let b:undo_ftplugin = "setl com< cms< et< fo<" +let b:undo_ftplugin = "setlocal comments< commentstring< expandtab< formatoptions<" setlocal comments=fb:.. commentstring=..\ %s expandtab setlocal formatoptions+=tcroql @@ -32,15 +33,17 @@ setlocal formatoptions+=tcroql if exists("g:rst_style") && g:rst_style != 0 setlocal expandtab shiftwidth=3 softtabstop=3 tabstop=8 + let b:undo_ftplugin .= " | setlocal softtabstop< shiftwidth< tabstop<" endif -if g:rst_fold_enabled != 0 && has('patch-7.3.867') " Introduced the TextChanged event. +if g:rst_fold_enabled != 0 setlocal foldmethod=expr setlocal foldexpr=RstFold#GetRstFold() setlocal foldtext=RstFold#GetRstFoldText() augroup RstFold autocmd TextChanged,InsertLeave unlet! b:RstFoldCache augroup END + let b:undo_ftplugin .= " | setlocal foldexpr< foldmethod< foldtext<" endif let &cpo = s:cpo_save From c5d85646eb61a3bd7d4f7754f31a5538b505008a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 14 Oct 2025 10:44:55 +0800 Subject: [PATCH 10/10] vim-patch:64c8105: runtime(rst): Preserve indentation of directives This patch preserves indentation in comments. It work by removing the explicit 3-space indentation and replaces with with an expression which uses the current value with a minimum of three spaces. Discussed in the mailing list: https://groups.google.com/g/vim_dev/c/rn8ZLDrCbYU Thanks to Friedrich Romstedt for reporting and Christian Brabandt for investigating the issue. closes: vim/vim#18566 https://github.com/vim/vim/commit/64c8105867ae6342b632246ac5430a59521e740d Co-authored-by: Marshall Ward --- runtime/indent/rst.vim | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/runtime/indent/rst.vim b/runtime/indent/rst.vim index e3c10865a6..e10079213b 100644 --- a/runtime/indent/rst.vim +++ b/runtime/indent/rst.vim @@ -4,13 +4,18 @@ " Maintainer: Marshall Ward " Previous Maintainer: Nikolai Weibull " Latest Revision: 2020-03-31 -" 2023 Aug 28 by Vim Project (undo_indent) +" 2023 Aug 28 by Vim Project (undo_indent) +" 2025 Oct 13 by Vim project: preserve indentation #18566 if exists("b:did_indent") finish endif let b:did_indent = 1 +" Save and modify cpoptions +let s:save_cpo = &cpo +set cpo&vim + setlocal indentexpr=GetRSTIndent() setlocal indentkeys=!^F,o,O setlocal nosmartindent @@ -27,7 +32,8 @@ let s:note_pattern = '^\.\. ' function! s:get_paragraph_start() let paragraph_mark_start = getpos("'{")[1] - return getline(paragraph_mark_start) =~ '\S' ? paragraph_mark_start : paragraph_mark_start + 1 + return getline(paragraph_mark_start) =~ + \ '\S' ? paragraph_mark_start : paragraph_mark_start + 1 endfunction function GetRSTIndent() @@ -42,7 +48,7 @@ function GetRSTIndent() let psnum = s:get_paragraph_start() if psnum != 0 if getline(psnum) =~ s:note_pattern - let ind = 3 + let ind = max([3, ind]) endif endif @@ -75,3 +81,7 @@ function GetRSTIndent() return ind endfunction + +" Restore 'cpoptions' +let &cpo = s:save_cpo +unlet s:save_cpo