pretty: support %>> that steal trailing spaces
This is pretty useful in `%<(100)%s%Cred%>(20)% an' where %s does not use up all 100 columns and %an needs more than 20 columns. By replacing %>(20) with %>>(20), %an can steal spaces from %s. %>> understands escape sequences, so %Cred does not stop it from stealing spaces in %<(100). 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
a7f01c6b4d
commit
1640632b4f
@ -173,7 +173,10 @@ The placeholders are:
|
||||
columns, padding spaces on the right if necessary
|
||||
- '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
|
||||
respectively, but padding spaces on the left
|
||||
- '%><(<N>)', '%><|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
|
||||
- '%>>(<N>)', '%>>|(<N>)': similar to '%>(<N>)', '%>|(<N>)'
|
||||
respectively, except that if the next placeholder takes more spaces
|
||||
than given and there are spaces on its left, use those spaces
|
||||
- '%><(<N>)', '%><|(<N>)': similar to '% <(<N>)', '%<|(<N>)'
|
||||
respectively, but padding both sides (i.e. the text is centered)
|
||||
|
||||
NOTE: Some placeholders may depend on other options given to the
|
||||
|
34
pretty.c
34
pretty.c
@ -773,6 +773,7 @@ enum flush_type {
|
||||
no_flush,
|
||||
flush_right,
|
||||
flush_left,
|
||||
flush_left_and_steal,
|
||||
flush_both
|
||||
};
|
||||
|
||||
@ -1026,6 +1027,9 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
|
||||
if (*ch == '<') {
|
||||
flush_type = flush_both;
|
||||
ch++;
|
||||
} else if (*ch == '>') {
|
||||
flush_type = flush_left_and_steal;
|
||||
ch++;
|
||||
} else
|
||||
flush_type = flush_left;
|
||||
break;
|
||||
@ -1334,6 +1338,36 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
|
||||
total_consumed++;
|
||||
}
|
||||
len = utf8_strnwidth(local_sb.buf, -1, 1);
|
||||
|
||||
if (c->flush_type == flush_left_and_steal) {
|
||||
const char *ch = sb->buf + sb->len - 1;
|
||||
while (len > padding && ch > sb->buf) {
|
||||
const char *p;
|
||||
if (*ch == ' ') {
|
||||
ch--;
|
||||
padding++;
|
||||
continue;
|
||||
}
|
||||
/* check for trailing ansi sequences */
|
||||
if (*ch != 'm')
|
||||
break;
|
||||
p = ch - 1;
|
||||
while (ch - p < 10 && *p != '\033')
|
||||
p--;
|
||||
if (*p != '\033' ||
|
||||
ch + 1 - p != display_mode_esc_sequence_len(p))
|
||||
break;
|
||||
/*
|
||||
* got a good ansi sequence, put it back to
|
||||
* local_sb as we're cutting sb
|
||||
*/
|
||||
strbuf_insert(&local_sb, 0, p, ch + 1 - p);
|
||||
ch = p - 1;
|
||||
}
|
||||
strbuf_setlen(sb, ch + 1 - sb->buf);
|
||||
c->flush_type = flush_left;
|
||||
}
|
||||
|
||||
if (len > padding) {
|
||||
switch (c->truncate) {
|
||||
case trunc_left:
|
||||
|
@ -260,4 +260,18 @@ EOF
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_expect_success 'left/right alignment formatting with stealing' '
|
||||
git commit --amend -m short --author "long long long <long@me.com>" &&
|
||||
git log --pretty="format:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual &&
|
||||
# complete the incomplete line at the end
|
||||
echo >>actual &&
|
||||
cat <<\EOF >expected &&
|
||||
short long long long
|
||||
message .. A U Thor
|
||||
add bar A U Thor
|
||||
initial A U Thor
|
||||
EOF
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
2
utf8.c
2
utf8.c
@ -9,7 +9,7 @@ struct interval {
|
||||
int last;
|
||||
};
|
||||
|
||||
static size_t display_mode_esc_sequence_len(const char *s)
|
||||
size_t display_mode_esc_sequence_len(const char *s)
|
||||
{
|
||||
const char *p = s;
|
||||
if (*p++ != '\033')
|
||||
|
1
utf8.h
1
utf8.h
@ -3,6 +3,7 @@
|
||||
|
||||
typedef unsigned int ucs_char_t; /* assuming 32bit int */
|
||||
|
||||
size_t display_mode_esc_sequence_len(const char *s);
|
||||
int utf8_width(const char **start, size_t *remainder_p);
|
||||
int utf8_strnwidth(const char *string, int len, int skip_ansi);
|
||||
int utf8_strwidth(const char *string);
|
||||
|
Loading…
Reference in New Issue
Block a user