From 6029ee98159303e85008518d002c4fd168a5a5ca Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 11 Dec 2021 09:27:51 +1100 Subject: [PATCH] Fix explicit line completion trim_indent call was incorrect, trim_indent is intended to work on multi-line strings and trims trailing whitespace as well (could benefit from a better name). Fixes #4378 --- src/insert_completer.cc | 19 +++++++++++++------ .../4378-line-explicit-completion-buggy/cmd | 1 + .../4378-line-explicit-completion-buggy/in | 2 ++ .../4378-line-explicit-completion-buggy/out | 2 ++ 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 test/regression/4378-line-explicit-completion-buggy/cmd create mode 100644 test/regression/4378-line-explicit-completion-buggy/in create mode 100644 test/regression/4378-line-explicit-completion-buggy/out diff --git a/src/insert_completer.cc b/src/insert_completer.cc index d7733ccc..54792052 100644 --- a/src/insert_completer.cc +++ b/src/insert_completer.cc @@ -348,7 +348,14 @@ InsertCompletion complete_line(const SelectionList& sels, const ColumnCount tabstop = options["tabstop"].get(); const ColumnCount column = get_column(buffer, tabstop, cursor_pos); - String prefix = trim_indent(buffer[cursor_pos.line].substr(0_byte, cursor_pos.column)); + auto trim_leading_whitespaces = [](StringView s) { + utf8::iterator it{s.begin(), s}; + while (it != s.end() and is_horizontal_blank(*it)) + ++it; + return StringView{it.base(), s.end()}; + }; + + StringView prefix = trim_leading_whitespaces(buffer[cursor_pos.line].substr(0_byte, cursor_pos.column)); BufferCoord replace_begin = buffer.advance(cursor_pos, -prefix.length()); InsertCompletion::CandidateList candidates; @@ -358,15 +365,15 @@ InsertCompletion complete_line(const SelectionList& sels, if (buf.name() == buffer.name() && l == cursor_pos.line) continue; - String line = trim_indent(buf[l]); + StringView line = buf[l]; + StringView candidate = trim_leading_whitespaces(line.substr(0_byte, line.length()-1)); - if (line.length() == 0) + if (candidate.length() == 0) continue; - if (prefix == line.substr(0_byte, prefix.length())) + if (prefix == candidate.substr(0_byte, prefix.length())) { - String candidate = trim_indent(line.substr(0_byte, line.length())); - candidates.push_back({candidate, "", {expand_tabs(candidate, tabstop, column), {}} }); + candidates.push_back({candidate.str(), "", {expand_tabs(candidate, tabstop, column), {}} }); // perf: it's unlikely the user intends to search among >10 candidates anyway if (candidates.size() == 100) break; diff --git a/test/regression/4378-line-explicit-completion-buggy/cmd b/test/regression/4378-line-explicit-completion-buggy/cmd new file mode 100644 index 00000000..b1b9b0f1 --- /dev/null +++ b/test/regression/4378-line-explicit-completion-buggy/cmd @@ -0,0 +1 @@ +al diff --git a/test/regression/4378-line-explicit-completion-buggy/in b/test/regression/4378-line-explicit-completion-buggy/in new file mode 100644 index 00000000..d5a6416c --- /dev/null +++ b/test/regression/4378-line-explicit-completion-buggy/in @@ -0,0 +1,2 @@ +a b +a%( ) diff --git a/test/regression/4378-line-explicit-completion-buggy/out b/test/regression/4378-line-explicit-completion-buggy/out new file mode 100644 index 00000000..17397552 --- /dev/null +++ b/test/regression/4378-line-explicit-completion-buggy/out @@ -0,0 +1,2 @@ +a b +a b