On Sat, Mar 16, 2013 at 2:24 AM, Nguyễn Thái Ngọc Duy <[email protected]> wrote:
> %>(N,trunc) truncates the righ part after N columns and replace the
> last two letters with "..". ltrunc does the same on the left. mtrunc
> cuts the middle out.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
> ---
s/righ/right/
> Documentation/pretty-formats.txt | 6 +++--
> pretty.c | 51
> +++++++++++++++++++++++++++++++++++++---
> utf8.c | 46 ++++++++++++++++++++++++++++++++++++
> utf8.h | 2 ++
> 4 files changed, 100 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/pretty-formats.txt
> b/Documentation/pretty-formats.txt
> index 87ca2c4..17f82f4 100644
> --- a/Documentation/pretty-formats.txt
> +++ b/Documentation/pretty-formats.txt
> @@ -162,8 +162,10 @@ The placeholders are:
> - '%x00': print a byte from a hex code
> - '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
> linkgit:git-shortlog[1].
> -- '%<(<N>)': make the next placeholder take at least N columns,
> - padding spaces on the right if necessary
> +- '%<(<N>[,trunc|ltrunc|mtrunc])': make the next placeholder take at
> + least N columns, padding spaces on the right if necessary.
> + Optionally truncate at the beginning (ltrunc), the middle (mtrunc)
> + or the end (trunc) if the output is longer than N columns.
> - '%<|(<N>)': make the next placeholder take at least until Nth
> columns, padding spaces on the right if necessary
> - '%>(<N>)', '%>|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
> diff --git a/pretty.c b/pretty.c
> index 233d69c..29384b5 100644
> --- a/pretty.c
> +++ b/pretty.c
> @@ -767,6 +767,13 @@ enum flush_type {
> flush_both
> };
>
> +enum trunc_type {
> + trunc_none,
> + trunc_left,
> + trunc_middle,
> + trunc_right
> +};
> +
> struct format_commit_context {
> const struct commit *commit;
> const struct pretty_print_context *pretty_ctx;
> @@ -774,6 +781,7 @@ struct format_commit_context {
> unsigned commit_message_parsed:1;
> unsigned commit_signature_parsed:1;
> enum flush_type flush_type;
> + enum trunc_type truncate;
> struct {
> char *gpg_output;
> char good_bad;
> @@ -1044,7 +1052,7 @@ static size_t parse_padding_placeholder(struct strbuf
> *sb,
>
> if (*ch == '(') {
> const char *start = ch + 1;
> - const char *end = strchr(start, ')');
> + const char *end = start + strcspn(start, ",)");
> char *next;
> int width;
> if (!end || end == start)
> @@ -1054,6 +1062,23 @@ static size_t parse_padding_placeholder(struct strbuf
> *sb,
> return 0;
> c->padding = to_column ? -width : width;
> c->flush_type = flush_type;
> +
> + if (*end == ',') {
> + start = end + 1;
> + end = strchr(start, ')');
> + if (!end || end == start)
> + return 0;
> + if (!prefixcmp(start, "trunc)"))
> + c->truncate = trunc_right;
> + else if (!prefixcmp(start, "ltrunc)"))
> + c->truncate = trunc_left;
> + else if (!prefixcmp(start, "mtrunc)"))
> + c->truncate = trunc_middle;
> + else
> + return 0;
> + } else
> + c->truncate = trunc_none;
> +
> return end - placeholder + 1;
> }
> return 0;
> @@ -1335,9 +1360,29 @@ static size_t format_and_pad_commit(struct strbuf *sb,
> /* in UTF-8 */
> total_consumed++;
> }
> len = utf8_strnwidth(local_sb.buf, -1, 1);
> - if (len > padding)
> + if (len > padding) {
> + switch (c->truncate) {
> + case trunc_left:
> + strbuf_utf8_replace(&local_sb,
> + 0, len - (padding - 2),
> + "..");
> + break;
> + case trunc_middle:
> + strbuf_utf8_replace(&local_sb,
> + padding / 2 - 1,
> + len - (padding - 2),
> + "..");
> + break;
> + case trunc_right:
> + strbuf_utf8_replace(&local_sb,
> + padding - 2, len - (padding - 2),
> + "..");
> + break;
> + case trunc_none:
> + break;
> + }
> strbuf_addstr(sb, local_sb.buf);
> - else {
> + } else {
> int sb_len = sb->len, offset = 0;
> if (c->flush_type == flush_left)
> offset = padding - len;
> diff --git a/utf8.c b/utf8.c
> index 9d98043..766df80 100644
> --- a/utf8.c
> +++ b/utf8.c
> @@ -421,6 +421,52 @@ void strbuf_add_wrapped_bytes(struct strbuf *buf, const
> char *data, int len,
> free(tmp);
> }
>
> +void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width,
> + const char *subst)
> +{
> + struct strbuf sb_dst = STRBUF_INIT;
> + char *src = sb_src->buf;
> + char *end = src + sb_src->len;
> + char *dst;
> + int w = 0, subst_len = 0;
> +
> + if (subst)
> + subst_len = strlen(subst);
> + strbuf_grow(&sb_dst, sb_src->len + subst_len);
> + dst = sb_dst.buf;
> +
> + while (src < end) {
> + char *old;
> + size_t n;
> +
> + while ((n = display_mode_esc_sequence_len(src))) {
> + memcpy(dst, src, n);
> + src += n;
> + dst += n;
> + }
> +
> + old = src;
> + n = utf8_width((const char**)&src, NULL);
> + if (!src) /* broken utf-8, do nothing */
> + return;
> + if (n && w >= pos && w < pos + width) {
> + if (subst) {
> + memcpy(dst, subst, subst_len);
> + dst += subst_len;
> + subst = NULL;
> + }
> + w += n;
> + continue;
> + }
> + memcpy(dst, old, src - old);
> + dst += src - old;
> + w += n;
> + }
> + strbuf_setlen(&sb_dst, dst - sb_dst.buf);
> + strbuf_attach(sb_src, strbuf_detach(&sb_dst, NULL),
> + sb_dst.len, sb_dst.alloc);
> +}
> +
> int is_encoding_utf8(const char *name)
> {
> if (!name)
> diff --git a/utf8.h b/utf8.h
> index 99db3e0..faf2f91 100644
> --- a/utf8.h
> +++ b/utf8.h
> @@ -15,6 +15,8 @@ void strbuf_add_wrapped_text(struct strbuf *buf,
> const char *text, int indent, int indent2, int width);
> void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
> int indent, int indent2, int width);
> +void strbuf_utf8_replace(struct strbuf *sb, int pos, int width,
> + const char *subst);
>
> #ifndef NO_ICONV
> char *reencode_string_iconv(const char *in, size_t insz,
> --
> 1.8.2.83.gc99314b
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Paul [W] Campbell
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html