-
-
Notifications
You must be signed in to change notification settings - Fork 372
info: indent wrapped annotation lines (fixes #3914) #3963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -44,8 +44,50 @@ | |||||
|
||||||
#include <algorithm> | ||||||
#include <sstream> | ||||||
#include <string> | ||||||
|
||||||
//////////////////////////////////////////////////////////////////////////////// | ||||||
|
||||||
static std::string wrapWithPrefixes(const std::string& text, size_t width, | ||||||
const std::string& prefixFirst, const std::string& prefixCont) { | ||||||
if (width == 0) return prefixFirst + text; | ||||||
|
||||||
std::ostringstream out; | ||||||
std::istringstream is(text); | ||||||
std::string word, line; | ||||||
bool firstLine = true; | ||||||
|
||||||
auto safeSub = [](size_t a, size_t b) { return (a > b) ? (a - b) : 0u; }; | ||||||
const size_t effFirst = safeSub(width, prefixFirst.size()); | ||||||
const size_t effCont = safeSub(width, prefixCont.size()); | ||||||
|
||||||
auto flush = [&](bool isFirst) { | ||||||
if (!line.empty()) { | ||||||
out << (isFirst ? prefixFirst : prefixCont) << line << '\n'; | ||||||
line.clear(); | ||||||
} | ||||||
}; | ||||||
|
||||||
while (is >> word) { | ||||||
size_t eff = firstLine ? effFirst : effCont; | ||||||
if (line.empty()) { | ||||||
line = word; | ||||||
} else if (line.size() + 1 + word.size() <= eff) { | ||||||
line += ' '; | ||||||
line += word; | ||||||
} else { | ||||||
flush(firstLine); | ||||||
firstLine = false; | ||||||
line = word; | ||||||
} | ||||||
} | ||||||
flush(firstLine); | ||||||
|
||||||
std::string s = out.str(); | ||||||
if (!s.empty() && s.back() == '\n') s.pop_back(); | ||||||
return s; | ||||||
} | ||||||
|
||||||
CmdInfo::CmdInfo() { | ||||||
_keyword = "information"; | ||||||
_usage = "task <filter> information"; | ||||||
|
@@ -116,9 +158,27 @@ int CmdInfo::execute(std::string& output) { | |||||
auto description = task.get("description"); | ||||||
auto indent = Context::getContext().config.getInteger("indent.annotation"); | ||||||
|
||||||
for (auto& anno : task.getAnnotations()) | ||||||
description += '\n' + std::string(indent, ' ') + | ||||||
Datetime(anno.first.substr(11)).toString(dateformatanno) + ' ' + anno.second; | ||||||
{ | ||||||
const size_t termWidth = Context::getContext().getWidth(); | ||||||
const size_t approxNameCol = 20; // conservative; covers labels like "Last modified" | ||||||
const size_t valueWidth = termWidth > approxNameCol ? termWidth - approxNameCol : termWidth; | ||||||
Comment on lines
+162
to
+164
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, this seems a bit of a hack, as it's "guessing" the size of the If that requires improvements to the libshared repo, that's fine -- it's only used by Taskwarrior and Timewarrior so we can modify it pretty easily. |
||||||
|
||||||
for (const auto& anno : task.getAnnotations()) { | ||||||
// first line looks exactly like before: <indent><timestamp><space> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "before" won't mean much to a reader outside the context of this PR -- rephrase to the context of the code
Suggested change
|
||||||
const std::string firstPrefix = std::string(indent, ' ') + | ||||||
Datetime(anno.first.substr(11)).toString(dateformatanno) + | ||||||
' '; | ||||||
|
||||||
// continuation lines: same width, all spaces | ||||||
const std::string contPrefix(firstPrefix.size(), ' '); | ||||||
|
||||||
// wrap just the annotation body with our prefixes | ||||||
const std::string wrapped = | ||||||
wrapWithPrefixes(anno.second, valueWidth, firstPrefix, contPrefix); | ||||||
|
||||||
description += '\n' + wrapped; | ||||||
} | ||||||
} | ||||||
|
||||||
if (task.has("description")) { | ||||||
row = view.addRow(); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's existing wrapping support in src/libshared/src/shared.cpp, and I think that could be re-used for this purpose rather than re-implementing it.