From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 8/9] pretty: support truncating in %>, %< and %><
Date: Sun, 23 Sep 2012 16:10:32 +0700 [thread overview]
Message-ID: <1348391433-11300-9-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1348391433-11300-1-git-send-email-pclouds@gmail.com>
%>(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 <pclouds@gmail.com>
---
Documentation/pretty-formats.txt | 2 +-
pretty.c | 51 +++++++++++++++++++++++++++++++++++++---
utf8.c | 46 ++++++++++++++++++++++++++++++++++++
utf8.h | 2 ++
4 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 49d29ab..3f056dc 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -152,7 +152,7 @@ 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
- '%<|(<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)
diff --git a/pretty.c b/pretty.c
index d169673..673193e 100644
--- a/pretty.c
+++ b/pretty.c
@@ -624,6 +624,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;
@@ -631,6 +638,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;
@@ -956,7 +964,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)
@@ -966,6 +974,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;
@@ -1197,9 +1222,29 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */
}
consumed = format_commit_one(&local_sb, placeholder, c);
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 {
int sb_len = sb->len, offset;
switch (c->flush_type) {
case flush_left:
diff --git a/utf8.c b/utf8.c
index 791499e..095c5ff 100644
--- a/utf8.c
+++ b/utf8.c
@@ -422,6 +422,52 @@ int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
return r;
}
+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)
{
if (!name)
diff --git a/utf8.h b/utf8.h
index 58d5b6b..0451a70 100644
--- a/utf8.h
+++ b/utf8.h
@@ -13,6 +13,8 @@ int strbuf_add_wrapped_text(struct strbuf *buf,
const char *text, int indent, int indent2, int width);
int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
int indent, int indent2, int width);
+void strbuf_utf8_replace(struct strbuf *sb, int pos, int width,
+ const char *subst);
#ifndef NO_ICONV
char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv);
--
1.7.12.1.406.g6ab07c4
next prev parent reply other threads:[~2012-09-23 9:18 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-22 4:22 [PATCH 0/6] Advanced --oneline layout Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 1/6] pretty: share code between format_decoration and show_decorations Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 2/6] pretty: split parsing %C into a separate function Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 3/6] pretty: support %C(auto[,N]) to turn on coloring on next placeholder(s) Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 4/6] utf8.c: move display_mode_esc_sequence_len() for use by other functions Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 5/6] utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences Nguyễn Thái Ngọc Duy
2012-09-22 4:22 ` [PATCH 6/6] pretty: support padding placeholders, %< %> and %<> Nguyễn Thái Ngọc Duy
2012-09-22 4:26 ` [PATCH 7/6] pretty: trim trailing spaces due to padding Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH v2 0/9] Advanced --oneline layout Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 1/9] pretty: share code between format_decoration and show_decorations Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 2/9] pretty: split parsing %C into a separate function Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 3/9] pretty: support %C(auto[,N]) to turn on coloring on next placeholder(s) Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 4/9] utf8.c: move display_mode_esc_sequence_len() for use by other functions Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 5/9] utf8.c: add utf8_strnwidth() with the ability to skip ansi sequences Nguyễn Thái Ngọc Duy
2012-09-23 9:10 ` [PATCH 6/9] pretty: two phase conversion for non utf-8 commits Nguyễn Thái Ngọc Duy
2012-09-23 13:54 ` Robin Rosenberg
2012-09-24 1:21 ` Nguyen Thai Ngoc Duy
2012-09-23 9:10 ` [PATCH 7/9] pretty: support padding placeholders, %< %> and %>< Nguyễn Thái Ngọc Duy
2012-10-24 8:25 ` Jeff King
2012-09-23 9:10 ` Nguyễn Thái Ngọc Duy [this message]
2012-09-23 9:10 ` [PATCH 9/9] pretty: support %>> that steal trailing spaces Nguyễn Thái Ngọc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1348391433-11300-9-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.