зеркало из https://github.com/microsoft/git.git
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:
Родитель
a7f01c6b4d
Коммит
1640632b4f
|
@ -173,7 +173,10 @@ The placeholders are:
|
||||||
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>)'
|
||||||
respectively, but padding spaces on the left
|
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)
|
respectively, but padding both sides (i.e. the text is centered)
|
||||||
|
|
||||||
NOTE: Some placeholders may depend on other options given to the
|
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,
|
no_flush,
|
||||||
flush_right,
|
flush_right,
|
||||||
flush_left,
|
flush_left,
|
||||||
|
flush_left_and_steal,
|
||||||
flush_both
|
flush_both
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1026,6 +1027,9 @@ static size_t parse_padding_placeholder(struct strbuf *sb,
|
||||||
if (*ch == '<') {
|
if (*ch == '<') {
|
||||||
flush_type = flush_both;
|
flush_type = flush_both;
|
||||||
ch++;
|
ch++;
|
||||||
|
} else if (*ch == '>') {
|
||||||
|
flush_type = flush_left_and_steal;
|
||||||
|
ch++;
|
||||||
} else
|
} else
|
||||||
flush_type = flush_left;
|
flush_type = flush_left;
|
||||||
break;
|
break;
|
||||||
|
@ -1334,6 +1338,36 @@ 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 (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) {
|
if (len > padding) {
|
||||||
switch (c->truncate) {
|
switch (c->truncate) {
|
||||||
case trunc_left:
|
case trunc_left:
|
||||||
|
|
|
@ -260,4 +260,18 @@ EOF
|
||||||
test_cmp expected actual
|
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
|
test_done
|
||||||
|
|
2
utf8.c
2
utf8.c
|
@ -9,7 +9,7 @@ struct interval {
|
||||||
int last;
|
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;
|
const char *p = s;
|
||||||
if (*p++ != '\033')
|
if (*p++ != '\033')
|
||||||
|
|
1
utf8.h
1
utf8.h
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
typedef unsigned int ucs_char_t; /* assuming 32bit int */
|
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_width(const char **start, size_t *remainder_p);
|
||||||
int utf8_strnwidth(const char *string, int len, int skip_ansi);
|
int utf8_strnwidth(const char *string, int len, int skip_ansi);
|
||||||
int utf8_strwidth(const char *string);
|
int utf8_strwidth(const char *string);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче