1*3c2881dcSBram Moolenaar" Author: Stephen Sugden <[email protected]> 2*3c2881dcSBram Moolenaar" 3*3c2881dcSBram Moolenaar" Adapted from https://github.com/fatih/vim-go 4*3c2881dcSBram Moolenaar" For bugs, patches and license go to https://github.com/rust-lang/rust.vim 5*3c2881dcSBram Moolenaar 6*3c2881dcSBram Moolenaarif !exists("g:rustfmt_autosave") 7*3c2881dcSBram Moolenaar let g:rustfmt_autosave = 0 8*3c2881dcSBram Moolenaarendif 9*3c2881dcSBram Moolenaar 10*3c2881dcSBram Moolenaarif !exists("g:rustfmt_command") 11*3c2881dcSBram Moolenaar let g:rustfmt_command = "rustfmt" 12*3c2881dcSBram Moolenaarendif 13*3c2881dcSBram Moolenaar 14*3c2881dcSBram Moolenaarif !exists("g:rustfmt_options") 15*3c2881dcSBram Moolenaar let g:rustfmt_options = "" 16*3c2881dcSBram Moolenaarendif 17*3c2881dcSBram Moolenaar 18*3c2881dcSBram Moolenaarif !exists("g:rustfmt_fail_silently") 19*3c2881dcSBram Moolenaar let g:rustfmt_fail_silently = 0 20*3c2881dcSBram Moolenaarendif 21*3c2881dcSBram Moolenaar 22*3c2881dcSBram Moolenaarlet s:got_fmt_error = 0 23*3c2881dcSBram Moolenaar 24*3c2881dcSBram Moolenaarfunction! s:RustfmtCommandRange(filename, line1, line2) 25*3c2881dcSBram Moolenaar let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]} 26*3c2881dcSBram Moolenaar return printf("%s %s --write-mode=overwrite --file-lines '[%s]'", g:rustfmt_command, g:rustfmt_options, json_encode(l:arg)) 27*3c2881dcSBram Moolenaarendfunction 28*3c2881dcSBram Moolenaar 29*3c2881dcSBram Moolenaarfunction! s:RustfmtCommand(filename) 30*3c2881dcSBram Moolenaar return g:rustfmt_command . " --write-mode=overwrite " . g:rustfmt_options . " " . shellescape(a:filename) 31*3c2881dcSBram Moolenaarendfunction 32*3c2881dcSBram Moolenaar 33*3c2881dcSBram Moolenaarfunction! s:RunRustfmt(command, curw, tmpname) 34*3c2881dcSBram Moolenaar if exists("*systemlist") 35*3c2881dcSBram Moolenaar let out = systemlist(a:command) 36*3c2881dcSBram Moolenaar else 37*3c2881dcSBram Moolenaar let out = split(system(a:command), '\r\?\n') 38*3c2881dcSBram Moolenaar endif 39*3c2881dcSBram Moolenaar 40*3c2881dcSBram Moolenaar if v:shell_error == 0 || v:shell_error == 3 41*3c2881dcSBram Moolenaar " remove undo point caused via BufWritePre 42*3c2881dcSBram Moolenaar try | silent undojoin | catch | endtry 43*3c2881dcSBram Moolenaar 44*3c2881dcSBram Moolenaar " Replace current file with temp file, then reload buffer 45*3c2881dcSBram Moolenaar call rename(a:tmpname, expand('%')) 46*3c2881dcSBram Moolenaar silent edit! 47*3c2881dcSBram Moolenaar let &syntax = &syntax 48*3c2881dcSBram Moolenaar 49*3c2881dcSBram Moolenaar " only clear location list if it was previously filled to prevent 50*3c2881dcSBram Moolenaar " clobbering other additions 51*3c2881dcSBram Moolenaar if s:got_fmt_error 52*3c2881dcSBram Moolenaar let s:got_fmt_error = 0 53*3c2881dcSBram Moolenaar call setloclist(0, []) 54*3c2881dcSBram Moolenaar lwindow 55*3c2881dcSBram Moolenaar endif 56*3c2881dcSBram Moolenaar elseif g:rustfmt_fail_silently == 0 57*3c2881dcSBram Moolenaar " otherwise get the errors and put them in the location list 58*3c2881dcSBram Moolenaar let errors = [] 59*3c2881dcSBram Moolenaar 60*3c2881dcSBram Moolenaar for line in out 61*3c2881dcSBram Moolenaar " src/lib.rs:13:5: 13:10 error: expected `,`, or `}`, found `value` 62*3c2881dcSBram Moolenaar let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\):\s*\(\d\+:\d\+\s*\)\?\s*error: \(.*\)') 63*3c2881dcSBram Moolenaar if !empty(tokens) 64*3c2881dcSBram Moolenaar call add(errors, {"filename": @%, 65*3c2881dcSBram Moolenaar \"lnum": tokens[2], 66*3c2881dcSBram Moolenaar \"col": tokens[3], 67*3c2881dcSBram Moolenaar \"text": tokens[5]}) 68*3c2881dcSBram Moolenaar endif 69*3c2881dcSBram Moolenaar endfor 70*3c2881dcSBram Moolenaar 71*3c2881dcSBram Moolenaar if empty(errors) 72*3c2881dcSBram Moolenaar % | " Couldn't detect rustfmt error format, output errors 73*3c2881dcSBram Moolenaar endif 74*3c2881dcSBram Moolenaar 75*3c2881dcSBram Moolenaar if !empty(errors) 76*3c2881dcSBram Moolenaar call setloclist(0, errors, 'r') 77*3c2881dcSBram Moolenaar echohl Error | echomsg "rustfmt returned error" | echohl None 78*3c2881dcSBram Moolenaar endif 79*3c2881dcSBram Moolenaar 80*3c2881dcSBram Moolenaar let s:got_fmt_error = 1 81*3c2881dcSBram Moolenaar lwindow 82*3c2881dcSBram Moolenaar " We didn't use the temp file, so clean up 83*3c2881dcSBram Moolenaar call delete(a:tmpname) 84*3c2881dcSBram Moolenaar endif 85*3c2881dcSBram Moolenaar 86*3c2881dcSBram Moolenaar call winrestview(a:curw) 87*3c2881dcSBram Moolenaarendfunction 88*3c2881dcSBram Moolenaar 89*3c2881dcSBram Moolenaarfunction! rustfmt#FormatRange(line1, line2) 90*3c2881dcSBram Moolenaar let l:curw = winsaveview() 91*3c2881dcSBram Moolenaar let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt" 92*3c2881dcSBram Moolenaar call writefile(getline(1, '$'), l:tmpname) 93*3c2881dcSBram Moolenaar 94*3c2881dcSBram Moolenaar let command = s:RustfmtCommandRange(l:tmpname, a:line1, a:line2) 95*3c2881dcSBram Moolenaar 96*3c2881dcSBram Moolenaar call s:RunRustfmt(command, l:curw, l:tmpname) 97*3c2881dcSBram Moolenaarendfunction 98*3c2881dcSBram Moolenaar 99*3c2881dcSBram Moolenaarfunction! rustfmt#Format() 100*3c2881dcSBram Moolenaar let l:curw = winsaveview() 101*3c2881dcSBram Moolenaar let l:tmpname = expand("%:p:h") . "/." . expand("%:p:t") . ".rustfmt" 102*3c2881dcSBram Moolenaar call writefile(getline(1, '$'), l:tmpname) 103*3c2881dcSBram Moolenaar 104*3c2881dcSBram Moolenaar let command = s:RustfmtCommand(l:tmpname) 105*3c2881dcSBram Moolenaar 106*3c2881dcSBram Moolenaar call s:RunRustfmt(command, l:curw, l:tmpname) 107*3c2881dcSBram Moolenaarendfunction 108