Browse Source

Smart indentation/brackets/insertions cleanup and improvements

merge-requests/365/head
eidheim 9 years ago
parent
commit
f656b76afe
  1. 349
      src/source.cc
  2. 4
      src/source.h
  3. 44
      src/source_spellcheck.cc

349
src/source.cc

@ -1023,39 +1023,32 @@ long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char,
bool break_on_curly=true; bool break_on_curly=true;
if(positive_char=='{' || negative_char=='}') if(positive_char=='{' || negative_char=='}')
break_on_curly=false; break_on_curly=false;
bool check_if_previous_or_next_iter_is_code_iter=false; bool check_if_next_iter_is_code_iter=false;
if(positive_char=='\'' || negative_char=='\'' || positive_char=='"' || negative_char=='"') if(positive_char=='\'' || negative_char=='\'' || positive_char=='"' || negative_char=='"')
check_if_previous_or_next_iter_is_code_iter=true; check_if_next_iter_is_code_iter=true;
Gtk::TextIter previous_iter; Gtk::TextIter previous_iter;
do { do {
previous_iter=iter; if(*iter==positive_char && is_code_iter(iter))
previous_iter.backward_char(); symbol_count++;
if(!(*previous_iter=='\'' && is_code_iter(previous_iter))) { else if(*iter==negative_char && is_code_iter(iter))
if(*iter==positive_char && is_code_iter(iter)) symbol_count--;
symbol_count++; else if(*iter=='{' && is_code_iter(iter))
else if(*iter==negative_char && is_code_iter(iter)) curly_count++;
symbol_count--; else if(*iter=='}' && is_code_iter(iter))
else if(*iter=='{' && is_code_iter(iter)) curly_count--;
curly_count++; else if(check_if_next_iter_is_code_iter) {
else if(*iter=='}' && is_code_iter(iter)) auto next_iter=iter;
curly_count--; if(next_iter.forward_char()) {
else if(check_if_previous_or_next_iter_is_code_iter) { if(*iter==positive_char && is_code_iter(next_iter))
auto next_iter=iter;
next_iter.forward_char();
if(*iter==positive_char && is_code_iter(previous_iter))
symbol_count++;
else if(*iter==negative_char && is_code_iter(previous_iter))
symbol_count--;
else if(*iter==positive_char && is_code_iter(next_iter))
symbol_count++; symbol_count++;
else if(*iter==negative_char && is_code_iter(next_iter)) else if(*iter==negative_char && is_code_iter(next_iter))
symbol_count--; symbol_count--;
} }
if(break_on_curly && curly_count>0)
break;
} }
if(break_on_curly && curly_count>0)
break;
} while(iter.backward_char()); } while(iter.backward_char());
iter=iter_stored; iter=iter_stored;
@ -1073,17 +1066,14 @@ long Source::View::symbol_count(Gtk::TextIter iter, unsigned int positive_char,
curly_count++; curly_count++;
else if(*iter=='}' && is_code_iter(iter)) else if(*iter=='}' && is_code_iter(iter))
curly_count--; curly_count--;
else if(check_if_previous_or_next_iter_is_code_iter) { else if(check_if_next_iter_is_code_iter) {
auto next_iter=iter; auto next_iter=iter;
next_iter.forward_char(); if(next_iter.forward_char()) {
if(*iter==positive_char && is_code_iter(previous_iter)) if(*iter==positive_char && is_code_iter(next_iter))
symbol_count++; symbol_count++;
else if(*iter==negative_char && is_code_iter(previous_iter)) else if(*iter==negative_char && is_code_iter(next_iter))
symbol_count--; symbol_count--;
else if(*iter==positive_char && is_code_iter(next_iter)) }
symbol_count++;
else if(*iter==negative_char && is_code_iter(next_iter))
symbol_count--;
} }
if(break_on_curly && curly_count<0) if(break_on_curly && curly_count<0)
@ -1236,80 +1226,53 @@ bool Source::View::on_key_press_event(GdkEventKey* key) {
return true; return true;
} }
if(get_buffer()->get_has_selection()) get_buffer()->begin_user_action();
return on_key_press_event_basic(key);
auto iter=get_buffer()->get_insert()->get_iter();
if(is_bracket_language && Config::get().source.smart_insertions) { if(!spellcheck_all) {
auto previous_iter=iter; if(Config::get().source.smart_brackets && on_key_press_event_smart_brackets(key)) {
previous_iter.backward_char(); get_buffer()->end_user_action();
if(key->keyval==GDK_KEY_apostrophe && !is_code_iter(iter)) { return true;
if(*previous_iter!='\\' && *iter=='\'') {
auto next_iter=iter;
next_iter.forward_char();
get_buffer()->place_cursor(next_iter);
scroll_to(get_buffer()->get_insert());
return true;
}
}
else if(key->keyval==GDK_KEY_quotedbl && *iter=='\"' && !is_code_iter(iter)) {
bool perform_move=false;
if(*previous_iter!='\\')
perform_move=true;
else {
auto it=previous_iter;
long backslash_count=1;
while(it.backward_char() && *it=='\\') {
++backslash_count;
}
if(backslash_count%2==0)
perform_move=true;
}
if(perform_move) {
auto next_iter=iter;
next_iter.forward_char();
get_buffer()->place_cursor(next_iter);
scroll_to(get_buffer()->get_insert());
return true;
}
} }
else if(key->keyval==GDK_KEY_BackSpace || key->keyval==GDK_KEY_Delete) { if(Config::get().source.smart_insertions && on_key_press_event_smart_insertions(key)) {
auto previous_previous_iter=previous_iter; get_buffer()->end_user_action();
previous_previous_iter.backward_char(); return true;
if(*previous_iter=='\'' && *iter=='\'' && is_code_iter(previous_previous_iter)) {
auto next_iter=iter;
next_iter.forward_char();
get_buffer()->begin_user_action();
get_buffer()->erase(previous_iter, next_iter);
scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true;
}
else if(*previous_iter=='"' && *iter=='"' && !is_code_iter(iter) && is_code_iter(previous_previous_iter)) {
auto next_iter=iter;
next_iter.forward_char();
get_buffer()->begin_user_action();
get_buffer()->erase(previous_iter, next_iter);
scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true;
}
} }
} }
if(!is_code_iter(iter)) if(get_buffer()->get_has_selection()) {
return on_key_press_event_basic(key); auto return_value=on_key_press_event_basic(key);
get_buffer()->end_user_action();
if(return_value)
return true;
else
return Gsv::View::on_key_press_event(key);
}
if(is_bracket_language) if(!is_code_iter(get_buffer()->get_insert()->get_iter())) {
return on_key_press_event_bracket_language(key); auto return_value=on_key_press_event_basic(key);
else get_buffer()->end_user_action();
return on_key_press_event_basic(key); if(return_value)
return true;
else
return Gsv::View::on_key_press_event(key);
}
if(is_bracket_language && on_key_press_event_bracket_language(key)) {
get_buffer()->end_user_action();
return true;
}
else if(on_key_press_event_basic(key)) {
get_buffer()->end_user_action();
return true;
}
else {
get_buffer()->end_user_action();
return Gsv::View::on_key_press_event(key);
}
} }
//Basic indentation //Basic indentation
bool Source::View::on_key_press_event_basic(GdkEventKey* key) { bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
get_buffer()->begin_user_action();
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
//Indent as in next or previous line //Indent as in next or previous line
if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() && !iter.starts_line()) { if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !get_buffer()->get_has_selection() && !iter.starts_line()) {
@ -1330,28 +1293,50 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
} }
iter=get_buffer()->get_insert()->get_iter(); iter=get_buffer()->get_insert()->get_iter();
auto previous_iter=iter;
previous_iter.backward_char();
auto start_iter=previous_iter;
Gtk::TextIter open_non_curly_bracket_iter;
bool open_non_curly_bracket_iter_found=false;
if(find_open_non_curly_bracket_backward(start_iter, open_non_curly_bracket_iter)) {
open_non_curly_bracket_iter_found=true;
start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(open_non_curly_bracket_iter.get_line()));
}
else
start_iter=get_tabs_end_iter(get_buffer()->get_iter_at_line(find_start_of_sentence(start_iter).get_line()));
auto tabs=get_line_before(start_iter);
//Indent multiline expressions
if(open_non_curly_bracket_iter_found) {
auto tabs_end_iter=get_tabs_end_iter(open_non_curly_bracket_iter);
auto tabs=get_line_before(get_tabs_end_iter(open_non_curly_bracket_iter));
auto iter=tabs_end_iter;
while(iter<=open_non_curly_bracket_iter) {
tabs+=' ';
iter.forward_char();
}
get_buffer()->insert_at_cursor("\n"+tabs);
scroll_to(get_buffer()->get_insert());
return true;
}
int line_nr=iter.get_line(); int line_nr=iter.get_line();
auto tabs_end_iter=get_tabs_end_iter();
auto line_tabs=get_line_before(tabs_end_iter);
if((line_nr+1)<get_buffer()->get_line_count()) { if((line_nr+1)<get_buffer()->get_line_count()) {
auto next_line_tabs_end_iter=get_tabs_end_iter(line_nr+1); auto next_line_tabs_end_iter=get_tabs_end_iter(line_nr+1);
auto next_line_tabs=get_line_before(next_line_tabs_end_iter); auto next_line_tabs=get_line_before(next_line_tabs_end_iter);
if(iter.ends_line() && next_line_tabs.size()>line_tabs.size()) { if(iter.ends_line() && next_line_tabs.size()>tabs.size()) {
get_buffer()->insert_at_cursor("\n"+next_line_tabs); get_buffer()->insert_at_cursor("\n"+next_line_tabs);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
get_buffer()->insert_at_cursor("\n"+line_tabs); get_buffer()->insert_at_cursor("\n"+tabs);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
else if(key->keyval==GDK_KEY_Tab && (key->state&GDK_SHIFT_MASK)==0) { else if(key->keyval==GDK_KEY_Tab && (key->state&GDK_SHIFT_MASK)==0) {
if(!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) { if(!Config::get().source.tab_indents_line && !get_buffer()->get_has_selection()) {
get_buffer()->insert_at_cursor(tab); get_buffer()->insert_at_cursor(tab);
get_buffer()->end_user_action();
return true; return true;
} }
//Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text. //Indent right when clicking tab, no matter where in the line the cursor is. Also works on selected text.
@ -1374,7 +1359,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
tabs=next_line_tabs; tabs=next_line_tabs;
if(tabs.size()>=tab_size) { if(tabs.size()>=tab_size) {
get_buffer()->insert_at_cursor(tabs); get_buffer()->insert_at_cursor(tabs);
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1388,7 +1372,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
if(!get_buffer()->get_has_selection() || line_it!=selection_end) if(!get_buffer()->get_has_selection() || line_it!=selection_end)
get_buffer()->insert(line_it, tab); get_buffer()->insert(line_it, tab);
} }
get_buffer()->end_user_action();
return true; return true;
} }
//Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text. //Indent left when clicking shift-tab, no matter where in the line the cursor is. Also works on selected text.
@ -1413,10 +1396,8 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
indent_left_steps=std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size())); indent_left_steps=std::min(indent_left_steps, static_cast<unsigned>(line_tabs.size()));
ignore_line.push_back(false); ignore_line.push_back(false);
} }
else { else
get_buffer()->end_user_action();
return true; return true;
}
} }
} }
} }
@ -1430,7 +1411,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
get_buffer()->erase(line_it, line_plus_it); get_buffer()->erase(line_it, line_plus_it);
} }
} }
get_buffer()->end_user_action();
return true; return true;
} }
//"Smart" backspace key //"Smart" backspace key
@ -1494,7 +1474,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
get_buffer()->place_cursor(end_line_iter); get_buffer()->place_cursor(end_line_iter);
} }
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
else if(key->keyval==GDK_KEY_Home && (key->state&GDK_CONTROL_MASK)==0) { else if(key->keyval==GDK_KEY_Home && (key->state&GDK_CONTROL_MASK)==0) {
@ -1517,7 +1496,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
get_buffer()->place_cursor(start_line_iter); get_buffer()->place_cursor(start_line_iter);
} }
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
@ -1534,7 +1512,6 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
get_buffer()->erase(selection_start, selection_end); get_buffer()->erase(selection_start, selection_end);
} }
get_buffer()->insert_at_cursor(Glib::ustring(1, unicode)); get_buffer()->insert_at_cursor(Glib::ustring(1, unicode));
get_buffer()->end_user_action();
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
//Trick to make the cursor visible right after insertion: //Trick to make the cursor visible right after insertion:
@ -1544,14 +1521,11 @@ bool Source::View::on_key_press_event_basic(GdkEventKey* key) {
return true; return true;
} }
auto stop=Gsv::View::on_key_press_event(key); return false;
get_buffer()->end_user_action();
return stop;
} }
//Bracket language indentation //Bracket language indentation
bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) { bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
get_buffer()->begin_user_action();
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
//Indent depending on if/else/etc and brackets //Indent depending on if/else/etc and brackets
if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !iter.starts_line()) { if((key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_KP_Enter) && !iter.starts_line()) {
@ -1603,7 +1577,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->place_cursor(insert_it); get_buffer()->place_cursor(insert_it);
} }
get_buffer()->end_user_action();
return true; return true;
} }
else if(!has_right_curly_bracket) { else if(!has_right_curly_bracket) {
@ -1627,13 +1600,11 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->place_cursor(insert_it); get_buffer()->place_cursor(insert_it);
} }
get_buffer()->end_user_action();
return true; return true;
} }
else { else {
get_buffer()->insert_at_cursor("\n"+tabs+tab); get_buffer()->insert_at_cursor("\n"+tabs+tab);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1649,7 +1620,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
} }
get_buffer()->insert_at_cursor("\n"+tabs); get_buffer()->insert_at_cursor("\n"+tabs);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
auto line=get_line_before(); auto line=get_line_before();
@ -1657,13 +1627,11 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
if(std::regex_match(line, sm, no_bracket_statement_regex)) { if(std::regex_match(line, sm, no_bracket_statement_regex)) {
get_buffer()->insert_at_cursor("\n"+tabs+tab); get_buffer()->insert_at_cursor("\n"+tabs+tab);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
else if(std::regex_match(line, sm, no_bracket_no_para_statement_regex)) { else if(std::regex_match(line, sm, no_bracket_no_para_statement_regex)) {
get_buffer()->insert_at_cursor("\n"+tabs+tab); get_buffer()->insert_at_cursor("\n"+tabs+tab);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
//Indenting after for instance if(...)\n...;\n //Indenting after for instance if(...)\n...;\n
@ -1676,13 +1644,11 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
if(std::regex_match(previous_line, sm2, no_bracket_statement_regex)) { if(std::regex_match(previous_line, sm2, no_bracket_statement_regex)) {
get_buffer()->insert_at_cursor("\n"+sm2[1].str()); get_buffer()->insert_at_cursor("\n"+sm2[1].str());
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
else if(std::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) { else if(std::regex_match(previous_line, sm2, no_bracket_no_para_statement_regex)) {
get_buffer()->insert_at_cursor("\n"+sm2[1].str()); get_buffer()->insert_at_cursor("\n"+sm2[1].str());
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1714,7 +1680,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
else { else {
get_buffer()->insert_at_cursor("\n"+tabs+tab); get_buffer()->insert_at_cursor("\n"+tabs+tab);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1722,7 +1687,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
} }
get_buffer()->insert_at_cursor("\n"+tabs); get_buffer()->insert_at_cursor("\n"+tabs);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
//Indent left when writing } on a new line //Indent left when writing } on a new line
@ -1743,7 +1707,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
line_plus_it.forward_chars(tab_size); line_plus_it.forward_chars(tab_size);
get_buffer()->erase(line_it, line_plus_it); get_buffer()->erase(line_it, line_plus_it);
get_buffer()->insert_at_cursor("}"); get_buffer()->insert_at_cursor("}");
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1766,7 +1729,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
get_buffer()->erase(start_iter, iter); get_buffer()->erase(start_iter, iter);
get_buffer()->insert_at_cursor("{"); get_buffer()->insert_at_cursor("{");
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1774,14 +1736,23 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
} }
} }
if(Config::get().source.smart_brackets) { return false;
}
bool Source::View::on_key_press_event_smart_brackets(GdkEventKey *key) {
if(get_buffer()->get_has_selection())
return false;
auto iter=get_buffer()->get_insert()->get_iter();
auto previous_iter=iter;
previous_iter.backward_char();
if(is_code_iter(iter)) {
//Move after ')' if closed expression //Move after ')' if closed expression
if(key->keyval==GDK_KEY_parenright) { if(key->keyval==GDK_KEY_parenright) {
if(*iter==')' && symbol_count(iter, '(', ')')==0) { if(*iter==')' && symbol_count(iter, '(', ')')==0) {
iter.forward_char(); iter.forward_char();
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1793,7 +1764,6 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
if(*iter=='(' && is_templated_function(iter, parenthesis_end_iter)) { if(*iter=='(' && is_templated_function(iter, parenthesis_end_iter)) {
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
@ -1808,47 +1778,95 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
iter.forward_char(); iter.forward_char();
get_buffer()->select_range(iter, parenthesis_end_iter); get_buffer()->select_range(iter, parenthesis_end_iter);
scroll_to(iter); scroll_to(iter);
get_buffer()->end_user_action();
return true; return true;
} }
} }
} }
} }
return false;
}
bool Source::View::on_key_press_event_smart_insertions(GdkEventKey *key) {
if(get_buffer()->get_has_selection())
return false;
auto iter=get_buffer()->get_insert()->get_iter();
auto previous_iter=iter; auto previous_iter=iter;
previous_iter.backward_char(); previous_iter.backward_char();
if(Config::get().source.smart_insertions && *previous_iter!='\'' && *iter!='\'') { auto next_iter=iter;
next_iter.forward_char();
// Move right when clicking ' before a ' or when clicking " before a "
if(((key->keyval==GDK_KEY_apostrophe && *iter=='\'') ||
(key->keyval==GDK_KEY_quotedbl && *iter=='\"')) && is_code_iter(next_iter)) {
bool perform_move=false;
if(*previous_iter!='\\')
perform_move=true;
else {
auto it=previous_iter;
long backslash_count=1;
while(it.backward_char() && *it=='\\') {
++backslash_count;
}
if(backslash_count%2==0)
perform_move=true;
}
if(perform_move) {
get_buffer()->place_cursor(next_iter);
scroll_to(get_buffer()->get_insert());
return true;
}
}
// When to delete '' or ""
else if(key->keyval==GDK_KEY_BackSpace) {
if(((*previous_iter=='\'' && *iter=='\'') ||
(*previous_iter=='"' && *iter=='"')) && is_code_iter(previous_iter)) {
get_buffer()->erase(previous_iter, next_iter);
scroll_to(get_buffer()->get_insert());
return true;
}
}
if(is_code_iter(iter)) {
// Insert ()
if(key->keyval==GDK_KEY_parenleft) { if(key->keyval==GDK_KEY_parenleft) {
if(symbol_count(iter, '(', ')')==0) { //Allowed symbols
get_buffer()->insert_at_cursor("()"); if(iter.ends_line() || *iter==' ' || *iter=='\t' || *iter==';' || *iter==')' || *iter==']' || *iter=='[' || *iter=='{' || *iter=='}') {
auto iter=get_buffer()->get_insert()->get_iter(); if(symbol_count(iter, '(', ')')==0) {
iter.backward_char(); get_buffer()->insert_at_cursor("()");
get_buffer()->place_cursor(iter); auto iter=get_buffer()->get_insert()->get_iter();
scroll_to(get_buffer()->get_insert()); iter.backward_char();
get_buffer()->end_user_action(); get_buffer()->place_cursor(iter);
return true; scroll_to(get_buffer()->get_insert());
return true;
}
} }
} }
// Insert []
else if(key->keyval==GDK_KEY_bracketleft) { else if(key->keyval==GDK_KEY_bracketleft) {
if(symbol_count(iter, '[', ']')==0) { //Allowed symbols
get_buffer()->insert_at_cursor("[]"); if(iter.ends_line() || *iter==' ' || *iter=='\t' || *iter==';' || *iter==')' || *iter==']' || *iter=='[' || *iter=='{' || *iter=='}') {
auto iter=get_buffer()->get_insert()->get_iter(); if(symbol_count(iter, '[', ']')==0) {
iter.backward_char(); get_buffer()->insert_at_cursor("[]");
get_buffer()->place_cursor(iter); auto iter=get_buffer()->get_insert()->get_iter();
scroll_to(get_buffer()->get_insert()); iter.backward_char();
get_buffer()->end_user_action(); get_buffer()->place_cursor(iter);
return true; scroll_to(get_buffer()->get_insert());
return true;
}
} }
} }
// Move left on ] in []
else if(key->keyval==GDK_KEY_bracketright) { else if(key->keyval==GDK_KEY_bracketright) {
if(*iter==']' && symbol_count(iter, '[', ']')==0) { if(*iter==']' && symbol_count(iter, '[', ']')==0) {
iter.forward_char(); iter.forward_char();
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
// Insert {}
// else if(key->keyval==GDK_KEY_braceleft) { // else if(key->keyval==GDK_KEY_braceleft) {
// if(symbol_count(iter, '{', '}')==0) { // if(symbol_count(iter, '{', '}')==0) {
// get_buffer()->insert_at_cursor("{}"); // get_buffer()->insert_at_cursor("{}");
@ -1856,44 +1874,41 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
// iter.backward_char(); // iter.backward_char();
// get_buffer()->place_cursor(iter); // get_buffer()->place_cursor(iter);
// scroll_to(get_buffer()->get_insert()); // scroll_to(get_buffer()->get_insert());
// get_buffer()->end_user_action();
// return true; // return true;
// } // }
// } // }
// Move on } in {}
// else if(key->keyval==GDK_KEY_braceright) { // else if(key->keyval==GDK_KEY_braceright) {
// if(*iter=='}') { // if(*iter=='}') {
// if(symbol_count(iter, '{', '}')==0) { // if(symbol_count(iter, '{', '}')==0) {
// iter.forward_char(); // iter.forward_char();
// get_buffer()->place_cursor(iter); // get_buffer()->place_cursor(iter);
// scroll_to(get_buffer()->get_insert()); // scroll_to(get_buffer()->get_insert());
// get_buffer()->end_user_action();
// return true; // return true;
// } // }
// } // }
// } // }
// Insert ''
if(key->keyval==GDK_KEY_apostrophe && symbol_count(iter, '\'', '\0')%2==0) { else if(key->keyval==GDK_KEY_apostrophe && symbol_count(iter, '\'', -1)%2==0) {
get_buffer()->insert_at_cursor("''"); get_buffer()->insert_at_cursor("''");
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
iter.backward_char(); iter.backward_char();
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
else if(key->keyval==GDK_KEY_quotedbl && symbol_count(iter, '"', '\0')%2==0) { // Insert ""
else if(key->keyval==GDK_KEY_quotedbl && symbol_count(iter, '"', -1)%2==0) {
get_buffer()->insert_at_cursor("\"\""); get_buffer()->insert_at_cursor("\"\"");
auto iter=get_buffer()->get_insert()->get_iter(); auto iter=get_buffer()->get_insert()->get_iter();
iter.backward_char(); iter.backward_char();
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
// Insert ; at the end of line, if iter is at the last )
else if(key->keyval==GDK_KEY_semicolon) { else if(key->keyval==GDK_KEY_semicolon) {
if(*iter==')' && symbol_count(iter, '(', ')')==0) { if(*iter==')' && symbol_count(iter, '(', ')')==0) {
auto next_iter=iter;
next_iter.forward_char();
if(next_iter.ends_line()) { if(next_iter.ends_line()) {
Gtk::TextIter open_non_curly_bracket_iter; Gtk::TextIter open_non_curly_bracket_iter;
if(find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) { if(find_open_non_curly_bracket_backward(previous_iter, open_non_curly_bracket_iter)) {
@ -1905,43 +1920,41 @@ bool Source::View::on_key_press_event_bracket_language(GdkEventKey* key) {
get_buffer()->place_cursor(iter); get_buffer()->place_cursor(iter);
get_buffer()->insert_at_cursor(";"); get_buffer()->insert_at_cursor(";");
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
} }
} }
} }
} }
else if(key->keyval==GDK_KEY_BackSpace || key->keyval==GDK_KEY_Delete) { // Delete ()
else if(key->keyval==GDK_KEY_BackSpace) {
if(*previous_iter=='(' && *iter==')' && symbol_count(iter, '(', ')')==0) { if(*previous_iter=='(' && *iter==')' && symbol_count(iter, '(', ')')==0) {
auto next_iter=iter; auto next_iter=iter;
next_iter.forward_char(); next_iter.forward_char();
get_buffer()->erase(previous_iter, next_iter); get_buffer()->erase(previous_iter, next_iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
// Delete []
else if(*previous_iter=='[' && *iter==']' && symbol_count(iter, '[', ']')==0) { else if(*previous_iter=='[' && *iter==']' && symbol_count(iter, '[', ']')==0) {
auto next_iter=iter; auto next_iter=iter;
next_iter.forward_char(); next_iter.forward_char();
get_buffer()->erase(previous_iter, next_iter); get_buffer()->erase(previous_iter, next_iter);
scroll_to(get_buffer()->get_insert()); scroll_to(get_buffer()->get_insert());
get_buffer()->end_user_action();
return true; return true;
} }
// Delete {}
// else if(*previous_iter=='{' && *iter=='}' && symbol_count(iter, '{', '}')==0) { // else if(*previous_iter=='{' && *iter=='}' && symbol_count(iter, '{', '}')==0) {
// auto next_iter=iter; // auto next_iter=iter;
// next_iter.forward_char(); // next_iter.forward_char();
// get_buffer()->erase(previous_iter, next_iter); // get_buffer()->erase(previous_iter, next_iter);
// scroll_to(get_buffer()->get_insert()); // scroll_to(get_buffer()->get_insert());
// get_buffer()->end_user_action();
// return true; // return true;
// } // }
} }
} }
get_buffer()->end_user_action(); return false;
return on_key_press_event_basic(key);
} }
bool Source::View::on_button_press_event(GdkEventButton *event) { bool Source::View::on_button_press_event(GdkEventButton *event) {

4
src/source.h

@ -135,10 +135,12 @@ namespace Source {
const static std::regex no_bracket_statement_regex; const static std::regex no_bracket_statement_regex;
const static std::regex no_bracket_no_para_statement_regex; const static std::regex no_bracket_no_para_statement_regex;
bool is_bracket_language=false;
bool on_key_press_event(GdkEventKey* key) override; bool on_key_press_event(GdkEventKey* key) override;
bool on_key_press_event_basic(GdkEventKey* key); bool on_key_press_event_basic(GdkEventKey* key);
bool on_key_press_event_bracket_language(GdkEventKey* key); bool on_key_press_event_bracket_language(GdkEventKey* key);
bool is_bracket_language=false; bool on_key_press_event_smart_brackets(GdkEventKey* key);
bool on_key_press_event_smart_insertions(GdkEventKey* key);
bool on_button_press_event(GdkEventButton *event) override; bool on_button_press_event(GdkEventButton *event) override;
bool on_focus_in_event(GdkEventFocus* focus_event) override; bool on_focus_in_event(GdkEventFocus* focus_event) override;

44
src/source_spellcheck.cc

@ -192,7 +192,7 @@ Source::SpellCheckView::~SpellCheckView() {
delayed_spellcheck_error_clear.disconnect(); delayed_spellcheck_error_clear.disconnect();
if(spellcheck_checker!=nullptr) if(spellcheck_checker!=nullptr)
delete_aspell_speller(spellcheck_checker);//asd delete_aspell_speller(spellcheck_checker);
} }
void Source::SpellCheckView::configure() { void Source::SpellCheckView::configure() {
@ -301,7 +301,47 @@ void Source::SpellCheckView::goto_next_spellcheck_error() {
} }
bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) { bool Source::SpellCheckView::is_code_iter(const Gtk::TextIter &iter) {
return !get_source_buffer()->iter_has_context_class(iter, "comment") && !get_source_buffer()->iter_has_context_class(iter, "string"); auto is_comment=[this](const Gtk::TextIter &iter) {
return get_source_buffer()->iter_has_context_class(iter, "comment");
};
auto is_string=[this](const Gtk::TextIter &iter) {
return get_source_buffer()->iter_has_context_class(iter, "string");
};
if(*iter=='\'') {
auto previous_iter=iter;
if(!iter.starts_line() && previous_iter.backward_char() && *previous_iter=='\'')
return false;
}
if(is_comment(iter))
return false;
if(is_string(iter)) {
//Add exception for in front of " and '
if(*iter=='\'' || *iter=='"') {
auto previous_iter=iter;
if(previous_iter.backward_char()) {
if(!is_string(previous_iter))
return true;
}
else
return true;
}
return false;
}
//Iters after '...' and "..." should be code iters at the end of line
if(iter.ends_line() && !iter.starts_line()) {
auto previous_iter=iter;
if(previous_iter.backward_char()) {
if(is_comment(previous_iter))
return false;
if(is_string(previous_iter) && *previous_iter!='\'' && *previous_iter!='"') {
auto next_iter=iter;
if(next_iter.forward_char() && !is_string(next_iter))
return false;
}
}
}
return true;
} }
bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter& iter) { bool Source::SpellCheckView::is_word_iter(const Gtk::TextIter& iter) {

Loading…
Cancel
Save