| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | " Vim indent file | 
					
						
							| 
									
										
										
										
											2020-06-07 21:07:18 +02:00
										 |  |  | " Language:	YAML | 
					
						
							|  |  |  | " Maintainer:	Nikolai Pavlov <zyx.vim@gmail.com> | 
					
						
							| 
									
										
										
										
											2022-09-04 17:45:43 +01:00
										 |  |  | " Last Updates:	Lukas Reineke, "lacygoill" | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | " Last Change:	2022 Jun 17 | 
					
						
							| 
									
										
										
										
											2024-08-15 22:29:47 +02:00
										 |  |  | " 2024 Feb 29 by Vim project: disable mulitline indent by default | 
					
						
							|  |  |  | " 2024 Aug 14 by Vim project: fix re-indenting when commenting out lines | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | " 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) | 
					
						
							| 
									
										
										
										
											2024-08-15 22:29:47 +02:00
										 |  |  | setlocal indentkeys=!^F,o,O,0},0],<:>,0- | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | setlocal nosmartindent | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " Only define the function once. | 
					
						
							|  |  |  | if exists('*GetYAMLIndent') | 
					
						
							|  |  |  |     finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-25 21:14:57 +01:00
										 |  |  | let s:save_cpo = &cpo | 
					
						
							|  |  |  | set cpo&vim | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | function s:FindPrevLessIndentedLine(lnum, ...) | 
					
						
							|  |  |  |     let prevlnum = prevnonblank(a:lnum-1) | 
					
						
							|  |  |  |     let curindent = a:0 ? a:1 : indent(a:lnum) | 
					
						
							|  |  |  |     while           prevlnum | 
					
						
							| 
									
										
										
										
											2022-09-04 17:45:43 +01:00
										 |  |  |                 \ && indent(prevlnum) >=  curindent | 
					
						
							|  |  |  |                 \ && getline(prevlnum) !~# '^\s*#' | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  |         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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | let s:mapkeyregex = '\v^\s*\#@!\S@=%(\''%([^'']|\''\'')*\''' .. | 
					
						
							|  |  |  |                 \                 '|\"%([^"\\]|\\.)*\"' .. | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  |                 \                 '|%(%(\:\ )@!.)*)\:%(\ |$)' | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | let s:liststartregex = '\v^\s*%(\-%(\ |$))' | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  | let s:c_ns_anchor_char = '\v%([\n\r\uFEFF \t,[\]{}]@!\p)' | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | let s:c_ns_anchor_name = s:c_ns_anchor_char .. '+' | 
					
						
							|  |  |  | let s:c_ns_anchor_property =  '\v\&' .. s:c_ns_anchor_name | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | let s:ns_word_char = '\v[[:alnum:]_\-]' | 
					
						
							| 
									
										
										
										
											2022-09-04 17:45:43 +01:00
										 |  |  | let s:ns_tag_char  = '\v%(\x\x|' .. s:ns_word_char .. '|[#/;?:@&=+$.~*''()])' | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | let s:c_named_tag_handle     = '\v\!' .. s:ns_word_char .. '+\!' | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  | let s:c_secondary_tag_handle = '\v\!\!' | 
					
						
							|  |  |  | let s:c_primary_tag_handle   = '\v\!' | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | 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 .. '+' | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  | let s:c_non_specific_tag = '\v\!' | 
					
						
							| 
									
										
										
										
											2022-09-04 17:45:43 +01:00
										 |  |  | let s:ns_uri_char  = '\v%(\x\x|' .. s:ns_word_char .. '\v|[#/;?:@&=+$,.!~*''()[\]])' | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | let s:block_scalar_header = '\v[|>]%([+-]?[1-9]|[1-9]?[+-])?' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2017-06-13 18:12:01 +02:00
										 |  |  |         return previndent+shiftwidth() | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  |     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 | 
					
						
							| 
									
										
										
										
											2015-09-25 20:34:21 +02:00
										 |  |  |         let prevmapline = s:FindPrevLEIndentedLineMatchingRegex(a:lnum, | 
					
						
							|  |  |  |                     \                                           s:mapkeyregex) | 
					
						
							|  |  |  |         if getline(prevmapline) =~# '^\s*- ' | 
					
						
							|  |  |  |             return indent(prevmapline) + 2 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             return indent(prevmapline) | 
					
						
							|  |  |  |         endif | 
					
						
							| 
									
										
										
										
											2024-02-29 17:23:51 +01:00
										 |  |  |     elseif get(g:, 'yaml_indent_multiline_scalar', 0) && | 
					
						
							|  |  |  |         \  prevline =~# '^\s*- ' | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  |         " - List with | 
					
						
							|  |  |  |         "   multiline scalar | 
					
						
							|  |  |  |         return previndent+2 | 
					
						
							| 
									
										
										
										
											2024-02-29 17:23:51 +01:00
										 |  |  |     elseif get(g:, 'yaml_indent_multiline_scalar', 0) && | 
					
						
							|  |  |  |         \ prevline =~# s:mapkeyregex .. '\v\s*%(%(' .. s:c_ns_tag_property .. | 
					
						
							| 
									
										
										
										
											2022-06-20 11:17:32 +01:00
										 |  |  |                 \                              '\v|' .. s:c_ns_anchor_property .. | 
					
						
							|  |  |  |                 \                              '\v|' .. s:block_scalar_header .. | 
					
						
							| 
									
										
										
										
											2016-08-16 18:33:43 +02:00
										 |  |  |                 \                             '\v)%(\s+|\s*%(\#.*)?$))*' | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  |         " Mapping with: value | 
					
						
							|  |  |  |         "     that is multiline scalar | 
					
						
							| 
									
										
										
										
											2017-06-13 18:12:01 +02:00
										 |  |  |         return previndent+shiftwidth() | 
					
						
							| 
									
										
										
										
											2012-12-05 19:01:43 +01:00
										 |  |  |     endif | 
					
						
							|  |  |  |     return previndent | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let &cpo = s:save_cpo |