From 85241413ed3246bd505af81e35c30548c213b162 Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 8 Sep 2015 20:18:24 +0200 Subject: [PATCH 01/14] Now restarts parse if autocomplete fails. Going to clean up autocomplete next. --- src/source.cc | 141 ++++++++++++++++++++++++++++---------------------- src/source.h | 18 ++++--- 2 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/source.cc b/src/source.cc index 2fa0193..8e14d87 100644 --- a/src/source.cc +++ b/src/source.cc @@ -929,7 +929,7 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib: clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::View(file_path), project_path(project_path) { +Source::View(file_path), project_path(project_path), parse_error(false) { DEBUG("start"); auto scheme = get_source_buffer()->get_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); @@ -1042,17 +1042,16 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { - int status=reparse(parse_thread_buffer_map); + reparse(parse_thread_buffer_map); parse_thread_go=false; - if(status!=0) - parse_thread_stop=true; parsing_mutex.unlock(); parse_thread_buffer_map_mutex.unlock(); - if(status!=0) { + if(parse_error) { parse_fail(); - return; + parse_thread_stop=true; } - parse_done(); + else + parse_done(); } } }); @@ -1077,19 +1076,18 @@ void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; source_readable=false; delayed_reparse_connection.disconnect(); - if(!parse_thread_stop) { - delayed_reparse_connection=Glib::signal_timeout().connect([this]() { - source_readable=false; - parse_thread_go=true; - set_status("parsing..."); - return false; - }, 1000); - } + delayed_reparse_connection=Glib::signal_timeout().connect([this]() { + source_readable=false; + parse_thread_go=true; + set_status("parsing..."); + return false; + }, 1000); } int Source::ClangViewParse::reparse(const std::map &buffer) { int status = clang_tu->ReparseTranslationUnit(buffer); if(status!=0) { + parse_error=true; return status; } clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); @@ -1436,6 +1434,23 @@ Source::ClangViewParse(file_path, project_path), autocomplete_cancel_starting(fa return false; }); + + autocomplete_fail.connect([this]() { + Singleton::terminal()->print("Error: autocomplete failed, reparsing "+this->file_path.string()+"\n"); + restart_parse(); + autocomplete_starting=false; + autocomplete_cancel_starting=false; + }); + + do_delete_object.connect([this](){ + if(delete_thread.joinable()) + delete_thread.join(); + delete this; + }); + do_restart_parse.connect([this](){ + init_parse(); + restart_parse_running=false; + }); } bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { @@ -1489,6 +1504,10 @@ void Source::ClangViewAutocomplete::start_autocomplete() { } void Source::ClangViewAutocomplete::autocomplete() { + if(parse_thread_stop) { + return; + } + if(!autocomplete_starting) { autocomplete_starting=true; autocomplete_cancel_starting=false; @@ -1505,6 +1524,7 @@ void Source::ClangViewAutocomplete::autocomplete() { completion_dialog->on_hide=[this](){ get_source_buffer()->end_user_action(); completion_dialog_shown=false; + source_readable=false; start_reparse(); }; completion_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { @@ -1581,16 +1601,23 @@ void Source::ClangViewAutocomplete::autocomplete() { parsing_mutex.lock(); if(!parse_thread_stop) *ac_data=move(get_autocomplete_suggestions(line_nr, column_nr, *buffer_map)); - autocomplete_done(); + if(!parse_thread_stop) + autocomplete_done(); + else + autocomplete_fail(); parsing_mutex.unlock(); }); } } -std::vector Source::ClangViewAutocomplete:: -get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map) { +std::vector Source::ClangViewAutocomplete::get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map) { std::vector suggestions; auto results=clang_tu->get_code_completions(buffer_map, line_number, column); + if(results.cx_results==NULL) { + parse_thread_stop=true; + return suggestions; + } + if(!autocomplete_cancel_starting) { prefix_mutex.lock(); auto prefix_copy=prefix; @@ -1617,6 +1644,40 @@ get_autocomplete_suggestions(int line_number, int column, std::mapcancel("canceled, freeing resources in the background"); + parse_thread_stop=true; + delete_thread=std::thread([this](){ + //TODO: Is it possible to stop the clang-process in progress? + if(restart_parse_thread.joinable()) + restart_parse_thread.join(); + if(parse_thread.joinable()) + parse_thread.join(); + if(autocomplete_thread.joinable()) + autocomplete_thread.join(); + do_delete_object(); + }); +} + +bool Source::ClangViewAutocomplete::restart_parse() { + if(!restart_parse_running && !parse_error) { + reparse_needed=false; + restart_parse_running=true; + parse_thread_stop=true; + if(restart_parse_thread.joinable()) + restart_parse_thread.join(); + restart_parse_thread=std::thread([this](){ + if(parse_thread.joinable()) + parse_thread.join(); + if(autocomplete_thread.joinable()) + autocomplete_thread.join(); + do_restart_parse(); + }); + return true; + } + return false; +} + //////////////////////////// //// ClangViewRefactor ///// //////////////////////////// @@ -1772,48 +1833,4 @@ Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boo get_source_buffer()->set_highlight_syntax(true); get_source_buffer()->set_language(language); } - - do_delete_object.connect([this](){ - if(delete_thread.joinable()) - delete_thread.join(); - delete this; - }); - do_restart_parse.connect([this](){ - init_parse(); - restart_parse_running=false; - }); -} - -void Source::ClangView::async_delete() { - parsing_in_progress->cancel("canceled, freeing resources in the background"); - parse_thread_stop=true; - delete_thread=std::thread([this](){ - //TODO: Is it possible to stop the clang-process in progress? - if(restart_parse_thread.joinable()) - restart_parse_thread.join(); - if(parse_thread.joinable()) - parse_thread.join(); - if(autocomplete_thread.joinable()) - autocomplete_thread.join(); - do_delete_object(); - }); -} - -bool Source::ClangView::restart_parse() { - if(!restart_parse_running && !parse_thread_stop) { - reparse_needed=false; - restart_parse_running=true; - parse_thread_stop=true; - if(restart_parse_thread.joinable()) - restart_parse_thread.join(); - restart_parse_thread=std::thread([this](){ - if(parse_thread.joinable()) - parse_thread.join(); - if(autocomplete_thread.joinable()) - autocomplete_thread.join(); - do_restart_parse(); - }); - return true; - } - return false; } diff --git a/src/source.h b/src/source.h index e28b9d5..4f46c54 100644 --- a/src/source.h +++ b/src/source.h @@ -150,6 +150,7 @@ namespace Source { std::shared_ptr parsing_in_progress; std::thread parse_thread; std::atomic parse_thread_stop; + std::atomic parse_error; std::regex bracket_regex; std::regex no_bracket_statement_regex; @@ -179,6 +180,8 @@ namespace Source { class ClangViewAutocomplete : public ClangViewParse { public: ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + void async_delete(); + bool restart_parse(); protected: bool on_key_press_event(GdkEventKey* key); std::thread autocomplete_thread; @@ -190,11 +193,18 @@ namespace Source { std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map); Glib::Dispatcher autocomplete_done; sigc::connection autocomplete_done_connection; + Glib::Dispatcher autocomplete_fail; bool autocomplete_starting=false; std::atomic autocomplete_cancel_starting; guint last_keyval=0; std::string prefix; std::mutex prefix_mutex; + + Glib::Dispatcher do_delete_object; + Glib::Dispatcher do_restart_parse; + std::thread delete_thread; + std::thread restart_parse_thread; + bool restart_parse_running=false; }; class ClangViewRefactor : public ClangViewAutocomplete { @@ -212,14 +222,6 @@ namespace Source { class ClangView : public ClangViewRefactor { public: ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); - void async_delete(); - bool restart_parse(); - private: - Glib::Dispatcher do_delete_object; - Glib::Dispatcher do_restart_parse; - std::thread delete_thread; - std::thread restart_parse_thread; - bool restart_parse_running=false; }; }; // class Source #endif // JUCI_SOURCE_H_ From b9292f207633f3a7a666f01fac580c66a50c861b Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 8 Sep 2015 21:57:26 +0200 Subject: [PATCH 02/14] Minor cleanup. --- src/source.cc | 30 ++++++++---------------------- src/source.h | 3 --- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/source.cc b/src/source.cc index 8e14d87..56304b3 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1025,7 +1025,8 @@ void Source::ClangViewParse::init_parse() { } pos++; } - init_syntax_highlighting(buffer_map); + clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), buffer_map)); + clang_tokens=clang_tu->get_tokens(0, buffer_map.find(file_path.string())->second.size()-1); update_syntax(); set_status("parsing..."); @@ -1042,11 +1043,15 @@ void Source::ClangViewParse::init_parse() { parse_start(); } else if (parse_thread_mapped && parsing_mutex.try_lock() && parse_thread_buffer_map_mutex.try_lock()) { - reparse(parse_thread_buffer_map); + int status=clang_tu->ReparseTranslationUnit(parse_thread_buffer_map); + if(status==0) + clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); + else + parse_error=true; parse_thread_go=false; parsing_mutex.unlock(); parse_thread_buffer_map_mutex.unlock(); - if(parse_error) { + if(status!=0) { parse_fail(); parse_thread_stop=true; } @@ -1057,15 +1062,6 @@ void Source::ClangViewParse::init_parse() { }); } -void Source::ClangViewParse::init_syntax_highlighting(const std::map &buffers) { - std::vector arguments = get_compilation_commands(); - clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, - file_path.string(), - arguments, - buffers)); - clang_tokens=clang_tu->get_tokens(0, buffers.find(file_path.string())->second.size()-1); -} - std::map Source::ClangViewParse::get_buffer_map() const { std::map buffer_map; buffer_map[file_path.string()]=get_source_buffer()->get_text(); @@ -1084,16 +1080,6 @@ void Source::ClangViewParse::start_reparse() { }, 1000); } -int Source::ClangViewParse::reparse(const std::map &buffer) { - int status = clang_tu->ReparseTranslationUnit(buffer); - if(status!=0) { - parse_error=true; - return status; - } - clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path.string())->second.size()-1); - return status; -} - std::vector Source::ClangViewParse::get_compilation_commands() { clang::CompilationDatabase db(project_path.string()); clang::CompileCommands commands(file_path.string(), db); diff --git a/src/source.h b/src/source.h index 4f46c54..6fb4a18 100644 --- a/src/source.h +++ b/src/source.h @@ -157,9 +157,6 @@ namespace Source { std::regex no_bracket_no_para_statement_regex; private: std::map get_buffer_map() const; - // inits the syntax highligthing on file open - void init_syntax_highlighting(const std::map &buffers); - int reparse(const std::map &buffers); void update_syntax(); std::set last_syntax_tags; void update_diagnostics(); From 6d7ddd623567517933eb8f4adf04de9b9b94a672 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 08:56:32 +0200 Subject: [PATCH 03/14] Now opens files that are not UTF-8 valid, if a language is found for the file, that is, this does not include binary files. --- src/source.cc | 31 ++++++++++++++++++++----------- src/source.h | 8 ++++---- src/sourcefile.cc | 38 +++++++++++++++++++++++++++++--------- src/sourcefile.h | 3 +++ 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/source.cc b/src/source.cc index 56304b3..1bb3654 100644 --- a/src/source.cc +++ b/src/source.cc @@ -48,13 +48,22 @@ Glib::RefPtr Source::guess_language(const boost::filesystem::path ////////////// AspellConfig* Source::View::spellcheck_config=NULL; -Source::View::View(const boost::filesystem::path &file_path): file_path(file_path) { +Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr language): file_path(file_path) { set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); + get_source_buffer()->begin_not_undoable_action(); - if(juci::filesystem::read(file_path, get_buffer())==-1) - Singleton::terminal()->print("Error: "+file_path.string()+" is not a valid UTF-8 file."); + if(language) { + if(juci::filesystem::read_non_utf8(file_path, get_buffer())==-1) + Singleton::terminal()->print("Warning: "+file_path.string()+" is not a valid UTF-8 file. Saving might corrupt the file.\n"); + } + else { + if(juci::filesystem::read(file_path, get_buffer())==-1) + Singleton::terminal()->print("Error: "+file_path.string()+" is not a valid UTF-8 file.\n"); + } get_source_buffer()->end_not_undoable_action(); + get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(0)); + search_settings = gtk_source_search_settings_new(); gtk_source_search_settings_set_wrap_around(search_settings, true); search_context = gtk_source_search_context_new(get_source_buffer()->gobj(), search_settings); @@ -908,7 +917,7 @@ std::vector Source::View::spellcheck_get_suggestions(const Gtk::Tex ///////////////////// //// GenericView //// ///////////////////// -Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language) : View(file_path) { +Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib::RefPtr language) : View(file_path, language) { if(language) { get_source_buffer()->set_language(language); Singleton::terminal()->print("Language for file "+file_path.string()+" set to "+language->get_name()+".\n"); @@ -928,8 +937,8 @@ Source::GenericView::GenericView(const boost::filesystem::path &file_path, Glib: //////////////////////// clang::Index Source::ClangViewParse::clang_index(0, 0); -Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::View(file_path), project_path(project_path), parse_error(false) { +Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::View(file_path, language), project_path(project_path), parse_error(false) { DEBUG("start"); auto scheme = get_source_buffer()->get_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); @@ -1385,8 +1394,8 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// -Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::ClangViewParse(file_path, project_path), autocomplete_cancel_starting(false) { +Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::ClangViewParse(file_path, project_path, language), autocomplete_cancel_starting(false) { get_buffer()->signal_changed().connect([this](){ if(completion_dialog_shown) delayed_reparse_connection.disconnect(); @@ -1668,8 +1677,8 @@ bool Source::ClangViewAutocomplete::restart_parse() { //// ClangViewRefactor ///// //////////////////////////// -Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path): -Source::ClangViewAutocomplete(file_path, project_path) { +Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): +Source::ClangViewAutocomplete(file_path, project_path, language) { similar_tokens_tag=get_buffer()->create_tag(); similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; @@ -1814,7 +1823,7 @@ Source::ClangViewRefactor::~ClangViewRefactor() { delayed_tag_similar_tokens_connection.disconnect(); } -Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path) { +Source::ClangView::ClangView(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): ClangViewRefactor(file_path, project_path, language) { if(language) { get_source_buffer()->set_highlight_syntax(true); get_source_buffer()->set_language(language); diff --git a/src/source.h b/src/source.h index 6fb4a18..2d80aad 100644 --- a/src/source.h +++ b/src/source.h @@ -52,7 +52,7 @@ namespace Source { class View : public Gsv::View { public: - View(const boost::filesystem::path &file_path); + View(const boost::filesystem::path &file_path, Glib::RefPtr language); ~View(); void search_highlight(const std::string &text, bool case_sensitive, bool regex); @@ -134,7 +134,7 @@ namespace Source { class ClangViewParse : public View { public: - ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); ~ClangViewParse(); boost::filesystem::path project_path; void start_reparse(); @@ -176,7 +176,7 @@ namespace Source { class ClangViewAutocomplete : public ClangViewParse { public: - ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewAutocomplete(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); void async_delete(); bool restart_parse(); protected: @@ -206,7 +206,7 @@ namespace Source { class ClangViewRefactor : public ClangViewAutocomplete { public: - ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path); + ClangViewRefactor(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); ~ClangViewRefactor(); private: Glib::RefPtr similar_tokens_tag; diff --git a/src/sourcefile.cc b/src/sourcefile.cc index 2ee7219..ef9fdd6 100644 --- a/src/sourcefile.cc +++ b/src/sourcefile.cc @@ -25,15 +25,6 @@ int juci::filesystem::read(const std::string &path, Glib::RefPtrinsert_at_cursor(ustr); @@ -69,6 +60,35 @@ int juci::filesystem::read(const std::string &path, Glib::RefPtr text_buffer) { + std::ifstream input(path, std::ofstream::binary); + + if(input) { + //need to read the whole file to make this work... + std::stringstream ss; + ss << input.rdbuf(); + Glib::ustring ustr=std::move(ss.str()); + + bool valid=true; + Glib::ustring::iterator iter; + while(!ustr.validate(iter)) { + auto next_char_iter=iter; + next_char_iter++; + ustr.replace(iter, next_char_iter, "?"); + valid=false; + } + + text_buffer->insert_at_cursor(ustr); + + input.close(); + if(valid) + return 1; + else + return -1; + } + return 0; +} + //Only use on small files std::vector juci::filesystem::read_lines(const std::string &path) { std::vector res; diff --git a/src/sourcefile.h b/src/sourcefile.h index 9ddc937..4507ab7 100644 --- a/src/sourcefile.h +++ b/src/sourcefile.h @@ -13,6 +13,9 @@ namespace juci { static int read(const std::string &path, Glib::RefPtr text_buffer); static int read(const boost::filesystem::path &path, Glib::RefPtr text_buffer) { return read(path.string(), text_buffer); } + static int read_non_utf8(const std::string &path, Glib::RefPtr text_buffer); + static int read_non_utf8(const boost::filesystem::path &path, Glib::RefPtr text_buffer) { return read_non_utf8(path.string(), text_buffer); } + static std::vector read_lines(const std::string &path); static std::vector read_lines(const boost::filesystem::path &path) { return read_lines(path.string()); }; From 9291b8082b1d557a54414d10ecf11f3a1a63b27f Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 13:45:44 +0200 Subject: [PATCH 04/14] Tabs are now reordable, and removed resize symbol that overlapped status field on Debian at least. --- src/notebook.cc | 1 + src/window.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/notebook.cc b/src/notebook.cc index 7f472b5..dbac5fa 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -83,6 +83,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { std::string title=file_path.filename().string(); append_page(*hboxes.back(), title); + set_tab_reorderable(*hboxes.back(), true); show_all_children(); set_current_page(size()-1); set_focus_child(*source_views.back()); diff --git a/src/window.cc b/src/window.cc index 3b09318..397b243 100644 --- a/src/window.cc +++ b/src/window.cc @@ -36,6 +36,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil DEBUG("start"); set_title("juCi++"); set_default_size(600, 400); + set_has_resize_grip(false); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(box); From 784456b7d3044f13101f6e09421a0668c4bc59ae Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 15:41:50 +0200 Subject: [PATCH 05/14] Reorder tabs should now work. --- src/notebook.cc | 19 ++++++++++++++----- src/notebook.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index dbac5fa..4c382e9 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -32,7 +32,15 @@ int Notebook::size() { } Source::View* Notebook::get_view(int page) { - return source_views.at(page); + return source_views.at(get_index(page)); +} + +size_t Notebook::get_index(int page) { + for(size_t c=0;c(source_view)) source_clang_view->async_delete(); else delete source_view; - source_views.erase(source_views.begin()+ page); - scrolled_windows.erase(scrolled_windows.begin()+page); - hboxes.erase(hboxes.begin()+page); + source_views.erase(source_views.begin()+index); + scrolled_windows.erase(scrolled_windows.begin()+index); + hboxes.erase(hboxes.begin()+index); } DEBUG("end true"); return true; diff --git a/src/notebook.h b/src/notebook.h index 3c75e0c..68f6d99 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -14,6 +14,7 @@ class Notebook : public Gtk::Notebook { public: Notebook(Directories &directories); Source::View* get_view(int page); + size_t get_index(int page); int size(); Source::View* get_current_view(); bool close_current_page(); From 81029f713fb7438479ac11e609e1ac0c85b8fbc5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 15:47:27 +0200 Subject: [PATCH 06/14] Resize grips are depricated, removed it. --- src/window.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/window.cc b/src/window.cc index 397b243..3b09318 100644 --- a/src/window.cc +++ b/src/window.cc @@ -36,7 +36,6 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil DEBUG("start"); set_title("juCi++"); set_default_size(600, 400); - set_has_resize_grip(false); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(box); From fa2f76390ff307b0ecdfad5e7d05facbb6ee4032 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 21:34:45 +0200 Subject: [PATCH 07/14] Added info at bottom left line, showing line and line offset as well as number of warnings and errors. --- src/notebook.cc | 17 +++++++++++++---- src/singletons.cc | 6 ++++++ src/singletons.h | 2 ++ src/source.cc | 35 +++++++++++++++++++++++++++++++++-- src/source.h | 8 +++++--- src/tooltips.cc | 4 ++-- src/window.cc | 18 ++++++++++++------ src/window.h | 2 +- 8 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 4c382e9..37bcefd 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -83,6 +83,18 @@ void Notebook::open(const boost::filesystem::path &file_path) { } else source_views.emplace_back(new Source::GenericView(file_path, language)); + + source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) { + if(get_current_page()!=-1 && get_current_view()==view) + Singleton::status()->set_text(status+" "); + }; + source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) { + if(get_current_page()!=-1 && get_current_view()==view) { + auto iter=get_current_view()->get_buffer()->get_insert()->get_iter(); + auto positions=std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1); + Singleton::info()->set_text(" "+positions+" "+info); + } + }; scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); hboxes.emplace_back(new Gtk::HBox()); @@ -90,6 +102,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { hboxes.back()->pack_start(*scrolled_windows.back(), true, true); std::string title=file_path.filename().string(); + append_page(*hboxes.back(), title); set_tab_reorderable(*hboxes.back(), true); show_all_children(); @@ -114,10 +127,6 @@ void Notebook::open(const boost::filesystem::path &file_path) { set_tab_label_text(*(get_nth_page(page)), title); }); - get_current_view()->on_update_status=[this](Source::View* view, const std::string &status) { - if(get_current_page()!=-1 && get_current_view()==view) - Singleton::status()->set_text(status); - }; DEBUG("end"); } diff --git a/src/singletons.cc b/src/singletons.cc index dd9d926..4633763 100644 --- a/src/singletons.cc +++ b/src/singletons.cc @@ -17,3 +17,9 @@ Gtk::Label *Singleton::status() { status_=std::unique_ptr(new Gtk::Label()); return status_.get(); } +std::unique_ptr Singleton::info_=std::unique_ptr(); +Gtk::Label *Singleton::info() { + if(!info_) + info_=std::unique_ptr(new Gtk::Label()); + return info_.get(); +} diff --git a/src/singletons.h b/src/singletons.h index de07113..8fa6a86 100644 --- a/src/singletons.h +++ b/src/singletons.h @@ -31,9 +31,11 @@ public: static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; } static Terminal *terminal(); static Gtk::Label *status(); + static Gtk::Label *info(); private: static std::unique_ptr terminal_; static std::unique_ptr status_; + static std::unique_ptr info_; }; #endif // JUCI_SINGLETONS_H_ diff --git a/src/source.cc b/src/source.cc index 1bb3654..ae3e1d3 100644 --- a/src/source.cc +++ b/src/source.cc @@ -265,6 +265,10 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrsignal_changed().connect([this](){ + set_info(info); + }); + set_tooltip_events(); } @@ -316,6 +320,7 @@ void Source::View::set_tooltip_events() { }, 500); type_tooltips.hide(); diagnostic_tooltips.hide(); + set_info(info); } }); @@ -530,6 +535,12 @@ void Source::View::set_status(const std::string &status) { on_update_status(this, status); } +void Source::View::set_info(const std::string &info) { + this->info=info; + if(on_update_info) + on_update_info(this, this->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 = iter; @@ -1185,6 +1196,8 @@ void Source::ClangViewParse::update_diagnostics() { get_buffer()->remove_tag_by_name("def:warning_underline", get_buffer()->begin(), get_buffer()->end()); get_buffer()->remove_tag_by_name("def:error_underline", get_buffer()->begin(), get_buffer()->end()); auto diagnostics=clang_tu->get_diagnostics(); + size_t warnings=0; + size_t errors=0; for(auto &diagnostic: diagnostics) { if(diagnostic.path==file_path.string()) { auto start_line=get_line(diagnostic.offsets.first.line-1); //index is sometimes off the line @@ -1206,10 +1219,14 @@ void Source::ClangViewParse::update_diagnostics() { auto start=get_buffer()->get_iter_at_line_index(diagnostic.offsets.first.line-1, start_line_index); auto end=get_buffer()->get_iter_at_line_index(diagnostic.offsets.second.line-1, end_line_index); std::string diagnostic_tag_name; - if(diagnostic.severity<=CXDiagnostic_Warning) + if(diagnostic.severity<=CXDiagnostic_Warning) { diagnostic_tag_name="def:warning"; - else + warnings++; + } + else { diagnostic_tag_name="def:error"; + errors++; + } auto spelling=diagnostic.spelling; auto severity_spelling=diagnostic.severity_spelling; @@ -1230,6 +1247,20 @@ void Source::ClangViewParse::update_diagnostics() { } } } + std::string diagnostic_info; + if(warnings>0) { + diagnostic_info+=std::to_string(warnings)+" warning"; + if(warnings>1) + diagnostic_info+='s'; + } + if(errors>0) { + if(warnings>0) + diagnostic_info+=", "; + diagnostic_info+=std::to_string(errors)+" error"; + if(errors>1) + diagnostic_info+='s'; + } + set_info(" "+diagnostic_info); } void Source::ClangViewParse::update_types() { diff --git a/src/source.h b/src/source.h index 2d80aad..8fd6409 100644 --- a/src/source.h +++ b/src/source.h @@ -75,7 +75,11 @@ namespace Source { std::function rename_similar_tokens; std::function on_update_status; + std::function on_update_info; + void set_status(const std::string &status); + void set_info(const std::string &info); std::string status; + std::string info; protected: bool source_readable; Tooltips diagnostic_tooltips; @@ -84,9 +88,7 @@ namespace Source { gdouble on_motion_last_y; sigc::connection delayed_tooltips_connection; void set_tooltip_events(); - - void set_status(const std::string &status); - + std::string get_line(const Gtk::TextIter &iter); std::string get_line(Glib::RefPtr mark); std::string get_line(int line_nr); diff --git a/src/tooltips.cc b/src/tooltips.cc index 113ce64..f5082d9 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -1,8 +1,8 @@ #include "tooltips.h" #include "singletons.h" -#include -using namespace std; +#include //TODO: remove +using namespace std; //TODO: remove namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE diff --git a/src/window.cc b/src/window.cc index 3b09318..3164382 100644 --- a/src/window.cc +++ b/src/window.cc @@ -54,8 +54,9 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil terminal_scrolled_window.add(*Singleton::terminal()); terminal_vbox.pack_start(terminal_scrolled_window); - status_hbox.pack_end(*Singleton::status(), Gtk::PACK_SHRINK); - terminal_vbox.pack_end(status_hbox, Gtk::PACK_SHRINK); + info_and_status_hbox.pack_start(*Singleton::info(), Gtk::PACK_SHRINK); + info_and_status_hbox.pack_end(*Singleton::status(), Gtk::PACK_SHRINK); + terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); vpaned.pack2(terminal_vbox, true, true); box.pack_end(vpaned); @@ -110,7 +111,8 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil } } - Singleton::status()->set_text(notebook.get_current_view()->status); + notebook.get_current_view()->set_status(notebook.get_current_view()->status); + notebook.get_current_view()->set_info(notebook.get_current_view()->info); } }); notebook.signal_page_removed().connect([this](Gtk::Widget* page, guint page_num) { @@ -322,10 +324,14 @@ void Window::create_menu() { }); menu.action_group->add(Gtk::Action::create("WindowCloseTab", "Close Tab"), Gtk::AccelKey(menu.key_map["close_tab"]), [this]() { notebook.close_current_page(); - if(notebook.get_current_page()!=-1) - Singleton::status()->set_text(notebook.get_current_view()->status); - else + if(notebook.get_current_page()!=-1) { + notebook.get_current_view()->set_status(notebook.get_current_view()->status); + notebook.get_current_view()->set_info(notebook.get_current_view()->info); + } + else { Singleton::status()->set_text(""); + Singleton::info()->set_text(""); + } }); menu.action_group->add(Gtk::Action::create("HelpAbout", "About"), [this] () { about.show(); diff --git a/src/window.h b/src/window.h index 693b526..5c8b349 100644 --- a/src/window.h +++ b/src/window.h @@ -33,7 +33,7 @@ private: Gtk::VBox notebook_vbox; Gtk::VBox terminal_vbox; Gtk::ScrolledWindow terminal_scrolled_window; - Gtk::HBox status_hbox; + Gtk::HBox info_and_status_hbox; Gtk::AboutDialog about; EntryBox entry_box; Menu menu; From d4a8c3b1326559d7c3172b6426b18f181b08c84f Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 21:43:05 +0200 Subject: [PATCH 08/14] Minor changes to info. --- src/notebook.cc | 4 ++-- src/source.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 37bcefd..0b8ef04 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -86,13 +86,13 @@ void Notebook::open(const boost::filesystem::path &file_path) { source_views.back()->on_update_status=[this](Source::View* view, const std::string &status) { if(get_current_page()!=-1 && get_current_view()==view) - Singleton::status()->set_text(status+" "); + Singleton::status()->set_text(status+" "); }; source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) { if(get_current_page()!=-1 && get_current_view()==view) { auto iter=get_current_view()->get_buffer()->get_insert()->get_iter(); auto positions=std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1); - Singleton::info()->set_text(" "+positions+" "+info); + Singleton::info()->set_text(" "+positions+" "+info); } }; diff --git a/src/source.cc b/src/source.cc index ae3e1d3..ab4f00a 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1255,7 +1255,7 @@ void Source::ClangViewParse::update_diagnostics() { } if(errors>0) { if(warnings>0) - diagnostic_info+=", "; + diagnostic_info+=", "; diagnostic_info+=std::to_string(errors)+" error"; if(errors>1) diagnostic_info+='s'; From 079a9374bbfc9974e29bc0afda66c25b633b96e3 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 21:51:12 +0200 Subject: [PATCH 09/14] Minor change to info. --- src/source.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/source.cc b/src/source.cc index ab4f00a..06a1668 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1003,6 +1003,7 @@ Source::View(file_path, language), project_path(project_path), parse_error(false parse_fail.connect([this](){ Singleton::terminal()->print("Error: failed to reparse "+this->file_path.string()+".\n"); set_status(""); + set_info(""); parsing_in_progress->cancel("failed"); }); init_parse(); From eef806f5eec29f006a215ebbcb505d330e7687b9 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 9 Sep 2015 22:12:57 +0200 Subject: [PATCH 10/14] Minor info cleanup. --- src/notebook.cc | 7 ++----- src/source.cc | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index 0b8ef04..40b9874 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -89,11 +89,8 @@ void Notebook::open(const boost::filesystem::path &file_path) { Singleton::status()->set_text(status+" "); }; source_views.back()->on_update_info=[this](Source::View* view, const std::string &info) { - if(get_current_page()!=-1 && get_current_view()==view) { - auto iter=get_current_view()->get_buffer()->get_insert()->get_iter(); - auto positions=std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1); - Singleton::info()->set_text(" "+positions+" "+info); - } + if(get_current_page()!=-1 && get_current_view()==view) + Singleton::info()->set_text(" "+info); }; scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); diff --git a/src/source.cc b/src/source.cc index 06a1668..44e41fc 100644 --- a/src/source.cc +++ b/src/source.cc @@ -537,8 +537,10 @@ void Source::View::set_status(const std::string &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, this->info); + on_update_info(this, positions+" "+info); } std::string Source::View::get_line(const Gtk::TextIter &iter) { From 4cd5654252f2c4aaab5b5e58c40797516ef9bfde Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 10 Sep 2015 08:55:29 +0200 Subject: [PATCH 11/14] Filenames without language support are now gray in the directory window. --- src/directories.cc | 22 +++++++++++++++++++++- src/directories.h | 3 +++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/directories.cc b/src/directories.cc index 52a31c7..5a761a4 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -29,6 +29,9 @@ Directories::Directories() : stop_update_thread(false) { tree_store = Gtk::TreeStore::create(column_record); tree_view.set_model(tree_store); tree_view.append_column("", column_record.name); + auto renderer=dynamic_cast(tree_view.get_column(0)->get_first_cell()); + tree_view.get_column(0)->add_attribute(renderer->property_foreground_rgba(), column_record.color); + tree_store->set_sort_column(column_record.id, Gtk::SortType::SORT_ASCENDING); tree_view.set_enable_search(true); //TODO: why does this not work in OS X? tree_view.set_search_column(column_record.name); @@ -67,6 +70,9 @@ Directories::Directories() : stop_update_thread(false) { } auto child=tree_store->append(iter->children()); child->set_value(column_record.name, std::string("(empty)")); + Gdk::RGBA rgba; + rgba.set_rgba(0.5, 0.5, 0.5); + child->set_value(column_record.color, rgba); } }); @@ -243,9 +249,20 @@ void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::T child->set_value(column_record.id, "a"+filename); auto grandchild=tree_store->append(child->children()); grandchild->set_value(column_record.name, std::string("(empty)")); + Gdk::RGBA rgba; + rgba.set_rgba(0.5, 0.5, 0.5); + grandchild->set_value(column_record.color, rgba); } - else + else { child->set_value(column_record.id, "b"+filename); + + auto language=Source::guess_language(it->path().filename()); + if(!language) { + Gdk::RGBA rgba; + rgba.set_rgba(0.5, 0.5, 0.5); + child->set_value(column_record.color, rgba); + } + } } } } @@ -261,5 +278,8 @@ void Directories::add_path(const boost::filesystem::path& dir_path, const Gtk::T if(!*children) { auto child=tree_store->append(*children); child->set_value(column_record.name, std::string("(empty)")); + Gdk::RGBA rgba; + rgba.set_rgba(0.5, 0.5, 0.5); + child->set_value(column_record.color, rgba); } } diff --git a/src/directories.h b/src/directories.h index c34e319..74878a7 100644 --- a/src/directories.h +++ b/src/directories.h @@ -24,10 +24,12 @@ public: add(id); add(name); add(path); + add(color); } Gtk::TreeModelColumn id; Gtk::TreeModelColumn name; Gtk::TreeModelColumn path; + Gtk::TreeModelColumn color; }; Directories(); @@ -46,6 +48,7 @@ private: Gtk::TreeView tree_view; Glib::RefPtr tree_store; ColumnRecord column_record; + std::unordered_map > last_write_times; std::mutex update_mutex; std::thread update_thread; From 4fc6cee3734b314ca94c9a8b0c868cc57822e56e Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 10 Sep 2015 09:46:06 +0200 Subject: [PATCH 12/14] Menu xml is now hardcoded in menu.cc. Now we do not have to worry about how to update the menu for those already having a ~/.juci directory. menu.xml is no longer created in this directory. --- src/config.cc | 3 +-- src/files.h | 56 ------------------------------------------------- src/menu.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/menu.h | 2 +- src/window.cc | 2 -- 5 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/config.cc b/src/config.cc index cb434b7..d7bcaa1 100644 --- a/src/config.cc +++ b/src/config.cc @@ -20,14 +20,13 @@ MainConfig::MainConfig() { } void MainConfig::find_or_create_config_files() { - std::vector files = {"config.json", "menu.xml", "plugins.py"}; + std::vector files = {"config.json", "plugins.py"}; boost::filesystem::create_directories(boost::filesystem::path(Singleton::config_dir())); for (auto &file : files) { auto path = boost::filesystem::path(Singleton::config_dir() + file); if (!boost::filesystem::is_regular_file(path)) { if (file == "config.json") juci::filesystem::write(path, configjson); if (file == "plugins.py") juci::filesystem::write(path, pluginspy); - if (file == "menu.xml") juci::filesystem::write(path, menuxml); } } diff --git a/src/files.h b/src/files.h index 50476c7..6ded01b 100644 --- a/src/files.h +++ b/src/files.h @@ -83,62 +83,6 @@ const std::string configjson = " }\n" "}\n"; -const std::string menuxml = -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n"; - const std::string juci_light_style = "\n" "\n" diff --git a/src/menu.cc b/src/menu.cc index 10daca9..6f0d2ef 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -14,6 +14,62 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { action_group->add(Gtk::Action::create("SourceMenu", "_Source")); action_group->add(Gtk::Action::create("PluginMenu", "_Plugins")); action_group->add(Gtk::Action::create("HelpMenu", "Help")); + + ui_xml = + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"; } Gtk::Widget& Menu::get_widget() { @@ -22,7 +78,7 @@ Gtk::Widget& Menu::get_widget() { void Menu::build() { try { - ui_manager->add_ui_from_string(ui); + ui_manager->add_ui_from_string(ui_xml); } catch (const Glib::Error &ex) { std::cerr << "building menu failed" << ex.what(); diff --git a/src/menu.h b/src/menu.h index 9dcc6eb..257854e 100644 --- a/src/menu.h +++ b/src/menu.h @@ -13,7 +13,7 @@ public: Gtk::Box box; std::unordered_map key_map; - std::string ui; + std::string ui_xml; Glib::RefPtr ui_manager; Glib::RefPtr action_group; }; diff --git a/src/window.cc b/src/window.cc index 3164382..13bfa5a 100644 --- a/src/window.cc +++ b/src/window.cc @@ -24,8 +24,6 @@ namespace sigc { } void Window::generate_keybindings() { - boost::filesystem::path path(Singleton::config_dir() + "menu.xml"); - menu.ui = juci::filesystem::read(path); for (auto &i : Singleton::Config::window()->keybindings) { auto key = i.second.get_value(); menu.key_map[i.first] = key; From 8437fae54b057cd62807daea808c7f6b0178ff8f Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 10 Sep 2015 13:31:38 +0200 Subject: [PATCH 13/14] Numbers are no longer included in spellcheck. --- src/source.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index 44e41fc..4e9416a 100644 --- a/src/source.cc +++ b/src/source.cc @@ -879,7 +879,7 @@ std::pair Source::View::find_tab_char_and_size() { } bool Source::View::is_word_iter(const Gtk::TextIter& iter) { - return ((*iter>=48 && *iter<=57) || (*iter>=65 && *iter<=90) || (*iter>=97 && *iter<=122) || *iter==39 || *iter>=128); + return ((*iter>=65 && *iter<=90) || (*iter>=97 && *iter<=122) || *iter==39 || *iter>=128); } std::pair Source::View::spellcheck_get_word(Gtk::TextIter iter) { From 60136fe560bede4513a845e5fbc3f17f7863984b Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 10 Sep 2015 14:21:04 +0200 Subject: [PATCH 14/14] Spellcheck fixes when for instance uncommenting code and moving cursor to positions where previous spellcheck errors were found. --- src/source.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/source.cc b/src/source.cc index 4e9416a..98cb8ff 100644 --- a/src/source.cc +++ b/src/source.cc @@ -202,8 +202,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtriter_has_context_class(context_iter, "no-spell-check")) || get_source_buffer()->iter_has_context_class(context_iter, "comment") || get_source_buffer()->iter_has_context_class(context_iter, "string")) { - if(last_keyval_is_backspace && !is_word_iter(iter) && iter.forward_char()) {} //backspace fix if(!is_word_iter(iter)) { //Might have used space or - to split two words auto first=iter; auto second=iter; @@ -220,6 +220,20 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrproperty_name()=="spellcheck_error") { + has_spellcheck_error=true; + break; + } + } + if(has_spellcheck_error) { + auto word=spellcheck_get_word(iter); + get_buffer()->remove_tag_by_name("spellcheck_error", word.first, word.second); + } + } } } }); @@ -239,6 +253,12 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_insert()->get_iter(); + if(!((spellcheck_all && !get_source_buffer()->iter_has_context_class(iter, "no-spell-check")) || get_source_buffer()->iter_has_context_class(iter, "comment") || get_source_buffer()->iter_has_context_class(iter, "string"))) { + auto word=spellcheck_get_word(iter); + get_buffer()->remove_tag_by_name("spellcheck_error", word.first, word.second); + return false; + } spellcheck_suggestions_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false)); spellcheck_suggestions_dialog->on_hide=[this](){ spellcheck_suggestions_dialog_shown=false;