Skip to content

Commit

Permalink
Change list cleaning/closing behavior
Browse files Browse the repository at this point in the history
- Allow errors on autosave to show up in same list
  • Loading branch information
bluk committed Nov 8, 2018
1 parent 6069a2b commit f9457c1
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 53 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ autocmd FileType swift nmap <leader>sgl <Plug>(swift-spm-test-generate-linuxmain
let g:swift_swiftformat_autosave = 1
" Run SwiftLint on save.
let g:swift_swiftlint_autosave = 1
" If there are errors during autosave, add all errors in the quickfix window.
let g:swift_list_type_commands = { 'Autosave': 'quickfix' }
```

## Documentation / Help
Expand Down
31 changes: 31 additions & 0 deletions autoload/swift/autosave.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
" Vim autoload file
" Language: Swift
" Maintainer: Bryant Luk <[email protected]>
" Description: Functions related to autosave.

" Copyright 2018 Bryant Luk
"
" Licensed under the Apache License, Version 2.0 (the "License");
" you may not use this file except in compliance with the License.
" You may obtain a copy of the License at
"
" http://www.apache.org/licenses/LICENSE-2.0
"
" Unless required by applicable law or agreed to in writing, software
" distributed under the License is distributed on an "AS IS" BASIS,
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
" See the License for the specific language governing permissions and
" limitations under the License.

function! swift#autosave#Start() abort
let b:swift_autosave_internal_lists = {}
endfunction

function! swift#autosave#CleanIfNeeded(list_type) abort
if !has_key(b:swift_autosave_internal_lists, a:list_type)
if g:swift_list_clean_on_autosave
call swift#list#Clean(a:list_type)
endif
let b:swift_autosave_internal_lists[a:list_type] = 1
endif
endfunction
18 changes: 15 additions & 3 deletions autoload/swift/job.vim
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ endfunction
" 'jump_to_error':
" Set to 1 to jump to the first error in the error list.
" Defaults to 0.
" 'on_autosave':
" Set to 1 if this job is being invoked because the buffer is being saved.
" Defaults to 0.
" 'status_type':
" The status type to use when updating the status.
" 'list_type':
Expand Down Expand Up @@ -94,6 +97,7 @@ function! s:job_options(args) abort
\ 'job_dir': fnameescape(expand("%:p:h")),
\ 'messages': [],
\ 'jump_to_error': 0,
\ 'on_autosave': 0,
\ 'list_title': "",
\ 'list_type': "_job",
\ 'exited': 0,
Expand All @@ -115,6 +119,10 @@ function! s:job_options(args) abort
let state.list_type = a:args.list_type
endif

if has_key(a:args, 'on_autosave')
let state.on_autosave = a:args.on_autosave
endif

if has_key(a:args, 'status_type')
let state.status_type = a:args.status_type
endif
Expand Down Expand Up @@ -158,7 +166,9 @@ function! s:job_options(args) abort
call win_gotoid(self.winid)

if a:exit_status == 0 && len(a:data) == 0
call swift#list#Clean(self.list_type)
if empty(swift#list#Get(self.list_type))
call swift#list#Close(self.list_type)
endif
call win_gotoid(l:winid)
return
endif
Expand All @@ -168,15 +178,17 @@ function! s:job_options(args) abort
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
try
execute l:cd self.job_dir
call swift#list#ParseFormat(self.list_type, self.errorformat, out, self.list_title)
call swift#list#ParseFormat(self.list_type, self.errorformat, out, self.list_title, self.on_autosave)
let errors = swift#list#Get(self.list_type)
finally
execute l:cd fnameescape(self.dir)
endtry

if empty(errors)
if a:exit_status == 0
call swift#list#Clean(self.list_type)
if empty(swift#list#Get(self.list_type))
call swift#list#Close(self.list_type)
endif
else
call swift#echo#EchoError([self.dir] + self.messages)
endif
Expand Down
59 changes: 49 additions & 10 deletions autoload/swift/list.vim
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,47 @@ function! swift#list#Get(list_type) abort
endif
endfunction

function! swift#list#ParseFormat(list_type, format, items, title) abort
function! swift#list#ParseFormat(list_type, format, items, title, keep_existing_items) abort
let old_errorformat = &errorformat
let &errorformat = a:format

try
if a:list_type ==# "locationlist"
if a:keep_existing_items
let l:existing_items = getloclist(0)
let l:existing_options = getloclist(0, { 'title': 1})
let l:existing_title = has_key(l:existing_options, "title") ? l:existing_options.title : ""
endif

lgetexpr a:items
call setloclist(0, [], 'a', { 'title': a:title })

if a:keep_existing_items && l:existing_title != ": lex []"
call setloclist(0, [], 'a', { 'title': l:existing_title . " / " . a:title })
else
call setloclist(0, [], 'a', { 'title': a:title })
endif

if a:keep_existing_items && len(l:existing_items) > 0
call setloclist(0, l:existing_items, 'a')
endif
else
if a:keep_existing_items
let l:existing_items = getqflist()
let l:existing_options = getqflist({ 'title': 1 })
let l:existing_title = has_key(l:existing_options, "title") ? l:existing_options.title : ""
endif

cgetexpr a:items
call setqflist([], 'a', { 'title': a:title })

if a:keep_existing_items && l:existing_title != ": cex []"
call setqflist([], 'a', { 'title': l:existing_title . " / " . a:title })
else
call setqflist([], 'a', { 'title': a:title })
endif

if a:keep_existing_items && len(l:existing_items) > 0
call setqflist(l:existing_items, 'a')
endif
endif
finally
let &errorformat = old_errorformat
Expand All @@ -105,18 +135,17 @@ function! swift#list#JumpToFirst(list_type) abort
endif
endfunction

" Clean cleans and closes the location list
function! swift#list#Clean(list_type) abort
if a:list_type ==# "locationlist"
lex []
else
cex []
endif

call s:close_list(a:list_type)
call swift#list#Close(a:list_type)
endfunction

function! s:close_list(list_type) abort
function! swift#list#Close(list_type) abort
if !g:swift_list_autoclose
return
endif
Expand All @@ -129,19 +158,29 @@ function! s:close_list(list_type) abort
endfunction

let s:default_list_type_commands = {
\ "SwiftBuild": "quickfix",
\ "Autosave": "",
\ "SwiftFormat": "locationlist",
\ "SwiftLint": "quickfix",
\ "SwiftLintAutoSave": "locationlist",
\ "SwiftTest": "quickfix",
\ "SwiftPMBuild": "quickfix",
\ "SwiftPMTest": "quickfix",
\ "_job": "locationlist",
\ }

function! swift#list#Type(for) abort
function! swift#list#Type(for, on_autosave) abort
if !empty(g:swift_list_type)
return g:swift_list_type
endif

if a:on_autosave
let l:list_type = get(g:swift_list_type_commands, "Autosave")
if empty(l:list_type)
let l:list_type = get(s:default_list_type_commands, "Autosave")
endif
if !empty(l:list_type)
return l:list_type
endif
endif

let l:list_type = get(g:swift_list_type_commands, a:for)
if l:list_type ==# "0"
return get(s:default_list_type_commands, a:for, "quickfix")
Expand Down
41 changes: 31 additions & 10 deletions autoload/swift/spm.vim
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
" See the License for the specific language governing permissions and
" limitations under the License.

if !exists("g:swift_compiler_spm_path")
let g:swift_compiler_spm_path = "swift"
endif

let s:format=",%E%f:%l:%c: error: %m"
let s:format.=",%W%f:%l:%c: warning: %m"
let s:format.=",%E%f:%l: error: %.%# : %m"
Expand Down Expand Up @@ -52,14 +48,22 @@ function! swift#spm#SourceBuild(...) abort
let l:opts = (a:0 > 0) ? copy(a:1) : {}
let l:jump_to_error = has_key(l:opts, 'jump_to_error') ? l:opts.jump_to_error
\ : g:swift_jump_to_error
let l:on_autosave = has_key(l:opts, 'on_autosave') ? l:opts.on_autosave : 0

let l:list_should_clean = !l:on_autosave && g:swift_list_clean
let l:list_title = "SwiftPMBuild"
let l:list_type = swift#list#Type(l:list_title, l:on_autosave)

if l:list_should_clean
call swift#list#Clean(l:list_type)
endif

let l:args = ['build'] + map(copy(a:000[1:]), "expand(v:val)")

let l:list_title = "SwiftBuild"
let l:list_type = swift#list#Type(l:list_title)
call swift#job#Spawn({
\ 'cmd': [g:swift_compiler_spm_path] + l:args,
\ 'jump_to_error': l:jump_to_error,
\ 'on_autosave': l:on_autosave,
\ 'list_title': l:list_title,
\ 'list_type': l:list_type,
\ 'status_type': 'build',
Expand All @@ -71,8 +75,17 @@ function! swift#spm#Test(...) abort
let l:opts = (a:0 > 0) ? copy(a:1) : {}
let l:jump_to_error = has_key(l:opts, 'jump_to_error') ? l:opts.jump_to_error
\ : g:swift_jump_to_error
let l:on_autosave = has_key(l:opts, 'on_autosave') ? l:opts.on_autosave : 0
let l:only_compile = has_key(l:opts, 'only_compile') ? l:opts.only_compile : 0

let l:list_should_clean = !l:on_autosave && g:swift_list_clean
let l:list_title = "SwiftPMTest"
let l:list_type = swift#list#Type(l:list_title, l:on_autosave)

if l:list_should_clean
call swift#list#Clean(l:list_type)
endif

if l:only_compile == 1
let l:args = ["build", "--build-tests"]
else
Expand All @@ -81,11 +94,10 @@ function! swift#spm#Test(...) abort

call extend(l:args, map(copy(a:000[1:]), "expand(v:val)"))

let l:list_title = "SwiftTest"
let l:list_type = swift#list#Type(l:list_title)
call swift#job#Spawn({
\ 'cmd': [g:swift_compiler_spm_path] + l:args,
\ 'jump_to_error': l:jump_to_error,
\ 'on_autosave': l:on_autosave,
\ 'list_title': l:list_title,
\ 'list_type': l:list_type,
\ 'status_type': l:only_compile ? 'compile test' : 'test',
Expand Down Expand Up @@ -118,15 +130,23 @@ function! swift#spm#TestGenerateLinuxMain(...) abort
let l:opts = (a:0 > 0) ? copy(a:1) : {}
let l:jump_to_error = has_key(l:opts, 'jump_to_error') ? l:opts.jump_to_error
\ : g:swift_jump_to_error
let l:on_autosave = has_key(l:opts, 'on_autosave') ? l:opts.on_autosave : 0

let l:list_should_clean = !l:on_autosave && g:swift_list_clean
let l:list_title = "SwiftPMTest"
let l:list_type = swift#list#Type(l:list_title, l:on_autosave)

if l:list_should_clean
call swift#list#Clean(l:list_type)
endif

let l:args = ["test", "--generate-linuxmain"]
call extend(l:args, map(copy(a:000[1:]), "expand(v:val)"))

let l:list_title = "SwiftTest"
let l:list_type = swift#list#Type(l:list_title)
call swift#job#Spawn({
\ 'cmd': [g:swift_compiler_spm_path] + l:args,
\ 'jump_to_error': l:jump_to_error,
\ 'on_autosave': l:on_autosave,
\ 'list_title': l:list_title,
\ 'list_type': l:list_type,
\ 'status_type': 'test generate-linuxmain',
Expand All @@ -139,6 +159,7 @@ function! swift#spm#GenerateXcodeProject(...) abort
let l:opts = (a:0 > 0) ? copy(a:1) : {}
let l:jump_to_error = has_key(l:opts, 'jump_to_error') ? l:opts.jump_to_error
\ : g:swift_jump_to_error
let l:on_autosave = has_key(l:opts, 'on_autosave') ? l:opts.on_autosave : 0

let l:command = [g:swift_compiler_spm_path, 'package', 'generate-xcodeproj']
call extend(l:command, map(copy(a:000[1:]), "expand(v:val)"))
Expand Down
39 changes: 22 additions & 17 deletions autoload/swift/swiftformat.vim
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,26 @@ if !exists("g:swift_swiftformat_options")
let g:swift_swiftformat_options = []
endif

let s:list_title = "SwiftFormat"

let s:format="%E%f:error: %m at %l:%c"
let s:format.=",%W%f:warning: %m at %l:%c"
let s:format.=",%E%f:error: %m"
let s:format.=",%W%f:warning: %m"
let s:format.=",%-G%.%#"

function! swift#swiftformat#Format(...) abort
let l:opts = (a:0 > 0) ? copy(a:1) : {}
let l:jump_to_error = has_key(l:opts, 'jump_to_error') ? l:opts.jump_to_error
\ : g:swift_jump_to_error
let l:on_autosave = has_key(l:opts, 'on_autosave') ? l:opts.on_autosave : 0

let l:list_should_clean = !l:on_autosave && g:swift_list_clean
let l:list_type = swift#list#Type(s:list_title, l:on_autosave)

if l:list_should_clean
call swift#list#Clean(l:list_type)
endif

mkview!

Expand All @@ -70,8 +86,6 @@ function! swift#swiftformat#Format(...) abort
let l:stderr = readfile(l:stderr_tmpname)
call delete(l:stderr_tmpname)

let l:list_type = swift#list#Type("SwiftFormat")

if v:shell_error == 0
try | silent undojoin | catch | endtry

Expand All @@ -80,13 +94,8 @@ function! swift#swiftformat#Format(...) abort

silent! execute '%!cat ' . l:output_tmpname

if l:list_type ==# "quickfix"
let l:list_title = getqflist({'title': 1})
else
let l:list_title = getloclist(0, {'title': 1})
endif
if has_key(l:list_title, "title") && l:list_title['title'] ==# "Format"
call swift#list#Clean(l:list_type)
if empty(swift#list#Get(l:list_type))
call swift#list#Close(l:list_type)
endif

silent! loadview
Expand All @@ -98,13 +107,7 @@ function! swift#swiftformat#Format(...) abort
" Hack in the filename to the beginning of the error output.
let l:stderr = map(copy(l:stderr), "'" . expand('%') . ":'" . ' . v:val')

let l:format="%E%f:error: %m at %l:%c"
let l:format.=",%W%f:warning: %m at %l:%c"
let l:format.=",%E%f:error: %m"
let l:format.=",%W%f:warning: %m"
let l:format.=",%-G%.%#"

call swift#list#ParseFormat(l:list_type, l:format, l:stderr, 'Format')
call swift#list#ParseFormat(l:list_type, s:format, l:stderr, s:list_title, l:on_autosave)
let errors = swift#list#Get(l:list_type)
if empty(errors)
call swift#echo#EchoError(l:stderr)
Expand All @@ -128,7 +131,9 @@ endfunction

function! swift#swiftformat#PreWrite() abort
if get(g:, "swift_swiftformat_autosave", 0)
call swift#swiftformat#Format({})
let l:list_type = swift#list#Type(s:list_title, 1)
call swift#autosave#CleanIfNeeded(l:list_type)
call swift#swiftformat#Format({ "on_autosave": 1 })
endif
endfunction

Expand Down
Loading

0 comments on commit f9457c1

Please sign in to comment.