From: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>

The struct pretty_print_context contains the context in which the
placeholders in format_commit_one() should be parsed.  Although
format_commit_one() primarily acts as a parser, there is no way for a
caller to plug in custom callbacks.  Now, callers can:

1. Parse a custom placeholder that is not supported by
   format_commit_one(), and act on it independently of the pretty
   machinery.

2. Parse a custom placeholder to substitute the custom placeholder with
   a placeholder that format_commit_one() understands.  This is
   especially useful for supporting %>(*), where * is substituted with a
   length computed by the caller.

To support these two usecases, the interface for the function looks
like:

typedef size_t (*format_message_fn)(struct strbuf *sb,
                                const char *placeholder,
                                void *format_context,
                                void *user_data,
                                struct strbuf *placeholder_subst)

It is exactly like format_commit_one(), except that there are two
additional fields: user_data (to pass custom data to the callback), and
placeholder_subst (to set the substitution).  The callback should return
the length of the original string parsed, and optionally set
placeholder_subst.

[rr: commit message, minor modifications]

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artag...@gmail.com>
---
 commit.h |  8 ++++++++
 pretty.c | 25 +++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/commit.h b/commit.h
index 6e9c7cd..38dc0c0 100644
--- a/commit.h
+++ b/commit.h
@@ -78,6 +78,12 @@ enum cmit_fmt {
        CMIT_FMT_UNSPECIFIED
 };
 
+typedef size_t (*format_message_fn)(struct strbuf *sb,
+                               const char *placeholder,
+                               void *format_context,
+                               void *user_data,
+                               struct strbuf *placeholder_subst);
+
 struct pretty_print_context {
        enum cmit_fmt fmt;
        int abbrev;
@@ -92,6 +98,8 @@ struct pretty_print_context {
        const char *output_encoding;
        struct string_list *mailmap;
        int color;
+       format_message_fn format;
+       void *user_data;
 };
 
 struct userformat_want {
diff --git a/pretty.c b/pretty.c
index 9e43154..095e5ba 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1069,6 +1069,31 @@ static size_t format_commit_one(struct strbuf *sb, /* in 
UTF-8 */
        struct commit_list *p;
        int h1, h2;
 
+       if (c->pretty_ctx->format) {
+               struct strbuf subst = STRBUF_INIT;
+               int ret = c->pretty_ctx->format(sb, placeholder, context,
+                                               c->pretty_ctx->user_data,
+                                               &subst);
+               if (ret && subst.len) {
+                       /*
+                        * Something was parsed by format(), and a
+                        * placeholder-substitution was set.
+                        * Recursion is required to override the
+                        * return value of format_commit_one() with
+                        * ret: the length of the original string
+                        * before substitution.
+                        */
+                       ret = format_commit_one(sb, subst.buf, context) ? ret : 
0;
+                       strbuf_release(&subst);
+                       return ret;
+               } else if (ret)
+                       /*
+                        * Something was parsed by format(), but
+                        * no placeholder-substitution was set.
+                        */
+                       return ret;
+       }
+
        /* these are independent of the commit */
        switch (placeholder[0]) {
        case 'C':
-- 
1.8.3.247.g485169c

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to