Replaced Syntastic support with YCM-native code
Currently, the only supported Syntastic features are the error signs in the gutter. Other features will be added in the future.
This commit is contained in:
parent
e8d1a4cef8
commit
6c01881e1a
@ -29,7 +29,7 @@ let s:cursor_moved = 0
|
||||
let s:moved_vertically_in_insert_mode = 0
|
||||
let s:previous_num_chars_on_current_line = -1
|
||||
|
||||
let s:forced_syntastic_checker_for = {
|
||||
let s:diagnostic_ui_filetypes = {
|
||||
\ 'cpp': 1,
|
||||
\ 'c': 1,
|
||||
\ 'objc': 1,
|
||||
@ -70,10 +70,12 @@ function! youcompleteme#Enable()
|
||||
call s:SetUpCompleteopt()
|
||||
call s:SetUpKeyMappings()
|
||||
|
||||
if g:ycm_register_as_syntastic_checker
|
||||
call s:TweakSyntasticOptions()
|
||||
if g:ycm_show_diagnostics_ui
|
||||
call s:TurnOffSyntasticForCFamily()
|
||||
endif
|
||||
|
||||
call s:SetUpSigns()
|
||||
|
||||
if g:ycm_allow_changing_updatetime
|
||||
set ut=2000
|
||||
endif
|
||||
@ -157,6 +159,41 @@ function! s:SetUpKeyMappings()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:SetUpSigns()
|
||||
" We try to ensure backwards compatibility with Syntastic if the user has
|
||||
" already defined styling for Syntastic highlight groups.
|
||||
|
||||
if !hlexists( 'YcmErrorSign' )
|
||||
if hlexists( 'SyntasticErrorSign')
|
||||
highlight link YcmErrorSign SyntasticErrorSign
|
||||
else
|
||||
highlight link YcmErrorSign error
|
||||
endif
|
||||
endif
|
||||
|
||||
if !hlexists( 'YcmWarningSign' )
|
||||
if hlexists( 'SyntasticWarningSign')
|
||||
highlight link YcmWarningSign SyntasticWarningSign
|
||||
else
|
||||
highlight link YcmWarningSign todo
|
||||
endif
|
||||
endif
|
||||
|
||||
if !hlexists( 'YcmErrorLine' )
|
||||
highlight link YcmErrorLine SyntasticErrorLine
|
||||
endif
|
||||
|
||||
if !hlexists( 'YcmWarningLine' )
|
||||
highlight link YcmWarningLine SyntasticWarningLine
|
||||
endif
|
||||
|
||||
exe 'sign define YcmError text=' . g:ycm_error_symbol .
|
||||
\ ' texthl=YcmErrorSign linehl=YcmErrorLine'
|
||||
exe 'sign define YcmWarning text=' . g:ycm_warning_symbol .
|
||||
\ ' texthl=YcmWarningSign linehl=YcmWarningLine'
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:SetUpBackwardsCompatibility()
|
||||
let complete_in_comments_and_strings =
|
||||
\ get( g:, 'ycm_complete_in_comments_and_strings', 0 )
|
||||
@ -173,38 +210,17 @@ function! s:SetUpBackwardsCompatibility()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:TweakSyntasticOptions()
|
||||
call s:ForceCFamilyFiletypesSyntasticPassiveMode()
|
||||
call s:ForceSyntasticCFamilyChecker()
|
||||
|
||||
" We set this to work around segfaults in old versions of Vim
|
||||
" See here for details: https://github.com/scrooloose/syntastic/issues/834
|
||||
let g:syntastic_delayed_redraws = 1
|
||||
" Needed so that YCM is used instead of Syntastic
|
||||
function! s:TurnOffSyntasticForCFamily()
|
||||
let g:syntastic_cpp_checkers = []
|
||||
let g:syntastic_c_checkers = []
|
||||
let g:syntastic_objc_checkers = []
|
||||
let g:syntastic_objcpp_checkers = []
|
||||
endfunction
|
||||
|
||||
|
||||
" Needed so that YCM is used as the syntastic checker
|
||||
function! s:ForceSyntasticCFamilyChecker()
|
||||
let g:syntastic_cpp_checkers = ['ycm']
|
||||
let g:syntastic_c_checkers = ['ycm']
|
||||
let g:syntastic_objc_checkers = ['ycm']
|
||||
let g:syntastic_objcpp_checkers = ['ycm']
|
||||
endfunction
|
||||
|
||||
|
||||
" Needed so that Syntastic doesn't call :SyntasticCheck (and thus YCM code) on
|
||||
" file save unnecessarily. We call :SyntasticCheck ourselves often enough.
|
||||
function! s:ForceCFamilyFiletypesSyntasticPassiveMode()
|
||||
let mode_map = get( g:, 'syntastic_mode_map', {} )
|
||||
let mode_map.passive_filetypes = get( mode_map, 'passive_filetypes', [] ) +
|
||||
\ ['cpp', 'c', 'objc', 'objcpp']
|
||||
let g:syntastic_mode_map = mode_map
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:ForcedAsSyntasticCheckerForCurrentFiletype()
|
||||
return g:ycm_register_as_syntastic_checker &&
|
||||
\ get( s:forced_syntastic_checker_for, &filetype, 0 )
|
||||
function! s:DiagnosticUiSupportedForCurrentFiletype()
|
||||
return get( s:diagnostic_ui_filetypes, &filetype, 0 )
|
||||
endfunction
|
||||
|
||||
|
||||
@ -464,18 +480,15 @@ endfunction
|
||||
|
||||
|
||||
function! s:UpdateDiagnosticNotifications()
|
||||
let should_display_diagnostics =
|
||||
\ get( g:, 'loaded_syntastic_plugin', 0 ) &&
|
||||
\ s:ForcedAsSyntasticCheckerForCurrentFiletype() &&
|
||||
let should_display_diagnostics = g:ycm_show_diagnostics_ui &&
|
||||
\ s:DiagnosticUiSupportedForCurrentFiletype() &&
|
||||
\ pyeval( 'ycm_state.NativeFiletypeCompletionUsable()' )
|
||||
|
||||
if !should_display_diagnostics
|
||||
return
|
||||
endif
|
||||
|
||||
if pyeval( 'ycm_state.DiagnosticsForCurrentFileReady()' )
|
||||
SyntasticCheck
|
||||
endif
|
||||
py ycm_state.UpdateDiagnosticInterface()
|
||||
endfunction
|
||||
|
||||
|
||||
@ -639,14 +652,6 @@ endfunction
|
||||
command! YcmShowDetailedDiagnostic call s:ShowDetailedDiagnostic()
|
||||
|
||||
|
||||
" This is what Syntastic calls indirectly when it decides an auto-check is
|
||||
" required (currently that's on buffer save) OR when the SyntasticCheck command
|
||||
" is invoked
|
||||
function! youcompleteme#CurrentFileDiagnostics()
|
||||
return pyeval( 'ycm_state.GetDiagnosticsFromStoredRequest()' )
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:DebugInfo()
|
||||
echom "Printing YouCompleteMe debug information..."
|
||||
let debug_info = pyeval( 'ycm_state.DebugInfo()' )
|
||||
|
@ -71,9 +71,6 @@ let g:loaded_youcompleteme = 1
|
||||
" The only defaults that are here are the ones that are only relevant to the YCM
|
||||
" Vim client and not the server.
|
||||
|
||||
let g:ycm_register_as_syntastic_checker =
|
||||
\ get( g:, 'ycm_register_as_syntastic_checker', 1 )
|
||||
|
||||
let g:ycm_allow_changing_updatetime =
|
||||
\ get( g:, 'ycm_allow_changing_updatetime', 1 )
|
||||
|
||||
@ -116,6 +113,17 @@ let g:ycm_extra_conf_vim_data =
|
||||
let g:ycm_path_to_python_interpreter =
|
||||
\ get( g:, 'ycm_path_to_python_interpreter', '' )
|
||||
|
||||
let g:ycm_show_diagnostics_ui =
|
||||
\ get( g:, 'ycm_show_diagnostics_ui',
|
||||
\ get( g:, 'ycm_register_as_syntastic_checker', 1 ) )
|
||||
|
||||
let g:ycm_error_symbol =
|
||||
\ get( g:, 'ycm_error_symbol',
|
||||
\ get( g:, 'syntastic_error_symbol', '>>' ) )
|
||||
|
||||
let g:ycm_warning_symbol =
|
||||
\ get( g:, 'ycm_warning_symbol',
|
||||
\ get( g:, 'syntastic_warning_symbol', '>>' ) )
|
||||
|
||||
" On-demand loading. Let's use the autoload folder and not slow down vim's
|
||||
" startup procedure.
|
||||
|
@ -77,7 +77,7 @@ def _ConvertDiagnosticDataToVimData( diagnostic ):
|
||||
# line/column numbers are 1 or 0 based in its various APIs. Here, it wants
|
||||
# them to be 1-based.
|
||||
return {
|
||||
'bufnr' : vimsupport.GetBufferNumberForFilename( diagnostic[ 'filepath' ]),
|
||||
'bufnr' : vimsupport.GetBufferNumberForFilename( diagnostic[ 'filepath' ] ),
|
||||
'lnum' : diagnostic[ 'line_num' ] + 1,
|
||||
'col' : diagnostic[ 'column_num' ] + 1,
|
||||
'text' : diagnostic[ 'text' ],
|
||||
|
55
python/ycm/diagnostic_interface.py
Normal file
55
python/ycm/diagnostic_interface.py
Normal file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2013 Strahinja Val Markovic <val@markovic.io>
|
||||
#
|
||||
# This file is part of YouCompleteMe.
|
||||
#
|
||||
# YouCompleteMe is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# YouCompleteMe is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from collections import defaultdict
|
||||
from operator import itemgetter
|
||||
from ycm import vimsupport
|
||||
|
||||
|
||||
class DiagnosticInterface( object ):
|
||||
def __init__( self ):
|
||||
self._buffer_number_to_diags = {}
|
||||
self._next_sign_id = 1
|
||||
|
||||
|
||||
def UpdateWithNewDiagnostics( self, diags ):
|
||||
self._buffer_number_to_diags = ConvertDiagListToDict( diags )
|
||||
for buffer_number, buffer_diags in self._buffer_number_to_diags.iteritems():
|
||||
if not vimsupport.BufferIsVisible( buffer_number ):
|
||||
continue
|
||||
|
||||
vimsupport.UnplaceAllSignsInBuffer( buffer_number )
|
||||
for diag in buffer_diags:
|
||||
vimsupport.PlaceSign( self._next_sign_id,
|
||||
diag[ 'lnum' ],
|
||||
buffer_number,
|
||||
diag[ 'type' ] == 'E' )
|
||||
self._next_sign_id += 1
|
||||
|
||||
|
||||
def ConvertDiagListToDict( diags ):
|
||||
buffer_to_diags = defaultdict( list )
|
||||
for diag in diags:
|
||||
buffer_to_diags[ diag[ 'bufnr' ] ].append( diag )
|
||||
for buffer_diags in buffer_to_diags.itervalues():
|
||||
# We also want errors to be listed before warnings so that errors aren't
|
||||
# hidden by the warnings; Vim won't place a sign oven an existing one.
|
||||
buffer_diags.sort( key = lambda diag: itemgetter( 'lnum', 'col', 'type' ) )
|
||||
return buffer_to_diags
|
||||
|
@ -83,15 +83,22 @@ def GetUnsavedAndCurrentBufferData():
|
||||
|
||||
|
||||
def GetBufferNumberForFilename( filename, open_file_if_needed = True ):
|
||||
return int( vim.eval( "bufnr('{0}', {1})".format(
|
||||
return GetIntValue( "bufnr('{0}', {1})".format(
|
||||
os.path.realpath( filename ),
|
||||
int( open_file_if_needed ) ) ) )
|
||||
int( open_file_if_needed ) ) )
|
||||
|
||||
|
||||
def GetCurrentBufferFilepath():
|
||||
return GetBufferFilepath( vim.current.buffer )
|
||||
|
||||
|
||||
def BufferIsVisible( buffer_number ):
|
||||
if buffer_number < 0:
|
||||
return False
|
||||
window_number = GetIntValue( "bufwinnr({0})".format( buffer_number ) )
|
||||
return window_number != -1
|
||||
|
||||
|
||||
def GetBufferFilepath( buffer_object ):
|
||||
if buffer_object.name:
|
||||
return buffer_object.name
|
||||
@ -100,6 +107,18 @@ def GetBufferFilepath( buffer_object ):
|
||||
return os.path.join( os.getcwd(), str( buffer_object.number ) )
|
||||
|
||||
|
||||
def UnplaceAllSignsInBuffer( buffer_number ):
|
||||
if buffer_number < 0:
|
||||
return
|
||||
vim.command( 'sign unplace * buffer={0}'.format( buffer_number ) )
|
||||
|
||||
|
||||
def PlaceSign( sign_id, line_num, buffer_num, is_error = True ):
|
||||
sign_name = 'YcmError' if is_error else 'YcmWarning'
|
||||
vim.command( 'sign place {0} line={1} name={2} buffer={3}'.format(
|
||||
sign_id, line_num, sign_name, buffer_num ) )
|
||||
|
||||
|
||||
# Given a dict like {'a': 1}, loads it into Vim as if you ran 'let g:a = 1'
|
||||
# When |overwrite| is True, overwrites the existing value in Vim.
|
||||
def LoadDictIntoVimGlobals( new_globals, overwrite = True ):
|
||||
@ -164,6 +183,7 @@ def PostVimMessage( message ):
|
||||
vim.command( "echohl WarningMsg | echom '{0}' | echohl None"
|
||||
.format( EscapeForVim( str( message ) ) ) )
|
||||
|
||||
|
||||
# Unlike PostVimMesasge, this supports messages with newlines in them because it
|
||||
# uses 'echo' instead of 'echomsg'. This also means that the message will NOT
|
||||
# appear in Vim's message log.
|
||||
|
@ -23,6 +23,7 @@ import tempfile
|
||||
import json
|
||||
from ycm import vimsupport
|
||||
from ycm import utils
|
||||
from ycm.diagnostic_interface import DiagnosticInterface
|
||||
from ycm.completers.all.omni_completer import OmniCompleter
|
||||
from ycm.completers.general import syntax_parse
|
||||
from ycm.completers.completer_utils import FiletypeCompleterExistsForFiletype
|
||||
@ -64,6 +65,7 @@ class YouCompleteMe( object ):
|
||||
def __init__( self, user_options ):
|
||||
self._user_options = user_options
|
||||
self._user_notified_about_crash = False
|
||||
self._diag_interface = DiagnosticInterface()
|
||||
self._omnicomp = OmniCompleter( user_options )
|
||||
self._latest_completion_request = None
|
||||
self._latest_file_parse_request = None
|
||||
@ -271,6 +273,13 @@ class YouCompleteMe( object ):
|
||||
return []
|
||||
|
||||
|
||||
def UpdateDiagnosticInterface( self ):
|
||||
if not self.DiagnosticsForCurrentFileReady():
|
||||
return
|
||||
self._diag_interface.UpdateWithNewDiagnostics(
|
||||
self.GetDiagnosticsFromStoredRequest() )
|
||||
|
||||
|
||||
def ShowDetailedDiagnostic( self ):
|
||||
if not self._IsServerAlive():
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user