Browse Source

Updated status bar, and cleanup of update signals affecting status bar and tab texts

merge-requests/365/head
eidheim 9 years ago
parent
commit
99d63ba477
  1. 16
      src/config.cc
  2. 4
      src/config.h
  3. 2
      src/debug_lldb.cc
  4. 24
      src/directories.cc
  5. 21
      src/git.cc
  6. 2
      src/git.h
  7. 2
      src/juci.cc
  8. 148
      src/notebook.cc
  9. 9
      src/notebook.h
  10. 2
      src/project.cc
  11. 35
      src/source.cc
  12. 16
      src/source.h
  13. 67
      src/source_clang.cc
  14. 2
      src/source_clang.h
  15. 17
      src/source_diff.cc
  16. 10
      src/source_diff.h
  17. 58
      src/window.cc
  18. 6
      tests/source_clang_test.cc

16
src/config.cc

@ -12,12 +12,12 @@ Config::Config() {
for (auto &variable : environment_variables) {
ptr=std::getenv(variable.c_str());
if (ptr!=nullptr && boost::filesystem::exists(ptr)) {
home /= ptr;
home /= ".juci";
home_path = ptr;
home_juci_path = home_path / ".juci";
break;
}
}
if(home.empty()) {
if(home_juci_path.empty()) {
std::string searched_envs = "[";
for(auto &variable : environment_variables)
searched_envs+=variable+", ";
@ -34,7 +34,7 @@ Config::Config() {
}
void Config::load() {
auto config_json = (home/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support
auto config_json = (home_juci_path/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support
try {
find_or_create_config_files();
boost::property_tree::json_parser::read_json(config_json, cfg);
@ -52,7 +52,7 @@ void Config::load() {
}
void Config::find_or_create_config_files() {
auto config_dir = home/"config";
auto config_dir = home_juci_path/"config";
auto config_json = config_dir/"config.json";
boost::filesystem::create_directories(config_dir); // io exp captured by calling method
@ -60,7 +60,7 @@ void Config::find_or_create_config_files() {
if (!boost::filesystem::exists(config_json))
filesystem::write(config_json, default_config_file);
auto juci_style_path = home/"styles";
auto juci_style_path = home_juci_path/"styles";
boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method
juci_style_path/="juci-light.xml";
@ -168,7 +168,7 @@ void Config::update_config_file() {
if(cfg.count("version")>0)
cfg.find("version")->second.data()=default_cfg.get<std::string>("version");
auto style_path=home/"styles";
auto style_path=home_juci_path/"styles";
filesystem::write(style_path/"juci-light.xml", juci_light_style);
filesystem::write(style_path/"juci-dark.xml", juci_dark_style);
filesystem::write(style_path/"juci-dark-blue.xml", juci_dark_blue_style);
@ -183,7 +183,7 @@ void Config::update_config_file() {
cfg_ok&=add_missing_nodes(default_cfg);
cfg_ok&=remove_deprecated_nodes(default_cfg, cfg);
if(!cfg_ok)
boost::property_tree::write_json((home/"config"/"config.json").string(), cfg);
boost::property_tree::write_json((home_juci_path/"config"/"config.json").string(), cfg);
}
void Config::get_source() {

4
src/config.h

@ -96,7 +96,8 @@ public:
Project project;
Source source;
const boost::filesystem::path& juci_home_path() const { return home; }
boost::filesystem::path home_path;
boost::filesystem::path home_juci_path;
private:
void find_or_create_config_files();
@ -107,6 +108,5 @@ private:
void get_source();
boost::property_tree::ptree cfg;
boost::filesystem::path home;
};
#endif

2
src/debug_lldb.cc

@ -174,7 +174,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
if(line_entry.IsValid()) {
lldb::SBStream stream;
line_entry.GetFileSpec().GetDescription(stream);
status +=" - "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line_entry.GetLine());
status +=" "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line_entry.GetLine());
}
}
status_callback(status);

24
src/directories.cc

@ -94,19 +94,11 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat
auto new_file_path=target_path;
for(;file_it!=view->file_path.end();file_it++)
new_file_path/=*file_it;
{
std::unique_lock<std::mutex> lock(view->file_path_mutex);
view->file_path=new_file_path;
}
g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed");
view->rename(new_file_path);
}
}
else if(view->file_path==source_path) {
{
std::unique_lock<std::mutex> lock(view->file_path_mutex);
view->file_path=target_path;
}
g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed");
view->rename(target_path);
break;
}
}
@ -299,19 +291,11 @@ Directories::Directories() : Gtk::ListViewText(1) {
auto new_file_path=target_path;
for(;file_it!=view->file_path.end();file_it++)
new_file_path/=*file_it;
{
std::unique_lock<std::mutex> lock(view->file_path_mutex);
view->file_path=new_file_path;
}
g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed");
view->rename(new_file_path);
}
}
else if(view->file_path==*source_path) {
{
std::unique_lock<std::mutex> lock(view->file_path_mutex);
view->file_path=target_path;
}
g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed");
view->rename(target_path);
std::string old_language_id;
if(view->language)

21
src/git.cc

@ -242,6 +242,27 @@ Git::Repository::Diff Git::Repository::get_diff(const boost::filesystem::path &p
return Diff(path, repository.get());
}
std::string Git::Repository::get_branch() noexcept {
std::string branch;
git_reference *reference;
if(git_repository_head(&reference, repository.get())==0) {
if(auto reference_name_cstr=git_reference_name(reference)) {
std::string reference_name(reference_name_cstr);
size_t pos;
if((pos=reference_name.rfind('/'))!=std::string::npos) {
if(pos+1<reference_name.size())
branch=reference_name.substr(pos+1);
}
else if((pos=reference_name.rfind('\\'))!=std::string::npos) {
if(pos+1<reference_name.size())
branch=reference_name.substr(pos+1);
}
}
git_reference_free(reference);
}
return branch;
}
void Git::initialize() noexcept {
std::lock_guard<std::mutex> lock(mutex);
if(!initialized) {

2
src/git.h

@ -79,6 +79,8 @@ public:
Diff get_diff(const boost::filesystem::path &path);
std::string get_branch() noexcept;
Glib::RefPtr<Gio::FileMonitor> monitor;
};

2
src/juci.cc

@ -49,7 +49,7 @@ void Application::on_activate() {
if(directories.empty() && files.empty()) {
try {
boost::property_tree::ptree pt;
boost::property_tree::read_json((Config::get().juci_home_path()/"last_session.json").string(), pt);
boost::property_tree::read_json((Config::get().home_juci_path/"last_session.json").string(), pt);
auto folder=pt.get<std::string>("folder");
if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder))
directories.emplace_back(folder);

148
src/notebook.cc

@ -170,13 +170,112 @@ void Notebook::open(const boost::filesystem::path &file_path, size_t notebook_in
view->hide_tooltips();
}
};
source_views.back()->on_update_status=[this](Source::View* view, const std::string &status_text) {
if(get_current_view()==view)
status.set_text(status_text+" ");
source_views.back()->update_status_location=[this](Source::View* view) {
if(get_current_view()==view) {
auto iter=view->get_buffer()->get_insert()->get_iter();
status_location.set_text(" "+std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1));
}
};
source_views.back()->update_status_file_path=[this](Source::View* view) {
if(get_current_view()==view) {
if(filesystem::file_in_path(view->file_path, Config::get().home_path)) {
auto relative_path=filesystem::get_relative_path(view->file_path, Config::get().home_path);
if(!relative_path.empty()) {
status_file_path.set_text((" ~"/relative_path).string());
return;
}
}
status_file_path.set_text(" "+view->file_path.string());
}
};
source_views.back()->update_status_branch=[this](Source::DiffView* view) {
if(get_current_view()==view) {
if(!view->status_branch.empty())
status_branch.set_text(" ("+view->status_branch+")");
else
status_branch.set_text("");
}
};
source_views.back()->update_tab_label=[this](Source::View *view) {
std::string title=view->file_path.filename().string();
if(view->get_buffer()->get_modified())
title+='*';
else
title+=' ';
for(size_t c=0;c<size();++c) {
if(source_views[c]==view) {
auto &tab_label=tab_labels.at(c);
tab_label->label.set_text(title);
tab_label->set_tooltip_text(view->file_path.string());
update_status(view);
return;
}
}
};
source_views.back()->on_update_info=[this](Source::View* view, const std::string &info_text) {
source_views.back()->update_status_diagnostics=[this](Source::View* view) {
if(get_current_view()==view) {
std::string diagnostic_info;
auto num_warnings=std::get<0>(view->status_diagnostics);
auto num_errors=std::get<1>(view->status_diagnostics);
auto num_fix_its=std::get<2>(view->status_diagnostics);
if(num_warnings>0 || num_errors>0 || num_fix_its>0) {
auto normal_color=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL);
Gdk::RGBA yellow;
yellow.set_rgba(1.0, 1.0, 0.2);
double factor=0.5;
yellow.set_red(normal_color.get_red()+factor*(yellow.get_red()-normal_color.get_red()));
yellow.set_green(normal_color.get_green()+factor*(yellow.get_green()-normal_color.get_green()));
yellow.set_blue(normal_color.get_blue()+factor*(yellow.get_blue()-normal_color.get_blue()));
Gdk::RGBA red;
red.set_rgba(1.0, 0.0, 0.0);
factor=0.5;
red.set_red(normal_color.get_red()+factor*(red.get_red()-normal_color.get_red()));
red.set_green(normal_color.get_green()+factor*(red.get_green()-normal_color.get_green()));
red.set_blue(normal_color.get_blue()+factor*(red.get_blue()-normal_color.get_blue()));
Gdk::RGBA green;
green.set_rgba(0.0, 1.0, 0.0);
factor=0.4;
green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red()));
green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green()));
green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue()));
std::stringstream yellow_ss, red_ss, green_ss;
yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(yellow.get_red_u()>>8) << std::setw(2) << (int)(yellow.get_green_u()>>8) << std::setw(2) << (int)(yellow.get_blue_u()>>8);
red_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(red.get_red_u()>>8) << std::setw(2) << (int)(red.get_green_u()>>8) << std::setw(2) << (int)(red.get_blue_u()>>8);
green_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(green.get_red_u()>>8) << std::setw(2) << (int)(green.get_green_u()>>8) << std::setw(2) << (int)(green.get_blue_u()>>8);
if(num_warnings>0) {
diagnostic_info+="<span color='#"+yellow_ss.str()+"'>";
diagnostic_info+=std::to_string(num_warnings)+" warning";
if(num_warnings>1)
diagnostic_info+='s';
diagnostic_info+="</span>";
}
if(num_errors>0) {
if(num_warnings>0)
diagnostic_info+=", ";
diagnostic_info+="<span color='#"+red_ss.str()+"'>";
diagnostic_info+=std::to_string(num_errors)+" error";
if(num_errors>1)
diagnostic_info+='s';
diagnostic_info+="</span>";
}
if(num_fix_its>0) {
if(num_warnings>0 || num_errors>0)
diagnostic_info+=", ";
diagnostic_info+="<span color='#"+green_ss.str()+"'>";
diagnostic_info+=std::to_string(num_fix_its)+" fix it";
if(num_fix_its>1)
diagnostic_info+='s';
diagnostic_info+="</span>";
}
}
status_diagnostics.set_markup(diagnostic_info);
}
};
source_views.back()->update_status_state=[this](Source::View* view) {
if(get_current_view()==view)
info.set_text(" "+info_text);
status_state.set_text(view->status_state+" ");
};
scrolled_windows.emplace_back(new Gtk::ScrolledWindow());
@ -200,20 +299,8 @@ void Notebook::open(const boost::filesystem::path &file_path, size_t notebook_in
//Add star on tab label when the page is not saved:
source_view->get_buffer()->signal_modified_changed().connect([this, source_view]() {
std::string title=source_view->file_path.filename().string();
if(source_view->get_buffer()->get_modified())
title+='*';
else
title+=' ';
for(size_t c=0;c<size();c++) {
if(source_views[c]==source_view) {
auto &tab_label=tab_labels.at(c);
tab_label->label.set_text(title);
tab_label->set_tooltip_text(source_view->file_path.string());
return;
}
}
if(source_view->update_tab_label)
source_view->update_tab_label(source_view);
});
source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) {
@ -319,7 +406,7 @@ void Notebook::save_session() {
pt_root.add_child("files", pt_files);
if(auto view=Notebook::get().get_current_view())
pt_root.put("current_file", view->file_path.string());
boost::property_tree::write_json((Config::get().juci_home_path()/"last_session.json").string(), pt_root);
boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), pt_root);
}
catch(const std::exception &) {}
}
@ -438,6 +525,27 @@ boost::filesystem::path Notebook::get_current_folder() {
return boost::filesystem::path();
}
void Notebook::update_status(Source::View *view) {
if(view->update_status_location)
view->update_status_location(view);
if(view->update_status_file_path)
view->update_status_file_path(view);
if(view->update_status_branch)
view->update_status_branch(view);
if(view->update_status_diagnostics)
view->update_status_diagnostics(view);
if(view->update_status_state)
view->update_status_state(view);
}
void Notebook::clear_status() {
status_location.set_text("");
status_file_path.set_text("");
status_branch.set_text("");
status_diagnostics.set_text("");
status_state.set_text("");
}
size_t Notebook::get_index(Source::View *view) {
for(size_t c=0;c<size();++c) {
if(source_views[c]==view)

9
src/notebook.h

@ -42,8 +42,13 @@ public:
void toggle_split();
boost::filesystem::path get_current_folder();
Gtk::Label info;
Gtk::Label status;
Gtk::Label status_location;
Gtk::Label status_file_path;
Gtk::Label status_branch;
Gtk::Label status_diagnostics;
Gtk::Label status_state;
void update_status(Source::View *view);
void clear_status();
std::function<void(Source::View*)> on_change_page;
std::function<void(Source::View*)> on_close_page;

2
src/project.cc

@ -73,7 +73,7 @@ void Project::debug_update_status(const std::string &new_debug_status) {
if(debug_status.empty())
debug_status_label().set_text("");
else
debug_status_label().set_text("debug: "+debug_status);
debug_status_label().set_text(debug_status);
debug_activate_menu_items();
}

35
src/source.cc

@ -89,7 +89,7 @@ const std::regex Source::View::bracket_regex("^([ \\t]*).*\\{ *$");
const std::regex Source::View::no_bracket_statement_regex("^([ \\t]*)(if|for|else if|while) *\\(.*[^;}] *$");
const std::regex Source::View::no_bracket_no_para_statement_regex("^([ \\t]*)(else) *$");
Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): Gsv::View(), SpellCheckView(), DiffView(file_path), language(language) {
Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language): Gsv::View(), SpellCheckView(), DiffView(file_path), language(language), status_diagnostics(0, 0, 0) {
get_source_buffer()->begin_not_undoable_action();
last_read_time=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
if(language) {
@ -147,7 +147,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::L
set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102);
get_buffer()->signal_changed().connect([this](){
set_info(info);
if(update_status_location)
update_status_location(this);
});
signal_realize().connect([this] {
@ -379,6 +380,17 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::L
}
}
void Source::View::rename(const boost::filesystem::path &path) {
{
std::unique_lock<std::mutex> lock(file_path_mutex);
file_path=path;
}
if(update_status_file_path)
update_status_file_path(this);
if(update_tab_label)
update_tab_label(this);
}
void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) {
this->tab_char=tab_char;
this->tab_size=tab_size;
@ -459,7 +471,7 @@ void Source::View::configure() {
//TODO: Move this to notebook? Might take up too much memory doing this for every tab.
auto style_scheme_manager=Gsv::StyleSchemeManager::get_default();
style_scheme_manager->prepend_search_path((Config::get().juci_home_path()/"styles").string());
style_scheme_manager->prepend_search_path((Config::get().home_juci_path/"styles").string());
if(Config::get().source.style.size()>0) {
auto scheme = style_scheme_manager->get_scheme(Config::get().source.style);
@ -596,7 +608,8 @@ void Source::View::set_tooltip_and_dialog_events() {
if(selection_dialog)
selection_dialog->hide();
set_info(info);
if(update_status_location)
update_status_location(this);
}
});
@ -853,20 +866,6 @@ void Source::View::hide_dialogs() {
autocomplete_dialog->hide();
}
void Source::View::set_status(const std::string &status) {
this->status=status;
if(on_update_status)
on_update_status(this, status);
}
void Source::View::set_info(const std::string &info) {
this->info=info;
auto iter=get_buffer()->get_insert()->get_iter();
auto positions=std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1);
if(on_update_info)
on_update_info(this, positions+" "+info);
}
std::string Source::View::get_line(const Gtk::TextIter &iter) {
auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line());
auto line_end_it = get_iter_at_line_end(iter.get_line());

16
src/source.h

@ -9,6 +9,7 @@
#include <unordered_map>
#include <vector>
#include <regex>
#include <tuple>
namespace Source {
Glib::RefPtr<Gsv::Language> guess_language(const boost::filesystem::path &file_path);
@ -43,6 +44,8 @@ namespace Source {
View(const boost::filesystem::path &file_path, Glib::RefPtr<Gsv::Language> language);
~View();
void rename(const boost::filesystem::path &path);
virtual bool save(const std::vector<Source::View*> &views);
void configure() override;
@ -84,12 +87,13 @@ namespace Source {
void hide_tooltips() override;
void hide_dialogs() override;
std::function<void(View* view, const std::string &status_text)> on_update_status;
std::function<void(View* view, const std::string &info_text)> on_update_info;
void set_status(const std::string &status);
void set_info(const std::string &info);
std::string status;
std::string info;
std::function<void(View *view)> update_tab_label;
std::function<void(View *view)> update_status_location;
std::function<void(View *view)> update_status_file_path;
std::function<void(View *view)> update_status_diagnostics;
std::function<void(View *view)> update_status_state;
std::tuple<size_t, size_t, size_t> status_diagnostics;
std::string status_state;
void set_tab_char_and_size(char tab_char, unsigned tab_size);
std::pair<char, unsigned> get_tab_char_and_size() {return {tab_char, tab_size};}

67
src/source_clang.cc

@ -108,7 +108,9 @@ void Source::ClangViewParse::parse_initialize() {
clang_tokens=clang_tu->get_tokens(0, buffer.bytes()-1);
update_syntax();
set_status("parsing...");
status_state="parsing...";
if(update_status_state)
update_status_state(this);
parse_thread=std::thread([this]() {
while(true) {
while(parse_state==ParseState::PROCESSING && parse_process_state!=ParseProcessState::STARTING && parse_process_state!=ParseProcessState::PROCESSING)
@ -137,7 +139,7 @@ void Source::ClangViewParse::parse_initialize() {
auto expected=ParseProcessState::PROCESSING;
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) {
clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1);
diagnostics=clang_tu->get_diagnostics();
clang_diagnostics=clang_tu->get_diagnostics();
parse_lock.unlock();
dispatcher.post([this] {
std::unique_lock<std::mutex> parse_lock(parse_mutex, std::defer_lock);
@ -147,7 +149,9 @@ void Source::ClangViewParse::parse_initialize() {
update_syntax();
update_diagnostics();
parsed=true;
set_status("");
status_state="";
if(update_status_state)
update_status_state(this);
}
parse_lock.unlock();
}
@ -161,8 +165,12 @@ void Source::ClangViewParse::parse_initialize() {
parse_lock.unlock();
dispatcher.post([this] {
Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true);
set_status("");
set_info("");
status_state="";
if(update_status_state)
update_status_state(this);
status_diagnostics=std::make_tuple(0, 0, 0);
if(update_status_diagnostics)
update_status_diagnostics(this);
parsing_in_progress->cancel("failed");
});
}
@ -181,8 +189,11 @@ void Source::ClangViewParse::soft_reparse() {
delayed_reparse_connection=Glib::signal_timeout().connect([this]() {
parsed=false;
auto expected=ParseProcessState::IDLE;
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING))
set_status("parsing...");
if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) {
status_state="parsing...";
if(update_status_state)
update_status_state(this);
}
return false;
}, 1000);
}
@ -276,7 +287,7 @@ void Source::ClangViewParse::update_diagnostics() {
size_t num_warnings=0;
size_t num_errors=0;
size_t num_fix_its=0;
for(auto &diagnostic: diagnostics) {
for(auto &diagnostic: clang_diagnostics) {
if(diagnostic.path==file_path.string()) {
int line=diagnostic.offsets.first.line-1;
if(line<0 || line>=get_buffer()->get_line_count())
@ -356,27 +367,9 @@ void Source::ClangViewParse::update_diagnostics() {
}
}
}
std::string diagnostic_info;
if(num_warnings>0) {
diagnostic_info+=std::to_string(num_warnings)+" warning";
if(num_warnings>1)
diagnostic_info+='s';
}
if(num_errors>0) {
if(num_warnings>0)
diagnostic_info+=", ";
diagnostic_info+=std::to_string(num_errors)+" error";
if(num_errors>1)
diagnostic_info+='s';
}
if(num_fix_its>0) {
if(num_warnings>0 || num_errors>0)
diagnostic_info+=", ";
diagnostic_info+=std::to_string(num_fix_its)+" fix it";
if(num_fix_its>1)
diagnostic_info+='s';
}
set_info(" "+diagnostic_info);
status_diagnostics=std::make_tuple(num_warnings, num_errors, num_fix_its);
if(update_status_diagnostics)
update_status_diagnostics(this);
}
void Source::ClangViewParse::show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) {
@ -674,7 +667,9 @@ void Source::ClangViewAutocomplete::autocomplete() {
autocomplete_state=AutocompleteState::STARTING;
set_status("autocomplete...");
status_state="autocomplete...";
if(update_status_state)
update_status_state(this);
if(autocomplete_thread.joinable())
autocomplete_thread.join();
auto buffer=std::make_shared<Glib::ustring>(get_buffer()->get_text());
@ -697,12 +692,16 @@ void Source::ClangViewAutocomplete::autocomplete() {
if(parse_state==ParseState::PROCESSING) {
dispatcher.post([this, autocomplete_data] {
if(autocomplete_state==AutocompleteState::CANCELED) {
set_status("");
status_state="";
if(update_status_state)
update_status_state(this);
soft_reparse();
autocomplete_state=AutocompleteState::IDLE;
}
else if(autocomplete_state==AutocompleteState::RESTARTING) {
set_status("");
status_state="";
if(update_status_state)
update_status_state(this);
soft_reparse();
autocomplete_state=AutocompleteState::IDLE;
autocomplete_check();
@ -729,7 +728,9 @@ void Source::ClangViewAutocomplete::autocomplete() {
}
}
autocomplete_data->clear();
set_status("");
status_state="";
if(update_status_state)
update_status_state(this);
autocomplete_state=AutocompleteState::IDLE;
if (!autocomplete_dialog_rows.empty()) {
get_buffer()->begin_user_action();

2
src/source_clang.h

@ -49,7 +49,7 @@ namespace Source {
std::set<std::string> last_syntax_tags;
void update_diagnostics();
std::vector<clang::Diagnostic> diagnostics;
std::vector<clang::Diagnostic> clang_diagnostics;
static clang::Index clang_index;
std::vector<std::string> get_compilation_commands();

17
src/source_diff.cc

@ -170,8 +170,15 @@ void Source::DiffView::configure() {
parse_thread=std::thread([this]() {
try {
diff=get_diff();
status_branch=repository->get_branch();
}
catch(const std::exception &) {}
catch(const std::exception &) {
status_branch="";
}
dispatcher.post([this] {
if(update_status_branch)
update_status_branch(this);
});
try {
while(true) {
@ -199,6 +206,11 @@ void Source::DiffView::configure() {
if(monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) {
try {
diff=get_diff();
status_branch=repository->get_branch();
dispatcher.post([this] {
if(update_status_branch)
update_status_branch(this);
});
}
catch(const std::exception &) {
dispatcher.post([this] {
@ -208,6 +220,9 @@ void Source::DiffView::configure() {
get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end());
get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end());
renderer->queue_draw();
status_branch="";
if(update_status_branch)
update_status_branch(this);
});
}
}

10
src/source_diff.h

@ -33,16 +33,20 @@ namespace Source {
DiffView(const boost::filesystem::path &file_path);
~DiffView();
boost::filesystem::path file_path;
protected:
std::mutex file_path_mutex;
public:
virtual void configure();
std::function<void(DiffView *view)> update_status_branch;
std::string status_branch;
Gtk::TextIter get_iter_at_line_end(int line_nr);
void git_goto_next_diff();
std::string git_get_diff_details();
boost::filesystem::path file_path;
///Only needed when using file_path in a thread, or when changing file_path
std::mutex file_path_mutex;
private:
std::unique_ptr<Renderer> renderer;
Dispatcher dispatcher;

58
src/window.cc

@ -54,14 +54,26 @@ Window::Window() {
hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK);
hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK);
auto info_and_status_hbox=Gtk::manage(new Gtk::HBox());
info_and_status_hbox->pack_start(Notebook::get().info, Gtk::PACK_SHRINK);
info_and_status_hbox->set_center_widget(Project::debug_status_label());
info_and_status_hbox->pack_end(Notebook::get().status, Gtk::PACK_SHRINK);
auto status_hbox=Gtk::manage(new Gtk::HBox());
status_hbox->set_homogeneous(true);
auto status_left_hbox=Gtk::manage(new Gtk::HBox());
status_left_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK);
status_left_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK);
status_left_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK);
status_hbox->pack_start(*status_left_hbox);
auto status_right_vbox=Gtk::manage(new Gtk::HBox());
status_right_vbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK);
auto status_right_overlay=Gtk::manage(new Gtk::Overlay());
status_right_overlay->add(*status_right_vbox);
status_right_overlay->add_overlay(Notebook::get().status_diagnostics);
status_hbox->pack_end(*status_right_overlay);
auto status_overlay=Gtk::manage(new Gtk::Overlay());
status_overlay->add(*status_hbox);
status_overlay->add_overlay(Project::debug_status_label());
auto vbox=Gtk::manage(new Gtk::VBox());
vbox->pack_start(*hpaned);
vbox->pack_start(*info_and_status_hbox, Gtk::PACK_SHRINK);
vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK);
auto overlay_vbox=Gtk::manage(new Gtk::VBox());
auto overlay_hbox=Gtk::manage(new Gtk::HBox());
@ -122,15 +134,14 @@ Window::Window() {
else if(view->soft_reparse_needed)
view->soft_reparse();
view->set_status(view->status);
view->set_info(view->info);
Notebook::get().update_status(view);
#ifdef JUCI_ENABLE_DEBUG
if(Project::debugging)
Project::debug_update_stop();
#endif
};
Notebook::get().on_close_page=[](Source::View *view) {
Notebook::get().on_close_page=[this](Source::View *view) {
#ifdef JUCI_ENABLE_DEBUG
if(Project::current && Project::debugging) {
auto iter=view->get_buffer()->begin();
@ -143,6 +154,13 @@ Window::Window() {
}
#endif
EntryBox::get().hide();
if(auto view=Notebook::get().get_current_view())
Notebook::get().update_status(view);
else {
Notebook::get().clear_status();
activate_menu_items();
}
};
signal_focus_out_event().connect([](GdkEventFocus *event) {
@ -155,6 +173,8 @@ Window::Window() {
Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [this] {
Directories::get().update();
if(auto view=Notebook::get().get_current_view())
Notebook::get().update_status(view);
});
about.signal_response().connect([this](int d){
@ -187,9 +207,11 @@ void Window::configure() {
css_provider=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant);
//TODO: add check if theme exists, or else write error to terminal
Gtk::StyleContext::add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
Directories::get().update();
Menu::get().set_keys();
Terminal::get().configure();
Directories::get().update();
if(auto view=Notebook::get().get_current_view())
Notebook::get().update_status(view);
}
void Window::set_menu_actions() {
@ -200,7 +222,7 @@ void Window::set_menu_actions() {
about.present();
});
menu.add_action("preferences", [this]() {
Notebook::get().open(Config::get().juci_home_path()/"config"/"config.json");
Notebook::get().open(Config::get().home_juci_path/"config"/"config.json");
});
menu.add_action("quit", [this]() {
close();
@ -326,7 +348,7 @@ void Window::set_menu_actions() {
menu.add_action("save", [this]() {
if(auto view=Notebook::get().get_current_view()) {
if(Notebook::get().save_current()) {
if(view->file_path==Config::get().juci_home_path()/"config"/"config.json") {
if(view->file_path==Config::get().home_juci_path/"config"/"config.json") {
configure();
for(size_t c=0;c<Notebook::get().size();c++) {
Notebook::get().get_view(c)->configure();
@ -1031,18 +1053,8 @@ void Window::set_menu_actions() {
Notebook::get().previous();
});
menu.add_action("close_tab", [this]() {
if(Notebook::get().get_current_view() && Notebook::get().close_current()) {
if(auto view=Notebook::get().get_current_view()) {
view->set_status(view->status);
view->set_info(view->info);
}
else {
Notebook::get().status.set_text("");
Notebook::get().info.set_text("");
activate_menu_items();
}
}
if(Notebook::get().get_current_view())
Notebook::get().close_current();
});
menu.add_action("window_toggle_split", [this] {
Notebook::get().toggle_split();

6
tests/source_clang_test.cc

@ -32,7 +32,7 @@ int main() {
Gsv::LanguageManager::get_default()->get_language("cpp"));
while(!clang_view->parsed)
flush_events();
g_assert_cmpuint(clang_view->diagnostics.size(), ==, 0);
g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0);
//test get_declaration and get_implementation
clang_view->place_cursor_at_line_index(13, 7);
@ -69,7 +69,7 @@ int main() {
iter.backward_char();
token=clang_view->get_token(iter);
g_assert_cmpstr(token.c_str(), ==, "RenamedTestClass");
g_assert_cmpuint(clang_view->diagnostics.size(), ==, 0);
g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0);
clang_view->get_buffer()->set_text(saved_main);
clang_view->save({clang_view});
@ -77,7 +77,7 @@ int main() {
clang_view->get_buffer()->set_text(main_error);
while(!clang_view->parsed)
flush_events();
g_assert_cmpuint(clang_view->diagnostics.size(), >, 0);
g_assert_cmpuint(clang_view->clang_diagnostics.size(), >, 0);
g_assert_cmpuint(clang_view->get_fix_its().size(), >, 0);
clang_view->async_delete();

Loading…
Cancel
Save