Skip to content

Commit

Permalink
Support editing multi-line annotations (Closes: GothenburgBitFactory#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
jspricke committed Jan 5, 2021
1 parent 1cbcdf0 commit 7d5a9d9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
32 changes: 28 additions & 4 deletions src/commands/CmdEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
{
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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));
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/commands/CmdEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ class CmdEdit : public Command
std::string findValue (const std::string&, const std::string&);
std::string findMultilineValue (const std::string&, const std::string&, const std::string&);
std::vector <std::string> findValues (const std::string&, const std::string&);
std::string replaceString (std::string text, const std::string& search, const std::string& replacement);
std::string formatDate (Task&, const std::string&, const std::string&);
std::string formatDuration (Task&, const std::string&);
std::string formatTask (Task, const std::string&);
void parseTask (Task&, const std::string&, const std::string&);
enum class editResult { error, changes, nochanges };
editResult editFile (Task&);
static const std::string ANNOTATION_EDIT_MARKER;
};

#endif
Expand Down

0 comments on commit 7d5a9d9

Please sign in to comment.