On Sat, Mar 16, 2013 at 2:24 AM, Nguyễn Thái Ngọc Duy 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
> ---
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([[,[,]]])': switch line wrapping, like the -w option of
>linkgit:git-shortlog[1].
> -- '%<()': make the next placeholder take at least N columns,
> - padding spaces on the right if necessary
> +- '%<([,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.
> - '%<|()': make the next placeholder take at least until Nth
>columns, padding spaces on the right if necessary
> - '%>()', '%>|()': similar to '%<( 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 {
>