Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automake: use dictwatcher (nvim) to invalidate cache #2431

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions autoload/neomake/configure.vim
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ let s:registered_events = []
" issue #2742).
let s:need_to_skip_first_textchanged = !has('nvim-0.3.2') && has('patch-8.0.1494') && !has('patch-8.0.1633')

" For debugging/tests.
let g:neomake#configure#_s = s:


" TODO: allow for namespaces, and prefer 'automake' here.
" TODO: handle bufnr! (getbufvar)
Expand Down Expand Up @@ -548,6 +551,9 @@ function! s:configure_buffer(bufnr, ...) abort
augroup neomake_automake_clean
autocmd BufWipeout <buffer> call s:neomake_automake_clean(expand('<abuf>'))
augroup END
if exists('*dictwatcheradd')
call dictwatcheradd(b:, 'neomake_*', function('s:dictwatcher_b'))
endif
endif

if implicit_config.ignore
Expand Down Expand Up @@ -795,6 +801,39 @@ function! neomake#configure#automake(...) abort
endif
endfunction

function! s:maybe_clear_buffer_cache(bufnr) abort
if has_key(s:configured_buffers, a:bufnr) && !s:configured_buffers[a:bufnr].custom
unlet s:configured_buffers[a:bufnr]
return 1
endif
return 0
endfunction

if exists('*dictwatcheradd')
function! s:dictwatcher(d, k, update) abort
if a:k =~# '_enabled_makers$'
let cleared = 0
for [bufnr, v] in items(s:configured_buffers)
if s:maybe_clear_buffer_cache(bufnr)
let cleared += 1
endif
endfor
if cleared
call s:debug_log(printf('cleared cached config for %d buffers', cleared))
endif
endif
endfunction
function! s:dictwatcher_b(d, k, update) abort
if a:k =~# '_enabled_makers$'
let bufnr = bufnr('%')
if s:maybe_clear_buffer_cache(bufnr)
call s:debug_log('cleared cached config for buffer', {'bufnr': bufnr})
endif
endif
endfunction
call dictwatcheradd(g:, 'neomake_*', function('s:dictwatcher'))
endif

augroup neomake_automake_base
au!
autocmd FileType * call s:maybe_reconfigure_buffer(expand('<abuf>'))
Expand Down
100 changes: 94 additions & 6 deletions tests/automake.vader
Original file line number Diff line number Diff line change
Expand Up @@ -297,24 +297,52 @@ Execute (Automake):
AssertEqual len(g:neomake_test_jobfinished), 4

new
let bufnr = bufnr('%')
exe 'doautocmd' event
AssertNeomakeMessage 'automake: configured buffer for ft= (no enabled makers).'
if event ==# 'TextChanged'
call NeomakeTestsHandleSecondTextChanged()
endif
AssertNeomakeMessage 'automake: no enabled makers.'

" Test behavior with regard to cache when changing settings.
let b:neomake_automake_enabled_makers = ['foo']
doautocmd FileType
AssertNeomakeMessage 'automake: configured buffer for ft= (no enabled makers).'
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: cleared cached config for buffer.'
exe 'doautocmd' event
AssertNeomakeMessage 'automake: configured buffer for ft= (no enabled makers).'
else
doautocmd FileType
AssertNeomakeMessage 'automake: configured buffer for ft= (no enabled makers).'
endif

let b:neomake = {'automake': {'enabled_makers': ['configured_maker']}}
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: cleared cached config for buffer.'
endif

