On Sat, Mar 16, 2013 at 2:24 AM, Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> 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 <pclouds@xxxxxxxxx> > --- 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 majordomo@xxxxxxxxxxxxxxx > 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html