diff --git a/src/debug.cc b/src/debug.cc index 29703c0..47c1e20 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -318,6 +318,48 @@ std::vector Debug::get_backtrace() { return backtrace; } +std::vector Debug::get_variables() { + vector variables; + event_mutex.lock(); + if(state==lldb::StateType::eStateStopped) { + for(uint32_t c_t=0;c_tGetNumThreads();c_t++) { + auto thread=process->GetThreadAtIndex(c_t); + for(uint32_t c_f=0;c_f run_command(const std::string &command); std::vector get_backtrace(); + std::vector get_variables(); void select_frame(uint32_t index); void delete_debug(); //can't use delete as function name diff --git a/src/files.h b/src/files.h index d50436e..0970ccf 100644 --- a/src/files.h +++ b/src/files.h @@ -2,7 +2,7 @@ #define JUCI_FILES_H_ #include -#define JUCI_VERSION "1.1.0-3" +#define JUCI_VERSION "1.1.0-4" const std::string configjson = "{\n" @@ -107,6 +107,7 @@ const std::string configjson = " \"debug_step_into\": \"t\",\n" " \"debug_step_out\": \"t\",\n" " \"debug_backtrace\": \"j\",\n" +" \"debug_show_variables\": \"b\",\n" " \"debug_run_command\": \"Return\",\n" " \"debug_toggle_breakpoint\": \"b\",\n" " \"debug_goto_stop\": \"l\",\n" diff --git a/src/menu.cc b/src/menu.cc index 3612c6c..3627947 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -320,6 +320,11 @@ Menu::Menu() { " app.debug_backtrace" +accels["debug_backtrace"]+ //For Ubuntu... " " + " " + " _Show _Variables" + " app.debug_show_variables" + +accels["debug_show_variables"]+ //For Ubuntu... + " " " " "
" " " diff --git a/src/selectiondialog.cc b/src/selectiondialog.cc index 187a304..f4c82cc 100644 --- a/src/selectiondialog.cc +++ b/src/selectiondialog.cc @@ -72,6 +72,18 @@ list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_searc }); } + list_view_text.signal_cursor_changed().connect([this]() { + if(!shown) + return; + auto it=list_view_text.get_selection()->get_selected(); + if(it) { + std::string row; + it->get_value(0, row); + if(on_changed) + on_changed(row); + } + }); + scrolled_window.add(list_view_text); if(!show_search_entry) window->add(scrolled_window); @@ -102,13 +114,13 @@ void SelectionDialogBase::show() { void SelectionDialogBase::hide() { if(!shown) return; + shown=false; window->hide(); if(tooltips) tooltips->hide(); if(on_hide) on_hide(); list_view_text.clear(); - shown=false; } void SelectionDialogBase::update_tooltips() { diff --git a/src/selectiondialog.h b/src/selectiondialog.h index 7c6d901..36f2747 100644 --- a/src/selectiondialog.h +++ b/src/selectiondialog.h @@ -35,6 +35,7 @@ public: virtual void move(); std::function on_hide; + std::function on_changed; std::function on_select; Glib::RefPtr start_mark; diff --git a/src/window.cc b/src/window.cc index cb31622..0e1ea3a 100644 --- a/src/window.cc +++ b/src/window.cc @@ -154,6 +154,7 @@ Window::Window() : compiling(false), debugging(false) { menu.actions["debug_step_into"]->set_enabled(false); menu.actions["debug_step_out"]->set_enabled(false); menu.actions["debug_backtrace"]->set_enabled(false); + menu.actions["debug_show_variables"]->set_enabled(false); menu.actions["debug_run_command"]->set_enabled(false); menu.actions["debug_goto_stop"]->set_enabled(false); #endif @@ -168,6 +169,7 @@ Window::Window() : compiling(false), debugging(false) { menu.actions["debug_step_into"]->set_enabled(false); menu.actions["debug_step_out"]->set_enabled(false); menu.actions["debug_backtrace"]->set_enabled(false); + menu.actions["debug_show_variables"]->set_enabled(false); menu.actions["debug_run_command"]->set_enabled(false); menu.actions["debug_goto_stop"]->set_enabled(false); } @@ -180,6 +182,7 @@ Window::Window() : compiling(false), debugging(false) { menu.actions["debug_step_into"]->set_enabled(); menu.actions["debug_step_out"]->set_enabled(); menu.actions["debug_backtrace"]->set_enabled(); + menu.actions["debug_show_variables"]->set_enabled(); menu.actions["debug_run_command"]->set_enabled(); menu.actions["debug_goto_stop"]->set_enabled(); } @@ -953,6 +956,92 @@ void Window::set_menu_actions() { view->selection_dialog->show(); } }); + menu.add_action("debug_show_variables", [this]() { + if(debugging && notebook.get_current_page()!=-1) { + auto variables=Debug::get().get_variables(); + + auto view=notebook.get_current_view(); + auto buffer=view->get_buffer(); + auto iter=buffer->get_insert()->get_iter(); + if(iter.get_line_offset()>=80) + iter=buffer->get_iter_at_line(iter.get_line()); + Gdk::Rectangle visible_rect; + view->get_visible_rect(visible_rect); + Gdk::Rectangle iter_rect; + view->get_iter_location(iter, iter_rect); + iter_rect.set_width(1); + if(!visible_rect.intersects(iter_rect)) { + view->get_iter_at_location(iter, 0, visible_rect.get_y()+visible_rect.get_height()/3); + } + view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, buffer->create_mark(iter), true, true)); + auto rows=std::make_shared >(); + if(variables.size()==0) + return; + + for(auto &variable: variables) { + std::string row=variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - "+Glib::Markup::escape_text(variable.name)+""; + + (*rows)[row]=variable; + view->selection_dialog->add_row(row); + } + + view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + auto variable=rows->at(selected); + if(!variable.file_path.empty()) { + notebook.open(variable.file_path); + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + + Debug::get().select_frame(variable.frame_index); + + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(variable.line_nr-1, variable.line_index-1)); + + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL, false); + if(notebook.get_current_page()!=-1 && notebook.get_current_view()==view) + view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); + } + } + }; + + view->selection_dialog->on_hide=[this]() { + if(debug_variable_tooltips) { + debug_variable_tooltips->hide(); + debug_variable_tooltips.reset(); + } + }; + + view->selection_dialog->on_changed=[this, rows, iter](const std::string &selected) { + if(notebook.get_current_page()!=-1) { + auto view=notebook.get_current_view(); + debug_variable_tooltips=std::unique_ptr(new Tooltips()); + auto create_tooltip_buffer=[this, rows, view, selected]() { + auto variable=rows->at(selected); + auto tooltip_buffer=Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()); + + Glib::ustring value=variable.value; + if(!value.empty()) { + Glib::ustring::iterator iter; + while(!value.validate(iter)) { + auto next_char_iter=iter; + next_char_iter++; + value.replace(iter, next_char_iter, "?"); + } + tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); + } + + return tooltip_buffer; + }; + + debug_variable_tooltips->emplace_back(create_tooltip_buffer, *view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter)); + + debug_variable_tooltips->show(true); + } + }; + + view->selection_dialog->show(); + } + }); menu.add_action("debug_run_command", [this]() { entry_box.clear(); entry_box.entries.emplace_back(last_run_debug_command, [this](const std::string& content){ diff --git a/src/window.h b/src/window.h index 51f5215..6c55d87 100644 --- a/src/window.h +++ b/src/window.h @@ -5,6 +5,7 @@ #include "entrybox.h" #include "notebook.h" #include "cmake.h" +#include "tooltips.h" #include class Window : public Gtk::ApplicationWindow { @@ -46,6 +47,8 @@ private: std::string debug_status; std::mutex debug_status_mutex; Glib::Dispatcher debug_update_status; + + std::unique_ptr debug_variable_tooltips; std::unique_ptr get_cmake(); std::unordered_map project_run_arguments;