Browse Source

Type info.

merge-requests/365/head
eidheim 11 years ago
parent
commit
655a30023a
  1. 61
      juci/source.cc
  2. 2
      juci/source.h
  3. 48
      juci/tooltips.cc
  4. 9
      juci/tooltips.h

61
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::SourceLocation end(tu_.get(), file_path, end_offset);
clang::SourceRange range(&start, &end); clang::SourceRange range(&start, &end);
clang::Tokens tokens(tu_.get(), &range); clang::Tokens tokens(tu_.get(), &range);
std::vector<clang::Token> tks = tokens.tokens(); tokens.get_token_types(tu_.get());
std::vector<clang::Token>& tks = tokens.tokens();
update_types(tks);
for (auto &token : tks) { for (auto &token : tks) {
switch (token.kind()) { switch (token.kind()) {
case 0: highlight_cursor(&token, &ranges); break; // PunctuationToken case 0: highlight_cursor(&token, &ranges); break; // PunctuationToken
@ -352,34 +354,63 @@ void Source::ClangView::update_syntax(const std::vector<Source::Range> &ranges)
void Source::ClangView::update_diagnostics() { void Source::ClangView::update_diagnostics() {
diagnostic_tooltips.clear(); diagnostic_tooltips.clear();
auto diagnostics=tu_->get_diagnostics(); auto diagnostics=tu_->get_diagnostics();
auto buffer=get_source_buffer();
for(auto& diagnostic: diagnostics) { for(auto& diagnostic: diagnostics) {
if(diagnostic.path==file_path) { if(diagnostic.path==file_path) {
auto start=buffer->get_iter_at_offset(diagnostic.start_location.offset); auto start=get_buffer()->get_iter_at_offset(diagnostic.start_location.offset);
auto end=buffer->get_iter_at_offset(diagnostic.end_location.offset); auto end=get_buffer()->get_iter_at_offset(diagnostic.end_location.offset);
std::string diagnostic_tag_name; std::string diagnostic_tag_name;
if(diagnostic.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 tooltip_widget=std::make_shared<Gtk::TextView>(Gtk::TextBuffer::create(buffer->get_tag_table())); std::string spelling=diagnostic.spelling;
tooltip_widget->set_editable(false); std::string severity_spelling=diagnostic.severity_spelling;
tooltip_widget->get_buffer()->insert_with_tag(tooltip_widget->get_buffer()->get_insert()->get_iter(), diagnostic.severity_spelling, diagnostic_tag_name); auto get_tooltip_buffer=[this, spelling, severity_spelling, diagnostic_tag_name]() {
tooltip_widget->get_buffer()->insert_at_cursor(": \n"+diagnostic.spelling); auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
//TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?) tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), severity_spelling, diagnostic_tag_name);
diagnostic_tooltips.emplace_back(tooltip_widget, *this, get_source_buffer()->create_mark(start), get_source_buffer()->create_mark(end)); tooltip_buffer->insert_at_cursor(":\n"+spelling);
//TODO: Insert newlines to diagnostic.spelling (use 80 chars, then newline?)
auto tag=buffer->create_tag(); return tooltip_buffer;
};
diagnostic_tooltips.emplace_back(get_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
auto tag=get_buffer()->create_tag();
tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; tag->property_underline()=Pango::Underline::UNDERLINE_ERROR;
auto tag_class=G_OBJECT_GET_CLASS(tag->gobj()); //For older GTK+ 3 versions: 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"); auto param_spec=g_object_class_find_property(tag_class, "underline-rgba");
if(param_spec!=NULL) { 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) if(diagnostic_tag!=0)
tag->set_property("underline-rgba", diagnostic_tag->property_foreground_rgba().get_value()); 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<clang::Token>& 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) { bool Source::ClangView::clangview_on_motion_notify_event(GdkEventMotion* event) {
Gdk::Rectangle rectangle(event->x, event->y, 1, 1); Gdk::Rectangle rectangle(event->x, event->y, 1, 1);
diagnostic_tooltips.init(); diagnostic_tooltips.init();
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle);
return false; 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_y(location_window_y);
rectangle.set_width(4); rectangle.set_width(4);
diagnostic_tooltips.init(); diagnostic_tooltips.init();
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle); diagnostic_tooltips.show(rectangle);
} }
} }

2
juci/source.h

@ -97,7 +97,9 @@ namespace Source {
std::vector<Range> extract_tokens(int, int); std::vector<Range> extract_tokens(int, int);
void update_syntax(const std::vector<Range> &locations); void update_syntax(const std::vector<Range> &locations);
void update_diagnostics(); void update_diagnostics();
void update_types(std::vector<clang::Token>& tokens);
Tooltips diagnostic_tooltips; Tooltips diagnostic_tooltips;
Tooltips type_tooltips;
bool clangview_on_motion_notify_event(GdkEventMotion* event); bool clangview_on_motion_notify_event(GdkEventMotion* event);
void clangview_on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark); void clangview_on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark);

48
juci/tooltips.cc

@ -3,19 +3,14 @@
Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle();
Tooltip::Tooltip(std::shared_ptr<Gtk::TextView> tooltip_widget, Gtk::TextView& text_view, Tooltip::Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer, Gtk::TextView& text_view,
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark): Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark):
tooltip_widget(tooltip_widget), text_view(text_view), Gtk::Window(Gtk::WindowType::WINDOW_POPUP), get_buffer(get_buffer), text_view(text_view),
start_mark(start_mark), end_mark(end_mark) { 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()); Tooltip::~Tooltip() {
layout->set_text(tooltip_widget->get_buffer()->get_text()); text_view.get_buffer()->delete_mark(start_mark);
layout->get_pixel_size(tooltip_width, tooltip_height); text_view.get_buffer()->delete_mark(end_mark);
} }
void Tooltip::update() { void Tooltip::update() {
@ -38,6 +33,24 @@ void Tooltip::update() {
} }
void Tooltip::adjust() { void Tooltip::adjust() {
if(!window) {
//init window
window=std::unique_ptr<Gtk::Window>(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<Gtk::TextView>(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; 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); 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; Gdk::Rectangle rectangle;
@ -54,7 +67,7 @@ void Tooltip::adjust() {
else else
Tooltips::drawn_tooltips_rectangle=rectangle; 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) { void Tooltips::show(const Gdk::Rectangle& rectangle) {
@ -62,10 +75,10 @@ void Tooltips::show(const Gdk::Rectangle& rectangle) {
tooltip.update(); tooltip.update();
if(rectangle.intersects(tooltip.activation_rectangle)) { if(rectangle.intersects(tooltip.activation_rectangle)) {
tooltip.adjust(); tooltip.adjust();
tooltip.show_all(); tooltip.window->show_all();
} }
else else if(tooltip.window)
tooltip.hide(); tooltip.window->hide();
} }
} }
@ -73,12 +86,13 @@ void Tooltips::show() {
for(auto& tooltip: *this) { for(auto& tooltip: *this) {
tooltip.update(); tooltip.update();
tooltip.adjust(); tooltip.adjust();
tooltip.show_all(); tooltip.window->show_all();
} }
} }
void Tooltips::hide() { void Tooltips::hide() {
for(auto& tooltip: *this) { for(auto& tooltip: *this) {
tooltip.hide(); if(tooltip.window)
tooltip.window->hide();
} }
} }

9
juci/tooltips.h

@ -4,16 +4,19 @@
#include <string> #include <string>
#include <list> #include <list>
class Tooltip : public Gtk::Window { class Tooltip {
public: public:
Tooltip(std::shared_ptr<Gtk::TextView> tooltip_widget, Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark); Tooltip(std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer, Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark);
~Tooltip();
void update(); void update();
void adjust(); void adjust();
Gdk::Rectangle activation_rectangle; Gdk::Rectangle activation_rectangle;
std::unique_ptr<Gtk::Window> window;
private: private:
std::shared_ptr<Gtk::TextView> tooltip_widget; std::function<Glib::RefPtr<Gtk::TextBuffer>()> get_buffer;
std::unique_ptr<Gtk::TextView> tooltip_widget;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
Gtk::TextView& text_view; Gtk::TextView& text_view;

Loading…
Cancel
Save