mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Support editing multi-line annotations (Closes: #2283)
Since e4b9c1f
annotations where JSON encoded in task edit to escape
new lines (\n). But other strings where mangled as well, like https://
becoming https:\/\/, making it hard to edit.
This patch removes the JSON encoding and indents new lines instead.
This commit is contained in:
parent
1cbcdf0969
commit
a95205357c
2 changed files with 30 additions and 4 deletions
|
@ -51,6 +51,8 @@
|
|||
#define STRING_EDIT_UNTIL_MOD "Until date modified."
|
||||
#define STRING_EDIT_WAIT_MOD "Wait date modified."
|
||||
|
||||
const std::string CmdEdit::ANNOTATION_EDIT_MARKER = "\n ";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CmdEdit::CmdEdit ()
|
||||
{
|
||||
|
@ -170,6 +172,23 @@ std::vector <std::string> CmdEdit::findValues (
|
|||
return results;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string CmdEdit::replaceString (
|
||||
std::string text,
|
||||
const std::string& search,
|
||||
const std::string& replacement)
|
||||
{
|
||||
std::string::size_type found = 0;
|
||||
|
||||
while ((found = text.find (search, found)) != std::string::npos)
|
||||
{
|
||||
text.replace (found, search.length (), replacement);
|
||||
found += replacement.length ();
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string CmdEdit::formatDate (
|
||||
Task& task,
|
||||
|
@ -246,13 +265,14 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat)
|
|||
if (verbose)
|
||||
before << "# Annotations look like this: <date> -- <text> and there can be any number of them.\n"
|
||||
"# The ' -- ' separator between the date and text field should not be removed.\n"
|
||||
"# Multiline annotations need to be indented up to <date> (" << ANNOTATION_EDIT_MARKER.length () - 1 << " spaces).\n"
|
||||
"# A \"blank slot\" for adding an annotation follows for your convenience.\n";
|
||||
|
||||
for (auto& anno : task.getAnnotations ())
|
||||
{
|
||||
Datetime dt (strtol (anno.first.substr (11).c_str (), nullptr, 10));
|
||||
before << " Annotation: " << dt.toString (dateformat)
|
||||
<< " -- " << json::encode (anno.second) << '\n';
|
||||
<< " -- " << replaceString (anno.second, "\n", ANNOTATION_EDIT_MARKER) << '\n';
|
||||
}
|
||||
|
||||
Datetime now;
|
||||
|
@ -610,10 +630,14 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
|||
{
|
||||
found += 14; // Length of "\n Annotation:".
|
||||
|
||||
auto eol = after.find ('\n', found + 1);
|
||||
auto eol = found;
|
||||
while ((eol = after.find ('\n', ++eol)) != std::string::npos)
|
||||
if (after.substr (eol, ANNOTATION_EDIT_MARKER.length ()) != ANNOTATION_EDIT_MARKER)
|
||||
break;
|
||||
|
||||
if (eol != std::string::npos)
|
||||
{
|
||||
auto value = Lexer::trim (after.substr (found, eol - found), "\t ");
|
||||
auto value = Lexer::trim (replaceString (after.substr (found, eol - found), ANNOTATION_EDIT_MARKER, "\n"), "\t ");
|
||||
auto gap = value.find (" -- ");
|
||||
if (gap != std::string::npos)
|
||||
{
|
||||
|
@ -641,7 +665,7 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
|
|||
while (annotations.find (name.str ()) != annotations.end ());
|
||||
|
||||
auto text = Lexer::trim (value.substr (gap + 4), "\t ");
|
||||
annotations.insert (std::make_pair (name.str (), json::decode (text)));
|
||||
annotations.insert (std::make_pair (name.str (), text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue