Browse Source

Merge branch 'master' of https://github.com/eidheim/jucipp

merge-requests/365/head
Jørgen Lien Sellæg 11 years ago
parent
commit
5f994564be
  1. 154
      juci/source.cc
  2. 24
      juci/source.h
  3. 2
      juci/tooltips.h

154
juci/source.cc

@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <regex> #include <regex>
#include "singletons.h" #include "singletons.h"
#include "notebook.h" //TODO: remove
namespace sigc { namespace sigc {
SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
@ -168,8 +169,7 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) {
} }
init_syntax_highlighting(buffer_map, init_syntax_highlighting(buffer_map,
start_offset, start_offset,
end_offset, end_offset);
&ClangView::clang_index);
update_syntax(); update_syntax();
//GTK-calls must happen in main thread, so the parse_thread //GTK-calls must happen in main thread, so the parse_thread
@ -251,17 +251,13 @@ void Source::ClangView::
init_syntax_highlighting(const std::map<std::string, std::string> init_syntax_highlighting(const std::map<std::string, std::string>
&buffers, &buffers,
int start_offset, int start_offset,
int end_offset, int end_offset) {
clang::Index *index) {
std::vector<string> arguments = get_compilation_commands(); std::vector<string> arguments = get_compilation_commands();
clang_tu = std::unique_ptr<clang::TranslationUnit>(new clang::TranslationUnit(index, clang_tu = std::unique_ptr<clang::TranslationUnit>(new clang::TranslationUnit(clang_index,
file_path, file_path,
arguments, arguments,
buffers)); buffers));
clang::SourceLocation start(clang_tu.get(), file_path, 0); clang_tokens=clang_tu->get_tokens(0, buffers.find(file_path)->second.size()-1);
clang::SourceLocation end(clang_tu.get(), file_path, buffers.find(file_path)->second.size()-1);
clang::SourceRange range(&start, &end);
clang_tokens=std::unique_ptr<clang::Tokens>(new clang::Tokens(clang_tu.get(), &range));
} }
std::map<std::string, std::string> Source::ClangView:: std::map<std::string, std::string> Source::ClangView::
@ -273,18 +269,15 @@ get_buffer_map() const {
int Source::ClangView:: int Source::ClangView::
reparse(const std::map<std::string, std::string> &buffer) { reparse(const std::map<std::string, std::string> &buffer) {
int status = clang_tu->ReparseTranslationUnit(file_path, buffer); int status = clang_tu->ReparseTranslationUnit(buffer);
clang::SourceLocation start(clang_tu.get(), file_path, 0); clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path)->second.size()-1);
clang::SourceLocation end(clang_tu.get(), file_path, parse_thread_buffer_map.find(file_path)->second.size()-1);
clang::SourceRange range(&start, &end);
clang_tokens=std::unique_ptr<clang::Tokens>(new clang::Tokens(clang_tu.get(), &range));
return status; return status;
} }
std::vector<std::string> Source::ClangView:: std::vector<std::string> Source::ClangView::
get_compilation_commands() { get_compilation_commands() {
clang::CompilationDatabase db(project_path); clang::CompilationDatabase db(project_path);
clang::CompileCommands commands(file_path, &db); clang::CompileCommands commands(file_path, db);
std::vector<clang::CompileCommand> cmds = commands.get_commands(); std::vector<clang::CompileCommand> cmds = commands.get_commands();
std::vector<std::string> arguments; std::vector<std::string> arguments;
for (auto &i : cmds) { for (auto &i : cmds) {
@ -301,13 +294,17 @@ get_compilation_commands() {
void Source::ClangView::update_syntax() { void Source::ClangView::update_syntax() {
std::vector<Source::Range> ranges; std::vector<Source::Range> ranges;
for (auto &token : *clang_tokens) { for (auto &token : *clang_tokens) {
switch (token.kind()) { auto range_data=token.source_range.get_range_data();
case 0: highlight_cursor(&token, &ranges); break; // PunctuationToken if(token.kind()==0) // PunctuationToken
case 1: highlight_token(&token, &ranges, 702); break; // KeywordToken ranges.emplace_back(range_data.start_offset, range_data.end_offset, (int) token.get_cursor().get_kind());
case 2: highlight_cursor(&token, &ranges); break; // IdentifierToken else if(token.kind()==1) // KeywordToken
case 3: highlight_token(&token, &ranges, 109); break; // LiteralToken ranges.emplace_back(range_data.start_offset, range_data.end_offset, 702);
case 4: highlight_token(&token, &ranges, 705); break; // CommentToken else if(token.kind()==2) // IdentifierToken
} ranges.emplace_back(range_data.start_offset, range_data.end_offset, (int) token.get_cursor().get_kind());
else if(token.kind()==3) // LiteralToken
ranges.emplace_back(range_data.start_offset, range_data.end_offset, 109);
else if(token.kind()==4) // CommentToken
ranges.emplace_back(range_data.start_offset, range_data.end_offset, 705);
} }
if (ranges.empty() || ranges.size() == 0) { if (ranges.empty() || ranges.size() == 0) {
return; return;
@ -321,17 +318,9 @@ void Source::ClangView::update_syntax() {
} catch (std::exception) { } catch (std::exception) {
continue; continue;
} }
int linum_start = range.start.line_number-1;
int linum_end = range.end.line_number-1;
int begin = range.start.column_offset-1;
int end = range.end.column_offset-1;
if (end < 0) end = 0; Gtk::TextIter begin_iter = buffer->get_iter_at_offset(range.start_offset);
if (begin < 0) begin = 0; Gtk::TextIter end_iter = buffer->get_iter_at_offset(range.end_offset);
Gtk::TextIter begin_iter =
buffer->get_iter_at_line_offset(linum_start, begin);
Gtk::TextIter end_iter =
buffer->get_iter_at_line_offset(linum_end, end);
buffer->apply_tag_by_name(Singletons::Config::source()->types.at(type), buffer->apply_tag_by_name(Singletons::Config::source()->types.at(type),
begin_iter, end_iter); begin_iter, end_iter);
} }
@ -339,21 +328,23 @@ void Source::ClangView::update_syntax() {
void Source::ClangView::update_diagnostics() { void Source::ClangView::update_diagnostics() {
diagnostic_tooltips.clear(); diagnostic_tooltips.clear();
clang_tu->update_diagnostics(); auto diagnostics=clang_tu->get_diagnostics();
for(size_t c=0;c<clang_tu->diagnostics.size();c++) { for(auto &diagnostic: diagnostics) {
if(clang_tu->diagnostics[c].path==file_path) { if(diagnostic.range.path==file_path) {
auto start=get_buffer()->get_iter_at_offset(clang_tu->diagnostics[c].start_location.offset); auto start=get_buffer()->get_iter_at_offset(diagnostic.range.start_offset);
auto end=get_buffer()->get_iter_at_offset(clang_tu->diagnostics[c].end_location.offset); auto end=get_buffer()->get_iter_at_offset(diagnostic.range.end_offset);
std::string diagnostic_tag_name; std::string diagnostic_tag_name;
if(clang_tu->diagnostics[c].severity<=CXDiagnostic_Warning) if(diagnostic.severity<=CXDiagnostic_Warning)
diagnostic_tag_name="diagnostic_warning"; diagnostic_tag_name="diagnostic_warning";
else else
diagnostic_tag_name="diagnostic_error"; diagnostic_tag_name="diagnostic_error";
auto get_tooltip_buffer=[this, c, diagnostic_tag_name]() { auto spelling=diagnostic.spelling;
auto severity_spelling=diagnostic.severity_spelling;
auto get_tooltip_buffer=[this, spelling, severity_spelling, diagnostic_tag_name]() {
auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), clang_tu->diagnostics[c].severity_spelling, diagnostic_tag_name); tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), severity_spelling, diagnostic_tag_name);
tooltip_buffer->insert_at_cursor(":\n"+clang_tu->diagnostics[c].spelling); tooltip_buffer->insert_at_cursor(":\n"+spelling);
//TODO: Insert newlines to clang_tu->diagnostics[c].spelling (use 80 chars, then newline?) //TODO: Insert newlines to clang_tu->diagnostics[c].spelling (use 80 chars, then newline?)
return tooltip_buffer; return tooltip_buffer;
}; };
@ -375,23 +366,16 @@ void Source::ClangView::update_diagnostics() {
void Source::ClangView::update_types() { void Source::ClangView::update_types() {
type_tooltips.clear(); type_tooltips.clear();
clang_tokens->update_types(clang_tu.get()); for(auto &token: *clang_tokens) {
for(size_t c=0;c<clang_tokens->size();c++) { if(token.has_type()) {
if((*clang_tokens)[c].type!="") { auto range_data=token.source_range.get_range_data();
clang::SourceRange range(clang_tu.get(), &((*clang_tokens)[c])); if(range_data.path==file_path) {
clang::SourceLocation start(&range, true); auto start=get_buffer()->get_iter_at_offset(range_data.start_offset);
clang::SourceLocation end(&range, false); auto end=get_buffer()->get_iter_at_offset(range_data.end_offset);
std::string path; auto get_tooltip_buffer=[this, &token]() {
unsigned start_offset, end_offset;
start.get_location_info(&path, NULL, NULL, &start_offset);
end.get_location_info(NULL, NULL, NULL, &end_offset);
if(path==file_path) {
auto start=get_buffer()->get_iter_at_offset(start_offset);
auto end=get_buffer()->get_iter_at_offset(end_offset);
auto get_tooltip_buffer=[this, c]() {
auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
tooltip_buffer->insert_at_cursor("Type: "+(*clang_tokens)[c].type); tooltip_buffer->insert_at_cursor("Type: "+token.get_type());
auto brief_comment=clang_tokens->get_brief_comments(c); auto brief_comment=token.get_brief_comments();
if(brief_comment!="") if(brief_comment!="")
tooltip_buffer->insert_at_cursor("\n\n"+brief_comment+"."); tooltip_buffer->insert_at_cursor("\n\n"+brief_comment+".");
return tooltip_buffer; return tooltip_buffer;
@ -407,7 +391,7 @@ bool Source::ClangView::on_motion_notify_event(GdkEventMotion* event) {
delayed_tooltips_connection.disconnect(); delayed_tooltips_connection.disconnect();
if(clang_readable) { if(clang_readable) {
Gdk::Rectangle rectangle(event->x, event->y, 1, 1); Gdk::Rectangle rectangle(event->x, event->y, 1, 1);
diagnostic_tooltips.init(); Tooltips::init();
type_tooltips.show(rectangle); type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle);
} }
@ -434,7 +418,7 @@ void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, c
rectangle.set_x(location_window_x-2); rectangle.set_x(location_window_x-2);
rectangle.set_y(location_window_y); rectangle.set_y(location_window_y);
rectangle.set_width(4); rectangle.set_width(4);
diagnostic_tooltips.init(); Tooltips::init();
type_tooltips.show(rectangle); type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle);
} }
@ -442,6 +426,18 @@ void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, c
}, 500); }, 500);
type_tooltips.hide(); type_tooltips.hide();
diagnostic_tooltips.hide(); diagnostic_tooltips.hide();
if(clang_readable) {
for(auto &token: *clang_tokens) {
if(token.has_type()) {
auto range_data=token.source_range.get_range_data();
auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset();
if(range_data.path==file_path && insert_offset>=range_data.start_offset && insert_offset<=range_data.end_offset) {
cout << token.get_type() << endl;
}
}
}
}
} }
} }
@ -459,38 +455,6 @@ bool Source::ClangView::on_scroll_event(GdkEventScroll* event) {
return Source::View::on_scroll_event(event); return Source::View::on_scroll_event(event);
} }
void Source::ClangView::
highlight_cursor(clang::Token *token,
std::vector<Source::Range> *source_ranges) {
clang::SourceLocation location = token->get_source_location(clang_tu.get());
clang::Cursor cursor(clang_tu.get(), &location);
clang::SourceRange range(&cursor);
clang::SourceLocation begin(&range, true);
clang::SourceLocation end(&range, false);
unsigned begin_line_num, begin_offset, end_line_num, end_offset;
begin.get_location_info(NULL, &begin_line_num, &begin_offset, NULL);
end.get_location_info(NULL, &end_line_num, &end_offset, NULL);
source_ranges->emplace_back(Source::Location(begin_line_num,
begin_offset),
Source::Location(end_line_num,
end_offset), (int) cursor.kind());
}
void Source::ClangView::
highlight_token(clang::Token *token,
std::vector<Source::Range> *source_ranges,
int token_kind) {
clang::SourceRange range = token->get_source_range(clang_tu.get());
unsigned begin_line_num, begin_offset, end_line_num, end_offset;
clang::SourceLocation begin(&range, true);
clang::SourceLocation end(&range, false);
begin.get_location_info(NULL, &begin_line_num, &begin_offset, NULL);
end.get_location_info(NULL, &end_line_num, &end_offset, NULL);
source_ranges->emplace_back(Source::Location(begin_line_num,
begin_offset),
Source::Location(end_line_num,
end_offset), token_kind);
}
//Clang indentation //Clang indentation
//TODO: replace indentation methods with a better implementation or maybe use libclang //TODO: replace indentation methods with a better implementation or maybe use libclang
bool Source::ClangView::on_key_press_event(GdkEventKey* key) { bool Source::ClangView::on_key_press_event(GdkEventKey* key) {
@ -659,7 +623,7 @@ void Source::ClangViewAutocomplete::autocomplete() {
if(!autocomplete_starting) { if(!autocomplete_starting) {
autocomplete_starting=true; autocomplete_starting=true;
autocomplete_cancel_starting=false; autocomplete_cancel_starting=false;
INFO("Source::ClangView::on_key_release getting autocompletions"); INFO("Source::ClangViewAutocomplete::autocomplete getting autocompletions");
std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >(); std::shared_ptr<std::vector<Source::AutoCompleteData> > ac_data=std::make_shared<std::vector<Source::AutoCompleteData> >();
autocomplete_done_connection.disconnect(); autocomplete_done_connection.disconnect();
autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){ autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){
@ -725,11 +689,7 @@ std::vector<Source::AutoCompleteData> Source::ClangViewAutocomplete::
get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map) { get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map) {
INFO("Getting auto complete suggestions"); INFO("Getting auto complete suggestions");
std::vector<Source::AutoCompleteData> suggestions; std::vector<Source::AutoCompleteData> suggestions;
clang::CodeCompleteResults results(clang_tu.get(), auto results=clang_tu->get_code_completions(buffer_map, line_number, column);
file_path,
buffer_map,
line_number,
column);
if(!autocomplete_cancel_starting) { if(!autocomplete_cancel_starting) {
prefix_mutex.lock(); prefix_mutex.lock();
auto prefix_copy=prefix; auto prefix_copy=prefix;

24
juci/source.h

@ -26,20 +26,12 @@ namespace Source {
std::unordered_map<std::string, std::string> tags, types; std::unordered_map<std::string, std::string> tags, types;
}; // class Config }; // class Config
class Location {
public:
Location(int line_number, int column_offset):
line_number(line_number), column_offset(column_offset) {}
int line_number;
int column_offset;
};
class Range { class Range {
public: public:
Range(const Location &start, const Location &end, int kind): Range(unsigned start_offset, unsigned end_offset, int kind):
start(start), end(end), kind(kind) {} start_offset(start_offset), end_offset(end_offset), kind(kind) {}
Location start; unsigned start_offset;
Location end; unsigned end_offset;
int kind; int kind;
}; };
@ -89,8 +81,7 @@ namespace Source {
void init_syntax_highlighting(const std::map<std::string, std::string> void init_syntax_highlighting(const std::map<std::string, std::string>
&buffers, &buffers,
int start_offset, int start_offset,
int end_offset, int end_offset);
clang::Index *index);
int reparse(const std::map<std::string, std::string> &buffers); int reparse(const std::map<std::string, std::string> &buffers);
void update_syntax(); void update_syntax();
void update_diagnostics(); void update_diagnostics();
@ -104,11 +95,6 @@ namespace Source {
static clang::Index clang_index; static clang::Index clang_index;
std::unique_ptr<clang::Tokens> clang_tokens; std::unique_ptr<clang::Tokens> clang_tokens;
bool clang_readable=false; bool clang_readable=false;
void highlight_token(clang::Token *token,
std::vector<Range> *source_ranges,
int token_kind);
void highlight_cursor(clang::Token *token,
std::vector<Range> *source_ranges);
std::vector<std::string> get_compilation_commands(); std::vector<std::string> get_compilation_commands();
Terminal::Controller& terminal; Terminal::Controller& terminal;

2
juci/tooltips.h

@ -27,7 +27,7 @@ private:
class Tooltips : public std::list<Tooltip> { class Tooltips : public std::list<Tooltip> {
public: public:
void init() {drawn_tooltips_rectangle=Gdk::Rectangle();} static void init() {drawn_tooltips_rectangle=Gdk::Rectangle();}
void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false); void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false);
void show(bool disregard_drawn=false); void show(bool disregard_drawn=false);
void hide(); void hide();

Loading…
Cancel
Save