| 
									
										
										
										
											2019-10-26 19:53:45 +02:00
										 |  |  | " Vim indent file | 
					
						
							|  |  |  | " Language:		Meson | 
					
						
							|  |  |  | " License:		VIM License | 
					
						
							|  |  |  | " Maintainer:		Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 
					
						
							| 
									
										
										
										
											2021-05-16 12:39:47 +02:00
										 |  |  | "	        	Liam Beguin <liambeguin@gmail.com> | 
					
						
							| 
									
										
										
										
											2019-10-26 19:53:45 +02:00
										 |  |  | " Original Authors:	David Bustos <bustos@caltech.edu> | 
					
						
							|  |  |  | "			Bram Moolenaar <Bram@vim.org> | 
					
						
							|  |  |  | " Last Change:		2019 Oct 18 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " Only load this indent file when no other was loaded. | 
					
						
							|  |  |  | if exists("b:did_indent") | 
					
						
							|  |  |  |   finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | let b:did_indent = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " Some preliminary settings | 
					
						
							|  |  |  | setlocal nolisp		" Make sure lisp indenting doesn't supersede us | 
					
						
							|  |  |  | setlocal autoindent	" indentexpr isn't much help otherwise | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setlocal indentexpr=GetMesonIndent(v:lnum) | 
					
						
							|  |  |  | setlocal indentkeys+==elif,=else,=endforeach,=endif,0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 20:27:04 +00:00
										 |  |  | let b:undo_indent = "setl ai< inde< indk< lisp<" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 19:53:45 +02:00
										 |  |  | " Only define the function once. | 
					
						
							|  |  |  | if exists("*GetMesonIndent") | 
					
						
							|  |  |  |   finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | let s:keepcpo= &cpo | 
					
						
							|  |  |  | set cpo&vim | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " Come here when loading the script the first time. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let s:maxoff = 50	" maximum number of lines to look backwards for () | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function GetMesonIndent(lnum) | 
					
						
							|  |  |  |   echom getline(line(".")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If this line is explicitly joined: If the previous line was also joined, | 
					
						
							|  |  |  |   " line it up with that one, otherwise add two 'shiftwidth' | 
					
						
							|  |  |  |   if getline(a:lnum - 1) =~ '\\$' | 
					
						
							|  |  |  |     if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$' | 
					
						
							|  |  |  |       return indent(a:lnum - 1) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |     return indent(a:lnum - 1) + (exists("g:mesonindent_continue") ? eval(g:mesonindent_continue) : (shiftwidth() * 2)) | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If the start of the line is in a string don't change the indent. | 
					
						
							|  |  |  |   if has('syntax_items') | 
					
						
							|  |  |  | 	\ && synIDattr(synID(a:lnum, 1, 1), "name") =~ "String$" | 
					
						
							|  |  |  |     return -1 | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " Search backwards for the previous non-empty line. | 
					
						
							|  |  |  |   let plnum = prevnonblank(v:lnum - 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if plnum == 0 | 
					
						
							|  |  |  |     " This is the first non-empty line, use zero indent. | 
					
						
							|  |  |  |     return 0 | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If the previous line is inside parenthesis, use the indent of the starting | 
					
						
							|  |  |  |   " line. | 
					
						
							|  |  |  |   " Trick: use the non-existing "dummy" variable to break out of the loop when | 
					
						
							|  |  |  |   " going too far back. | 
					
						
							|  |  |  |   call cursor(plnum, 1) | 
					
						
							|  |  |  |   let parlnum = searchpair('(\|{\|\[', '', ')\|}\|\]', 'nbW', | 
					
						
							|  |  |  | 	  \ "line('.') < " . (plnum - s:maxoff) . " ? dummy :" | 
					
						
							|  |  |  | 	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" | 
					
						
							|  |  |  | 	  \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") | 
					
						
							|  |  |  |   if parlnum > 0 | 
					
						
							|  |  |  |     let plindent = indent(parlnum) | 
					
						
							|  |  |  |     let plnumstart = parlnum | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     let plindent = indent(plnum) | 
					
						
							|  |  |  |     let plnumstart = plnum | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " When inside parenthesis: If at the first line below the parenthesis add | 
					
						
							|  |  |  |   " a 'shiftwidth', otherwise same as previous line. | 
					
						
							|  |  |  |   " i = (a | 
					
						
							|  |  |  |   "       + b | 
					
						
							|  |  |  |   "       + c) | 
					
						
							|  |  |  |   call cursor(a:lnum, 1) | 
					
						
							|  |  |  |   let p = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW', | 
					
						
							|  |  |  | 	  \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :" | 
					
						
							|  |  |  | 	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" | 
					
						
							|  |  |  | 	  \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") | 
					
						
							|  |  |  |   if p > 0 | 
					
						
							|  |  |  |     if p == plnum | 
					
						
							|  |  |  |       " When the start is inside parenthesis, only indent one 'shiftwidth'. | 
					
						
							|  |  |  |       let pp = searchpair('(\|{\|\[', '', ')\|}\|\]', 'bW', | 
					
						
							|  |  |  | 	  \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :" | 
					
						
							|  |  |  | 	  \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" | 
					
						
							|  |  |  | 	  \ . " =~ '\\(Comment\\|Todo\\|String\\)$'") | 
					
						
							|  |  |  |       if pp > 0 | 
					
						
							|  |  |  | 	return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth()) | 
					
						
							|  |  |  |       endif | 
					
						
							|  |  |  |       return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : shiftwidth()) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |     if plnumstart == p | 
					
						
							|  |  |  |       return indent(plnum) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |     return plindent | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " Get the line and remove a trailing comment. | 
					
						
							|  |  |  |   " Use syntax highlighting attributes when possible. | 
					
						
							|  |  |  |   let pline = getline(plnum) | 
					
						
							|  |  |  |   let pline_len = strlen(pline) | 
					
						
							|  |  |  |   if has('syntax_items') | 
					
						
							|  |  |  |     " If the last character in the line is a comment, do a binary search for | 
					
						
							|  |  |  |     " the start of the comment.  synID() is slow, a linear search would take | 
					
						
							|  |  |  |     " too long on a long line. | 
					
						
							|  |  |  |     if synIDattr(synID(plnum, pline_len, 1), "name") =~ "\\(Comment\\|Todo\\)$" | 
					
						
							|  |  |  |       let min = 1 | 
					
						
							|  |  |  |       let max = pline_len | 
					
						
							|  |  |  |       while min < max | 
					
						
							|  |  |  | 	let col = (min + max) / 2 | 
					
						
							|  |  |  | 	if synIDattr(synID(plnum, col, 1), "name") =~ "\\(Comment\\|Todo\\)$" | 
					
						
							|  |  |  | 	  let max = col | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	  let min = col + 1 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  |       endwhile | 
					
						
							|  |  |  |       let pline = strpart(pline, 0, min - 1) | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     let col = 0 | 
					
						
							|  |  |  |     while col < pline_len | 
					
						
							|  |  |  |       if pline[col] == '#' | 
					
						
							|  |  |  | 	let pline = strpart(pline, 0, col) | 
					
						
							|  |  |  | 	break | 
					
						
							|  |  |  |       endif | 
					
						
							|  |  |  |       let col = col + 1 | 
					
						
							|  |  |  |     endwhile | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If the previous line ended the conditional/loop | 
					
						
							|  |  |  |   if getline(plnum) =~ '^\s*\(endif\|endforeach\)\>\s*' | 
					
						
							|  |  |  |     " Maintain indent | 
					
						
							|  |  |  |     return -1 | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If the previous line ended with a builtin, indent this line | 
					
						
							|  |  |  |   if pline =~ '^\s*\(foreach\|if\|else\|elif\)\>\s*' | 
					
						
							|  |  |  |     return plindent + shiftwidth() | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " If the current line begins with a header keyword, deindent | 
					
						
							|  |  |  |   if getline(a:lnum) =~ '^\s*\(else\|elif\|endif\|endforeach\)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     " Unless the previous line was a one-liner | 
					
						
							|  |  |  |     if getline(plnumstart) =~ '^\s*\(foreach\|if\)\>\s*' | 
					
						
							|  |  |  |       return plindent | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     " Or the user has already dedented | 
					
						
							|  |  |  |     if indent(a:lnum) <= plindent - shiftwidth() | 
					
						
							|  |  |  |       return -1 | 
					
						
							|  |  |  |     endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return plindent - shiftwidth() | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   " When after a () construct we probably want to go back to the start line. | 
					
						
							|  |  |  |   " a = (b | 
					
						
							|  |  |  |   "       + c) | 
					
						
							|  |  |  |   " here | 
					
						
							|  |  |  |   if parlnum > 0 | 
					
						
							|  |  |  |     return plindent | 
					
						
							|  |  |  |   endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return -1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let &cpo = s:keepcpo | 
					
						
							|  |  |  | unlet s:keepcpo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " vim:sw=2 |