From: "René Scharfe" <rene.scharfe@lsrfire.ath.cx>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 0/3] Generalized "string function" syntax
Date: Sat, 17 Oct 2009 23:04:19 +0200 [thread overview]
Message-ID: <4ADA3153.7070606@lsrfire.ath.cx> (raw)
In-Reply-To: <1255681702-5215-1-git-send-email-gitster@pobox.com>
Junio C Hamano schrieb:
> I mentioned an idea to enhance the pretty=format language with a
> string function syntax that people can extend by adding new functions
> in one of the "What's cooking" messages earlier. The general syntax
> would be like
>
> %[function(args...)any string here%]
>
> where "any string here" part would have the usual pretty=format
> strings. E.g. git show -s --format='%{w(72,8,4)%s%+b%]' should give
> you a line wrapped commit log message if w(width,in1,in2) is such a
> function.
I pondered line wrapping with format strings briefly a long time ago, and
I always considered it to be more similar to a colour, i.e. a state that
one can change and that is applied to all following text until the next
state change. (Except that it's always reset at the end of the format
string.) The example above would then turn into '%w(72,8,4)%s%+b'.
Here's a patch to implement this behaviour. It leaves the implementation
of the actual wrap function as an exercise to the reader, too. ;-)
pretty.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/pretty.c b/pretty.c
index f5983f8..33464f1 100644
--- a/pretty.c
+++ b/pretty.c
@@ -445,6 +445,7 @@ struct format_commit_context {
enum date_mode dmode;
unsigned commit_header_parsed:1;
unsigned commit_message_parsed:1;
+ size_t width, indent1, indent2;
/* These offsets are relative to the start of the commit message. */
struct chunk author;
@@ -458,6 +459,7 @@ struct format_commit_context {
struct chunk abbrev_commit_hash;
struct chunk abbrev_tree_hash;
struct chunk abbrev_parent_hashes;
+ size_t wrap_start;
};
static int add_again(struct strbuf *sb, struct chunk *chunk)
@@ -595,6 +597,44 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
strbuf_addch(sb, ')');
}
+static void strbuf_wrap(struct strbuf *sb, size_t pos, size_t len,
+ size_t width, size_t indent1, size_t indent2)
+{
+ struct strbuf tmp = STRBUF_INIT;
+
+ if (!len)
+ return;
+ if (pos)
+ strbuf_add(&tmp, sb->buf, pos);
+
+ /* XXX: all that's missing is the wrapping code itself.. */
+ strbuf_addf(&tmp, "w(%u,%u,%u)[\n",
+ (unsigned)width, (unsigned)indent1, (unsigned)indent2);
+ strbuf_add(&tmp, sb->buf + pos, len);
+ strbuf_addstr(&tmp, "\n]");
+
+ if (pos + len < sb->len)
+ strbuf_add(&tmp, sb->buf + pos + len, sb->len - pos - len);
+ strbuf_swap(&tmp, sb);
+ strbuf_release(&tmp);
+}
+
+static void rewrap_message_tail(struct strbuf *sb,
+ struct format_commit_context *c,
+ size_t new_width, size_t new_indent1,
+ size_t new_indent2)
+{
+ if (c->width == new_width && c->indent1 == new_indent1 &&
+ c->indent2 == new_indent2)
+ return;
+ strbuf_wrap(sb, c->wrap_start, sb->len - c->wrap_start, c->width,
+ c->indent1, c->indent2);
+ c->wrap_start = sb->len;
+ c->width = new_width;
+ c->indent1 = new_indent1;
+ c->indent2 = new_indent2;
+}
+
static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
void *context)
{
@@ -645,6 +685,30 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
return 3;
} else
return 0;
+ case 'w':
+ if (placeholder[1] == '(') {
+ unsigned long width = 0, indent1 = 0, indent2 = 0;
+ char *next;
+ const char *start = placeholder + 2;
+ const char *end = strchr(start, ')');
+ if (!end)
+ return 0;
+ if (end > start) {
+ width = strtoul(start, &next, 10);
+ if (*next == ',') {
+ indent1 = strtoul(next + 1, &next, 10);
+ if (*next == ',') {
+ indent2 = strtoul(next + 1,
+ &next, 10);
+ }
+ }
+ if (*next != ')')
+ return 0;
+ }
+ rewrap_message_tail(sb, c, width, indent1, indent2);
+ return end - placeholder + 1;
+ } else
+ return 0;
}
/* these depend on the commit */
@@ -748,7 +812,9 @@ void format_commit_message(const struct commit *commit,
memset(&context, 0, sizeof(context));
context.commit = commit;
context.dmode = dmode;
+ context.wrap_start = sb->len;
strbuf_expand(sb, format, format_commit_item, &context);
+ rewrap_message_tail(sb, &context, 0, 0, 0);
}
static void pp_header(enum cmit_fmt fmt,
next prev parent reply other threads:[~2009-10-17 21:04 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-16 8:28 [PATCH 0/3] Generalized "string function" syntax Junio C Hamano
2009-10-16 8:28 ` [PATCH 1/3] format_commit_message(): fix function signature Junio C Hamano
2009-10-17 21:04 ` René Scharfe
2009-10-16 8:28 ` [PATCH 2/3] strbuf_nested_expand(): allow expansion to interrupt in the middle Junio C Hamano
2009-10-16 11:30 ` Johannes Schindelin
2009-10-16 17:22 ` Junio C Hamano
2009-10-16 8:28 ` [PATCH 3/3] Add proof-of-concept %[w(width,in1,in2)<<any-string>>%] implementation Junio C Hamano
2009-10-16 11:32 ` Johannes Schindelin
2009-10-16 17:25 ` Junio C Hamano
2009-10-16 18:02 ` Jakub Narebski
2009-10-16 19:01 ` Junio C Hamano
2009-10-16 22:19 ` Jakub Narebski
2009-10-16 23:23 ` Junio C Hamano
2009-10-17 0:00 ` Jakub Narebski
2009-10-17 0:18 ` Junio C Hamano
2009-10-17 21:04 ` René Scharfe [this message]
2009-10-18 4:18 ` [PATCH 0/3] Generalized "string function" syntax Junio C Hamano
2009-10-18 8:24 ` René Scharfe
2009-10-18 22:47 ` Junio C Hamano
2009-10-19 23:07 ` René Scharfe
2009-10-19 23:18 ` Junio C Hamano
2009-11-08 1:02 ` René Scharfe
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=4ADA3153.7070606@lsrfire.ath.cx \
--to=rene.scharfe@lsrfire.ath.cx \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).