forked from aniani/vim
		
	
		
			
	
	
		
			101 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
		
		
			
		
	
	
			101 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
|   | " Adapted from fatih/vim-go: autoload/go/fmt.vim | ||
|  | " | ||
|  | " Copyright 2011 The Go Authors. All rights reserved. | ||
|  | " Use of this source code is governed by a BSD-style | ||
|  | " license that can be found in the LICENSE file. | ||
|  | " | ||
|  | " Upstream: https://github.com/ziglang/zig.vim | ||
|  | 
 | ||
|  | function! zig#fmt#Format() abort | ||
|  |   " Save cursor position and many other things. | ||
|  |   let view = winsaveview() | ||
|  | 
 | ||
|  |   if !executable('zig') | ||
|  |     echohl Error | echomsg "no zig binary found in PATH" | echohl None | ||
|  |     return | ||
|  |   endif | ||
|  | 
 | ||
|  |   let cmdline = 'zig fmt --stdin --ast-check' | ||
|  |   let current_buf = bufnr('') | ||
|  | 
 | ||
|  |   " The formatted code is output on stdout, the errors go on stderr. | ||
|  |   if exists('*systemlist') | ||
|  |     silent let out = systemlist(cmdline, current_buf) | ||
|  |   else | ||
|  |     silent let out = split(system(cmdline, current_buf)) | ||
|  |   endif | ||
|  |   if len(out) == 1 | ||
|  |     if out[0] == "error: unrecognized parameter: '--ast-check'" | ||
|  |       let cmdline = 'zig fmt --stdin' | ||
|  |       if exists('*systemlist') | ||
|  |         silent let out = systemlist(cmdline, current_buf) | ||
|  |       else | ||
|  |         silent let out = split(system(cmdline, current_buf)) | ||
|  |       endif | ||
|  |     endif | ||
|  |   endif | ||
|  |   let err = v:shell_error | ||
|  | 
 | ||
|  | 
 | ||
|  |   if err == 0 | ||
|  |     " remove undo point caused via BufWritePre. | ||
|  |     try | silent undojoin | catch | endtry | ||
|  | 
 | ||
|  |     " Replace the file content with the formatted version. | ||
|  |     if exists('*deletebufline') | ||
|  |       call deletebufline(current_buf, len(out), line('$')) | ||
|  |     else | ||
|  |       silent execute ':' . len(out) . ',' . line('$') . ' delete _' | ||
|  |     endif | ||
|  |     call setline(1, out) | ||
|  | 
 | ||
|  |     " No errors detected, close the loclist. | ||
|  |     call setloclist(0, [], 'r') | ||
|  |     lclose | ||
|  |   elseif get(g:, 'zig_fmt_parse_errors', 1) | ||
|  |     let errors = s:parse_errors(expand('%'), out) | ||
|  | 
 | ||
|  |     call setloclist(0, [], 'r', { | ||
|  |         \ 'title': 'Errors', | ||
|  |         \ 'items': errors, | ||
|  |         \ }) | ||
|  | 
 | ||
|  |     let max_win_height = get(g:, 'zig_fmt_max_window_height', 5) | ||
|  |     " Prevent the loclist from becoming too long. | ||
|  |     let win_height = min([max_win_height, len(errors)]) | ||
|  |     " Open the loclist, but only if there's at least one error to show. | ||
|  |     execute 'silent! lwindow ' . win_height | ||
|  |   endif | ||
|  | 
 | ||
|  |   call winrestview(view) | ||
|  | 
 | ||
|  |   if err != 0 | ||
|  |     echohl Error | echomsg "zig fmt returned error" | echohl None | ||
|  |     return | ||
|  |   endif | ||
|  | 
 | ||
|  |   " Run the syntax highlighter on the updated content and recompute the folds if | ||
|  |   " needed. | ||
|  |   syntax sync fromstart | ||
|  | endfunction | ||
|  | 
 | ||
|  | " parse_errors parses the given errors and returns a list of parsed errors | ||
|  | function! s:parse_errors(filename, lines) abort | ||
|  |   " list of errors to be put into location list | ||
|  |   let errors = [] | ||
|  |   for line in a:lines | ||
|  |     let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') | ||
|  |     if !empty(tokens) | ||
|  |       call add(errors,{ | ||
|  |             \"filename": a:filename, | ||
|  |             \"lnum":     tokens[2], | ||
|  |             \"col":      tokens[3], | ||
|  |             \"text":     tokens[4], | ||
|  |             \ }) | ||
|  |     endif | ||
|  |   endfor | ||
|  | 
 | ||
|  |   return errors | ||
|  | endfunction | ||
|  | " vim: sw=2 ts=2 et |