From 73d4889b68cec137f318335e3175e0ed7d2f05d6 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 19 Nov 2015 17:48:12 +0100 Subject: [PATCH] Tokens are now bold when using go to usage and go to methods. --- src/selectiondialog.cc | 58 +++++++++++++++++++++++++++++------------- src/selectiondialog.h | 24 ++++++++++++++--- src/source_clang.cc | 47 ++++++++++++++++++++++++++++++---- src/window.cc | 2 +- 4 files changed, 105 insertions(+), 26 deletions(-) diff --git a/src/selectiondialog.cc b/src/selectiondialog.cc index 012ecb8..490371d 100644 --- a/src/selectiondialog.cc +++ b/src/selectiondialog.cc @@ -15,8 +15,31 @@ namespace sigc { #endif } -SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry): text_view(text_view), -start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, false, Gtk::SelectionMode::SELECTION_BROWSE) { +ListViewText::ListViewText(bool use_markup) : Gtk::TreeView(), use_markup(use_markup) { + list_store = Gtk::ListStore::create(column_record); + set_model(list_store); + append_column("", cell_renderer); + if(use_markup) + get_column(0)->add_attribute(cell_renderer.property_markup(), column_record.text); + else + get_column(0)->add_attribute(cell_renderer.property_text(), column_record.text); + + get_selection()->set_mode(Gtk::SelectionMode::SELECTION_BROWSE); + set_enable_search(true); + set_headers_visible(false); + set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); + set_activate_on_single_click(true); + set_hover_selection(false); + set_rules_hint(true); +} + +void ListViewText::ListViewText::append(const std::string& value) { + auto new_row=list_store->append(); + new_row->set_value(column_record.text, value); +} + +SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): text_view(text_view), +list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_search_entry) { if(!show_search_entry) window=std::unique_ptr(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); else @@ -27,13 +50,6 @@ start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, window->property_decorated()=false; window->set_skip_taskbar_hint(true); scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); - list_view_text.set_enable_search(true); - list_view_text.set_headers_visible(false); - list_view_text.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); - list_view_text.set_activate_on_single_click(true); - list_view_text.set_hover_selection(false); - list_view_text.set_rules_hint(true); - //list_view_text.set_fixed_height_mode(true); //TODO: This is buggy on OS X, remember to post an issue on GTK+ 3 list_view_text.signal_realize().connect([this](){ resize(); @@ -89,8 +105,8 @@ void SelectionDialogBase::hide() { } void SelectionDialogBase::update_tooltips() { - if(list_view_text.get_selected().size()>0) { - auto it=list_view_text.get_selection()->get_selected(); + auto it=list_view_text.get_selection()->get_selected(); + if(it) { std::string row; it->get_value(0, row); if(row!=last_row || last_row.size()==0) { @@ -155,7 +171,7 @@ void SelectionDialogBase::resize() { } } -SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry) : SelectionDialogBase(text_view, start_mark, show_search_entry) {} +SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) {} void SelectionDialog::show() { SelectionDialogBase::show(); @@ -168,6 +184,14 @@ void SelectionDialog::show() { auto search_key_lc=*search_key; std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower); std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower); + if(list_view_text.use_markup) { + size_t pos=0; + while((pos=row_lc.find('<', pos))!=std::string::npos) { + auto pos2=row_lc.find('>', pos+1); + row_lc.erase(pos, pos2-pos+1); + } + search_key_lc=Glib::Markup::escape_text(search_key_lc); + } if(row_lc.find(search_key_lc)!=std::string::npos) return true; return false; @@ -221,8 +245,8 @@ void SelectionDialog::show() { }); auto activate=[this](){ - if(on_select && list_view_text.get_selected().size()>0) { - auto it=list_view_text.get_selection()->get_selected(); + auto it=list_view_text.get_selection()->get_selected(); + if(on_select && it) { std::string row; it->get_value(0, row); on_select(row, true); @@ -288,7 +312,7 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) { return false; } -CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false) {} +CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false, false) {} void CompletionDialog::show() { SelectionDialogBase::show(); @@ -344,8 +368,8 @@ void CompletionDialog::show() { void CompletionDialog::select(bool hide_window) { row_in_entry=true; - if(list_view_text.get_selected().size()>0) { - auto it=list_view_text.get_selection()->get_selected(); + auto it=list_view_text.get_selection()->get_selected(); + if(it) { std::string row; it->get_value(0, row); if(on_select) diff --git a/src/selectiondialog.h b/src/selectiondialog.h index 499c86f..b580176 100644 --- a/src/selectiondialog.h +++ b/src/selectiondialog.h @@ -6,9 +6,27 @@ #include "tooltips.h" #include +class ListViewText : public Gtk::TreeView { + class ColumnRecord : public Gtk::TreeModel::ColumnRecord { + public: + ColumnRecord() { + add(text); + } + Gtk::TreeModelColumn text; + }; +public: + bool use_markup; + ListViewText(bool use_markup); + void append(const std::string& value); +private: + Glib::RefPtr list_store; + ColumnRecord column_record; + Gtk::CellRendererText cell_renderer; +}; + class SelectionDialogBase { public: - SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry); + SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup); ~SelectionDialogBase(); virtual void add_row(const std::string& row, const std::string& tooltip=""); virtual void show(); @@ -25,7 +43,7 @@ protected: std::unique_ptr window; Gtk::ScrolledWindow scrolled_window; - Gtk::ListViewText list_view_text; + ListViewText list_view_text; Gtk::Entry search_entry; bool show_search_entry; std::unique_ptr tooltips; @@ -37,7 +55,7 @@ private: class SelectionDialog : public SelectionDialogBase { public: - SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry=true); + SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry=true, bool use_markup=false); bool on_key_press(GdkEventKey* key); void show(); }; diff --git a/src/source_clang.cc b/src/source_clang.cc index 1173cfc..eb95b88 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1059,13 +1059,36 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { (token.language->get_id()=="chdr" || token.language->get_id()=="cpphdr" || token.language->get_id()=="c" || token.language->get_id()=="cpp" || token.language->get_id()=="objc")) { auto offsets=clang_tokens->get_similar_token_offsets(static_cast(token.type), token.spelling, token.usr); for(auto &offset: offsets) { + size_t whitespaces_removed=0; auto start_iter=get_buffer()->get_iter_at_line(offset.first.line-1); - while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) + while(!start_iter.ends_line() && (*start_iter==' ' || *start_iter=='\t')) { start_iter.forward_char(); + whitespaces_removed++; + } auto end_iter=start_iter; while(!end_iter.ends_line()) end_iter.forward_char(); - usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), get_buffer()->get_text(start_iter, end_iter)); + std::string line=Glib::Markup::escape_text(get_buffer()->get_text(start_iter, end_iter)); + + //markup token as bold + size_t token_start_pos=offset.first.index-1-whitespaces_removed; + size_t token_end_pos=offset.second.index-1-whitespaces_removed; + size_t pos=0; + while((pos=line.find('&', pos))!=std::string::npos) { + size_t pos2=line.find(';', pos+2); + if(token_start_pos>pos) { + token_start_pos+=pos2-pos; + token_end_pos+=pos2-pos; + } + else if(token_end_pos>pos) + token_end_pos+=pos2-pos; + else + break; + pos=pos2+1; + } + line.insert(token_end_pos, ""); + line.insert(token_start_pos, ""); + usages.emplace_back(Offset(offset.first.line-1, offset.first.index-1, this->file_path), line); } } @@ -1083,14 +1106,28 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { if(!visible_rect.intersects(iter_rect)) { get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); } - selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(iter))); + selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(iter), true, true)); auto rows=std::make_shared >(); auto methods=clang_tokens->get_cxx_methods(); if(methods.size()==0) return; for(auto &method: methods) { - (*rows)[method.first]=method.second; - selection_dialog->add_row(method.first); + std::string row=Glib::Markup::escape_text(method.first); + + //Add bold method token + size_t token_end_pos=row.find('('); + if(token_end_pos==0 || token_end_pos==std::string::npos) + continue; + auto pos=token_end_pos-1; + while(((row[pos]>='a' && row[pos]<='z') || + (row[pos]>='A' && row[pos]<='Z') || + (row[pos]>='0' && row[pos]<='9') || row[pos]=='_') && pos>0) + pos--; + row.insert(token_end_pos, ""); + row.insert(pos+1, ""); + + (*rows)[row]=method.second; + selection_dialog->add_row(row); } selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { auto offset=rows->at(selected); diff --git a/src/window.cc b/src/window.cc index d2b5526..0ddf799 100644 --- a/src/window.cc +++ b/src/window.cc @@ -427,7 +427,7 @@ void Window::set_menu_actions() { if(!visible_rect.intersects(iter_rect)) { current_view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); } - current_view->selection_dialog=std::unique_ptr(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter))); + current_view->selection_dialog=std::unique_ptr(new SelectionDialog(*current_view, current_view->get_buffer()->create_mark(iter), true, true)); auto rows=std::make_shared >(); //First add usages in current file