From 655a30023a9707d43b432ba2f478c092e7bb73b3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 3 Jul 2015 22:32:58 +0200 Subject: [PATCH] Type info. --- juci/source.cc | 59 +++++++++++++++++++++++++++++++++++++----------- juci/source.h | 2 ++ juci/tooltips.cc | 50 +++++++++++++++++++++++++--------------- juci/tooltips.h | 9 +++++--- 4 files changed, 86 insertions(+), 34 deletions(-) diff --git a/juci/source.cc b/juci/source.cc index 1c1215f..c5010d2 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -307,7 +307,9 @@ extract_tokens(int start_offset, int end_offset) { clang::SourceLocation end(tu_.get(), file_path, end_offset); clang::SourceRange range(&start, &end); clang::Tokens tokens(tu_.get(), &range); - std::vector tks = tokens.tokens(); + tokens.get_token_types(tu_.get()); + std::vector& tks = tokens.tokens(); + update_types(tks); for (auto &token : tks) { switch (token.kind()) { case 0: highlight_cursor(&token, &ranges); break; // PunctuationToken @@ -352,34 +354,63 @@ void Source::ClangView::update_syntax(const std::vector &ranges) void Source::ClangView::update_diagnostics() { diagnostic_tooltips.clear(); auto diagnostics=tu_->get_diagnostics(); - auto buffer=get_source_buffer(); for(auto& diagnostic: diagnostics) { if(diagnostic.path==file_path) { - auto start=buffer->get_iter_at_offset(diagnostic.start_location.offset); - auto end=buffer->get_iter_at_offset(diagnostic.end_location.offset); + auto start=get_buffer()->get_iter_at_offset(diagnostic.start_location.offset); + auto end=get_buffer()->get_iter_at_offset(diagnostic.end_location.offset); std::string diagnostic_tag_name; if(diagnostic.severity<=CXDiagnostic_Warning) diagnostic_tag_name="diagnostic_warning"; else diagnostic_tag_name="diagnostic_error"; - auto tooltip_widget=std::make_shared(Gtk::TextBuffer::create(buffer->get_tag_table())); - tooltip_widget->set_editable(false); - tooltip_widget->get_buffer()->insert_with_tag(tooltip_widget->get_buffer()->get_insert()->get_iter(), diagnostic.severity_spelling, diagnostic_tag_name); - tooltip_widget->get_buffer()->insert_at_cursor(": \n"+diagnostic.spelling); - //TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?) - diagnostic_tooltips.emplace_back(tooltip_widget, *this, get_source_buffer()->create_mark(start), get_source_buffer()->create_mark(end)); + std::string spelling=diagnostic.spelling; + std::string 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()); + tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), severity_spelling, diagnostic_tag_name); + tooltip_buffer->insert_at_cursor(":\n"+spelling); + //TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?) + return tooltip_buffer; + }; + diagnostic_tooltips.emplace_back(get_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); - auto tag=buffer->create_tag(); + auto tag=get_buffer()->create_tag(); tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; auto tag_class=G_OBJECT_GET_CLASS(tag->gobj()); //For older GTK+ 3 versions: auto param_spec=g_object_class_find_property(tag_class, "underline-rgba"); if(param_spec!=NULL) { - auto diagnostic_tag=buffer->get_tag_table()->lookup(diagnostic_tag_name); + auto diagnostic_tag=get_buffer()->get_tag_table()->lookup(diagnostic_tag_name); if(diagnostic_tag!=0) tag->set_property("underline-rgba", diagnostic_tag->property_foreground_rgba().get_value()); } - buffer->apply_tag(tag, start, end); + get_buffer()->apply_tag(tag, start, end); + } + } +} + +void Source::ClangView::update_types(std::vector& tokens) { + type_tooltips.clear(); + for(auto& token: tokens) { + if(token.type!="") { + clang::SourceRange range(tu_.get(), &token); + clang::SourceLocation start(&range, true); + clang::SourceLocation end(&range, false); + std::string path; + 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, token]() { + auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); + tooltip_buffer->insert_at_cursor("Type: "+token.type); + return tooltip_buffer; + }; + + type_tooltips.emplace_back(get_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); + } } } } @@ -387,6 +418,7 @@ void Source::ClangView::update_diagnostics() { bool Source::ClangView::clangview_on_motion_notify_event(GdkEventMotion* event) { Gdk::Rectangle rectangle(event->x, event->y, 1, 1); diagnostic_tooltips.init(); + type_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle); return false; } @@ -401,6 +433,7 @@ void Source::ClangView::clangview_on_mark_set(const Gtk::TextBuffer::iterator& i rectangle.set_y(location_window_y); rectangle.set_width(4); diagnostic_tooltips.init(); + type_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle); } } diff --git a/juci/source.h b/juci/source.h index a1caafe..1d8dc44 100644 --- a/juci/source.h +++ b/juci/source.h @@ -97,7 +97,9 @@ namespace Source { std::vector extract_tokens(int, int); void update_syntax(const std::vector &locations); void update_diagnostics(); + void update_types(std::vector& tokens); Tooltips diagnostic_tooltips; + Tooltips type_tooltips; bool clangview_on_motion_notify_event(GdkEventMotion* event); void clangview_on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark); diff --git a/juci/tooltips.cc b/juci/tooltips.cc index 5e77726..3676d4d 100644 --- a/juci/tooltips.cc +++ b/juci/tooltips.cc @@ -3,19 +3,14 @@ Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); -Tooltip::Tooltip(std::shared_ptr tooltip_widget, Gtk::TextView& text_view, +Tooltip::Tooltip(std::function()> get_buffer, Gtk::TextView& text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark): -tooltip_widget(tooltip_widget), text_view(text_view), Gtk::Window(Gtk::WindowType::WINDOW_POPUP), -start_mark(start_mark), end_mark(end_mark) { - add(*tooltip_widget); - property_decorated()=false; - set_accept_focus(false); - set_skip_taskbar_hint(true); - set_default_size(0, 0); - - auto layout=Pango::Layout::create(tooltip_widget->get_pango_context()); - layout->set_text(tooltip_widget->get_buffer()->get_text()); - layout->get_pixel_size(tooltip_width, tooltip_height); +get_buffer(get_buffer), text_view(text_view), +start_mark(start_mark), end_mark(end_mark) {} + +Tooltip::~Tooltip() { + text_view.get_buffer()->delete_mark(start_mark); + text_view.get_buffer()->delete_mark(end_mark); } void Tooltip::update() { @@ -38,6 +33,24 @@ void Tooltip::update() { } void Tooltip::adjust() { + if(!window) { + //init window + window=std::unique_ptr(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); + + window->property_decorated()=false; + window->set_accept_focus(false); + window->set_skip_taskbar_hint(true); + window->set_default_size(0, 0); + + tooltip_widget=std::unique_ptr(new Gtk::TextView(this->get_buffer())); + tooltip_widget->set_editable(false); + window->add(*tooltip_widget); + + auto layout=Pango::Layout::create(tooltip_widget->get_pango_context()); + layout->set_text(tooltip_widget->get_buffer()->get_text()); + layout->get_pixel_size(tooltip_width, tooltip_height); + } + int root_x, root_y; text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle.get_x(), activation_rectangle.get_y(), root_x, root_y); Gdk::Rectangle rectangle; @@ -54,7 +67,7 @@ void Tooltip::adjust() { else Tooltips::drawn_tooltips_rectangle=rectangle; - move(rectangle.get_x(), rectangle.get_y()); + window->move(rectangle.get_x(), rectangle.get_y()); } void Tooltips::show(const Gdk::Rectangle& rectangle) { @@ -62,10 +75,10 @@ void Tooltips::show(const Gdk::Rectangle& rectangle) { tooltip.update(); if(rectangle.intersects(tooltip.activation_rectangle)) { tooltip.adjust(); - tooltip.show_all(); + tooltip.window->show_all(); } - else - tooltip.hide(); + else if(tooltip.window) + tooltip.window->hide(); } } @@ -73,12 +86,13 @@ void Tooltips::show() { for(auto& tooltip: *this) { tooltip.update(); tooltip.adjust(); - tooltip.show_all(); + tooltip.window->show_all(); } } void Tooltips::hide() { for(auto& tooltip: *this) { - tooltip.hide(); + if(tooltip.window) + tooltip.window->hide(); } } diff --git a/juci/tooltips.h b/juci/tooltips.h index 94b2c69..decaff4 100644 --- a/juci/tooltips.h +++ b/juci/tooltips.h @@ -4,16 +4,19 @@ #include #include -class Tooltip : public Gtk::Window { +class Tooltip { public: - Tooltip(std::shared_ptr tooltip_widget, Gtk::TextView& text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark); + Tooltip(std::function()> get_buffer, Gtk::TextView& text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark); + ~Tooltip(); void update(); void adjust(); Gdk::Rectangle activation_rectangle; + std::unique_ptr window; private: - std::shared_ptr tooltip_widget; + std::function()> get_buffer; + std::unique_ptr tooltip_widget; Glib::RefPtr start_mark; Glib::RefPtr end_mark; Gtk::TextView& text_view;