Accept docstrings with last line not fully indented

When trimming indent, the last line, if only containing
whitespaces does not need to match the indent, so that
this indentation style works:

    -docstring %{
        indented string
    }
This commit is contained in:
Maxime Coste 2019-09-17 21:48:00 +10:00
parent c787128a7c
commit 8cca77c949
2 changed files with 21 additions and 25 deletions

View File

@ -26,10 +26,11 @@ define-command -params ..1 \
fi fi
cat "$namecache" cat "$namecache"
done} \ done} \
-docstring %{ctags-search [<symbol>]: jump to a symbol's definition -docstring %{
If no symbol is passed then the current selection is used as symbol name} \ ctags-search [<symbol>]: jump to a symbol's definition
ctags-search \ If no symbol is passed then the current selection is used as symbol name
%[ evaluate-commands %sh[ } \
ctags-search %[ evaluate-commands %sh[
realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) } realpath() { ( cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) }
export tagname="${1:-${kak_selection}}" export tagname="${1:-${kak_selection}}"
eval "set -- $kak_quoted_opt_ctagsfiles" eval "set -- $kak_quoted_opt_ctagsfiles"

View File

@ -23,31 +23,25 @@ String trim_indent(StringView str)
{ {
if (str.empty()) if (str.empty())
return {}; return {};
else if (str[0_byte] != '\n')
return trim_whitespaces(str).str();
if (str[0_byte] == '\n')
str = str.substr(1_byte); str = str.substr(1_byte);
const CharCount docstring_length = str.char_length(); while (not str.empty() and is_blank(str.back()))
str = str.substr(0, str.length() - 1);
CharCount level_indent = 0; utf8::iterator it{str.begin(), str};
while (level_indent < docstring_length while (it != str.end() and is_horizontal_blank(*it))
and is_horizontal_blank(str[level_indent])) it++;
level_indent++;
if (level_indent >= docstring_length or not level_indent) const StringView indent{str.begin(), it.base()};
return trim_whitespaces(str).str(); return accumulate(str | split_after<StringView>('\n') | transform([&](auto&& line) {
if (line == "\n")
const auto str_indent = str.substr(0, level_indent);
auto s = str | split<StringView>('\n') | transform([&](auto&& line) {
if (line.empty())
return line; return line;
else if (not prefix_match(line, str_indent)) else if (not prefix_match(line, indent))
throw runtime_error("inconsistent indentation in the string"); throw runtime_error("inconsistent indentation in the string");
return line.substr(str_indent.char_length()); return line.substr(indent.length());
}); }), String{}, [](String& s, StringView l) -> decltype(auto) { return s += l; });
return trim_whitespaces(join(s, '\n', false)).str();
} }
String escape(StringView str, StringView characters, char escape) 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("\nno-indent") == "no-indent");
kak_assert(trim_indent("\n indent\n indent") == "indent\nindent"); 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") == "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")); kak_expect_throw(runtime_error, trim_indent("\n indent\nno-indent"));