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;
|
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
|
} // unnamed namespace
|
||||||
|
|
||||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
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;
|
Diagnostic diagnostic;
|
||||||
|
|
||||||
if ( !diagnostic_wrap )
|
if ( !diagnostic_wrap )
|
||||||
@ -178,8 +215,11 @@ Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap ) {
|
|||||||
if ( diagnostic.kind_ == 'I' )
|
if ( diagnostic.kind_ == 'I' )
|
||||||
return diagnostic;
|
return diagnostic;
|
||||||
|
|
||||||
diagnostic.location_ = Location(
|
CXSourceLocation source_location =
|
||||||
clang_getDiagnosticLocation( diagnostic_wrap.get() ) );
|
clang_getDiagnosticLocation( diagnostic_wrap.get() );
|
||||||
|
diagnostic.location_ = Location( source_location );
|
||||||
|
diagnostic.location_extent_ = GetLocationExtent( source_location,
|
||||||
|
translation_unit );
|
||||||
diagnostic.ranges_ = GetRanges( diagnostic_wrap );
|
diagnostic.ranges_ = GetRanges( diagnostic_wrap );
|
||||||
diagnostic.text_ = CXStringToString(
|
diagnostic.text_ = CXStringToString(
|
||||||
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
|
clang_getDiagnosticSpelling( diagnostic_wrap.get() ) );
|
||||||
|
@ -40,7 +40,8 @@ std::vector< CompletionData > ToCompletionDataVector(
|
|||||||
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
std::vector< CXUnsavedFile > ToCXUnsavedFiles(
|
||||||
const std::vector< UnsavedFile > &unsaved_files );
|
const std::vector< UnsavedFile > &unsaved_files );
|
||||||
|
|
||||||
Diagnostic DiagnosticWrapToDiagnostic( DiagnosticWrap diagnostic_wrap );
|
Diagnostic BuildDiagnostic( DiagnosticWrap diagnostic_wrap,
|
||||||
|
CXTranslationUnit translation_unit );
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ struct Diagnostic {
|
|||||||
|
|
||||||
Location location_;
|
Location location_;
|
||||||
|
|
||||||
|
Range location_extent_;
|
||||||
|
|
||||||
std::vector< Range > ranges_;
|
std::vector< Range > ranges_;
|
||||||
|
|
||||||
// Vim's error "kind"
|
// Vim's error "kind"
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace YouCompleteMe {
|
namespace YouCompleteMe {
|
||||||
|
|
||||||
|
// Half-open, [start, end>
|
||||||
struct Range {
|
struct Range {
|
||||||
Range() {}
|
Range() {}
|
||||||
|
|
||||||
|
@ -270,9 +270,10 @@ void TranslationUnit::UpdateLatestDiagnostics() {
|
|||||||
|
|
||||||
for ( uint i = 0; i < num_diagnostics; ++i ) {
|
for ( uint i = 0; i < num_diagnostics; ++i ) {
|
||||||
Diagnostic diagnostic =
|
Diagnostic diagnostic =
|
||||||
DiagnosticWrapToDiagnostic(
|
BuildDiagnostic(
|
||||||
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
|
DiagnosticWrap( clang_getDiagnostic( clang_translation_unit_, i ),
|
||||||
clang_disposeDiagnostic ) );
|
clang_disposeDiagnostic ),
|
||||||
|
clang_translation_unit_ );
|
||||||
|
|
||||||
if ( diagnostic.kind_ != 'I' )
|
if ( diagnostic.kind_ != 'I' )
|
||||||
latest_diagnostics_.push_back( diagnostic );
|
latest_diagnostics_.push_back( diagnostic );
|
||||||
|
@ -128,6 +128,7 @@ BOOST_PYTHON_MODULE(ycm_core)
|
|||||||
class_< Diagnostic >( "Diagnostic" )
|
class_< Diagnostic >( "Diagnostic" )
|
||||||
.def_readonly( "ranges_", &Diagnostic::ranges_ )
|
.def_readonly( "ranges_", &Diagnostic::ranges_ )
|
||||||
.def_readonly( "location_", &Diagnostic::location_ )
|
.def_readonly( "location_", &Diagnostic::location_ )
|
||||||
|
.def_readonly( "location_extent_", &Diagnostic::location_extent_ )
|
||||||
.def_readonly( "kind_", &Diagnostic::kind_ )
|
.def_readonly( "kind_", &Diagnostic::kind_ )
|
||||||
.def_readonly( "text_", &Diagnostic::text_ )
|
.def_readonly( "text_", &Diagnostic::text_ )
|
||||||
.def_readonly( "long_formatted_text_", &Diagnostic::long_formatted_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 diags in line_to_diags.itervalues():
|
||||||
for diag in diags:
|
for diag in diags:
|
||||||
location = diag[ 'location' ]
|
location_extent = diag[ 'location_extent' ]
|
||||||
is_error = _DiagnosticIsError( diag )
|
is_error = _DiagnosticIsError( diag )
|
||||||
|
|
||||||
vimsupport.AddDiagnosticSyntaxMatch(
|
vimsupport.AddDiagnosticSyntaxMatch(
|
||||||
location[ 'line_num' ] + 1,
|
location_extent[ 'start' ][ 'line_num' ] + 1,
|
||||||
location[ 'column_num' ] + 1,
|
location_extent[ 'start' ][ 'column_num' ] + 1,
|
||||||
|
location_extent[ 'end' ][ 'line_num' ] + 1,
|
||||||
|
location_extent[ 'end' ][ 'column_num' ] + 1,
|
||||||
is_error = is_error )
|
is_error = is_error )
|
||||||
|
|
||||||
|
vimsupport.EchoText( diag )
|
||||||
|
|
||||||
for diag_range in diag[ 'ranges' ]:
|
for diag_range in diag[ 'ranges' ]:
|
||||||
vimsupport.AddDiagnosticSyntaxMatch(
|
vimsupport.AddDiagnosticSyntaxMatch(
|
||||||
diag_range[ 'start' ][ 'line_num' ] + 1,
|
diag_range[ 'start' ][ 'line_num' ] + 1,
|
||||||
|
@ -118,6 +118,7 @@ def BuildDiagnosticData( diagnostic ):
|
|||||||
return {
|
return {
|
||||||
'ranges': [ BuildRangeData( x ) for x in diagnostic.ranges_ ],
|
'ranges': [ BuildRangeData( x ) for x in diagnostic.ranges_ ],
|
||||||
'location': BuildLocationData( diagnostic.location_ ),
|
'location': BuildLocationData( diagnostic.location_ ),
|
||||||
|
'location_extent': BuildRangeData( diagnostic.location_extent_ ),
|
||||||
'text': diagnostic.text_,
|
'text': diagnostic.text_,
|
||||||
'kind': diagnostic.kind_
|
'kind': diagnostic.kind_
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ void foo() {
|
|||||||
filetype = 'cpp' )
|
filetype = 'cpp' )
|
||||||
|
|
||||||
results = app.post_json( '/event_notification', event_data ).json
|
results = app.post_json( '/event_notification', event_data ).json
|
||||||
print results
|
|
||||||
assert_that( results,
|
assert_that( results,
|
||||||
contains(
|
contains(
|
||||||
has_entries( {
|
has_entries( {
|
||||||
@ -66,9 +65,53 @@ void foo() {
|
|||||||
'location': has_entries( {
|
'location': has_entries( {
|
||||||
'line_num': 2,
|
'line_num': 2,
|
||||||
'column_num': 9
|
'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 )
|
@with_setup( Setup )
|
||||||
def Diagnostics_ClangCompleter_PragmaOnceWarningIgnored_test():
|
def Diagnostics_ClangCompleter_PragmaOnceWarningIgnored_test():
|
||||||
app = TestApp( handlers.app )
|
app = TestApp( handlers.app )
|
||||||
|
@ -143,7 +143,7 @@ def AddDiagnosticSyntaxMatch( line_num,
|
|||||||
"matchadd('{0}', '\%{1}l\%{2}c')".format( group, line_num, column_num ) )
|
"matchadd('{0}', '\%{1}l\%{2}c')".format( group, line_num, column_num ) )
|
||||||
else:
|
else:
|
||||||
return GetIntValue(
|
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 ) )
|
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'
|
command = 'echom' if log_as_message else 'echo'
|
||||||
vim.command( "{0} '{1}'".format( command, EscapeForVim( text ) ) )
|
vim.command( "{0} '{1}'".format( command, EscapeForVim( text ) ) )
|
||||||
|
|
||||||
for line in text.split( '\n' ):
|
for line in str( text ).split( '\n' ):
|
||||||
EchoLine( line )
|
EchoLine( line )
|
||||||
|
|
||||||
|
|
||||||
# Echos text but truncates the text so that it all fits on one line
|
# Echos text but truncates the text so that it all fits on one line
|
||||||
def EchoTextVimWidth( text ):
|
def EchoTextVimWidth( text ):
|
||||||
vim_width = GetIntValue( '&columns' )
|
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', ' ' )
|
truncated_text.replace( '\n', ' ' )
|
||||||
EchoText( truncated_text, False )
|
EchoText( truncated_text, False )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user