mirror of
				https://github.com/vim/vim.git
				synced 2025-10-30 09:47:20 -04:00 
			
		
		
		
	
		
			
	
	
		
			181 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
		
		
			
		
	
	
			181 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
|   | " Vim indent file | ||
|  | " Language:		Meson | ||
|  | " License:		VIM License | ||
|  | " Maintainer:		Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | ||
|  | " 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) | ||
|  | 
 | ||
|  | " 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 |