Browse Source

Cleanup and fixing of ' handling in is_code_iter and is_spellcheck_iter, and added tests for is_spellcheck_iter and is_code_iter

merge-requests/389/head
eidheim 7 years ago
parent
commit
f00957776b
  1. 50
      src/source_spellcheck.cc
  2. 2
      src/source_spellcheck.h
  3. 144
      tests/source_key_test.cc

50
src/source_spellcheck.cc

@ -335,9 +335,9 @@ void Source::SpellCheckView::goto_next_spellcheck_error() {
}
bool Source::SpellCheckView::is_spellcheck_iter(const Gtk::TextIter &iter) {
if(*iter == '\'') {
if(*iter == '\'') { // Handle iter inside ''
auto previous_iter = iter;
if(!iter.starts_line() && previous_iter.backward_char() && *previous_iter == '\'')
if(previous_iter.backward_char() && *previous_iter == '\'')
return true;
}
if(spellcheck_all) {
@ -356,7 +356,7 @@ bool Source::SpellCheckView::is_spellcheck_iter(const Gtk::TextIter &iter) {
}
}
}
// for example, mark first " as code iter in this case: r""
// for example, mark first " as not spellcheck iter in this case: r""
if(*iter == '\'' || *iter == '"') {
auto previous_iter = iter;
if(previous_iter.backward_char() && *previous_iter != '\'' && *previous_iter != '\"' && previous_iter.ends_tag(no_spell_check_tag))
@ -374,14 +374,14 @@ bool Source::SpellCheckView::is_spellcheck_iter(const Gtk::TextIter &iter) {
if(previous_iter.backward_char() && *previous_iter == '/') {
auto previous_previous_iter = previous_iter;
if(previous_previous_iter.backward_char() && *previous_previous_iter == '*') {
auto it = previous_iter;
while(!it.begins_tag(comment_tag) && it.backward_to_tag_toggle(comment_tag)) {
}
auto next_iter = it;
if(it.begins_tag(comment_tag) && next_iter.forward_char() && *it == '/' && *next_iter == '*' && previous_iter != it)
auto start_iter = iter;
if(start_iter.backward_to_tag_toggle(comment_tag)) {
auto next_iter = start_iter;
if(start_iter.begins_tag(comment_tag) && next_iter.forward_char() && *start_iter == '/' && *next_iter == '*')
return false;
}
}
}
return true;
}
}
@ -391,24 +391,20 @@ bool Source::SpellCheckView::is_spellcheck_iter(const Gtk::TextIter &iter) {
// If iter is at the end of string_tag, with exception of after " and '
else if(iter.ends_tag(string_tag)) {
auto previous_iter = iter;
if(!iter.starts_line() && previous_iter.backward_char()) {
if((*previous_iter == '"' || *previous_iter == '\'')) {
if(previous_iter.backward_char() && (*previous_iter == '"' || *previous_iter == '\'')) {
long backslash_count = 0;
auto it = previous_iter;
while(it.backward_char() && *it == '\\')
++backslash_count;
if(backslash_count % 2 == 0) {
auto it = previous_iter;
while(!it.begins_tag(string_tag) && it.backward_to_tag_toggle(string_tag)) {
}
if(it.begins_tag(string_tag) && *previous_iter == *it && previous_iter != it)
auto start_iter = iter;
if(start_iter.backward_to_tag_toggle(string_tag) && start_iter.begins_tag(string_tag) && *previous_iter == *start_iter)
return false;
}
}
return true;
}
}
}
return false;
}
@ -441,10 +437,30 @@ bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) {
if(!is_code_iter && (*iter == '\'' || *iter == '"')) {
if(comment_tag && iter.ends_tag(comment_tag)) // ' or " at end of comments are not code iters
return false;
if(*iter == '"') {
auto next_iter = iter;
next_iter.forward_char();
return !is_spellcheck_iter(next_iter);
}
// Have to look up ' manually since it can be a word iter:
auto previous_iter = iter;
if(previous_iter.backward_char() && *previous_iter == '\'') { // First, handle iter inside '':
auto next_iter = iter;
next_iter.forward_char();
return !is_spellcheck_iter(next_iter);
}
if(string_tag && (iter.has_tag(string_tag) || iter.ends_tag(string_tag))) {
long backslash_count = 0;
auto previous_iter = iter;
while(previous_iter.backward_char() && *previous_iter == '\\')
++backslash_count;
if(backslash_count % 2 == 0) {
auto start_iter = iter;
if(start_iter.backward_to_tag_toggle(string_tag) && start_iter.begins_tag(string_tag) && *start_iter == '\'')
return true;
}
}
}
if(is_bracket_language)
return is_code_iter;
@ -502,7 +518,9 @@ void Source::SpellCheckView::spellcheck_word(Gtk::TextIter start, Gtk::TextIter
}
auto word = get_buffer()->get_text(start, end);
if(word.size() > 0) {
if(word == "''")
get_buffer()->remove_tag(spellcheck_error_tag, start, end);
else if(word.size() > 0) {
auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
if(correct == 0)
get_buffer()->apply_tag(spellcheck_error_tag, start, end);

2
src/source_spellcheck.h

@ -28,9 +28,9 @@ namespace Source {
Glib::RefPtr<Gtk::TextTag> comment_tag;
Glib::RefPtr<Gtk::TextTag> string_tag;
Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
private:
Glib::RefPtr<Gtk::TextTag> no_spell_check_tag;
Glib::RefPtr<Gtk::TextTag> spellcheck_error_tag;
sigc::connection signal_tag_added_connection;

144
tests/source_key_test.cc

@ -18,6 +18,150 @@ int main() {
GdkEventKey event;
event.state = 0;
{
auto language = language_manager->get_language("js");
Source::View view(source_file, language);
view.get_source_buffer()->set_highlight_syntax(true);
view.set_tab_char_and_size(' ', 2);
auto buffer = view.get_buffer();
{
buffer->set_text(" ''\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(3);
assert(view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" \"\"\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(3);
assert(view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" 'test\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_to_line_end();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
}
{
buffer->set_text(" \"test'\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_to_line_end();
iter.backward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
}
{
buffer->set_text(" 'test'\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(2);
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_chars(4);
assert(view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" \"test\"\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(2);
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_chars(4);
assert(view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" '\\''\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(2);
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
iter.forward_char();
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" /**/\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(2);
assert(!view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(!view.is_spellcheck_iter(iter));
assert(view.is_code_iter(iter));
}
{
buffer->set_text(" //t\n");
while(Gtk::Main::events_pending())
Gtk::Main::iteration(false);
auto iter = buffer->get_iter_at_line(0);
iter.forward_chars(2);
assert(!view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
iter.forward_char();
assert(view.is_spellcheck_iter(iter));
assert(!view.is_code_iter(iter));
}
}
{
auto language = language_manager->get_language("cpp");
Source::View view(source_file, language);

Loading…
Cancel
Save