diff --git a/src/source_clang.cc b/src/source_clang.cc index 6202c37..2525b7e 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -209,11 +209,14 @@ void Source::ClangViewParse::parse_initialize() { void Source::ClangViewParse::soft_reparse(bool delayed) { soft_reparse_needed = false; parsed = false; + delayed_reparse_connection.disconnect(); + if(parse_state != ParseState::PROCESSING) return; + parse_process_state = ParseProcessState::IDLE; - delayed_reparse_connection.disconnect(); - delayed_reparse_connection = Glib::signal_timeout().connect([this]() { + + auto reparse = [this] { parsed = false; auto expected = ParseProcessState::IDLE; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) { @@ -222,7 +225,11 @@ void Source::ClangViewParse::soft_reparse(bool delayed) { update_status_state(this); } return false; - }, delayed ? 1000 : 0); + }; + if(delayed) + delayed_reparse_connection = Glib::signal_timeout().connect(reparse, 1000); + else + reparse(); } const std::map &Source::ClangViewParse::clang_types() { @@ -1869,39 +1876,43 @@ Source::ClangView::ClangView(const boost::filesystem::path &file_path, const Gli } void Source::ClangView::full_reparse() { - auto print_error = [this] { - Terminal::get().async_print("Error: failed to reparse " + file_path.string() + ". Please reopen the file manually.\n", true); - }; - full_reparse_needed = false; + soft_reparse_needed = false; + parsed = false; + delayed_reparse_connection.disconnect(); + delayed_full_reparse_connection.disconnect(); + + if(parse_state != ParseState::PROCESSING) + return; + if(full_reparse_running) { - print_error(); + delayed_full_reparse_connection = Glib::signal_timeout().connect([this] { + full_reparse(); + return false; + }, 100); return; } - else { - auto expected = ParseState::PROCESSING; - if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) { - expected = ParseState::RESTARTING; - if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) { - print_error(); - return; - } - } - autocomplete.state = Autocomplete::State::IDLE; - soft_reparse_needed = false; - full_reparse_running = true; - if(full_reparse_thread.joinable()) - full_reparse_thread.join(); - full_reparse_thread = std::thread([this]() { - if(parse_thread.joinable()) - parse_thread.join(); - if(autocomplete.thread.joinable()) - autocomplete.thread.join(); - dispatcher.post([this] { - parse_initialize(); - full_reparse_running = false; - }); + + full_reparse_needed = false; + + parse_process_state = ParseProcessState::IDLE; + autocomplete.state = Autocomplete::State::IDLE; + auto expected = ParseState::PROCESSING; + if(!parse_state.compare_exchange_strong(expected, ParseState::RESTARTING)) + return; + + full_reparse_running = true; + if(full_reparse_thread.joinable()) + full_reparse_thread.join(); + full_reparse_thread = std::thread([this]() { + if(parse_thread.joinable()) + parse_thread.join(); + if(autocomplete.thread.joinable()) + autocomplete.thread.join(); + dispatcher.post([this] { + parse_initialize(); + full_reparse_running = false; }); - } + }); } void Source::ClangView::async_delete() { @@ -1919,21 +1930,17 @@ void Source::ClangView::async_delete() { Usages::Clang::erase_unused_caches(project_paths_in_use); Usages::Clang::cache_in_progress(); - if(!get_buffer()->get_modified()) { - if(full_reparse_needed) - full_reparse(); - else if(soft_reparse_needed) - soft_reparse(); - } + delayed_reparse_connection.disconnect(); + if(full_reparse_needed) + full_reparse(); + else if(soft_reparse_needed || !parsed) + soft_reparse(); auto before_parse_time = std::time(nullptr); delete_thread = std::thread([this, before_parse_time, project_paths_in_use = std::move(project_paths_in_use), buffer_modified = get_buffer()->get_modified()] { - while(!parsed) + while(!parsed && parse_state != ParseState::STOP) std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - delayed_reparse_connection.disconnect(); parse_state = ParseState::STOP; - dispatcher.disconnect(); if(buffer_modified) { std::ifstream stream(file_path.string(), std::ios::binary); diff --git a/src/source_clang.h b/src/source_clang.h index 541c4c9..34d4ebb 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -32,6 +32,7 @@ namespace Source { std::unique_ptr clang_tokens; std::vector> clang_tokens_offsets; sigc::connection delayed_reparse_connection; + sigc::connection delayed_full_reparse_connection; void show_type_tooltips(const Gdk::Rectangle &rectangle) override; diff --git a/src/source_diff.cc b/src/source_diff.cc index 517d2b9..be4cae2 100644 --- a/src/source_diff.cc +++ b/src/source_diff.cc @@ -48,7 +48,6 @@ Source::DiffView::DiffView(const boost::filesystem::path &file_path, const Glib: } Source::DiffView::~DiffView() { - dispatcher.disconnect(); if(repository) { get_gutter(Gtk::TextWindowType::TEXT_WINDOW_LEFT)->remove(renderer.get()); buffer_insert_connection.disconnect(); diff --git a/src/source_diff.h b/src/source_diff.h index 4d29a49..d04137b 100644 --- a/src/source_diff.h +++ b/src/source_diff.h @@ -48,7 +48,6 @@ namespace Source { std::unique_ptr renderer; Dispatcher dispatcher; - Mutex parse_mutex; std::shared_ptr repository;