Fix for "lclose not allowed here" error on open
The problem was caused by a race condition of all things. ClangCompleter would set possibly_completions_ready when starting the first parse pass for the file and then would try to extract diagnostics for the file before the diagnostics were done. Technically this was not a problem because only an empty diagnostics vector would be returned, but this triggered Syntastic because hey, we have some diagnostics to show (even though we don't). And then Syntastic would try to close the location list window during startup when this operation is not available. Technically it's Syntastic's fault, but a more principled way to check for done diagnostics is to return and use a future for file parsing operations and this solution also works around the Syntastic issue.
This commit is contained in:
parent
fef702eef0
commit
f99e89f812
@ -108,8 +108,10 @@ endfunction
|
||||
|
||||
|
||||
function! s:OnCursorHold()
|
||||
call s:OnFileReadyToParse()
|
||||
" Order is important here; we need to extract any done diagnostics before
|
||||
" reparsing the file again
|
||||
call s:UpdateDiagnosticNotifications()
|
||||
call s:OnFileReadyToParse()
|
||||
endfunction
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@ void ClangCompleter::UpdateTranslationUnit(
|
||||
}
|
||||
|
||||
|
||||
void ClangCompleter::UpdateTranslationUnitAsync(
|
||||
Future< void > ClangCompleter::UpdateTranslationUnitAsync(
|
||||
std::string filename,
|
||||
std::vector< UnsavedFile > unsaved_files,
|
||||
std::vector< std::string > flags )
|
||||
@ -186,8 +186,14 @@ void ClangCompleter::UpdateTranslationUnitAsync(
|
||||
shared_ptr< ClangPackagedTask > clang_packaged_task =
|
||||
make_shared< ClangPackagedTask >();
|
||||
|
||||
// TODO: vim hangs when we just open it and try to enter insert mode after the
|
||||
// last '_' in ->parsing_task_ here
|
||||
clang_packaged_task->parsing_task_ = packaged_task< void >( functor );
|
||||
unique_future< void > future =
|
||||
clang_packaged_task->parsing_task_.get_future();
|
||||
clang_task_.Set( clang_packaged_task );
|
||||
|
||||
return Future< void >( boost::move( future ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
|
||||
// NOTE: params are taken by value on purpose! With a C++11 compiler we can
|
||||
// avoid internal copies if params are taken by value (move ctors FTW)
|
||||
void UpdateTranslationUnitAsync(
|
||||
Future< void > UpdateTranslationUnitAsync(
|
||||
std::string filename,
|
||||
std::vector< UnsavedFile > unsaved_files,
|
||||
std::vector< std::string > flags );
|
||||
|
@ -67,6 +67,10 @@ BOOST_PYTHON_MODULE(ycm_core)
|
||||
.def( "ResultsReady", &Future< AsyncCompletions >::ResultsReady )
|
||||
.def( "GetResults", &Future< AsyncCompletions >::GetResults );
|
||||
|
||||
class_< Future< void > >( "FutureVoid" )
|
||||
.def( "ResultsReady", &Future< void >::ResultsReady )
|
||||
.def( "GetResults", &Future< void >::GetResults );
|
||||
|
||||
class_< IdentifierCompleter, boost::noncopyable >( "IdentifierCompleter" )
|
||||
.def( "EnableThreading", &IdentifierCompleter::EnableThreading )
|
||||
.def( "AddCandidatesToDatabase",
|
||||
|
@ -33,7 +33,7 @@ class ClangCompleter( Completer ):
|
||||
self.contents_holder = []
|
||||
self.filename_holder = []
|
||||
self.last_diagnostics = []
|
||||
self.possibly_new_diagnostics = False
|
||||
self.parse_future = None
|
||||
self.flags = Flags()
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@ class ClangCompleter( Completer ):
|
||||
line, _ = vim.current.window.cursor
|
||||
column = int( vim.eval( "s:completion_start_column" ) ) + 1
|
||||
current_buffer = vim.current.buffer
|
||||
# TODO: rename future to completions_future
|
||||
self.future = self.completer.CandidatesForQueryAndLocationInFileAsync(
|
||||
query,
|
||||
current_buffer.name,
|
||||
@ -110,26 +111,25 @@ class ClangCompleter( Completer ):
|
||||
if vimsupport.NumLinesInBuffer( vim.current.buffer ) < 5:
|
||||
return
|
||||
|
||||
self.possibly_new_diagnostics = True
|
||||
|
||||
filename = vim.current.buffer.name
|
||||
self.completer.UpdateTranslationUnitAsync(
|
||||
self.parse_future = self.completer.UpdateTranslationUnitAsync(
|
||||
filename,
|
||||
self.GetUnsavedFilesVector(),
|
||||
self.flags.FlagsForFile( filename ) )
|
||||
|
||||
|
||||
def DiagnosticsForCurrentFileReady( self ):
|
||||
return ( self.possibly_new_diagnostics and not
|
||||
self.completer.UpdatingTranslationUnit( vim.current.buffer.name ) )
|
||||
if not self.parse_future:
|
||||
return False
|
||||
|
||||
return self.parse_future.ResultsReady()
|
||||
|
||||
def GetDiagnosticsForCurrentFile( self ):
|
||||
if self.DiagnosticsForCurrentFileReady():
|
||||
self.last_diagnostics = [ DiagnosticToDict( x ) for x in
|
||||
self.completer.DiagnosticsForFile(
|
||||
vim.current.buffer.name ) ]
|
||||
self.possibly_new_diagnostics = False
|
||||
self.parse_future = None
|
||||
return self.last_diagnostics
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user