From be4c03817d221d44e350e8d1bb5d0d7bed5f2f12 Mon Sep 17 00:00:00 2001 From: eidheim Date: Mon, 9 Jul 2018 20:30:34 +0200 Subject: [PATCH] Cleanup of Source::View::find_non_whitespace_code_iter_backward and Source::View::get_start_of_expression --- src/source.cc | 27 +++++++++++----------- src/source_spellcheck.cc | 18 +++++++++++++++ src/source_spellcheck.h | 2 ++ tests/source_key_test.cc | 48 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/source.cc b/src/source.cc index 0f92289..0e7ab1b 100644 --- a/src/source.cc +++ b/src/source.cc @@ -1252,20 +1252,13 @@ Gtk::TextIter Source::View::find_non_whitespace_code_iter_backward(Gtk::TextIter return iter; if(!comment_tag) return iter; - while(!iter.starts_line() && (iter.has_tag(comment_tag) || -#if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 20) - iter.starts_tag(comment_tag) || -#else - *iter == '/' || -#endif - *iter == ' ' || *iter == '\t' || iter.ends_line()) && - iter.backward_char()) { + while(!iter.starts_line() && (is_comment_iter(iter) || *iter == ' ' || *iter == '\t' || iter.ends_line()) && iter.backward_char()) { } return iter; } Gtk::TextIter Source::View::get_start_of_expression(Gtk::TextIter iter) { - while(!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line() || !is_code_iter(iter) || *iter == '/') && iter.backward_char()) { + while(!iter.starts_line() && (*iter == ' ' || *iter == '\t' || iter.ends_line() || !is_code_iter(iter) || is_comment_iter(iter)) && iter.backward_char()) { } if(iter.starts_line()) @@ -1323,15 +1316,21 @@ Gtk::TextIter Source::View::get_start_of_expression(Gtk::TextIter iter) { if(!test_iter.starts_line() && *test_iter == ':' && is_code_iter(test_iter)) colon_found = true; } - // Handle : , = & | on previous line + const auto is_multiline_operator = [](const Gtk::TextIter &iter) { + if(*iter == '=' || *iter == '+' || *iter == '-' || *iter == '*' || *iter == '/' || + *iter == '%' || *iter == '<' || *iter == '>' || *iter == '&' || *iter == '|') + return true; + return false; + }; + // Handle ':', ',', or operators that can be used between two lines, on previous line: if(!stream_operator_found && !colon_found) { auto previous_iter = iter; previous_iter.backward_char(); - while(!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line()) && previous_iter.backward_char()) { + while(!previous_iter.starts_line() && (*previous_iter == ' ' || previous_iter.ends_line() || is_comment_iter(previous_iter)) && previous_iter.backward_char()) { } - if(*previous_iter != ',' && *previous_iter != ':' && *previous_iter != '=' && *previous_iter != '&' && *previous_iter != '|') + if((*previous_iter != ',' && *previous_iter != ':' && !is_multiline_operator(previous_iter)) || !is_code_iter(previous_iter) || is_comment_iter(previous_iter)) return iter; - else if(*previous_iter == ':' && is_code_iter(previous_iter)) { + else if(*previous_iter == ':') { previous_iter.backward_char(); while(!previous_iter.starts_line() && *previous_iter == ' ' && previous_iter.backward_char()) { } @@ -1344,7 +1343,7 @@ Gtk::TextIter Source::View::get_start_of_expression(Gtk::TextIter iter) { return iter; } // Handle for instance: int a =\n b; - else if((*previous_iter == '=' || *previous_iter == '&' || *previous_iter == '|') && !has_semicolon && is_code_iter(previous_iter)) + else if(!has_semicolon && is_multiline_operator(previous_iter)) return iter; } } diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc index 8b54707..2638c08 100644 --- a/src/source_spellcheck.cc +++ b/src/source_spellcheck.cc @@ -427,6 +427,24 @@ bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) { return true; } +bool Source::SpellCheckView::is_comment_iter(const Gtk::TextIter &iter) { + if(!comment_tag) + return false; + if(iter.has_tag(comment_tag)) + return true; +#if GTKMM_MAJOR_VERSION > 3 || (GTKMM_MAJOR_VERSION == 3 && GTKMM_MINOR_VERSION >= 20) + if(iter.starts_tag(comment_tag)) + return true; +#else + if(*iter == '/') { + auto next_iter = iter; + if(!next_iter.ends_line() && next_iter.forward_char() && next_iter.has_tag(comment_tag)) + return true; + } +#endif + return false; +} + bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter &iter) { auto previous_iter = iter; size_t backslash_count = 0; diff --git a/src/source_spellcheck.h b/src/source_spellcheck.h index 1153b68..11459d6 100644 --- a/src/source_spellcheck.h +++ b/src/source_spellcheck.h @@ -17,6 +17,8 @@ namespace Source { protected: bool is_code_iter(const Gtk::TextIter &iter); + /// Returns true, for instance for C++, if iter is at either characters of // or /* + bool is_comment_iter(const Gtk::TextIter &iter); bool spellcheck_all = false; guint last_keyval = 0; diff --git a/tests/source_key_test.cc b/tests/source_key_test.cc index 1acbb96..7a861b2 100644 --- a/tests/source_key_test.cc +++ b/tests/source_key_test.cc @@ -663,6 +663,54 @@ int main() { g_assert(buffer->get_insert()->get_iter() == buffer->end()); } + { + buffer->set_text(" int a = 2 +\n" + " 2;"); + view.on_key_press_event(&event); + g_assert(buffer->get_text() == " int a = 2 +\n" + " 2;\n" + " "); + g_assert(buffer->get_insert()->get_iter() == buffer->end()); + } + { + buffer->set_text(" int a = 2 /\n" + " 2;"); + view.on_key_press_event(&event); + g_assert(buffer->get_text() == " int a = 2 /\n" + " 2;\n" + " "); + g_assert(buffer->get_insert()->get_iter() == buffer->end()); + } + { + buffer->set_text(" int a = 2 + // test\n" + " 2;"); + while(Gtk::Main::events_pending()) + Gtk::Main::iteration(false); + view.on_key_press_event(&event); + g_assert(buffer->get_text() == " int a = 2 + // test\n" + " 2;\n" + " "); + g_assert(buffer->get_insert()->get_iter() == buffer->end()); + } + { + buffer->set_text(" int a = 2;\n" + " 2;"); + view.on_key_press_event(&event); + g_assert(buffer->get_text() == " int a = 2;\n" + " 2;\n" + " "); + g_assert(buffer->get_insert()->get_iter() == buffer->end()); + } + { + buffer->set_text(" int a = 2 #\n" + " 2;"); + view.on_key_press_event(&event); + g_assert(buffer->get_text() == " int a = 2 #\n" + " 2;\n" + " "); + g_assert(buffer->get_insert()->get_iter() == buffer->end()); + } + { buffer->set_text(" func(["); view.on_key_press_event(&event);