diff --git a/rc/tools/ctags.kak b/rc/tools/ctags.kak index 4f9103ae4..143e90c32 100644 --- a/rc/tools/ctags.kak +++ b/rc/tools/ctags.kak @@ -26,10 +26,11 @@ define-command -params ..1 \ fi cat "$namecache" done} \ - -docstring %{ctags-search []: jump to a symbol's definition -If no symbol is passed then the current selection is used as symbol name} \ - ctags-search \ - %[ evaluate-commands %sh[ + -docstring %{ + ctags-search []: jump to a symbol's definition + If no symbol is passed then the current selection is used as symbol name + } \ + ctags-search %[ evaluate-commands %sh[ realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } export tagname="${1:-${kak_selection}}" eval "set -- $kak_quoted_opt_ctagsfiles" diff --git a/src/string_utils.cc b/src/string_utils.cc index 348526e9a..a87d4cc3e 100644 --- a/src/string_utils.cc +++ b/src/string_utils.cc @@ -23,31 +23,25 @@ String trim_indent(StringView str) { if (str.empty()) return {}; - else if (str[0_byte] != '\n') - return trim_whitespaces(str).str(); - str = str.substr(1_byte); - const CharCount docstring_length = str.char_length(); + if (str[0_byte] == '\n') + str = str.substr(1_byte); + while (not str.empty() and is_blank(str.back())) + str = str.substr(0, str.length() - 1); - CharCount level_indent = 0; - while (level_indent < docstring_length - and is_horizontal_blank(str[level_indent])) - level_indent++; + utf8::iterator it{str.begin(), str}; + while (it != str.end() and is_horizontal_blank(*it)) + it++; - if (level_indent >= docstring_length or not level_indent) - return trim_whitespaces(str).str(); + const StringView indent{str.begin(), it.base()}; + return accumulate(str | split_after('\n') | transform([&](auto&& line) { + if (line == "\n") + return line; + else if (not prefix_match(line, indent)) + throw runtime_error("inconsistent indentation in the string"); - const auto str_indent = str.substr(0, level_indent); - auto s = str | split('\n') | transform([&](auto&& line) { - if (line.empty()) - return line; - else if (not prefix_match(line, str_indent)) - throw runtime_error("inconsistent indentation in the string"); - - return line.substr(str_indent.char_length()); - }); - - return trim_whitespaces(join(s, '\n', false)).str(); + return line.substr(indent.length()); + }), String{}, [](String& s, StringView l) -> decltype(auto) { return s += l; }); } String escape(StringView str, StringView characters, char escape) @@ -414,6 +408,7 @@ UnitTest test_string{[]() kak_assert(trim_indent("\nno-indent") == "no-indent"); kak_assert(trim_indent("\n indent\n indent") == "indent\nindent"); kak_assert(trim_indent("\n indent\n indent") == "indent\n indent"); + kak_assert(trim_indent("\n indent\n indent\n ") == "indent\nindent"); kak_expect_throw(runtime_error, trim_indent("\n indent\nno-indent"));