Browse Source

Improved extend selection for non-bracket languages like Python and Julia

merge-requests/404/merge
eidheim 5 years ago
parent
commit
9a67a7557e
  1. 167
      src/source.cpp

167
src/source.cpp

@ -1548,7 +1548,7 @@ void Source::View::extend_selection() {
// Attempt to select a sentence, for instance: int a = 2; // Attempt to select a sentence, for instance: int a = 2;
if(!is_bracket_language) { // If for instance cmake, meson or python if(!is_bracket_language) { // If for instance cmake, meson or python
if(!select_matching_brackets) { if(!select_matching_brackets) {
bool select_end_block = is_language({"cmake", "meson"}); bool select_end_block = is_language({"cmake", "meson", "julia"});
auto get_tabs = [this](Gtk::TextIter iter) -> boost::optional<int> { auto get_tabs = [this](Gtk::TextIter iter) -> boost::optional<int> {
iter = get_buffer()->get_iter_at_line(iter.get_line()); iter = get_buffer()->get_iter_at_line(iter.get_line());
@ -1563,94 +1563,134 @@ void Source::View::extend_selection() {
return tabs; return tabs;
}; };
// Forward start to non-empty line
start = start_stored; start = start_stored;
end = end_stored;
if(start == get_buffer()->begin() && end == get_buffer()->end()) {
get_buffer()->select_range(start, end);
return;
}
// Select following line with code (for instance when inside comment)
// Forward start to non-empty line
forward_to_code(start); forward_to_code(start);
start = get_buffer()->get_iter_at_line(start.get_line()); start = get_buffer()->get_iter_at_line(start.get_line());
while(!start.is_end() && (*start == ' ' || *start == '\t') && start.forward_char()) { while(!start.is_end() && (*start == ' ' || *start == '\t') && start.forward_char()) {
} }
// Forward end of line
// Forward end to end of line
end = end_stored;
if(start > end) if(start > end)
end = start; end = start;
if(!end.ends_line()) end = get_iter_at_line_end(end.get_line());
end.forward_to_line_end(); while(end.backward_char() && (*end == ' ' || *end == '\t' || end.ends_line())) {
}
end.forward_char();
if(end == end_stored) // Cancel line selection if the line is already selected
start = start_stored;
// Try select block that starts at cursor if(start != start_stored || end != end_stored) {
auto iter = end; get_buffer()->select_range(start, end);
if(auto end_tabs = get_tabs(end)) { return;
bool can_select_end_block = false; }
while(iter.forward_char()) {
auto tabs = get_tabs(iter); // Select current line
if(!tabs || tabs > end_tabs || (select_end_block && can_select_end_block && tabs == end_tabs)) { // Backward to line start
if(!iter.ends_line()) start = get_buffer()->get_iter_at_line(start.get_line());
iter.forward_to_line_end(); auto start_tabs = get_tabs(start);
end = iter; while((*start == ' ' || *start == '\t' || start.ends_line()) && start.forward_char()) {
if(tabs > end_tabs) }
can_select_end_block = true; // Forward to line end
else if(tabs == end_tabs) end = get_iter_at_line_end(end.get_line());
bool include_children = false;
if(start_tabs) {
while(end.forward_char()) {
auto tabs = get_tabs(end);
if(tabs) {
if(tabs > start_tabs)
include_children = true;
else if(tabs == start_tabs) {
if(include_children && select_end_block)
end = get_iter_at_line_end(end.get_line());
break; break;
continue;
} }
else
break; break;
} }
end = get_iter_at_line_end(end.get_line());
} }
while(end > end_stored && end.starts_line() && end.ends_line() && end.backward_char()) {
} }
// Backward end to non-empty line
while(end.backward_char() && (*end == ' ' || *end == '\t' || end.ends_line())) {
}
end.forward_char();
if(start == start_stored && end == end_stored) { // Try select block that cursor is within if(start != start_stored || end != end_stored) {
// Backward start to line with less indentation get_buffer()->select_range(start, end);
auto iter = get_buffer()->get_iter_at_line(start.get_line()); return;
auto start_tabs = get_tabs(iter); }
if(start_tabs >= 0) {
while(iter.backward_char()) { // Select block that cursor is within
auto tabs = get_tabs(iter); // Backward start block start
iter = get_buffer()->get_iter_at_line(iter.get_line()); if(start_tabs > 0) {
if(tabs >= 0 && tabs < start_tabs) { start = get_buffer()->get_iter_at_line(start.get_line());
start = iter; while(start.backward_char()) {
auto tabs = get_tabs(start);
if(tabs && tabs < start_tabs)
break; break;
start = get_buffer()->get_iter_at_line(start.get_line());
} }
while((*start == ' ' || *start == '\t' || start.ends_line()) && start.forward_char()) {
} }
// Forward to block end
end = get_iter_at_line_end(end.get_line());
while(end.forward_char()) {
auto tabs = get_tabs(end);
if(tabs && tabs < start_tabs)
break;
end = get_iter_at_line_end(end.get_line());
} }
// Forward start to non-empty line // Backward end to non-empty line
start = get_buffer()->get_iter_at_line(start.get_line()); while(end.backward_char() && (*end == ' ' || *end == '\t' || end.ends_line())) {
while(!start.is_end() && (*start == ' ' || *start == '\t') && start.forward_char()) {
} }
end.forward_char();
if(start != start_stored) { if(start != start_stored || end != end_stored) {
// Forward end through lines with higher indentation get_buffer()->select_range(start, end);
start_tabs = get_tabs(start); return;
iter = end;
if(start_tabs >= 0) {
while(iter.forward_char()) {
auto tabs = get_tabs(iter);
if(tabs < 0 || tabs > start_tabs || (select_end_block && tabs == start_tabs)) {
if(!iter.ends_line())
iter.forward_to_line_end();
end = iter;
if(tabs == start_tabs)
break;
continue;
} }
break;
// Select expression surrounding block
// Backward to expression starting block
if(start.backward_char()) {
backward_to_code(start);
if(start_tabs > get_tabs(start)) {
start = get_buffer()->get_iter_at_line(start.get_line());
while((*start == ' ' || *start == '\t' || start.ends_line()) && start.forward_char()) {
} }
} }
while(end > end_stored && end.starts_line() && end.ends_line() && end.backward_char()) { else
start = start_stored;
} }
// Forward to expression ending block
if(select_end_block) {
forward_to_code(end);
if(start_tabs > get_tabs(end)) {
end = get_iter_at_line_end(end.get_line());
while(end.backward_char() && (*end == ' ' || *end == '\t' || end.ends_line())) {
}
end.forward_char();
}
else
end = end_stored;
} }
if(start == start_stored && end == end_stored) { if(start != start_stored || end != end_stored) {
start = get_buffer()->begin(); get_buffer()->select_range(start, end);
end = get_buffer()->end(); return;
} }
} }
// Select no_spellcheck_tag block if markdown // Select no_spellcheck_tag block if markdown
if(no_spellcheck_tag && language_id == "markdown" && start_stored.has_tag(no_spellcheck_tag) && end_stored.has_tag(no_spellcheck_tag) && if(language_id == "markdown" && no_spellcheck_tag && start.has_tag(no_spellcheck_tag) && end.has_tag(no_spellcheck_tag)) {
(!start.has_tag(no_spellcheck_tag) || !end.has_tag(no_spellcheck_tag))) {
start = start_stored;
end = end_stored;
if(!start.starts_tag(no_spellcheck_tag)) if(!start.starts_tag(no_spellcheck_tag))
start.backward_to_tag_toggle(no_spellcheck_tag); start.backward_to_tag_toggle(no_spellcheck_tag);
if(!end.ends_tag(no_spellcheck_tag)) if(!end.ends_tag(no_spellcheck_tag))
@ -1667,13 +1707,13 @@ void Source::View::extend_selection() {
if(!end.ends_line()) if(!end.ends_line())
end.forward_char(); end.forward_char();
if(start == start_stored && end == end_stored) { if(start != start_stored || end != end_stored) {
start = get_buffer()->begin(); get_buffer()->select_range(start, end);
end = get_buffer()->end(); return;
} }
} }
get_buffer()->select_range(start, end); get_buffer()->select_range(get_buffer()->begin(), get_buffer()->end());
return; return;
} }
} }
@ -1709,9 +1749,8 @@ void Source::View::extend_selection() {
if(start == start_stored && end == end_stored) { // In case of no change due to inbalanced brackets if(start == start_stored && end == end_stored) { // In case of no change due to inbalanced brackets
previous_extended_selections.pop_back(); previous_extended_selections.pop_back();
if(!start.backward_char() && !end.forward_char()) { if(!start.backward_char() && !end.forward_char())
return; return;
}
get_buffer()->select_range(start, end); get_buffer()->select_range(start, end);
extend_selection(); extend_selection();
return; return;

Loading…
Cancel
Save