let n = len(g:neomake_test_messages)
exe 'doautocmd' event
let m = len(g:neomake_test_messages)
AssertEqual g:neomake_test_messages[n : m], [
\ [3, 'automake: handling event '.event.'.', {'bufnr': bufnr('%'), 'winnr': winnr()}],
\ [3, 'automake: no enabled makers.', {'bufnr': bufnr('%'), 'winnr': winnr()}],
\ ]
let winnr = winnr()
if exists('*dictwatcheradd')
AssertEqual g:neomake_test_messages[n : m], [
\ [3, 'Using setting automake.events={''InsertLeave'': {}, ''TextChanged'': {}} from ''global''.', {'bufnr': bufnr, 'winnr': winnr}],
\ [3, 'Using setting automake.enabled_makers=[''configured_maker''] from ''buffer''.', {'bufnr': bufnr, 'winnr': winnr}],
\ [0, 'Maker not found (for empty filetype): configured_maker.', {'winnr': winnr}],
\ [3, 'automake: configured buffer for ft= (no enabled makers).', {'bufnr': bufnr, 'winnr': winnr}],
\ [3, 'automake: setting tick for new buffer.', {'bufnr': bufnr, 'winnr': winnr}],
\ [3, 'automake: handling event TextChanged.', {'bufnr': bufnr, 'winnr': winnr}],
\ [3, 'automake: no enabled makers.', {'bufnr': bufnr, 'winnr': winnr}]
\ ]
" ACK error message.
AssertNeomakeMessage 'Maker not found (for empty filetype): configured_maker.', 0
else
AssertEqual g:neomake_test_messages[n : m], [
\ [3, 'automake: handling event '.event.'.', {'bufnr': bufnr('%'), 'winnr': winnr()}],
\ [3, 'automake: no enabled makers.', {'bufnr': bufnr('%'), 'winnr': winnr()}],
\ ]
endif

call neomake#configure#automake('nw')
normal! ifoo
Expand Down Expand Up @@ -1629,3 +1657,63 @@ Execute (automake: abort automake with manual run):
AssertEqualQf getloclist(0), expected_loclist
bwipe!
endif

Execute (Reconfigures buffers with dictwatcher):
new
let bufnr = bufnr('%')
set filetype=neomake_tests
Save g:neomake_test_enabledmakers
let g:neomake_test_enabledmakers = [g:entry_maker]
call g:NeomakeSetupAutocmdWrappers()

call neomake#configure#automake('w')

exe 'w' tempname()
AssertNeomakeMessage 'Running makers: entry_maker (auto).', 3
AssertEqual len(g:neomake_test_finished), 1

AssertEqual g:neomake#configure#_s.configured_buffers[bufnr].custom, 0

Save g:neomake_neomake_tests_enabled_makers
let g:neomake_neomake_tests_enabled_makers = []
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: cleared cached config for 1 buffers.', 3
endif

w
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: configured buffer for ft=neomake_tests (no enabled makers).', 3
AssertNeomakeMessage 'automake: setting tick for new buffer.', 3
AssertNeomakeMessage 'automake: handling event BufWritePost.', 3
AssertNeomakeMessage 'automake: no enabled makers.', 3
else
AssertNeomakeMessage 'automake: handling event BufWritePost.', 3
AssertNeomakeMessage 'automake: automake for event BufWritePost.', 3
AssertNeomakeMessage 'automake: neomake_do_automake: BufWritePost.', 3
AssertNeomakeMessage 'automake: tick is unchanged.', 3
AssertNeomakeMessage 'automake: buffer was not changed.', 3
endif
AssertEqual len(g:neomake_test_finished), 1

let b:neomake_neomake_tests_enabled_makers = [g:entry_maker]
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: cleared cached config for buffer.', 3
endif

w
if exists('*dictwatcheradd')
AssertNeomakeMessage 'automake: configured buffer for ft=neomake_tests (entry_maker (default)).', 3
AssertNeomakeMessage 'automake: setting tick for new buffer.', 3
AssertNeomakeMessage 'automake: handling event BufWritePost.', 3
AssertNeomakeMessage 'automake: enabled makers: entry_maker.', 3
AssertEqual len(g:neomake_test_finished), 2
else
AssertNeomakeMessage 'automake: handling event BufWritePost.', 3
AssertNeomakeMessage 'automake: automake for event BufWritePost.', 3
AssertNeomakeMessage 'automake: neomake_do_automake: BufWritePost.', 3
AssertNeomakeMessage 'automake: tick is unchanged.', 3
AssertNeomakeMessage 'automake: buffer was not changed.', 3
AssertEqual len(g:neomake_test_finished), 1
endif

bwipe