forked from enlightenment/edi
Merge the clang syntax highlight parsing work from edi PROTO.
That's the parsing complete but I need to hook it into style the elm_entry widget...
This commit is contained in:
parent
d40c220e68
commit
f11369a361
1
AUTHORS
1
AUTHORS
|
@ -2,4 +2,5 @@ ajwillia.ms (Andy Williams) <andy@andywilliams.me>
|
||||||
|
|
||||||
|
|
||||||
With sections from Ecrire by Tom Hacohen <tom@stosb.com>
|
With sections from Ecrire by Tom Hacohen <tom@stosb.com>
|
||||||
|
Clang syntax higlighting from cedric and TAsn in the edi PROTO project
|
||||||
|
|
||||||
|
|
25
configure.ac
25
configure.ac
|
@ -46,6 +46,30 @@ AC_ARG_WITH([tests],
|
||||||
[build_tests=${withval}],
|
[build_tests=${withval}],
|
||||||
[build_tests=auto])
|
[build_tests=auto])
|
||||||
|
|
||||||
|
|
||||||
|
HAVE_LIBCLANG=0
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(libclang,
|
||||||
|
[ --disable-libclang Disable use of libclang.],,)
|
||||||
|
|
||||||
|
build_clang="no"
|
||||||
|
if test "$enable_libclang" != "no"; then
|
||||||
|
AC_CHECK_HEADERS("clang-c/Index.h")
|
||||||
|
if test "$ac_cv_header_clang_c_Index_h" = "yes"; then
|
||||||
|
AC_CHECK_LIB(clang, clang_Cursor_getArgument)
|
||||||
|
if test "$ac_cv_lib_clang_clang_Cursor_getArgument" = "yes"; then
|
||||||
|
HAVE_LIBCLANG=1;
|
||||||
|
MORE_LIBS="$MORE_LIBS -lclang"
|
||||||
|
build_clang="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test "$HAVE_LIBCLANG" = "0"; then
|
||||||
|
AC_MSG_WARN([Could not find a usable libclang. Please install libclang to enable syntax highlighting features.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(HAVE_LIBCLANG)
|
||||||
|
|
||||||
EFL_TESTS([${build_tests}])
|
EFL_TESTS([${build_tests}])
|
||||||
|
|
||||||
# doxygen program for documentation building
|
# doxygen program for documentation building
|
||||||
|
@ -90,6 +114,7 @@ echo
|
||||||
echo "Compilation..............: make (or gmake)"
|
echo "Compilation..............: make (or gmake)"
|
||||||
echo " CFLAGS.................: $CFLAGS"
|
echo " CFLAGS.................: $CFLAGS"
|
||||||
echo " edje_cc................: ${edje_cc}"
|
echo " edje_cc................: ${edje_cc}"
|
||||||
|
echo " clang..................: ${build_clang}"
|
||||||
echo
|
echo
|
||||||
echo "Building documentation...: ${build_doc}"
|
echo "Building documentation...: ${build_doc}"
|
||||||
echo "Building tests...........: ${have_tests}"
|
echo "Building tests...........: ${have_tests}"
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
#ifndef _CLANG_DEBUG_H
|
||||||
|
#define _CLANG_DEBUG_H
|
||||||
|
#include <clang-c/Index.h>
|
||||||
|
|
||||||
|
static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
|
||||||
|
unsigned end_line, unsigned end_column) {
|
||||||
|
fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
|
||||||
|
end_line, end_column);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintRange(CXSourceRange R, const char *str) {
|
||||||
|
CXFile begin_file, end_file;
|
||||||
|
unsigned begin_line, begin_column, end_line, end_column;
|
||||||
|
|
||||||
|
clang_getSpellingLocation(clang_getRangeStart(R),
|
||||||
|
&begin_file, &begin_line, &begin_column, 0);
|
||||||
|
clang_getSpellingLocation(clang_getRangeEnd(R),
|
||||||
|
&end_file, &end_line, &end_column, 0);
|
||||||
|
if (!begin_file || !end_file)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
printf(" %s=", str);
|
||||||
|
PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintToken(CXTranslationUnit tx, CXToken token)
|
||||||
|
{
|
||||||
|
CXString str = clang_getTokenSpelling(tx, token);
|
||||||
|
PrintRange(clang_getTokenExtent(tx, token), clang_getCString(str));
|
||||||
|
clang_disposeString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
int want_display_name = 0;
|
||||||
|
|
||||||
|
void PrintCursor(CXCursor Cursor) {
|
||||||
|
CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
|
||||||
|
if (clang_isInvalid(Cursor.kind)) {
|
||||||
|
CXString ks = clang_getCursorKindSpelling(Cursor.kind);
|
||||||
|
printf("Invalid Cursor => %s", clang_getCString(ks));
|
||||||
|
clang_disposeString(ks);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CXString string, ks;
|
||||||
|
CXCursor Referenced;
|
||||||
|
unsigned line, column;
|
||||||
|
CXCursor SpecializationOf;
|
||||||
|
CXCursor *overridden;
|
||||||
|
unsigned num_overridden;
|
||||||
|
unsigned RefNameRangeNr;
|
||||||
|
CXSourceRange CursorExtent;
|
||||||
|
CXSourceRange RefNameRange;
|
||||||
|
|
||||||
|
ks = clang_getCursorKindSpelling(Cursor.kind);
|
||||||
|
string = want_display_name? clang_getCursorDisplayName(Cursor)
|
||||||
|
: clang_getCursorSpelling(Cursor);
|
||||||
|
printf("%s=%s", clang_getCString(ks),
|
||||||
|
clang_getCString(string));
|
||||||
|
clang_disposeString(ks);
|
||||||
|
clang_disposeString(string);
|
||||||
|
|
||||||
|
Referenced = clang_getCursorReferenced(Cursor);
|
||||||
|
if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
|
||||||
|
if (clang_getCursorKind(Referenced) == CXCursor_OverloadedDeclRef) {
|
||||||
|
unsigned I, N = clang_getNumOverloadedDecls(Referenced);
|
||||||
|
printf("[");
|
||||||
|
for (I = 0; I != N; ++I) {
|
||||||
|
CXCursor Ovl = clang_getOverloadedDecl(Referenced, I);
|
||||||
|
CXSourceLocation Loc;
|
||||||
|
if (I)
|
||||||
|
printf(", ");
|
||||||
|
|
||||||
|
Loc = clang_getCursorLocation(Ovl);
|
||||||
|
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
|
||||||
|
printf("%d:%d", line, column);
|
||||||
|
}
|
||||||
|
printf("]");
|
||||||
|
} else {
|
||||||
|
CXFile cfile;
|
||||||
|
CXSourceLocation Loc = clang_getCursorLocation(Referenced);
|
||||||
|
clang_getSpellingLocation(Loc, &cfile, &line, &column, 0);
|
||||||
|
CXString str = clang_getFileName(cfile);
|
||||||
|
printf(":%s:%d:%d", clang_getCString(str), line, column);
|
||||||
|
clang_disposeString(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clang_isCursorDefinition(Cursor))
|
||||||
|
printf(" (Definition)");
|
||||||
|
|
||||||
|
switch (clang_getCursorAvailability(Cursor)) {
|
||||||
|
case CXAvailability_Available:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CXAvailability_Deprecated:
|
||||||
|
printf(" (deprecated)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CXAvailability_NotAvailable:
|
||||||
|
printf(" (unavailable)");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CXAvailability_NotAccessible:
|
||||||
|
printf(" (inaccessible)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clang_CXXMethod_isStatic(Cursor))
|
||||||
|
printf(" (static)");
|
||||||
|
if (clang_CXXMethod_isVirtual(Cursor))
|
||||||
|
printf(" (virtual)");
|
||||||
|
|
||||||
|
if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
|
||||||
|
CXType T =
|
||||||
|
clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
|
||||||
|
CXString S = clang_getTypeKindSpelling(T.kind);
|
||||||
|
printf(" [IBOutletCollection=%s]", clang_getCString(S));
|
||||||
|
clang_disposeString(S);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
|
||||||
|
enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
|
||||||
|
unsigned isVirtual = clang_isVirtualBase(Cursor);
|
||||||
|
const char *accessStr = 0;
|
||||||
|
|
||||||
|
switch (access) {
|
||||||
|
case CX_CXXInvalidAccessSpecifier:
|
||||||
|
accessStr = "invalid"; break;
|
||||||
|
case CX_CXXPublic:
|
||||||
|
accessStr = "public"; break;
|
||||||
|
case CX_CXXProtected:
|
||||||
|
accessStr = "protected"; break;
|
||||||
|
case CX_CXXPrivate:
|
||||||
|
accessStr = "private"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" [access=%s isVirtual=%s]", accessStr,
|
||||||
|
isVirtual ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
|
||||||
|
if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
|
||||||
|
CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
|
||||||
|
CXString Name = clang_getCursorSpelling(SpecializationOf);
|
||||||
|
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
|
||||||
|
printf(" [Specialization of %s:%d:%d]",
|
||||||
|
clang_getCString(Name), line, column);
|
||||||
|
clang_disposeString(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
clang_getOverriddenCursors(Cursor, &overridden, &num_overridden);
|
||||||
|
if (num_overridden) {
|
||||||
|
unsigned I;
|
||||||
|
printf(" [Overrides ");
|
||||||
|
for (I = 0; I != num_overridden; ++I) {
|
||||||
|
CXSourceLocation Loc = clang_getCursorLocation(overridden[I]);
|
||||||
|
clang_getSpellingLocation(Loc, 0, &line, &column, 0);
|
||||||
|
if (I)
|
||||||
|
printf(", ");
|
||||||
|
printf("@%d:%d", line, column);
|
||||||
|
}
|
||||||
|
printf("]");
|
||||||
|
clang_disposeOverriddenCursors(overridden);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cursor.kind == CXCursor_InclusionDirective) {
|
||||||
|
CXFile File = clang_getIncludedFile(Cursor);
|
||||||
|
CXString Included = clang_getFileName(File);
|
||||||
|
printf(" (%s)", clang_getCString(Included));
|
||||||
|
clang_disposeString(Included);
|
||||||
|
|
||||||
|
if (clang_isFileMultipleIncludeGuarded(TU, File))
|
||||||
|
printf(" [multi-include guarded]");
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorExtent = clang_getCursorExtent(Cursor);
|
||||||
|
RefNameRange = clang_getCursorReferenceNameRange(Cursor,
|
||||||
|
CXNameRange_WantQualifier
|
||||||
|
| CXNameRange_WantSinglePiece
|
||||||
|
| CXNameRange_WantTemplateArgs,
|
||||||
|
0);
|
||||||
|
if (!clang_equalRanges(CursorExtent, RefNameRange))
|
||||||
|
PrintRange(RefNameRange, "SingleRefName");
|
||||||
|
|
||||||
|
for (RefNameRangeNr = 0; 1; RefNameRangeNr++) {
|
||||||
|
RefNameRange = clang_getCursorReferenceNameRange(Cursor,
|
||||||
|
CXNameRange_WantQualifier
|
||||||
|
| CXNameRange_WantTemplateArgs,
|
||||||
|
RefNameRangeNr);
|
||||||
|
if (clang_equalRanges(clang_getNullRange(), RefNameRange))
|
||||||
|
break;
|
||||||
|
if (!clang_equalRanges(CursorExtent, RefNameRange))
|
||||||
|
PrintRange(RefNameRange, "RefName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -9,12 +9,31 @@
|
||||||
|
|
||||||
#include "edi_editor.h"
|
#include "edi_editor.h"
|
||||||
|
|
||||||
|
#define CLANG_DEBUG 0
|
||||||
|
#if CLANG_DEBUG
|
||||||
|
#include "clang_debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mainview/edi_mainview.h"
|
#include "mainview/edi_mainview.h"
|
||||||
|
|
||||||
#include "edi_private.h"
|
#include "edi_private.h"
|
||||||
|
|
||||||
#define EDITOR_FONT "DEFAULT='font=Monospace font_size=12'"
|
#define EDITOR_FONT "DEFAULT='font=Monospace font_size=12'"
|
||||||
|
|
||||||
|
#define Edi_Color const char *
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int line;
|
||||||
|
unsigned int col;
|
||||||
|
} Edi_Location;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Edi_Location start;
|
||||||
|
Edi_Location end;
|
||||||
|
} Edi_Range;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_update_lines(Edi_Editor *editor);
|
_update_lines(Edi_Editor *editor);
|
||||||
|
|
||||||
|
@ -236,6 +255,244 @@ _edi_editor_statusbar_add(Evas_Object *panel, Edi_Editor *editor, Edi_Mainview_I
|
||||||
evas_object_smart_callback_add(editor->entry, "cursor,changed", _edit_cursor_moved, position);
|
evas_object_smart_callback_add(editor->entry, "cursor,changed", _edit_cursor_moved, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_range_color_set(Edi_Editor *editor, Edi_Range range, Edi_Color color)
|
||||||
|
{
|
||||||
|
Evas_Object *textblock;
|
||||||
|
printf("Setting color %s for range(%d:%d, %d:%d)\n", color, range.start.line, range.start.col, range.end.line, range.end.col);
|
||||||
|
|
||||||
|
textblock = elm_entry_textblock_get(editor->entry);
|
||||||
|
// TODO actually set some styling on our textblock
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_LIBCLANG
|
||||||
|
static void
|
||||||
|
_clang_load_highlighting(const char *path, Edi_Editor *editor)
|
||||||
|
{
|
||||||
|
CXToken *tokens = NULL;
|
||||||
|
unsigned int n = 0;
|
||||||
|
unsigned int i = 0;
|
||||||
|
CXCursor *cursors = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
CXFile cfile = clang_getFile(editor->tx_unit, path);
|
||||||
|
int tgridw = 0, tgridh = 0;
|
||||||
|
evas_object_textblock_size_native_get(elm_entry_textblock_get(editor->entry), &tgridw, &tgridh);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* FIXME: Should be used, I don't know why tokenize doesn't work in mid
|
||||||
|
* comment cases and etc. */
|
||||||
|
int range_start, range_end;
|
||||||
|
range_start = editor->offset;
|
||||||
|
range_end = editor->offset + tgridh;
|
||||||
|
CXSourceRange range = clang_getRange(clang_getLocation(editor->tx_unit, cfile, range_start, 1), clang_getLocation(editor->tx_unit, cfile, range_end, tgridw));
|
||||||
|
#else
|
||||||
|
CXSourceRange range = clang_getRange(
|
||||||
|
clang_getLocationForOffset(editor->tx_unit, cfile, 0),
|
||||||
|
clang_getLocationForOffset(editor->tx_unit, cfile, eina_file_size_get(eina_file_open(path, EINA_FALSE))));
|
||||||
|
#endif
|
||||||
|
clang_tokenize(editor->tx_unit, range, &tokens, &n);
|
||||||
|
/* FIXME: We should use annotate tokens and then use a lot more
|
||||||
|
* color classes. I don't know why it's broken ATM... :( */
|
||||||
|
cursors = (CXCursor *) malloc(n * sizeof(CXCursor));
|
||||||
|
clang_annotateTokens(editor->tx_unit, tokens, n, cursors);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < n ; i++)
|
||||||
|
{
|
||||||
|
Edi_Range range;
|
||||||
|
Edi_Color color = "";
|
||||||
|
//EDI_COLOR_FOREGROUND_DEFAULT;
|
||||||
|
|
||||||
|
CXSourceRange tkrange = clang_getTokenExtent(editor->tx_unit, tokens[i]);
|
||||||
|
clang_getSpellingLocation(clang_getRangeStart(tkrange), NULL,
|
||||||
|
&range.start.line, &range.start.col, NULL);
|
||||||
|
clang_getSpellingLocation(clang_getRangeEnd(tkrange), NULL,
|
||||||
|
&range.end.line, &range.end.col, NULL);
|
||||||
|
/* FIXME: Should probably do something fancier, this is only a limited
|
||||||
|
* number of types. */
|
||||||
|
switch (clang_getTokenKind(tokens[i]))
|
||||||
|
{
|
||||||
|
case CXToken_Punctuation:
|
||||||
|
case CXToken_Identifier:
|
||||||
|
switch (cursors[i].kind)
|
||||||
|
{
|
||||||
|
case CXCursor_DeclRefExpr:
|
||||||
|
/* Handle different ref kinds */
|
||||||
|
// color = EDI_COLOR_FOREGROUND_REF;
|
||||||
|
break;
|
||||||
|
case CXCursor_MacroDefinition:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_MACRO_DEFINITION;
|
||||||
|
break;
|
||||||
|
case CXCursor_InclusionDirective:
|
||||||
|
case CXCursor_PreprocessingDirective:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_PREPROCESSING_DIRECTIVE;
|
||||||
|
break;
|
||||||
|
case CXCursor_TypeRef:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_USER_TYPE;
|
||||||
|
break;
|
||||||
|
case CXCursor_MacroExpansion:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_MACRO_EXPANSION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_DEFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CXToken_Keyword:
|
||||||
|
switch (cursors[i].kind)
|
||||||
|
{
|
||||||
|
case CXCursor_PreprocessingDirective:
|
||||||
|
// color = EDI_COLOR_FOREGROUND_PREPROCESSING_DIRECTIVE;
|
||||||
|
break;
|
||||||
|
case CXCursor_CaseStmt:
|
||||||
|
case CXCursor_DefaultStmt:
|
||||||
|
case CXCursor_IfStmt:
|
||||||
|
case CXCursor_SwitchStmt:
|
||||||
|
case CXCursor_WhileStmt:
|
||||||
|
case CXCursor_DoStmt:
|
||||||
|
case CXCursor_ForStmt:
|
||||||
|
case CXCursor_GotoStmt:
|
||||||
|
case CXCursor_IndirectGotoStmt:
|
||||||
|
case CXCursor_ContinueStmt:
|
||||||
|
case CXCursor_BreakStmt:
|
||||||
|
case CXCursor_ReturnStmt:
|
||||||
|
case CXCursor_AsmStmt:
|
||||||
|
case CXCursor_ObjCAtTryStmt:
|
||||||
|
case CXCursor_ObjCAtCatchStmt:
|
||||||
|
case CXCursor_ObjCAtFinallyStmt:
|
||||||
|
case CXCursor_ObjCAtThrowStmt:
|
||||||
|
case CXCursor_ObjCAtSynchronizedStmt:
|
||||||
|
case CXCursor_ObjCAutoreleasePoolStmt:
|
||||||
|
case CXCursor_ObjCForCollectionStmt:
|
||||||
|
case CXCursor_CXXCatchStmt:
|
||||||
|
case CXCursor_CXXTryStmt:
|
||||||
|
case CXCursor_CXXForRangeStmt:
|
||||||
|
case CXCursor_SEHTryStmt:
|
||||||
|
case CXCursor_SEHExceptStmt:
|
||||||
|
case CXCursor_SEHFinallyStmt:
|
||||||
|
color = "stmt";
|
||||||
|
// color = EDI_COLOR_FOREGROUND_KEYWORD_STMT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "keyword";
|
||||||
|
// color = EDI_COLOR_FOREGROUND_KEYWORD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CXToken_Literal:
|
||||||
|
color = "literal";
|
||||||
|
// color = EDI_COLOR_FOREGROUND_LITERAL;
|
||||||
|
break;
|
||||||
|
case CXToken_Comment:
|
||||||
|
color = "comment";
|
||||||
|
// color = EDI_COLOR_FOREGROUND_COMMENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_edi_range_color_set(editor, range, color);
|
||||||
|
|
||||||
|
#if CLANG_DEBUG
|
||||||
|
const char *kind = NULL;
|
||||||
|
switch (clang_getTokenKind(tokens[i])) {
|
||||||
|
case CXToken_Punctuation: kind = "Punctuation"; break;
|
||||||
|
case CXToken_Keyword: kind = "Keyword"; break;
|
||||||
|
case CXToken_Identifier: kind = "Identifier"; break;
|
||||||
|
case CXToken_Literal: kind = "Literal"; break;
|
||||||
|
case CXToken_Comment: kind = "Comment"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s ", kind);
|
||||||
|
PrintToken(editor->tx_unit, tokens[i]);
|
||||||
|
|
||||||
|
if (!clang_isInvalid(cursors[i].kind)) {
|
||||||
|
printf(" ");
|
||||||
|
PrintCursor(cursors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cursors);
|
||||||
|
clang_disposeTokens(editor->tx_unit, tokens, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_clang_load_errors(const char *path, Edi_Editor *editor)
|
||||||
|
{
|
||||||
|
unsigned n = clang_getNumDiagnostics(editor->tx_unit);
|
||||||
|
unsigned i = 0;
|
||||||
|
|
||||||
|
for(i = 0, n = clang_getNumDiagnostics(editor->tx_unit); i != n; ++i)
|
||||||
|
{
|
||||||
|
CXDiagnostic diag = clang_getDiagnostic(editor->tx_unit, i);
|
||||||
|
Edi_Range range;
|
||||||
|
|
||||||
|
clang_getSpellingLocation(clang_getDiagnosticLocation(diag), NULL, &range.start.line, &range.start.col, NULL);
|
||||||
|
range.end = range.start;
|
||||||
|
|
||||||
|
/* FIXME: Also handle ranges and fix suggestions. */
|
||||||
|
|
||||||
|
Edi_Color color = "";
|
||||||
|
// EDI_COLOR_BACKGROUND_DEFAULT;
|
||||||
|
|
||||||
|
switch (clang_getDiagnosticSeverity(diag))
|
||||||
|
{
|
||||||
|
case CXDiagnostic_Ignored:
|
||||||
|
// color = EDI_COLOR_BACKGROUND_SEVIRITY_IGNORED;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Note:
|
||||||
|
// color = EDI_COLOR_BACKGROUND_SEVIRITY_NOTE;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Warning:
|
||||||
|
// color = EDI_COLOR_BACKGROUND_SEVIRITY_WARNING;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Error:
|
||||||
|
// color = EDI_COLOR_BACKGROUND_SEVIRITY_ERROR;
|
||||||
|
break;
|
||||||
|
case CXDiagnostic_Fatal:
|
||||||
|
// color = EDI_COLOR_BACKGROUND_SEVIRITY_FATAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_edi_range_color_set(editor, range, color);
|
||||||
|
|
||||||
|
#if CLANG_DEBUG
|
||||||
|
CXString str = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());
|
||||||
|
printf("DEBUG: Diag:%s\n", clang_getCString(str));
|
||||||
|
clang_disposeString(str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
clang_disposeDiagnostic(diag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_clang_setup(const char *path, Edi_Editor *editor)
|
||||||
|
{
|
||||||
|
/* Clang */
|
||||||
|
/* FIXME: index should probably be global. */
|
||||||
|
const char const *clang_argv[] = {"-I/usr/lib/clang/3.1/include/", "-Wall", "-Wextra"};
|
||||||
|
int clang_argc = sizeof(clang_argv) / sizeof(*clang_argv);
|
||||||
|
|
||||||
|
editor->idx = clang_createIndex(0, 0);
|
||||||
|
|
||||||
|
/* FIXME: Possibly activate more options? */
|
||||||
|
editor->tx_unit = clang_parseTranslationUnit(editor->idx, path, clang_argv, clang_argc, NULL, 0, clang_defaultEditingTranslationUnitOptions() | CXTranslationUnit_DetailedPreprocessingRecord);
|
||||||
|
|
||||||
|
_clang_load_errors(path, editor);
|
||||||
|
_clang_load_highlighting(path, editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_clang_dispose(Edi_Editor *editor)
|
||||||
|
{
|
||||||
|
clang_disposeTranslationUnit(editor->tx_unit);
|
||||||
|
clang_disposeIndex(editor->idx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
EAPI Evas_Object *edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item)
|
EAPI Evas_Object *edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item)
|
||||||
{
|
{
|
||||||
Evas_Object *txt, *lines, *vbox, *box, *searchbar, *statusbar;
|
Evas_Object *txt, *lines, *vbox, *box, *searchbar, *statusbar;
|
||||||
|
@ -316,5 +573,10 @@ EAPI Evas_Object *edi_editor_add(Evas_Object *parent, Edi_Mainview_Item *item)
|
||||||
|
|
||||||
evas_object_data_set(vbox, "editor", editor);
|
evas_object_data_set(vbox, "editor", editor);
|
||||||
_update_lines(editor);
|
_update_lines(editor);
|
||||||
|
|
||||||
|
#if HAVE_LIBCLANG
|
||||||
|
_edi_clang_setup(item->path, editor);
|
||||||
|
#endif
|
||||||
|
|
||||||
return vbox;
|
return vbox;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#include <Evas.h>
|
#include <Evas.h>
|
||||||
|
|
||||||
|
#if HAVE_LIBCLANG
|
||||||
|
#include <clang-c/Index.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mainview/edi_mainview_item.h"
|
#include "mainview/edi_mainview_item.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -40,6 +44,12 @@ struct _Edi_Editor
|
||||||
Edi_Editor_Search *search;
|
Edi_Editor_Search *search;
|
||||||
|
|
||||||
/* Add new members here. */
|
/* Add new members here. */
|
||||||
|
|
||||||
|
#if HAVE_LIBCLANG
|
||||||
|
/* Clang */
|
||||||
|
CXIndex idx;
|
||||||
|
CXTranslationUnit tx_unit;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue