mirror of
https://github.com/neovim/neovim.git
synced 2024-12-29 14:41:06 -07:00
c8299d15db
runtime(yaml): disable multiline_scalar detection by default
There have been many complaints about Yaml indenting too much, because
it considers values to be multi-line by default, which leads to
unintended indenting for (apparently most) users.
So let's hide this feature behind the new feature flag, keep it
simple and prefer single line value key pairs by default.
If you want the old behaviour, set the following value: >
:let g:yaml_indent_multiline_scalar = 1
If not set, it will indent the same as the previous line.
closes vim/vim#13845
b4eb3f1e44
Co-authored-by: Christian Brabandt <cb@256bit.org>
160 lines
5.6 KiB
VimL
160 lines
5.6 KiB
VimL
" Vim indent file
|
|
" Language: YAML
|
|
" Maintainer: Nikolai Pavlov <zyx.vim@gmail.com>
|
|
" Last Updates: Lukas Reineke, "lacygoill"
|
|
" Last Change: 2022 Jun 17
|
|
" 2024 Feb 29 disable mulitline indent by default (The Vim project)
|
|
|
|
" Only load this indent file when no other was loaded.
|
|
if exists('b:did_indent')
|
|
finish
|
|
endif
|
|
|
|
let b:did_indent = 1
|
|
|
|
setlocal indentexpr=GetYAMLIndent(v:lnum)
|
|
setlocal indentkeys=!^F,o,O,0#,0},0],<:>,0-
|
|
setlocal nosmartindent
|
|
|
|
let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<'
|
|
|
|
" Only define the function once.
|
|
if exists('*GetYAMLIndent')
|
|
finish
|
|
endif
|
|
|
|
let s:save_cpo = &cpo
|
|
set cpo&vim
|
|
|
|
function s:FindPrevLessIndentedLine(lnum, ...)
|
|
let prevlnum = prevnonblank(a:lnum-1)
|
|
let curindent = a:0 ? a:1 : indent(a:lnum)
|
|
while prevlnum
|
|
\ && indent(prevlnum) >= curindent
|
|
\ && getline(prevlnum) !~# '^\s*#'
|
|
let prevlnum = prevnonblank(prevlnum-1)
|
|
endwhile
|
|
return prevlnum
|
|
endfunction
|
|
|
|
function s:FindPrevLEIndentedLineMatchingRegex(lnum, regex)
|
|
let plilnum = s:FindPrevLessIndentedLine(a:lnum, indent(a:lnum)+1)
|
|
while plilnum && getline(plilnum) !~# a:regex
|
|
let plilnum = s:FindPrevLessIndentedLine(plilnum)
|
|
endwhile
|
|
return plilnum
|
|
endfunction
|
|
|
|
let s:mapkeyregex = '\v^\s*\#@!\S@=%(\''%([^'']|\''\'')*\''' ..
|
|
\ '|\"%([^"\\]|\\.)*\"' ..
|
|
\ '|%(%(\:\ )@!.)*)\:%(\ |$)'
|
|
let s:liststartregex = '\v^\s*%(\-%(\ |$))'
|
|
|
|
let s:c_ns_anchor_char = '\v%([\n\r\uFEFF \t,[\]{}]@!\p)'
|
|
let s:c_ns_anchor_name = s:c_ns_anchor_char .. '+'
|
|
let s:c_ns_anchor_property = '\v\&' .. s:c_ns_anchor_name
|
|
|
|
let s:ns_word_char = '\v[[:alnum:]_\-]'
|
|
let s:ns_tag_char = '\v%(\x\x|' .. s:ns_word_char .. '|[#/;?:@&=+$.~*''()])'
|
|
let s:c_named_tag_handle = '\v\!' .. s:ns_word_char .. '+\!'
|
|
let s:c_secondary_tag_handle = '\v\!\!'
|
|
let s:c_primary_tag_handle = '\v\!'
|
|
let s:c_tag_handle = '\v%(' .. s:c_named_tag_handle.
|
|
\ '|' .. s:c_secondary_tag_handle.
|
|
\ '|' .. s:c_primary_tag_handle .. ')'
|
|
let s:c_ns_shorthand_tag = '\v' .. s:c_tag_handle .. s:ns_tag_char .. '+'
|
|
let s:c_non_specific_tag = '\v\!'
|
|
let s:ns_uri_char = '\v%(\x\x|' .. s:ns_word_char .. '\v|[#/;?:@&=+$,.!~*''()[\]])'
|
|
let s:c_verbatim_tag = '\v\!\<' .. s:ns_uri_char.. '+\>'
|
|
let s:c_ns_tag_property = '\v' .. s:c_verbatim_tag.
|
|
\ '\v|' .. s:c_ns_shorthand_tag.
|
|
\ '\v|' .. s:c_non_specific_tag
|
|
|
|
let s:block_scalar_header = '\v[|>]%([+-]?[1-9]|[1-9]?[+-])?'
|
|
|
|
function GetYAMLIndent(lnum)
|
|
if a:lnum == 1 || !prevnonblank(a:lnum-1)
|
|
return 0
|
|
endif
|
|
|
|
let prevlnum = prevnonblank(a:lnum-1)
|
|
let previndent = indent(prevlnum)
|
|
|
|
let line = getline(a:lnum)
|
|
if line =~# '^\s*#' && getline(a:lnum-1) =~# '^\s*#'
|
|
" Comment blocks should have identical indent
|
|
return previndent
|
|
elseif line =~# '^\s*[\]}]'
|
|
" Lines containing only closing braces should have previous indent
|
|
return indent(s:FindPrevLessIndentedLine(a:lnum))
|
|
endif
|
|
|
|
" Ignore comment lines when calculating indent
|
|
while getline(prevlnum) =~# '^\s*#'
|
|
let prevlnum = prevnonblank(prevlnum-1)
|
|
if !prevlnum
|
|
return previndent
|
|
endif
|
|
endwhile
|
|
|
|
let prevline = getline(prevlnum)
|
|
let previndent = indent(prevlnum)
|
|
|
|
" Any examples below assume that shiftwidth=2
|
|
if prevline =~# '\v[{[:]$|[:-]\ [|>][+\-]?%(\s+\#.*|\s*)$'
|
|
" Mapping key:
|
|
" nested mapping: ...
|
|
"
|
|
" - {
|
|
" key: [
|
|
" list value
|
|
" ]
|
|
" }
|
|
"
|
|
" - |-
|
|
" Block scalar without indentation indicator
|
|
return previndent+shiftwidth()
|
|
elseif prevline =~# '\v[:-]\ [|>]%(\d+[+\-]?|[+\-]?\d+)%(\#.*|\s*)$'
|
|
" - |+2
|
|
" block scalar with indentation indicator
|
|
"#^^ indent+2, not indent+shiftwidth
|
|
return previndent + str2nr(matchstr(prevline,
|
|
\'\v([:-]\ [|>])@<=[+\-]?\d+%([+\-]?%(\s+\#.*|\s*)$)@='))
|
|
elseif prevline =~# '\v\"%([^"\\]|\\.)*\\$'
|
|
" "Multiline string \
|
|
" with escaped end"
|
|
let qidx = match(prevline, '\v\"%([^"\\]|\\.)*\\')
|
|
return virtcol([prevlnum, qidx+1])
|
|
elseif line =~# s:liststartregex
|
|
" List line should have indent equal to previous list line unless it was
|
|
" caught by one of the previous rules
|
|
return indent(s:FindPrevLEIndentedLineMatchingRegex(a:lnum,
|
|
\ s:liststartregex))
|
|
elseif line =~# s:mapkeyregex
|
|
" Same for line containing mapping key
|
|
let prevmapline = s:FindPrevLEIndentedLineMatchingRegex(a:lnum,
|
|
\ s:mapkeyregex)
|
|
if getline(prevmapline) =~# '^\s*- '
|
|
return indent(prevmapline) + 2
|
|
else
|
|
return indent(prevmapline)
|
|
endif
|
|
elseif get(g:, 'yaml_indent_multiline_scalar', 0) &&
|
|
\ prevline =~# '^\s*- '
|
|
" - List with
|
|
" multiline scalar
|
|
return previndent+2
|
|
elseif get(g:, 'yaml_indent_multiline_scalar', 0) &&
|
|
\ prevline =~# s:mapkeyregex .. '\v\s*%(%(' .. s:c_ns_tag_property ..
|
|
\ '\v|' .. s:c_ns_anchor_property ..
|
|
\ '\v|' .. s:block_scalar_header ..
|
|
\ '\v)%(\s+|\s*%(\#.*)?$))*'
|
|
" Mapping with: value
|
|
" that is multiline scalar
|
|
return previndent+shiftwidth()
|
|
endif
|
|
return previndent
|
|
endfunction
|
|
|
|
let &cpo = s:save_cpo
|