forked from aniani/vim
		
	
		
			
	
	
		
			79 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
		
		
			
		
	
	
			79 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
|   | " Vim indent file | ||
|  | " Language:	Go | ||
|  | " Maintainer:	David Barnett (https://github.com/google/vim-ft-go) | ||
|  | " Last Change:	2014 Aug 16 | ||
|  | " | ||
|  | " TODO: | ||
|  | " - function invocations split across lines | ||
|  | " - general line splits (line ends in an operator) | ||
|  | 
 | ||
|  | if exists('b:did_indent') | ||
|  |   finish | ||
|  | endif | ||
|  | let b:did_indent = 1 | ||
|  | 
 | ||
|  | " C indentation is too far off useful, mainly due to Go's := operator. | ||
|  | " Let's just define our own. | ||
|  | setlocal nolisp | ||
|  | setlocal autoindent | ||
|  | setlocal indentexpr=GoIndent(v:lnum) | ||
|  | setlocal indentkeys+=<:>,0=},0=) | ||
|  | 
 | ||
|  | if exists('*GoIndent') | ||
|  |   finish | ||
|  | endif | ||
|  | 
 | ||
|  | " The shiftwidth() function is relatively new. | ||
|  | " Don't require it to exist. | ||
|  | if exists('*shiftwidth') | ||
|  |   function s:sw() abort | ||
|  |     return shiftwidth() | ||
|  |   endfunction | ||
|  | else | ||
|  |   function s:sw() abort | ||
|  |     return &shiftwidth | ||
|  |   endfunction | ||
|  | endif | ||
|  | 
 | ||
|  | function! GoIndent(lnum) | ||
|  |   let l:prevlnum = prevnonblank(a:lnum-1) | ||
|  |   if l:prevlnum == 0 | ||
|  |     " top of file | ||
|  |     return 0 | ||
|  |   endif | ||
|  | 
 | ||
|  |   " grab the previous and current line, stripping comments. | ||
|  |   let l:prevl = substitute(getline(l:prevlnum), '//.*$', '', '') | ||
|  |   let l:thisl = substitute(getline(a:lnum), '//.*$', '', '') | ||
|  |   let l:previ = indent(l:prevlnum) | ||
|  | 
 | ||
|  |   let l:ind = l:previ | ||
|  | 
 | ||
|  |   if l:prevl =~ '[({]\s*$' | ||
|  |     " previous line opened a block | ||
|  |     let l:ind += s:sw() | ||
|  |   endif | ||
|  |   if l:prevl =~# '^\s*\(case .*\|default\):$' | ||
|  |     " previous line is part of a switch statement | ||
|  |     let l:ind += s:sw() | ||
|  |   endif | ||
|  |   " TODO: handle if the previous line is a label. | ||
|  | 
 | ||
|  |   if l:thisl =~ '^\s*[)}]' | ||
|  |     " this line closed a block | ||
|  |     let l:ind -= s:sw() | ||
|  |   endif | ||
|  | 
 | ||
|  |   " Colons are tricky. | ||
|  |   " We want to outdent if it's part of a switch ("case foo:" or "default:"). | ||
|  |   " We ignore trying to deal with jump labels because (a) they're rare, and | ||
|  |   " (b) they're hard to disambiguate from a composite literal key. | ||
|  |   if l:thisl =~# '^\s*\(case .*\|default\):$' | ||
|  |     let l:ind -= s:sw() | ||
|  |   endif | ||
|  | 
 | ||
|  |   return l:ind | ||
|  | endfunction | ||
|  | 
 | ||
|  | " vim: sw=2 sts=2 et |