diff options
-rw-r--r-- | .SRCINFO | 2 | ||||
-rw-r--r-- | PKGBUILD | 2 | ||||
-rw-r--r-- | command_pyroscope.cc | 48 | ||||
-rw-r--r-- | ui_pyroscope.cc | 2 |
4 files changed, 51 insertions, 3 deletions
@@ -1,6 +1,6 @@ pkgbase = rtorrent-ps pkgdesc = Extended rTorrent distribution with UI enhancements, colorization, and some added features - pkgver = 1.1.r29.g78a68a0 + pkgver = 1.1.r38.gd52abd2 pkgrel = 1 url = https://github.com/pyroscope/rtorrent-ps arch = any @@ -3,7 +3,7 @@ _pkgname=rtorrent pkgname=rtorrent-ps _pkgver=0.9.6 -pkgver=1.1.r29.g78a68a0 +pkgver=1.1.r38.gd52abd2 pkgrel=1 pkgdesc='Extended rTorrent distribution with UI enhancements, colorization, and some added features' url='https://github.com/pyroscope/rtorrent-ps' diff --git a/command_pyroscope.cc b/command_pyroscope.cc index 80fa52b54f0b..bff4e7f84155 100644 --- a/command_pyroscope.cc +++ b/command_pyroscope.cc @@ -933,6 +933,53 @@ torrent::Object cmd_string_substr(rpc::target_type target, const torrent::Object } +torrent::Object cmd_string_shorten(rpc::target_type target, const torrent::Object::list_type& args) { + const std::string text = string_get_first_arg("shorten", args); + + torrent::Object::list_const_iterator itr = args.begin() + 1; + int64_t u8len = u8_length(text), maxlen = u8len, tail = 5; + if (itr != args.end()) maxlen = string_get_value_arg("shorten(maxlen)", itr); + if (itr != args.end()) tail = string_get_value_arg("shorten(tail)", itr); + + if (maxlen < 0 || tail < 0) { + throw torrent::input_error("string.shorten: Invalid negative maximal or tail length!"); + } + + if (!maxlen) return std::string(); + if (u8len <= maxlen) return text; + + int64_t head = std::max(int64_t(0), std::min(u8len, maxlen - tail - 1)); + if (2*tail >= maxlen) { + tail = (maxlen - 1) / 2; + head = maxlen - tail - 1; + } + + std::mbstate_t mbs = std::mbstate_t(); + const char* pos = text.c_str(); + int bytes = 0, skip; + while (head-- > 0 && *pos && (skip = std::mbrlen(pos, text.length() - bytes, &mbs)) > 0) { + pos += skip; + bytes += skip; + } + std::string::size_type head_bytes = bytes; + std::string::size_type tail_bytes = bytes; + + std::string::size_type offsets[text.length() + 1]; + int64_t idx = 0; + while (*pos && (skip = std::mbrlen(pos, text.length() - bytes, &mbs)) > 0) { + offsets[idx++] = bytes; + pos += skip; + bytes += skip; + } + offsets[idx] = bytes; + if (tail <= idx) tail_bytes = offsets[idx - tail]; + + return text.substr(0, head_bytes) + + (head + tail < u8len ? "…" : "") + + (tail ? text.substr(tail_bytes) : ""); +} + + torrent::Object::value_type apply_string_contains(bool ignore_case, const torrent::Object::list_type& args) { if (args.size() < 2) { throw torrent::input_error("string.contains[_i] takes at least two arguments!"); @@ -1311,6 +1358,7 @@ void initialize_command_pyroscope() { CMD2_ANY_LIST("string.join", &cmd_string_join); CMD2_ANY_LIST("string.split", &cmd_string_split); CMD2_ANY_LIST("string.substr", &cmd_string_substr); + CMD2_ANY_LIST("string.shorten", &cmd_string_shorten); CMD2_ANY_LIST("string.contains", &cmd_string_contains); CMD2_ANY_LIST("string.contains_i", &cmd_string_contains_i); CMD2_ANY_LIST("string.map", &cmd_string_map); diff --git a/ui_pyroscope.cc b/ui_pyroscope.cc index d9dd1edd00a8..5ecc7e775e4b 100644 --- a/ui_pyroscope.cc +++ b/ui_pyroscope.cc @@ -494,7 +494,7 @@ static void decorate_download_title(Window* window, display::Canvas* canvas, cor // show ratio progress by color (ratio is scaled x1000) static int ratio_color(int ratio) { int rcol = sizeof(ratio_col) / sizeof(*ratio_col) - 1; - return ratio_col[std::min(rcol, ratio * rcol / 1200)]; + return ratio_col[std::min(rcol, std::max(0, ratio) * rcol / 1200)]; } |