pretty: support truncating in %>, %< and %><
%>(N,trunc) truncates the right 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@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
a57523428b
commit
a7f01c6b4d
@ -164,8 +164,11 @@ The placeholders are:
|
|||||||
- '%x00': print a byte from a hex code
|
- '%x00': print a byte from a hex code
|
||||||
- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
|
- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of
|
||||||
linkgit:git-shortlog[1].
|
linkgit:git-shortlog[1].
|
||||||
- '%<(<N>)': make the next placeholder take at least N columns,
|
- '%<(<N>[,trunc|ltrunc|mtrunc])': make the next placeholder take at
|
||||||
padding spaces on the right if necessary
|
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.
|
||||||
|
Note that truncating only works correctly with N >= 2.
|
||||||
- '%<|(<N>)': make the next placeholder take at least until Nth
|
- '%<|(<N>)': make the next placeholder take at least until Nth
|
||||||
columns, padding spaces on the right if necessary
|
columns, padding spaces on the right if necessary
|
||||||
- '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
|
- '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
|
||||||
|
51
pretty.c
51
pretty.c
@ -776,6 +776,13 @@ enum flush_type {
|
|||||||
flush_both
|
flush_both
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum trunc_type {
|
||||||
|
trunc_none,
|
||||||
|
trunc_left,
|
||||||
|
trunc_middle,
|
||||||
|
trunc_right
|
||||||
|
};
|
||||||
|
|
||||||
struct format_commit_context {
|
struct format_commit_context {
|
||||||
const struct commit *commit;
|
const struct commit *commit;
|
||||||
const struct pretty_print_context *pretty_ctx;
|
const struct pretty_print_context *pretty_ctx;
|
||||||
@ -783,6 +790,7 @@ struct format_commit_context {
|
|||||||
unsigned commit_message_parsed:1;
|
unsigned commit_message_parsed:1;
|
||||||
struct signature_check signature_check;
|
struct signature_check signature_check;
|
||||||
enum flush_type flush_type;
|
enum flush_type flush_type;
|
||||||
|
enum trunc_type truncate;
|
||||||
char *message;
|
char *message;
|
||||||
char *commit_encoding;
|
char *commit_encoding;
|
||||||
size_t width, indent1, indent2;
|
size_t width, indent1, indent2;
|
||||||
@ -1033,7 +1041,7 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
|
|||||||
|
|
||||||
if (*ch == '(') {
|
if (*ch == '(') {
|
||||||
const char *start = ch + 1;
|
const char *start = ch + 1;
|
||||||
const char *end = strchr(start, ')');
|
const char *end = start + strcspn(start, ",)");
|
||||||
char *next;
|
char *next;
|
||||||
int width;
|
int width;
|
||||||
if (!end || end == start)
|
if (!end || end == start)
|
||||||
@ -1043,6 +1051,23 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
|
|||||||
return 0;
|
return 0;
|
||||||
c->padding = to_column ? -width : width;
|
c->padding = to_column ? -width : width;
|
||||||
c->flush_type = flush_type;
|
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 end - placeholder + 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1309,9 +1334,29 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
|
|||||||
total_consumed++;
|
total_consumed++;
|
||||||
}
|
}
|
||||||
len = utf8_strnwidth(local_sb.buf, -1, 1);
|
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);
|
strbuf_addstr(sb, local_sb.buf);
|
||||||
else {
|
} else {
|
||||||
int sb_len = sb->len, offset = 0;
|
int sb_len = sb->len, offset = 0;
|
||||||
if (c->flush_type == flush_left)
|
if (c->flush_type == flush_left)
|
||||||
offset = padding - len;
|
offset = padding - len;
|
||||||
|
@ -143,6 +143,45 @@ EOF
|
|||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'left alignment formatting with trunc' '
|
||||||
|
git log --pretty="format:%<(10,trunc)%s" >actual &&
|
||||||
|
# complete the incomplete line at the end
|
||||||
|
echo >>actual &&
|
||||||
|
qz_to_tab_space <<\EOF >expected &&
|
||||||
|
message ..
|
||||||
|
message ..
|
||||||
|
add bar Z
|
||||||
|
initial Z
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'left alignment formatting with ltrunc' '
|
||||||
|
git log --pretty="format:%<(10,ltrunc)%s" >actual &&
|
||||||
|
# complete the incomplete line at the end
|
||||||
|
echo >>actual &&
|
||||||
|
qz_to_tab_space <<\EOF >expected &&
|
||||||
|
..sage two
|
||||||
|
..sage one
|
||||||
|
add bar Z
|
||||||
|
initial Z
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'left alignment formatting with mtrunc' '
|
||||||
|
git log --pretty="format:%<(10,mtrunc)%s" >actual &&
|
||||||
|
# complete the incomplete line at the end
|
||||||
|
echo >>actual &&
|
||||||
|
qz_to_tab_space <<\EOF >expected &&
|
||||||
|
mess.. two
|
||||||
|
mess.. one
|
||||||
|
add bar Z
|
||||||
|
initial Z
|
||||||
|
EOF
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'right alignment formatting' '
|
test_expect_success 'right alignment formatting' '
|
||||||
git log --pretty="format:%>(40)%s" >actual &&
|
git log --pretty="format:%>(40)%s" >actual &&
|
||||||
# complete the incomplete line at the end
|
# complete the incomplete line at the end
|
||||||
|
46
utf8.c
46
utf8.c
@ -421,6 +421,52 @@ void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
|
|||||||
free(tmp);
|
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)
|
int is_encoding_utf8(const char *name)
|
||||||
{
|
{
|
||||||
if (!name)
|
if (!name)
|
||||||
|
2
utf8.h
2
utf8.h
@ -15,6 +15,8 @@ void strbuf_add_wrapped_text(struct strbuf *buf,
|
|||||||
const char *text, int indent, int indent2, int width);
|
const char *text, int indent, int indent2, int width);
|
||||||
void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
|
void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
|
||||||
int indent, int indent2, int width);
|
int indent, int indent2, int width);
|
||||||
|
void strbuf_utf8_replace(struct strbuf *sb, int pos, int width,
|
||||||
|
const char *subst);
|
||||||
|
|
||||||
#ifndef NO_ICONV
|
#ifndef NO_ICONV
|
||||||
char *reencode_string_iconv(const char *in, size_t insz,
|
char *reencode_string_iconv(const char *in, size_t insz,
|
||||||
|
Loading…
Reference in New Issue
Block a user