Now highlighting the full identifier for diag
Instead of just underlining the first char of an identifier, we now underline. the full identifier.
This commit is contained in:
parent
6fdddc861b
commit
05552efd19
@ -107,6 +107,42 @@ std::vector< Range > GetRanges( const DiagnosticWrap &diagnostic_wrap ) {
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
||||
Range GetLocationExtent( CXSourceLocation source_location,
|
||||
CXTranslationUnit translation_unit ) {
|
||||
// If you think the below code is an idiotic way of getting the source range
|
||||
// for an identifier at a specific source location, you are not the only one.
|
||||
// I cannot believe that this is the only way to achieve this with the
|
||||
// libclang API in a robust way.
|
||||
// I've tried many simpler ways of doing this and they all fail in various
|
||||
// situations.
|
||||
|
||||
CXSourceRange range = clang_getCursorExtent(
|
||||
clang_getCursor( translation_unit, source_location ) );
|
||||
CXToken *tokens;
|
||||
uint num_tokens;
|
||||
clang_tokenize( translation_unit, range, &tokens, &num_tokens );
|
||||
|
||||
Location location( source_location );
|
||||
Range final_range;
|
||||
for ( uint i = 0; i < num_tokens; ++i ) {
|
||||
Location token_location( clang_getTokenLocation( translation_unit,
|
||||
tokens[ i ] ) );
|
||||
if ( token_location == location ) {
|
||||
std::string name = CXStringToString(
|
||||
clang_getTokenSpelling( translation_unit, tokens[ i ] ) );
|
||||
Location end_location = location;
|
||||
end_location.column_number_ += name.length();
|
||||
final_range = Range( location, end_location );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clang_disposeTokens( translation_unit, tokens, num_tokens );
|
||||
return final_range;
|
||||
}
|
||||
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||
@ -164,7 +200,8 @@ std::vector< CompletionData > ToCompletionDataVector(
|
||||
}
|
||||
|
||||
|
||||
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap ) {
|
||||
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
|
||||
CXTranslationUnit translation_unit ) {
|
||||
Diagnostic diagnostic;
|
||||
|
||||
if ( !diagnostic_wrap )
|
||||
@ -178,8 +215,11 @@ Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap ) {
|
||||
if ( diagnostic.kind_ == 'I' )
|
||||
return diagnostic;
|
||||
|
||||
diagnostic.location_ = Location(
|
||||
clang_getDiagnosticLocation( diagnostic_wrap.get() ) );
|
||||
CXSourceLocation source_location =
|
||||
clang_getDiagnosticLocation( diagnostic_wrap.get() );
|
||||
diagnostic.location_ = Location( source_location );
|
||||
diagnostic.location_extent_ = GetLocationExtent( source_location,
|
||||
translation_unit );
|
||||
diagnostic.ranges_ = GetRanges( diagnostic_wrap );
|
||||
diagnostic.text_ = CXStringToString(
|
||||
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
|
||||
|
@ -40,7 +40,8 @@ std::vector< CompletionData > ToCompletionDataVector(
|
||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||
const std::vector< UnsavedFile > &unsaved_files );
|
||||
|
||||
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap );
|
||||
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
|
||||
CXTranslationUnit translation_unit );
|
||||
|
||||
} // namespace YouCompleteMe
|
||||
|
||||
|
@ -37,6 +37,8 @@ struct Diagnostic {
|
||||
|
||||
Location location_;
|
||||
|
||||
Range location_extent_;
|
||||
|
||||
std::vector< Range > ranges_;
|
||||
|
||||
// Vim's error "kind"
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
namespace YouCompleteMe {
|
||||
|
||||
// Half-open, [start, end>
|
||||
struct Range {
|
||||
Range() {}
|
||||
|
||||
|
@ -270,9 +270,10 @@ void TranslationUnit::UpdateLatestDiagnostics() {
|
||||
|
||||
for ( uint i = 0; i < num_diagnostics; ++i ) {
|
||||
Diagnostic diagnostic =
|
||||
DiagnosticWrapToDiagnostic(
|
||||
BuildDiagnostic(
|
||||
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
|
||||
clang_disposeDiagnostic ) );
|
||||
clang_disposeDiagnostic ),
|
||||
clang_translation_unit_ );
|
||||
|
||||
if ( diagnostic.kind_ != 'I' )
|
||||
latest_diagnostics_.push_back( diagnostic );
|
||||
|
@ -128,6 +128,7 @@ BOOST_PYTHON_MODULE(ycm_core)
|
||||
class_< Diagnostic >( "Diagnostic" )
|
||||
.def_readonly( "ranges_", &Diagnostic::ranges_ )
|
||||
.def_readonly( "location_", &Diagnostic::location_ )
|
||||
.def_readonly( "location_extent_", &Diagnostic::location_extent_ )
|
||||
.def_readonly( "kind_", &Diagnostic::kind_ )
|
||||
.def_readonly( "text_", &Diagnostic::text_ )
|
||||
.def_readonly( "long_formatted_text_", &Diagnostic::long_formatted_text_ );
|
||||
|
@ -62,14 +62,18 @@ def _UpdateSquiggles( buffer_number_to_line_to_diags ):
|
||||
|
||||
for diags in line_to_diags.itervalues():
|
||||
for diag in diags:
|
||||
location = diag[ 'location' ]
|
||||
location_extent = diag[ 'location_extent' ]
|
||||
is_error = _DiagnosticIsError( diag )
|
||||
|
||||
vimsupport.AddDiagnosticSyntaxMatch(
|
||||
location[ 'line_num' ] + 1,
|
||||
location[ 'column_num' ] + 1,
|
||||
location_extent[ 'start' ][ 'line_num' ] + 1,
|
||||
location_extent[ 'start' ][ 'column_num' ] + 1,
|
||||
location_extent[ 'end' ][ 'line_num' ] + 1,
|
||||
location_extent[ 'end' ][ 'column_num' ] + 1,
|
||||
is_error = is_error )
|
||||
|
||||
vimsupport.EchoText( diag )
|
||||
|
||||
for diag_range in diag[ 'ranges' ]:
|
||||
vimsupport.AddDiagnosticSyntaxMatch(
|
||||
diag_range[ 'start' ][ 'line_num' ] + 1,
|
||||
|
@ -118,6 +118,7 @@ def BuildDiagnosticData( diagnostic ):
|
||||
return {
|
||||
'ranges': [ BuildRangeData( x ) for x in diagnostic.ranges_ ],
|
||||
'location': BuildLocationData( diagnostic.location_ ),
|
||||
'location_extent': BuildRangeData( diagnostic.location_extent_ ),
|
||||
'text': diagnostic.text_,
|
||||
'kind': diagnostic.kind_
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ void foo() {
|
||||
filetype = 'cpp' )
|
||||
|
||||
results = app.post_json( '/event_notification', event_data ).json
|
||||
print results
|
||||
assert_that( results,
|
||||
contains(
|
||||
has_entries( {
|
||||
@ -66,9 +65,53 @@ void foo() {
|
||||
'location': has_entries( {
|
||||
'line_num': 2,
|
||||
'column_num': 9
|
||||
} ),
|
||||
'location_extent': has_entries( {
|
||||
'start': has_entries( {
|
||||
'line_num': 2,
|
||||
'column_num': 9,
|
||||
} ),
|
||||
'end': has_entries( {
|
||||
'line_num': 2,
|
||||
'column_num': 12,
|
||||
} ),
|
||||
} )
|
||||
} ) ) )
|
||||
|
||||
|
||||
@with_setup( Setup )
|
||||
def Diagnostics_ClangCompleter_SimpleLocationExtent_test():
|
||||
app = TestApp( handlers.app )
|
||||
contents = """
|
||||
void foo() {
|
||||
baz = 5;
|
||||
}
|
||||
// Padding to 5 lines
|
||||
// Padding to 5 lines
|
||||
"""
|
||||
|
||||
event_data = BuildRequest( compilation_flags = ['-x', 'c++'],
|
||||
event_name = 'FileReadyToParse',
|
||||
contents = contents,
|
||||
filetype = 'cpp' )
|
||||
|
||||
results = app.post_json( '/event_notification', event_data ).json
|
||||
assert_that( results,
|
||||
contains(
|
||||
has_entries( {
|
||||
'location_extent': has_entries( {
|
||||
'start': has_entries( {
|
||||
'line_num': 2,
|
||||
'column_num': 2,
|
||||
} ),
|
||||
'end': has_entries( {
|
||||
'line_num': 2,
|
||||
'column_num': 5,
|
||||
} ),
|
||||
} )
|
||||
} ) ) )
|
||||
|
||||
|
||||
@with_setup( Setup )
|
||||
def Diagnostics_ClangCompleter_PragmaOnceWarningIgnored_test():
|
||||
app = TestApp( handlers.app )
|
||||
|
@ -143,7 +143,7 @@ def AddDiagnosticSyntaxMatch( line_num,
|
||||
"matchadd('{0}', '\%{1}l\%{2}c')".format( group, line_num, column_num ) )
|
||||
else:
|
||||
return GetIntValue(
|
||||
"matchadd('{0}', '\%{1}l\%{2}c.*\%{3}l\%{4}c')".format(
|
||||
"matchadd('{0}', '\%{1}l\%{2}c\_.*\%{3}l\%{4}c')".format(
|
||||
group, line_num, column_num, line_end_num, column_end_num ) )
|
||||
|
||||
|
||||
@ -253,14 +253,14 @@ def EchoText( text, log_as_message = True ):
|
||||
command = 'echom' if log_as_message else 'echo'
|
||||
vim.command( "{0} '{1}'".format( command, EscapeForVim( text ) ) )
|
||||
|
||||
for line in text.split( '\n' ):
|
||||
for line in str( text ).split( '\n' ):
|
||||
EchoLine( line )
|
||||
|
||||
|
||||
# Echos text but truncates the text so that it all fits on one line
|
||||
def EchoTextVimWidth( text ):
|
||||
vim_width = GetIntValue( '&columns' )
|
||||
truncated_text = text[ : int( vim_width * 0.9 ) ]
|
||||
truncated_text = str( text )[ : int( vim_width * 0.9 ) ]
|
||||
truncated_text.replace( '\n', ' ' )
|
||||
EchoText( truncated_text, False )
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user