This series was ejected out of pu some time ago due to gcc warnings. I
did not have time to look at it (and it worked ok for me so it was not
a pressing matter). This re-roll should fix that.
For demonstration, try
git log --pretty='format:%C(auto)%h %<(80,trunc)%s%>>(10,ltrunc)%C(auto)%d%>(15,mtrunc)% an'
Nguyễn Thái Ngọc Duy (12):
pretty-formats.txt: wrap long lines
pretty: share code between format_decoration and show_decorations
utf8.c: move display_mode_esc_sequence_len() for use by other functions
utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences
pretty: save commit encoding from logmsg_reencode if the caller needs it
pretty: get the correct encoding for --pretty:format=%e
utf8: keep NULs in reencode_string()
pretty: two phase conversion for non utf-8 commits
pretty: add %C(auto) for auto-coloring on the next placeholder
pretty: support padding placeholders, %< %> and %><
pretty: support truncating in %>, %< and %><
pretty: support %>> that steal trailing spaces
Documentation/pretty-formats.txt | 34 ++++-
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
builtin/fast-export.c | 3 +-
builtin/mailinfo.c | 3 +-
commit.h | 1 +
compat/precompose_utf8.c | 2 +-
log-tree.c | 60 +++++----
log-tree.h | 3 +
notes.c | 4 +-
pretty.c | 282 ++++++++++++++++++++++++++++++++++-----
revision.c | 2 +-
sequencer.c | 5 +-
t/t4207-log-decoration-colors.sh | 8 +-
t/t6006-rev-list-format.sh | 12 +-
utf8.c | 104 +++++++++++----
utf8.h | 14 +-
17 files changed, 434 insertions(+), 107 deletions(-)
--
1.8.2.83.gc99314b
@@ -44,15 +44,15 @@ test_expect_success setup '' cat>expected<<EOF-${c_commit}COMMIT_ID(${c_HEAD}HEAD${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_HEAD}HEAD${c_reset}${c_commit},\${c_tag}tag:v1.0${c_reset}${c_commit},\${c_tag}tag:B${c_reset}${c_commit},\${c_branch}master${c_reset}${c_commit})${c_reset}B-${c_commit}COMMIT_ID(${c_tag}tag:A1${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A1${c_reset}${c_commit},\${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset}A1-${c_commit}COMMIT_ID(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\Onmaster:ChangestoA.t-${c_commit}COMMIT_ID(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A EOF# We want log to show all, but the second parent to refs/stash is irrelevant
parse_commit_header() provides the commit encoding for '%e' and it
reads it from the re-encoded message, which contains the new encoding,
not the original one in the commit object.
Get the commit encoding from logmsg_reencode() instead.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
@@ -771,12 +771,12 @@ struct format_commit_context {char*signer;}signature;char*message;+char*commit_encoding;size_twidth,indent1,indent2;/* These offsets are relative to the start of the commit message. */structchunkauthor;structchunkcommitter;-structchunkencoding;size_tmessage_off;size_tsubject_off;size_tbody_off;
@@ -1210,7 +1207,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,msg+c->committer.off,c->committer.len,c->pretty_ctx->date_mode);case'e':/* encoding */-strbuf_add(sb,msg+c->encoding.off,c->encoding.len);+if(c->commit_encoding)+strbuf_addstr(sb,c->commit_encoding);return1;case'B':/* raw body *//* message_off is always left at the initial newline */
This is not simply convenient over $C(auto,xxx). Some placeholders
(actually only one, %d) do multi coloring and we can't emit a multiple
colors with %C(auto,xxx).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 3 ++-
pretty.c | 15 +++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
@@ -154,7 +154,8 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a- terminal)+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring+ on the following placeholder. - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%'
@@ -774,6 +774,7 @@ struct format_commit_context {char*message;char*commit_encoding;size_twidth,indent1,indent2;+intauto_color;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1011,7 +1012,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */conststructcommit*commit=c->commit;constchar*msg=c->message;structcommit_list*p;-inth1,h2;+inth1,h2,use_color;/* these are independent of the commit */switch(placeholder[0]){
Either %<, %> or %<> standing before a placeholder specifies how many
columns (at least as the placeholder can exceed it) it takes. Each
differs on how spaces are padded:
%< pads on the right (aka left alignment)
%> pads on the left (aka right alignment)
%>< pads both ways equally (aka centered)
The (<N>) follows them, e.g. `%<(100)', to specify the number of
columns the next placeholder takes.
However, if '|' stands before (<N>), e.g. `%>|(100)', then the number
of columns is calculated so that it reaches the Nth column on screen.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 8 +++
pretty.c | 117 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 124 insertions(+), 1 deletion(-)
@@ -162,6 +162,14 @@ 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>)': make the next placeholder take at least until Nth+ 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<)'+ respectively, but padding both sides (i.e. the text is centered) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will
@@ -775,6 +783,7 @@ struct format_commit_context {char*commit_encoding;size_twidth,indent1,indent2;intauto_color;+intpadding;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1004,6 +1013,52 @@ static int format_reflog_person(struct strbuf *sb,returnformat_person_part(sb,part,ident,strlen(ident),dmode);}+staticsize_tparse_padding_placeholder(structstrbuf*sb,+constchar*placeholder,+structformat_commit_context*c)+{+constchar*ch=placeholder;+enumflush_typeflush_type;+intto_column=0;++switch(*ch++){+case'<':+flush_type=flush_right;+break;+case'>':+if(*ch=='<'){+flush_type=flush_both;+ch++;+}else+flush_type=flush_left;+break;+default:+return0;+}++/* the next value means "wide enough to that column" */+if(*ch=='|'){+to_column=1;+ch++;+}++if(*ch=='('){+constchar*start=ch+1;+constchar*end=strchr(start,')');+char*next;+intwidth;+if(!end||end==start)+return0;+width=strtoul(start,&next,10);+if(next==start||width==0)+return0;+c->padding=to_column?-width:width;+c->flush_type=flush_type;+returnend-placeholder+1;+}+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -1090,6 +1145,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */returnend-placeholder+1;}elsereturn0;++case'<':+case'>':+returnparse_padding_placeholder(sb,placeholder,c);}/* these depend on the commit */
@@ -1247,6 +1306,59 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */return0;/* unknown placeholder */}+staticsize_tformat_and_pad_commit(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+structstrbuflocal_sb=STRBUF_INIT;+inttotal_consumed=0,len,padding=c->padding;+if(padding<0){+constchar*start=strrchr(sb->buf,'\n');+intoccupied;+if(!start)+start=sb->buf;+occupied=utf8_strnwidth(start,-1,1);+padding=(-padding)-occupied;+}+while(1){+intmodifier=*placeholder=='C';+intconsumed=format_commit_one(&local_sb,placeholder,c);+total_consumed+=consumed;++if(!modifier)+break;++placeholder+=consumed;+if(*placeholder!='%')+break;+placeholder++;+total_consumed++;+}+len=utf8_strnwidth(local_sb.buf,-1,1);+if(len>padding)+strbuf_addstr(sb,local_sb.buf);+else{+intsb_len=sb->len,offset=0;+if(c->flush_type==flush_left)+offset=padding-len;+elseif(c->flush_type==flush_both)+offset=(padding-len)/2;+/*+*wecalculatepaddingincolumns,now+*convertitbacktochars+*/+padding=padding-len+local_sb.len;+strbuf_grow(sb,padding);+strbuf_setlen(sb,sb_len+padding);+memset(sb->buf+sb_len,' ',sb->len-sb_len);+memcpy(sb->buf+sb_len+offset,local_sb.buf,+local_sb.len);+}+strbuf_release(&local_sb);+c->flush_type=no_flush;+returntotal_consumed;+}+staticsize_tformat_commit_item(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
%>(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 <redacted>
---
Documentation/pretty-formats.txt | 6 +++--
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
4 files changed, 100 insertions(+), 5 deletions(-)
@@ -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<)'
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 <redacted>
---
Documentation/pretty-formats.txt | 5 ++++-
pretty.c | 34 ++++++++++++++++++++++++++++++++++
utf8.c | 2 +-
utf8.h | 1 +
4 files changed, 40 insertions(+), 2 deletions(-)
@@ -170,7 +170,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
The commit encoding is parsed by logmsg_reencode, there's no need for
the caller to re-parse it again. The reencoded message now have the
new encoding, not the original one. The caller would need to read
commit object again before parsing.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
pretty.c | 16 ++++++++++++----
revision.c | 2 +-
5 files changed, 16 insertions(+), 7 deletions(-)
@@ -2290,7 +2290,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)*init.*/encoding=get_log_output_encoding();-message=logmsg_reencode(commit,encoding);+message=logmsg_reencode(commit,NULL,encoding);/* Copy the commit to temporary if we are using "fake" headers */if(buf.len)
Always assume format_commit_item() takes an utf-8 string for string
handling simplicity (we can handle utf-8 strings, but can't with other
encodings).
If commit message is in non-utf8, or output encoding is not, then the
commit is first converted to utf-8, processed, then output converted
to output encoding. This of course only works with encodings that are
compatible with Unicode.
This also fixes the iso8859-1 test in t6006. It's supposed to create
an iso8859-1 commit, but the commit content in t6006 is in UTF-8.
t6006 is now converted back in UTF-8 (the downside is we can't put
utf-8 strings there anymore).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 24 ++++++++++++++++++++++--
t/t6006-rev-list-format.sh | 12 ++++++------
2 files changed, 28 insertions(+), 8 deletions(-)
From: Paul Campbell <hidden> Date: 2016-06-15 22:56:24
On Sat, Mar 16, 2013 at 2:24 AM, Nguyễn Thái Ngọc Duy [off-list ref] 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 <redacted>
---
@@ -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<)'
1.8.2.83.gc99314b
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
@@ -154,7 +154,8 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a- terminal)+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring
@@ -162,6 +162,14 @@ 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>)': make the next placeholder take at least until Nth+ columns, padding spaces on the right if necessary+- '%>(<N>)', '%>|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
s/<N</<N>/g
+ respectively, but padding spaces on the left
+- '%><(<N>)', '%><|(<N>)': similar to '%<(<N<)', '%<|(<N<)'
Ditto: s/<N</<N>/g
+ respectively, but padding both sides (i.e. the text is centered)
@@ -170,7 +170,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<)'
s/<N</<N>/g
+ 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<)'
Ditto: s/<N</<N>/g
respectively, but padding both sides (i.e. the text is centered)
The only difference in v2 is typo fixes (mostly in commit messages,
but some in pretty-formats.txt). Also resend as a reminder to Junio if
he forgot to pick it up.
Nguyễn Thái Ngọc Duy (12):
pretty-formats.txt: wrap long lines
pretty: share code between format_decoration and show_decorations
utf8.c: move display_mode_esc_sequence_len() for use by other
functions
utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences
pretty: save commit encoding from logmsg_reencode if the caller needs
it
pretty: get the correct encoding for --pretty:format=%e
utf8: keep NULs in reencode_string()
pretty: two phase conversion for non utf-8 commits
pretty: add %C(auto) for auto-coloring on the next placeholder
pretty: support padding placeholders, %< %> and %><
pretty: support truncating in %>, %< and %><
pretty: support %>> that steal trailing spaces
Documentation/pretty-formats.txt | 34 ++++-
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
builtin/fast-export.c | 3 +-
builtin/mailinfo.c | 3 +-
commit.h | 1 +
compat/precompose_utf8.c | 2 +-
log-tree.c | 60 +++++----
log-tree.h | 3 +
notes.c | 4 +-
pretty.c | 282 ++++++++++++++++++++++++++++++++++-----
revision.c | 2 +-
sequencer.c | 5 +-
t/t4207-log-decoration-colors.sh | 8 +-
t/t6006-rev-list-format.sh | 12 +-
utf8.c | 104 +++++++++++----
utf8.h | 14 +-
17 files changed, 434 insertions(+), 107 deletions(-)
--
1.8.2.83.gc99314b
@@ -44,15 +44,15 @@ test_expect_success setup '' cat>expected<<EOF-${c_commit}COMMIT_ID(${c_HEAD}HEAD${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_HEAD}HEAD${c_reset}${c_commit},\${c_tag}tag:v1.0${c_reset}${c_commit},\${c_tag}tag:B${c_reset}${c_commit},\${c_branch}master${c_reset}${c_commit})${c_reset}B-${c_commit}COMMIT_ID(${c_tag}tag:A1${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A1${c_reset}${c_commit},\${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset}A1-${c_commit}COMMIT_ID(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\Onmaster:ChangestoA.t-${c_commit}COMMIT_ID(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A EOF# We want log to show all, but the second parent to refs/stash is irrelevant
The commit encoding is parsed by logmsg_reencode, there's no need for
the caller to re-parse it again. The reencoded message now has the new
encoding, not the original one. The caller would need to read commit
object again before parsing.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
pretty.c | 16 ++++++++++++----
revision.c | 2 +-
5 files changed, 16 insertions(+), 7 deletions(-)
@@ -2290,7 +2290,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)*init.*/encoding=get_log_output_encoding();-message=logmsg_reencode(commit,encoding);+message=logmsg_reencode(commit,NULL,encoding);/* Copy the commit to temporary if we are using "fake" headers */if(buf.len)
parse_commit_header() provides the commit encoding for '%e' and it
reads it from the re-encoded message, which contains the new encoding,
not the original one in the commit object.
Get the commit encoding from logmsg_reencode() instead.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
@@ -771,12 +771,12 @@ struct format_commit_context {char*signer;}signature;char*message;+char*commit_encoding;size_twidth,indent1,indent2;/* These offsets are relative to the start of the commit message. */structchunkauthor;structchunkcommitter;-structchunkencoding;size_tmessage_off;size_tsubject_off;size_tbody_off;
@@ -1210,7 +1207,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,msg+c->committer.off,c->committer.len,c->pretty_ctx->date_mode);case'e':/* encoding */-strbuf_add(sb,msg+c->encoding.off,c->encoding.len);+if(c->commit_encoding)+strbuf_addstr(sb,c->commit_encoding);return1;case'B':/* raw body *//* message_off is always left at the initial newline */
Always assume format_commit_item() takes an utf-8 string for string
handling simplicity (we can handle utf-8 strings, but can't with other
encodings).
If commit message is in non-utf8, or output encoding is not, then the
commit is first converted to utf-8, processed, then output converted
to output encoding. This of course only works with encodings that are
compatible with Unicode.
This also fixes the iso8859-1 test in t6006. It's supposed to create
an iso8859-1 commit, but the commit content in t6006 is in UTF-8.
t6006 is now converted back in UTF-8 (the downside is we can't put
utf-8 strings there anymore).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 24 ++++++++++++++++++++++--
t/t6006-rev-list-format.sh | 12 ++++++------
2 files changed, 28 insertions(+), 8 deletions(-)
This is not simply convenient over %C(auto,xxx). Some placeholders
(actually only one, %d) do multi coloring and we can't emit a multiple
colors with %C(auto,xxx).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 3 ++-
pretty.c | 15 +++++++++++++--
2 files changed, 15 insertions(+), 3 deletions(-)
@@ -154,7 +154,8 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a- terminal)+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring+ on the following placeholder. - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%'
@@ -774,6 +774,7 @@ struct format_commit_context {char*message;char*commit_encoding;size_twidth,indent1,indent2;+intauto_color;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1011,7 +1012,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */conststructcommit*commit=c->commit;constchar*msg=c->message;structcommit_list*p;-inth1,h2;+inth1,h2,use_color;/* these are independent of the commit */switch(placeholder[0]){
Either %<, %> or %>< standing before a placeholder specifies how many
columns (at least as the placeholder can exceed it) it takes. Each
differs on how spaces are padded:
%< pads on the right (aka left alignment)
%> pads on the left (aka right alignment)
%>< pads both ways equally (aka centered)
The (<N>) follows them, e.g. `%<(100)', to specify the number of
columns the next placeholder takes.
However, if '|' stands before (<N>), e.g. `%>|(100)', then the number
of columns is calculated so that it reaches the Nth column on screen.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 8 +++
pretty.c | 117 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 124 insertions(+), 1 deletion(-)
@@ -162,6 +162,14 @@ 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>)': make the next placeholder take at least until Nth+ 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>)'+ respectively, but padding both sides (i.e. the text is centered) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will
@@ -775,6 +783,7 @@ struct format_commit_context {char*commit_encoding;size_twidth,indent1,indent2;intauto_color;+intpadding;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1004,6 +1013,52 @@ static int format_reflog_person(struct strbuf *sb,returnformat_person_part(sb,part,ident,strlen(ident),dmode);}+staticsize_tparse_padding_placeholder(structstrbuf*sb,+constchar*placeholder,+structformat_commit_context*c)+{+constchar*ch=placeholder;+enumflush_typeflush_type;+intto_column=0;++switch(*ch++){+case'<':+flush_type=flush_right;+break;+case'>':+if(*ch=='<'){+flush_type=flush_both;+ch++;+}else+flush_type=flush_left;+break;+default:+return0;+}++/* the next value means "wide enough to that column" */+if(*ch=='|'){+to_column=1;+ch++;+}++if(*ch=='('){+constchar*start=ch+1;+constchar*end=strchr(start,')');+char*next;+intwidth;+if(!end||end==start)+return0;+width=strtoul(start,&next,10);+if(next==start||width==0)+return0;+c->padding=to_column?-width:width;+c->flush_type=flush_type;+returnend-placeholder+1;+}+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -1090,6 +1145,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */returnend-placeholder+1;}elsereturn0;++case'<':+case'>':+returnparse_padding_placeholder(sb,placeholder,c);}/* these depend on the commit */
@@ -1247,6 +1306,59 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */return0;/* unknown placeholder */}+staticsize_tformat_and_pad_commit(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+structstrbuflocal_sb=STRBUF_INIT;+inttotal_consumed=0,len,padding=c->padding;+if(padding<0){+constchar*start=strrchr(sb->buf,'\n');+intoccupied;+if(!start)+start=sb->buf;+occupied=utf8_strnwidth(start,-1,1);+padding=(-padding)-occupied;+}+while(1){+intmodifier=*placeholder=='C';+intconsumed=format_commit_one(&local_sb,placeholder,c);+total_consumed+=consumed;++if(!modifier)+break;++placeholder+=consumed;+if(*placeholder!='%')+break;+placeholder++;+total_consumed++;+}+len=utf8_strnwidth(local_sb.buf,-1,1);+if(len>padding)+strbuf_addstr(sb,local_sb.buf);+else{+intsb_len=sb->len,offset=0;+if(c->flush_type==flush_left)+offset=padding-len;+elseif(c->flush_type==flush_both)+offset=(padding-len)/2;+/*+*wecalculatepaddingincolumns,now+*convertitbacktochars+*/+padding=padding-len+local_sb.len;+strbuf_grow(sb,padding);+strbuf_setlen(sb,sb_len+padding);+memset(sb->buf+sb_len,' ',sb->len-sb_len);+memcpy(sb->buf+sb_len+offset,local_sb.buf,+local_sb.len);+}+strbuf_release(&local_sb);+c->flush_type=no_flush;+returntotal_consumed;+}+staticsize_tformat_commit_item(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
%>(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 <redacted>
---
Documentation/pretty-formats.txt | 6 +++--
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
4 files changed, 100 insertions(+), 5 deletions(-)
@@ -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>)'
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 <redacted>
---
Documentation/pretty-formats.txt | 5 ++++-
pretty.c | 34 ++++++++++++++++++++++++++++++++++
utf8.c | 2 +-
utf8.h | 1 +
4 files changed, 40 insertions(+), 2 deletions(-)
@@ -170,7 +170,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
On 30.03.13 10:35, Nguyễn Thái Ngọc Duy wrote:
[...]
The short version of a review:
Would it make sense to leave reencode_string() as it is,
and add a new function reencode_string_len()
+char *reencode_string_len(const char *in, int insz,
+ const char *out_encoding, const char *in_encoding,
+ int *outsz)
And I didn't manage to apply the patch on master (631bc94e67383b66da190550866566f09d32)
is there a specific commitID it should be applied on ?
/Torsten
On Sun, Mar 31, 2013 at 12:06 AM, Torsten Bögershausen [off-list ref] wrote:
On 30.03.13 10:35, Nguyễn Thái Ngọc Duy wrote:
[...]
The short version of a review:
Would it make sense to leave reencode_string() as it is,
and add a new function reencode_string_len()
Hmm.. yeah.
+char *reencode_string_len(const char *in, int insz,
+ const char *out_encoding, const char *in_encoding,
+ int *outsz)
And I didn't manage to apply the patch on master (631bc94e67383b66da190550866566f09d32)
is there a specific commitID it should be applied on ?
I've been updating this series on and off over a long span of time, I
don't think I remember exactly what changes I've made. But basically
I think I have covered all comments from v2. The only semantics change
is %C(auto) now turns auto coloring on for all following placeholders
until another valid %C is encountered.
Nguyễn Thái Ngọc Duy (13):
pretty: save commit encoding from logmsg_reencode if the caller needs it
pretty: get the correct encoding for --pretty:format=%e
pretty-formats.txt: wrap long lines
pretty: share code between format_decoration and show_decorations
utf8.c: move display_mode_esc_sequence_len() for use by other functions
utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences
utf8.c: add reencode_string_len() that can handle NULs in string
pretty: two phase conversion for non utf-8 commits
pretty: split color parsing into a separate function
pretty: add %C(auto) for auto-coloring
pretty: support padding placeholders, %< %> and %><
pretty: support truncating in %>, %< and %><
pretty: support %>> that steal trailing spaces
Documentation/pretty-formats.txt | 35 +++-
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
compat/precompose_utf8.c | 2 +-
log-tree.c | 48 ++++--
log-tree.h | 1 +
pretty.c | 349 ++++++++++++++++++++++++++++++++-------
revision.c | 2 +-
t/t4205-log-pretty-formats.sh | 179 ++++++++++++++++++++
t/t4207-log-decoration-colors.sh | 8 +-
t/t6006-rev-list-format.sh | 12 +-
utf8.c | 104 +++++++++---
utf8.h | 23 ++-
14 files changed, 644 insertions(+), 124 deletions(-)
--
1.8.2.82.gc24b958
The commit encoding is parsed by logmsg_reencode, there's no need for
the caller to re-parse it again. The reencoded message now has the new
encoding, not the original one. The caller would need to read commit
object again before parsing.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
pretty.c | 16 ++++++++++++----
revision.c | 2 +-
5 files changed, 16 insertions(+), 7 deletions(-)
@@ -2314,7 +2314,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)*init.*/encoding=get_log_output_encoding();-message=logmsg_reencode(commit,encoding);+message=logmsg_reencode(commit,NULL,encoding);/* Copy the commit to temporary if we are using "fake" headers */if(buf.len)
parse_commit_header() provides the commit encoding for '%e' and it
reads it from the re-encoded message, which contains the new encoding,
not the original one in the commit object. This never happens because
--pretty=format:xxx never respects i18n.logoutputencoding. But that's
a different story.
Get the commit encoding from logmsg_reencode() instead.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
@@ -776,12 +776,12 @@ struct format_commit_context {unsignedcommit_message_parsed:1;structsignature_checksignature_check;char*message;+char*commit_encoding;size_twidth,indent1,indent2;/* These offsets are relative to the start of the commit message. */structchunkauthor;structchunkcommitter;-structchunkencoding;size_tmessage_off;size_tsubject_off;size_tbody_off;
@@ -1185,7 +1182,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,msg+c->committer.off,c->committer.len,c->pretty_ctx->date_mode);case'e':/* encoding */-strbuf_add(sb,msg+c->encoding.off,c->encoding.len);+if(c->commit_encoding)+strbuf_addstr(sb,c->commit_encoding);return1;case'B':/* raw body *//* message_off is always left at the initial newline */
@@ -44,15 +44,15 @@ test_expect_success setup '' cat>expected<<EOF-${c_commit}COMMIT_ID(${c_HEAD}HEAD${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_HEAD}HEAD${c_reset}${c_commit},\${c_tag}tag:v1.0${c_reset}${c_commit},\${c_tag}tag:B${c_reset}${c_commit},\${c_branch}master${c_reset}${c_commit})${c_reset}B-${c_commit}COMMIT_ID(${c_tag}tag:A1${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A1${c_reset}${c_commit},\${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset}A1-${c_commit}COMMIT_ID(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\Onmaster:ChangestoA.t-${c_commit}COMMIT_ID(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A EOF# We want log to show all, but the second parent to refs/stash is irrelevant
Always assume format_commit_item() takes an utf-8 string for string
handling simplicity (we can handle utf-8 strings, but can't with other
encodings).
If commit message is in non-utf8, or output encoding is not, then the
commit is first converted to utf-8, processed, then output converted
to output encoding. This of course only works with encodings that are
compatible with Unicode.
This also fixes the iso8859-1 test in t6006. It's supposed to create
an iso8859-1 commit, but the commit content in t6006 is in UTF-8.
t6006 is now converted back in UTF-8 (the downside is we can't put
utf-8 strings there anymore).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 24 ++++++++++++++++++++++--
t/t6006-rev-list-format.sh | 12 ++++++------
2 files changed, 28 insertions(+), 8 deletions(-)
@@ -954,6 +954,44 @@ static int format_reflog_person(struct strbuf *sb,returnformat_person_part(sb,part,ident,strlen(ident),dmode);}+staticsize_tparse_color(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+if(placeholder[1]=='('){+constchar*begin=placeholder+2;+constchar*end=strchr(begin,')');+charcolor[COLOR_MAXLEN];++if(!end)+return0;+if(!prefixcmp(begin,"auto,")){+if(!want_color(c->pretty_ctx->color))+returnend-placeholder+1;+begin+=5;+}+color_parse_mem(begin,+end-begin,+"--pretty format",color);+strbuf_addstr(sb,color);+returnend-placeholder+1;+}+if(!prefixcmp(placeholder+1,"red")){+strbuf_addstr(sb,GIT_COLOR_RED);+return4;+}elseif(!prefixcmp(placeholder+1,"green")){+strbuf_addstr(sb,GIT_COLOR_GREEN);+return6;+}elseif(!prefixcmp(placeholder+1,"blue")){+strbuf_addstr(sb,GIT_COLOR_BLUE);+return5;+}elseif(!prefixcmp(placeholder+1,"reset")){+strbuf_addstr(sb,GIT_COLOR_RESET);+return6;+}else+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -967,38 +1005,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 *//* these are independent of the commit */switch(placeholder[0]){case'C':-if(placeholder[1]=='('){-constchar*begin=placeholder+2;-constchar*end=strchr(begin,')');-charcolor[COLOR_MAXLEN];--if(!end)-return0;-if(!prefixcmp(begin,"auto,")){-if(!want_color(c->pretty_ctx->color))-returnend-placeholder+1;-begin+=5;-}-color_parse_mem(begin,-end-begin,-"--pretty format",color);-strbuf_addstr(sb,color);-returnend-placeholder+1;-}-if(!prefixcmp(placeholder+1,"red")){-strbuf_addstr(sb,GIT_COLOR_RED);-return4;-}elseif(!prefixcmp(placeholder+1,"green")){-strbuf_addstr(sb,GIT_COLOR_GREEN);-return6;-}elseif(!prefixcmp(placeholder+1,"blue")){-strbuf_addstr(sb,GIT_COLOR_BLUE);-return5;-}elseif(!prefixcmp(placeholder+1,"reset")){-strbuf_addstr(sb,GIT_COLOR_RESET);-return6;-}else-return0;+returnparse_color(sb,placeholder,c);case'n':/* newline */strbuf_addch(sb,'\n');return1;
This is not simply convenient over %C(auto,xxx). Some placeholders
(actually only one, %d) do multi coloring and we can't emit a multiple
colors with %C(auto,xxx).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 3 ++-
pretty.c | 17 +++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
@@ -156,7 +156,8 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a- terminal)+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring+ on the next placeholders until the color is switched again. - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%'
@@ -778,6 +778,7 @@ struct format_commit_context {char*message;char*commit_encoding;size_twidth,indent1,indent2;+intauto_color_next;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1005,7 +1006,15 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 *//* these are independent of the commit */switch(placeholder[0]){case'C':-returnparse_color(sb,placeholder,c);+if(!prefixcmp(placeholder+1,"(auto)")){+c->auto_color_next=1;+return7;+}else{+intret=parse_color(sb,placeholder,c);+if(ret)+c->auto_color_next=0;+returnret;+}case'n':/* newline */strbuf_addch(sb,'\n');return1;
Either %<, %> or %>< standing before a placeholder specifies how many
columns (at least as the placeholder can exceed it) it takes. Each
differs on how spaces are padded:
%< pads on the right (aka left alignment)
%> pads on the left (aka right alignment)
%>< pads both ways equally (aka centered)
The (<N>) follows them, e.g. `%<(100)', to specify the number of
columns the next placeholder takes.
However, if '|' stands before (<N>), e.g. `%>|(100)', then the number
of columns is calculated so that it reaches the Nth column on screen.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 8 +++
pretty.c | 117 +++++++++++++++++++++++++++++++++++-
t/t4205-log-pretty-formats.sh | 126 +++++++++++++++++++++++++++++++++++++++
3 files changed, 250 insertions(+), 1 deletion(-)
@@ -164,6 +164,14 @@ 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>)': make the next placeholder take at least until Nth+ 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>)'+ respectively, but padding both sides (i.e. the text is centered) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will
@@ -769,16 +769,25 @@ struct chunk {size_tlen;};+enumflush_type{+no_flush,+flush_right,+flush_left,+flush_both+};+structformat_commit_context{conststructcommit*commit;conststructpretty_print_context*pretty_ctx;unsignedcommit_header_parsed:1;unsignedcommit_message_parsed:1;structsignature_checksignature_check;+enumflush_typeflush_type;char*message;char*commit_encoding;size_twidth,indent1,indent2;intauto_color_next;+intpadding;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -993,6 +1002,52 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */return0;}+staticsize_tparse_padding_placeholder(structstrbuf*sb,+constchar*placeholder,+structformat_commit_context*c)+{+constchar*ch=placeholder;+enumflush_typeflush_type;+intto_column=0;++switch(*ch++){+case'<':+flush_type=flush_right;+break;+case'>':+if(*ch=='<'){+flush_type=flush_both;+ch++;+}else+flush_type=flush_left;+break;+default:+return0;+}++/* the next value means "wide enough to that column" */+if(*ch=='|'){+to_column=1;+ch++;+}++if(*ch=='('){+constchar*start=ch+1;+constchar*end=strchr(start,')');+char*next;+intwidth;+if(!end||end==start)+return0;+width=strtoul(start,&next,10);+if(next==start||width==0)+return0;+c->padding=to_column?-width:width;+c->flush_type=flush_type;+returnend-placeholder+1;+}+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -1052,6 +1107,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */returnend-placeholder+1;}elsereturn0;++case'<':+case'>':+returnparse_padding_placeholder(sb,placeholder,c);}/* these depend on the commit */
@@ -1214,6 +1273,59 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */return0;/* unknown placeholder */}+staticsize_tformat_and_pad_commit(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+structstrbuflocal_sb=STRBUF_INIT;+inttotal_consumed=0,len,padding=c->padding;+if(padding<0){+constchar*start=strrchr(sb->buf,'\n');+intoccupied;+if(!start)+start=sb->buf;+occupied=utf8_strnwidth(start,-1,1);+padding=(-padding)-occupied;+}+while(1){+intmodifier=*placeholder=='C';+intconsumed=format_commit_one(&local_sb,placeholder,c);+total_consumed+=consumed;++if(!modifier)+break;++placeholder+=consumed;+if(*placeholder!='%')+break;+placeholder++;+total_consumed++;+}+len=utf8_strnwidth(local_sb.buf,-1,1);+if(len>padding)+strbuf_addstr(sb,local_sb.buf);+else{+intsb_len=sb->len,offset=0;+if(c->flush_type==flush_left)+offset=padding-len;+elseif(c->flush_type==flush_both)+offset=(padding-len)/2;+/*+*wecalculatepaddingincolumns,now+*convertitbacktochars+*/+padding=padding-len+local_sb.len;+strbuf_grow(sb,padding);+strbuf_setlen(sb,sb_len+padding);+memset(sb->buf+sb_len,' ',sb->len-sb_len);+memcpy(sb->buf+sb_len+offset,local_sb.buf,+local_sb.len);+}+strbuf_release(&local_sb);+c->flush_type=no_flush;+returntotal_consumed;+}+staticsize_tformat_commit_item(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -99,4 +99,130 @@ test_expect_failure 'NUL termination with --stat' 'test_i18ncmpexpectedactual'+test_expect_success'setup more commits''+test_commit"message one"oneonemessage-one&&+test_commit"message two"twotwomessage-two+'++delete_trailing_dollar(){+sed's/\$$//'+}++test_expect_success'left alignment formatting''+gitlog--pretty="format:%<(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+messagetwo$+messageone$+addbar$+initial$+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting at the nth column''+gitlog--pretty="format:%h %<|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+fa33ab1messagetwo$+7cd6c63messageone$+1711bf9addbar$+af20c06initial$+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with no padding''+gitlog--pretty="format:%<(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting''+gitlog--pretty="format:%>(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+messagetwo$+messageone$+addbar$+initial$+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting at the nth column''+gitlog--pretty="format:%h %>|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+fa33ab1messagetwo$+7cd6c63messageone$+1711bf9addbar$+af20c06initial$+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting with no padding''+gitlog--pretty="format:%>(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting''+gitlog--pretty="format:%><(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+messagetwo$+messageone$+addbar$+initial$+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting at the nth column''+gitlog--pretty="format:%h %><|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+fa33ab1messagetwo$+7cd6c63messageone$+1711bf9addbar$+af20c06initial$+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting with no padding''+gitlog--pretty="format:%><(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'+ test_done
%>(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 <redacted>
---
Documentation/pretty-formats.txt | 7 ++++--
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
t/t4205-log-pretty-formats.sh | 39 ++++++++++++++++++++++++++++++
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
5 files changed, 140 insertions(+), 5 deletions(-)
@@ -164,8 +164,11 @@ 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.+ Note that truncating only works correctly with N >= 2. - '%<|(<N>)': make the next placeholder take at least until Nth columns, padding spaces on the right if necessary - '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
@@ -147,6 +147,45 @@ EOFtest_cmpexpectedactual'+test_expect_success'left alignment formatting with trunc''+gitlog--pretty="format:%<(10,trunc)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+message..$+message..$+addbar$+initial$+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with ltrunc''+gitlog--pretty="format:%<(10,ltrunc)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+..sagetwo$+..sageone$+addbar$+initial$+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with mtrunc''+gitlog--pretty="format:%<(10,mtrunc)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+mess..two$+mess..one$+addbar$+initial$+EOF+test_cmpexpectedactual+'+ test_expect_success'right alignment formatting''gitlog--pretty="format:%>(40)%s">actual&&# complete the incomplete line at the end
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 <redacted>
---
Documentation/pretty-formats.txt | 5 ++++-
pretty.c | 34 ++++++++++++++++++++++++++++++++++
t/t4205-log-pretty-formats.sh | 14 ++++++++++++++
utf8.c | 2 +-
utf8.h | 1 +
5 files changed, 54 insertions(+), 2 deletions(-)
@@ -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
@@ -264,4 +264,18 @@ EOFtest_cmpexpectedactual'+test_expect_success'left/right alignment formatting with stealing''+gitcommit--amend-mshort--author"long long long <long@me.com>"&&+gitlog--pretty="format:%<(10,trunc)%s%>>(10,ltrunc)% an">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF|delete_trailing_dollar>expected&&+shortlonglonglong$+message..AUThor$+addbarAUThor$+initialAUThor$+EOF+test_cmpexpectedactual+'+ test_done
Torsten,
I can't compile compat/precomposed_utf8.c on linux even though I make
some changes there. Can you check if I break something? I'm pretty
sure I don't, but just in case.
On Tue, Apr 16, 2013 at 6:24 PM, Nguyễn Thái Ngọc Duy [off-list ref] wrote:
v4 fixes comments from v3, mainly in the auto-coloring patch, and uses
qz_to_tab_space for changes in t4205. It also fixes a coding style
issue in 06/13, spotted in v2 but I missed it in v3.
Nguyễn Thái Ngọc Duy (13):
pretty: save commit encoding from logmsg_reencode if the caller needs it
pretty: get the correct encoding for --pretty:format=%e
pretty-formats.txt: wrap long lines
pretty: share code between format_decoration and show_decorations
utf8.c: move display_mode_esc_sequence_len() for use by other functions
utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences
utf8.c: add reencode_string_len() that can handle NULs in string
pretty: two phase conversion for non utf-8 commits
pretty: split color parsing into a separate function
pretty: add %C(auto) for auto-coloring
pretty: support padding placeholders, %< %> and %><
pretty: support truncating in %>, %< and %><
pretty: support %>> that steal trailing spaces
Documentation/pretty-formats.txt | 35 +++-
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
compat/precompose_utf8.c | 2 +-
log-tree.c | 48 ++++--
log-tree.h | 1 +
pretty.c | 358 ++++++++++++++++++++++++++++++++-------
revision.c | 2 +-
t/t4205-log-pretty-formats.sh | 175 +++++++++++++++++++
t/t4207-log-decoration-colors.sh | 8 +-
t/t6006-rev-list-format.sh | 12 +-
utf8.c | 104 +++++++++---
utf8.h | 23 ++-
14 files changed, 648 insertions(+), 125 deletions(-)
--
1.8.2.82.gc24b958
The commit encoding is parsed by logmsg_reencode, there's no need for
the caller to re-parse it again. The reencoded message now has the new
encoding, not the original one. The caller would need to read commit
object again before parsing.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
builtin/blame.c | 2 +-
builtin/commit.c | 2 +-
commit.h | 1 +
pretty.c | 16 ++++++++++++----
revision.c | 2 +-
5 files changed, 16 insertions(+), 7 deletions(-)
@@ -2314,7 +2314,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)*init.*/encoding=get_log_output_encoding();-message=logmsg_reencode(commit,encoding);+message=logmsg_reencode(commit,NULL,encoding);/* Copy the commit to temporary if we are using "fake" headers */if(buf.len)
parse_commit_header() provides the commit encoding for '%e' and it
reads it from the re-encoded message, which contains the new encoding,
not the original one in the commit object. This never happens because
--pretty=format:xxx never respects i18n.logoutputencoding. But that's
a different story.
Get the commit encoding from logmsg_reencode() instead.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
@@ -776,12 +776,12 @@ struct format_commit_context {unsignedcommit_message_parsed:1;structsignature_checksignature_check;char*message;+char*commit_encoding;size_twidth,indent1,indent2;/* These offsets are relative to the start of the commit message. */structchunkauthor;structchunkcommitter;-structchunkencoding;size_tmessage_off;size_tsubject_off;size_tbody_off;
@@ -1185,7 +1182,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,msg+c->committer.off,c->committer.len,c->pretty_ctx->date_mode);case'e':/* encoding */-strbuf_add(sb,msg+c->encoding.off,c->encoding.len);+if(c->commit_encoding)+strbuf_addstr(sb,c->commit_encoding);return1;case'B':/* raw body *//* message_off is always left at the initial newline */
@@ -44,15 +44,15 @@ test_expect_success setup '' cat>expected<<EOF-${c_commit}COMMIT_ID(${c_HEAD}HEAD${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_HEAD}HEAD${c_reset}${c_commit},\${c_tag}tag:v1.0${c_reset}${c_commit},\${c_tag}tag:B${c_reset}${c_commit},\${c_branch}master${c_reset}${c_commit})${c_reset}B-${c_commit}COMMIT_ID(${c_tag}tag:A1${c_reset}${c_commit},\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A1${c_reset}${c_commit},\${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset}A1-${c_commit}COMMIT_ID(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\Onmaster:ChangestoA.t-${c_commit}COMMIT_ID(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A+${c_commit}COMMIT_ID${c_reset}${c_commit}(${c_tag}tag:A${c_reset}${c_commit})${c_reset}A EOF# We want log to show all, but the second parent to refs/stash is irrelevant
Always assume format_commit_item() takes an utf-8 string for string
handling simplicity (we can handle utf-8 strings, but can't with other
encodings).
If commit message is in non-utf8, or output encoding is not, then the
commit is first converted to utf-8, processed, then output converted
to output encoding. This of course only works with encodings that are
compatible with Unicode.
This also fixes the iso8859-1 test in t6006. It's supposed to create
an iso8859-1 commit, but the commit content in t6006 is in UTF-8.
t6006 is now converted back in UTF-8 (the downside is we can't put
utf-8 strings there anymore).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
pretty.c | 24 ++++++++++++++++++++++--
t/t6006-rev-list-format.sh | 12 ++++++------
2 files changed, 28 insertions(+), 8 deletions(-)
@@ -954,6 +954,44 @@ static int format_reflog_person(struct strbuf *sb,returnformat_person_part(sb,part,ident,strlen(ident),dmode);}+staticsize_tparse_color(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+if(placeholder[1]=='('){+constchar*begin=placeholder+2;+constchar*end=strchr(begin,')');+charcolor[COLOR_MAXLEN];++if(!end)+return0;+if(!prefixcmp(begin,"auto,")){+if(!want_color(c->pretty_ctx->color))+returnend-placeholder+1;+begin+=5;+}+color_parse_mem(begin,+end-begin,+"--pretty format",color);+strbuf_addstr(sb,color);+returnend-placeholder+1;+}+if(!prefixcmp(placeholder+1,"red")){+strbuf_addstr(sb,GIT_COLOR_RED);+return4;+}elseif(!prefixcmp(placeholder+1,"green")){+strbuf_addstr(sb,GIT_COLOR_GREEN);+return6;+}elseif(!prefixcmp(placeholder+1,"blue")){+strbuf_addstr(sb,GIT_COLOR_BLUE);+return5;+}elseif(!prefixcmp(placeholder+1,"reset")){+strbuf_addstr(sb,GIT_COLOR_RESET);+return6;+}else+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -967,38 +1005,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 *//* these are independent of the commit */switch(placeholder[0]){case'C':-if(placeholder[1]=='('){-constchar*begin=placeholder+2;-constchar*end=strchr(begin,')');-charcolor[COLOR_MAXLEN];--if(!end)-return0;-if(!prefixcmp(begin,"auto,")){-if(!want_color(c->pretty_ctx->color))-returnend-placeholder+1;-begin+=5;-}-color_parse_mem(begin,-end-begin,-"--pretty format",color);-strbuf_addstr(sb,color);-returnend-placeholder+1;-}-if(!prefixcmp(placeholder+1,"red")){-strbuf_addstr(sb,GIT_COLOR_RED);-return4;-}elseif(!prefixcmp(placeholder+1,"green")){-strbuf_addstr(sb,GIT_COLOR_GREEN);-return6;-}elseif(!prefixcmp(placeholder+1,"blue")){-strbuf_addstr(sb,GIT_COLOR_BLUE);-return5;-}elseif(!prefixcmp(placeholder+1,"reset")){-strbuf_addstr(sb,GIT_COLOR_RESET);-return6;-}else-return0;+returnparse_color(sb,placeholder,c);case'n':/* newline */strbuf_addch(sb,'\n');return1;
This is not simply convenient over %C(auto,xxx). Some placeholders
(actually only one, %d) do multi coloring and we can't emit a multiple
colors with %C(auto,xxx).
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 3 ++-
pretty.c | 26 +++++++++++++++++++++++---
2 files changed, 25 insertions(+), 4 deletions(-)
@@ -156,7 +156,8 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a- terminal)+ terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring+ on the next placeholders until the color is switched again. - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%'
@@ -778,6 +778,7 @@ struct format_commit_context {char*message;char*commit_encoding;size_twidth,indent1,indent2;+intauto_color;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -1005,7 +1006,20 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 *//* these are independent of the commit */switch(placeholder[0]){case'C':-returnparse_color(sb,placeholder,c);+if(!prefixcmp(placeholder+1,"(auto)")){+c->auto_color=1;+return7;/* consumed 7 bytes, "C(auto)" */+}else{+intret=parse_color(sb,placeholder,c);+if(ret)+c->auto_color=0;+/*+*Otherwise,wedecidedtotreat%C<unknown>+*asaliteralstring,andtheprevious+*%C(auto)isstillvalid.+*/+returnret;+}case'n':/* newline */strbuf_addch(sb,'\n');return1;
Either %<, %> or %>< standing before a placeholder specifies how many
columns (at least as the placeholder can exceed it) it takes. Each
differs on how spaces are padded:
%< pads on the right (aka left alignment)
%> pads on the left (aka right alignment)
%>< pads both ways equally (aka centered)
The (<N>) follows them, e.g. `%<(100)', to specify the number of
columns the next placeholder takes.
However, if '|' stands before (<N>), e.g. `%>|(100)', then the number
of columns is calculated so that it reaches the Nth column on screen.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Documentation/pretty-formats.txt | 8 +++
pretty.c | 117 ++++++++++++++++++++++++++++++++++++-
t/t4205-log-pretty-formats.sh | 122 +++++++++++++++++++++++++++++++++++++++
3 files changed, 246 insertions(+), 1 deletion(-)
@@ -164,6 +164,14 @@ 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>)': make the next placeholder take at least until Nth+ 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>)'+ respectively, but padding both sides (i.e. the text is centered) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will
@@ -769,16 +769,25 @@ struct chunk {size_tlen;};+enumflush_type{+no_flush,+flush_right,+flush_left,+flush_both+};+structformat_commit_context{conststructcommit*commit;conststructpretty_print_context*pretty_ctx;unsignedcommit_header_parsed:1;unsignedcommit_message_parsed:1;structsignature_checksignature_check;+enumflush_typeflush_type;char*message;char*commit_encoding;size_twidth,indent1,indent2;intauto_color;+intpadding;/* These offsets are relative to the start of the commit message. */structchunkauthor;
@@ -993,6 +1002,52 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */return0;}+staticsize_tparse_padding_placeholder(structstrbuf*sb,+constchar*placeholder,+structformat_commit_context*c)+{+constchar*ch=placeholder;+enumflush_typeflush_type;+intto_column=0;++switch(*ch++){+case'<':+flush_type=flush_right;+break;+case'>':+if(*ch=='<'){+flush_type=flush_both;+ch++;+}else+flush_type=flush_left;+break;+default:+return0;+}++/* the next value means "wide enough to that column" */+if(*ch=='|'){+to_column=1;+ch++;+}++if(*ch=='('){+constchar*start=ch+1;+constchar*end=strchr(start,')');+char*next;+intwidth;+if(!end||end==start)+return0;+width=strtoul(start,&next,10);+if(next==start||width==0)+return0;+c->padding=to_column?-width:width;+c->flush_type=flush_type;+returnend-placeholder+1;+}+return0;+}+staticsize_tformat_commit_one(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -1057,6 +1112,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */returnend-placeholder+1;}elsereturn0;++case'<':+case'>':+returnparse_padding_placeholder(sb,placeholder,c);}/* these depend on the commit */
@@ -1221,6 +1280,59 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */return0;/* unknown placeholder */}+staticsize_tformat_and_pad_commit(structstrbuf*sb,/* in UTF-8 */+constchar*placeholder,+structformat_commit_context*c)+{+structstrbuflocal_sb=STRBUF_INIT;+inttotal_consumed=0,len,padding=c->padding;+if(padding<0){+constchar*start=strrchr(sb->buf,'\n');+intoccupied;+if(!start)+start=sb->buf;+occupied=utf8_strnwidth(start,-1,1);+padding=(-padding)-occupied;+}+while(1){+intmodifier=*placeholder=='C';+intconsumed=format_commit_one(&local_sb,placeholder,c);+total_consumed+=consumed;++if(!modifier)+break;++placeholder+=consumed;+if(*placeholder!='%')+break;+placeholder++;+total_consumed++;+}+len=utf8_strnwidth(local_sb.buf,-1,1);+if(len>padding)+strbuf_addstr(sb,local_sb.buf);+else{+intsb_len=sb->len,offset=0;+if(c->flush_type==flush_left)+offset=padding-len;+elseif(c->flush_type==flush_both)+offset=(padding-len)/2;+/*+*wecalculatepaddingincolumns,now+*convertitbacktochars+*/+padding=padding-len+local_sb.len;+strbuf_grow(sb,padding);+strbuf_setlen(sb,sb_len+padding);+memset(sb->buf+sb_len,' ',sb->len-sb_len);+memcpy(sb->buf+sb_len+offset,local_sb.buf,+local_sb.len);+}+strbuf_release(&local_sb);+c->flush_type=no_flush;+returntotal_consumed;+}+staticsize_tformat_commit_item(structstrbuf*sb,/* in UTF-8 */constchar*placeholder,void*context)
@@ -99,4 +99,126 @@ test_expect_failure 'NUL termination with --stat' 'test_i18ncmpexpectedactual'+test_expect_success'setup more commits''+test_commit"message one"oneonemessage-one&&+test_commit"message two"twotwomessage-two+'++test_expect_success'left alignment formatting''+gitlog--pretty="format:%<(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+messagetwoZ+messageoneZ+addbarZ+initialZ+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting at the nth column''+gitlog--pretty="format:%h %<|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+fa33ab1messagetwoZ+7cd6c63messageoneZ+1711bf9addbarZ+af20c06initialZ+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with no padding''+gitlog--pretty="format:%<(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting''+gitlog--pretty="format:%>(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+Zmessagetwo+Zmessageone+Zaddbar+Zinitial+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting at the nth column''+gitlog--pretty="format:%h %>|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+fa33ab1messagetwo+7cd6c63messageone+1711bf9addbar+af20c06initial+EOF+test_cmpexpectedactual+'++test_expect_success'right alignment formatting with no padding''+gitlog--pretty="format:%>(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting''+gitlog--pretty="format:%><(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+ZmessagetwoZ+ZmessageoneZ+ZaddbarZ+ZinitialZ+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting at the nth column''+gitlog--pretty="format:%h %><|(40)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+fa33ab1messagetwoZ+7cd6c63messageoneZ+1711bf9addbarZ+af20c06initialZ+EOF+test_cmpexpectedactual+'++test_expect_success'center alignment formatting with no padding''+gitlog--pretty="format:%><(1)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+messagetwo+messageone+addbar+initial+EOF+test_cmpexpectedactual+'+ test_done
%>(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 <redacted>
---
Documentation/pretty-formats.txt | 7 ++++--
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
t/t4205-log-pretty-formats.sh | 39 ++++++++++++++++++++++++++++++
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
5 files changed, 140 insertions(+), 5 deletions(-)
@@ -164,8 +164,11 @@ 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.+ Note that truncating only works correctly with N >= 2. - '%<|(<N>)': make the next placeholder take at least until Nth columns, padding spaces on the right if necessary - '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)'
@@ -143,6 +143,45 @@ EOFtest_cmpexpectedactual'+test_expect_success'left alignment formatting with trunc''+gitlog--pretty="format:%<(10,trunc)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+message..+message..+addbarZ+initialZ+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with ltrunc''+gitlog--pretty="format:%<(10,ltrunc)%s">actual&&+# complete the incomplete line at the end+echo>>actual&&+qz_to_tab_space<<\EOF>expected&&+..sagetwo+..sageone+addbarZ+initialZ+EOF+test_cmpexpectedactual+'++test_expect_success'left alignment formatting with mtrunc''+gitlog--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+addbarZ+initialZ+EOF+test_cmpexpectedactual+'+ test_expect_success'right alignment formatting''gitlog--pretty="format:%>(40)%s">actual&&# complete the incomplete line at the end
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 <redacted>
---
Documentation/pretty-formats.txt | 5 ++++-
pretty.c | 34 ++++++++++++++++++++++++++++++++++
t/t4205-log-pretty-formats.sh | 14 ++++++++++++++
utf8.c | 2 +-
utf8.h | 1 +
5 files changed, 54 insertions(+), 2 deletions(-)
@@ -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
@@ -260,4 +260,18 @@ EOFtest_cmpexpectedactual'+test_expect_success'left/right alignment formatting with stealing''+gitcommit--amend-mshort--author"long long long <long@me.com>"&&+gitlog--pretty="format:%<(10,trunc)%s%>>(10,ltrunc)% an">actual&&+# complete the incomplete line at the end+echo>>actual&&+cat<<\EOF>expected&&+shortlonglonglong+message..AUThor+addbarAUThor+initialAUThor+EOF+test_cmpexpectedactual+'+ test_done