diff --git a/README.md b/README.md index bea62b4..14a0b36 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ towards libclang with speed in mind. ## Features * Fast and responsive -* Syntax highlighing (even C++11/14, and more than 100 other file types) +* Syntax highlighting (even C++11/14, and more than 100 other file types) * C++ warnings and errors on the fly * Fast C++ autocomletion (even external libraries) * Tooltips showing type information and doxygen documentation diff --git a/src/files.h b/src/files.h index 750f49c..dd14d1a 100644 --- a/src/files.h +++ b/src/files.h @@ -63,6 +63,9 @@ const std::string configjson = " \"edit_undo\": \"z\",\n" " \"edit_redo\": \"z\",\n" " \"edit_find\": \"f\",\n" +" \"source_spellcheck\": \"\",\n" +" \"source_spellcheck_clear\": \"\",\n" +" \"source_spellcheck_next_error\": \"e\",\n" " \"source_goto_line\": \"g\",\n" " \"source_center_cursor\": \"l\",\n" " \"source_goto_declaration\": \"d\",\n" diff --git a/src/menu.cc b/src/menu.cc index 0a66e34..5ae64be 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -45,6 +45,12 @@ Menu::Menu() { " \n" " \n" " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n" diff --git a/src/source.cc b/src/source.cc index 4d2350c..538b1aa 100644 --- a/src/source.cc +++ b/src/source.cc @@ -617,6 +617,89 @@ void Source::View::set_info(const std::string &info) { on_update_info(this, positions+" "+info); } +void Source::View::spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end) { + cout << start.get_line() << ", " << start.get_line_offset() << " -- "; + cout << end.get_line() << ", " << end.get_line_offset() << endl; + auto iter=start; + while(iter && iter<=end) { + if(is_word_iter(iter)) { + auto word=spellcheck_get_word(iter); + spellcheck_word(word.first, word.second); + iter=word.second; + } + iter.forward_char(); + } +} + +void Source::View::spellcheck() { + auto iter=get_buffer()->begin(); + Gtk::TextIter begin_spellcheck_iter; + if(spellcheck_all) { + bool spell_check=!get_source_buffer()->iter_has_context_class(iter, "no-spell-check"); + if(spell_check) + begin_spellcheck_iter=iter; + while(iter!=get_buffer()->end()) { + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check")) + iter=get_buffer()->end(); + + spell_check=!spell_check; + if(spell_check) + begin_spellcheck_iter=iter; + else + spellcheck(begin_spellcheck_iter, iter); + } + } + else { + bool spell_check=get_source_buffer()->iter_has_context_class(iter, "string") || get_source_buffer()->iter_has_context_class(iter, "comment"); + if(spell_check) + begin_spellcheck_iter=iter; + while(iter!=get_buffer()->end()) { + auto iter1=iter; + auto iter2=iter; + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string")) + iter1=get_buffer()->end(); + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment")) + iter2=get_buffer()->end(); + + if(iter2remove_tag_by_name("spellcheck_error", get_buffer()->begin(), get_buffer()->end()); +} + +void Source::View::goto_next_spellcheck_error() { + auto iter=get_buffer()->get_insert()->get_iter(); + auto insert_iter=iter; + bool wrapped=false; + iter.forward_char(); + while(iter && (!wrapped || iterproperty_name()=="spellcheck_error") { + get_buffer()->place_cursor(iter); + scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); + return; + } + } + iter.forward_char(); + if(!wrapped && iter==get_buffer()->end()) { + iter=get_buffer()->begin(); + wrapped=true; + } + } +} + 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; diff --git a/src/source.h b/src/source.h index 5d65421..49e63e0 100644 --- a/src/source.h +++ b/src/source.h @@ -97,6 +97,10 @@ namespace Source { void set_info(const std::string &info); std::string status; std::string info; + + void spellcheck(); + void remove_spellcheck_errors(); + void goto_next_spellcheck_error(); protected: bool source_readable; Tooltips diagnostic_tooltips; @@ -149,6 +153,8 @@ namespace Source { std::vector spellcheck_get_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end); sigc::connection delayed_spellcheck_suggestions_connection; sigc::connection delayed_spellcheck_error_clear; + + void spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end); }; class GenericView : public View { diff --git a/src/window.cc b/src/window.cc index 9b087b4..c4e3d7a 100644 --- a/src/window.cc +++ b/src/window.cc @@ -240,6 +240,19 @@ void Window::create_menu() { } }); + menu.action_group->add(Gtk::Action::create("SourceSpellCheck", "Spell Check")); + menu.action_group->add(Gtk::Action::create("SourceSpellCheckBuffer", "Spell Check Buffer"), Gtk::AccelKey(menu.key_map["source_spellcheck"]), [this]() { + if(notebook.get_current_page()!=-1) + notebook.get_current_view()->spellcheck(); + }); + menu.action_group->add(Gtk::Action::create("SourceSpellCheckClear", "Clear Spelling Errors"), Gtk::AccelKey(menu.key_map["source_spellcheck_clear"]), [this]() { + if(notebook.get_current_page()!=-1) + notebook.get_current_view()->remove_spellcheck_errors(); + }); + menu.action_group->add(Gtk::Action::create("SourceSpellCheckNextError", "Go to next Spelling Error"), Gtk::AccelKey(menu.key_map["source_spellcheck_next_error"]), [this]() { + if(notebook.get_current_page()!=-1) + notebook.get_current_view()->goto_next_spellcheck_error(); + }); menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(menu.key_map["source_goto_line"]), [this]() { goto_line_entry(); });