From: Karthik Nayak <karthik.188@xxxxxxxxx> Add a new atom "align" and support %(align:X) where X is a number. This will align the preceeding atom value to the left followed by spaces for a total length of X characters. If X is less than the item size, the entire atom value is printed. Helped-by: Duy Nguyen <pclouds@xxxxxxxxx> Helped-by: Junio C Hamano <gitster@xxxxxxxxx> Mentored-by: Christian Couder <christian.couder@xxxxxxxxx> Mentored-by: Matthieu Moy <matthieu.moy@xxxxxxxxxxxxxxx> Signed-off-by: Karthik Nayak <karthik.188@xxxxxxxxx> --- ref-filter.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++-------------- ref-filter.h | 6 ++++ 2 files changed, 77 insertions(+), 22 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 7561727..3c90ffc 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -10,6 +10,8 @@ #include "quote.h" #include "ref-filter.h" #include "revision.h" +#include "utf8.h" +#include "git-compat-util.h" typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; @@ -53,6 +55,7 @@ static struct { { "flag" }, { "HEAD" }, { "color" }, + { "align" }, }; /* @@ -597,7 +600,8 @@ static inline char *copy_advance(char *dst, const char *src) /* * Parse the object referred by ref, and grab needed value. */ -static void populate_value(struct ref_array_item *ref) +static void populate_value(struct ref_formatting_state *state, + struct ref_array_item *ref) { void *buf; struct object *obj; @@ -620,7 +624,7 @@ static void populate_value(struct ref_array_item *ref) const char *name = used_atom[i]; struct atom_value *v = &ref->value[i]; int deref = 0; - const char *refname; + const char *refname = NULL; const char *formatp; struct branch *branch = NULL; @@ -687,6 +691,18 @@ static void populate_value(struct ref_array_item *ref) else v->s = " "; continue; + } else if (starts_with(name, "align:")) { + const char *valp = NULL; + + skip_prefix(name, "align:", &valp); + if (!valp[0]) + die(_("no value given with 'align:'")); + if (strtoul_ui(valp, 10, &state->pad_to_right)) + die(_("positive integer expected after ':' in align:%u\n"), + state->pad_to_right); + v->pseudo_atom = 1; + v->s = ""; + continue; } else continue; @@ -809,10 +825,15 @@ static void populate_value(struct ref_array_item *ref) * Given a ref, return the value for the atom. This lazily gets value * out of the object by calling populate value. */ -static void get_ref_atom_value(struct ref_array_item *ref, int atom, struct atom_value **v) +static void get_ref_atom_value(struct ref_formatting_state *state, + struct ref_array_item *ref, int atom, struct atom_value **v) { - if (!ref->value) { - populate_value(ref); + /* + * If the atom is a pseudo_atom then we re-populate the value + * into the ref_formatting_state stucture. + */ + if (!ref->value || ref->value[atom].pseudo_atom) { + populate_value(state, ref); fill_missing_values(ref->value); } *v = &ref->value[atom]; @@ -1150,9 +1171,12 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru struct atom_value *va, *vb; int cmp; cmp_type cmp_type = used_atom_type[s->atom]; + struct ref_formatting_state state; - get_ref_atom_value(a, s->atom, &va); - get_ref_atom_value(b, s->atom, &vb); + memset(&state, 0, sizeof(state)); + + get_ref_atom_value(&state, a, s->atom, &va); + get_ref_atom_value(&state, b, s->atom, &vb); switch (cmp_type) { case FIELD_STR: cmp = strcmp(va->s, vb->s); @@ -1190,30 +1214,50 @@ void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array) qsort(array->items, array->nr, sizeof(struct ref_array_item *), compare_refs); } -static void print_value(struct atom_value *v, int quote_style) +static void ref_formatting(struct ref_formatting_state *state, struct atom_value *v, + struct strbuf *value) { - struct strbuf sb = STRBUF_INIT; - switch (quote_style) { + if (state->pad_to_right) { + if (!is_utf8(v->s)) + strbuf_addf(value, "%-*s", state->pad_to_right, v->s); + else { + int len = strlen(v->s) - utf8_strwidth(v->s); + strbuf_addf(value, "%-*s", state->pad_to_right + len, v->s); + } + } else + strbuf_addf(value, "%s", v->s); +} + +static void print_value(struct ref_formatting_state *state, struct atom_value *v) +{ + struct strbuf value = STRBUF_INIT; + struct strbuf formatted = STRBUF_INIT; + + if (v->pseudo_atom) + return; + ref_formatting(state, v, &value); + + switch (state->quote_style) { case QUOTE_NONE: - fputs(v->s, stdout); + fputs(value.buf, stdout); break; case QUOTE_SHELL: - sq_quote_buf(&sb, v->s); + sq_quote_buf(&formatted, value.buf); break; case QUOTE_PERL: - perl_quote_buf(&sb, v->s); + perl_quote_buf(&formatted, value.buf); break; case QUOTE_PYTHON: - python_quote_buf(&sb, v->s); + python_quote_buf(&formatted, value.buf); break; case QUOTE_TCL: - tcl_quote_buf(&sb, v->s); + tcl_quote_buf(&formatted, value.buf); break; } - if (quote_style != QUOTE_NONE) { - fputs(sb.buf, stdout); - strbuf_release(&sb); - } + if (state->quote_style != QUOTE_NONE) + fputs(formatted.buf, stdout); + strbuf_release(&formatted); + strbuf_release(&value); } static int hex1(char ch) @@ -1257,6 +1301,10 @@ static void emit(const char *cp, const char *ep) void show_ref_array_item(struct ref_array_item *info, const char *format, int quote_style) { const char *cp, *sp, *ep; + struct ref_formatting_state state; + + memset(&state, 0, sizeof(state)); + state.quote_style = quote_style; for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) { struct atom_value *atomv; @@ -1264,8 +1312,9 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu ep = strchr(sp, ')'); if (cp < sp) emit(cp, sp); - get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv); - print_value(atomv, quote_style); + get_ref_atom_value(&state, info, + parse_ref_filter_atom(sp + 2, ep), &atomv); + print_value(&state, atomv); } if (*cp) { sp = cp + strlen(cp); @@ -1278,7 +1327,7 @@ void show_ref_array_item(struct ref_array_item *info, const char *format, int qu if (color_parse("reset", color) < 0) die("BUG: couldn't parse 'reset' as a color"); resetv.s = color; - print_value(&resetv, quote_style); + print_value(&state, &resetv); } putchar('\n'); } diff --git a/ref-filter.h b/ref-filter.h index 6bf27d8..ea2d0e6 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -19,6 +19,7 @@ struct atom_value { const char *s; unsigned long ul; /* used for sorting when not FIELD_STR */ + unsigned int pseudo_atom : 1; /* atoms which aren't placeholders for ref attributes */ }; struct ref_sorting { @@ -27,6 +28,11 @@ struct ref_sorting { unsigned reverse : 1; }; +struct ref_formatting_state { + unsigned int pad_to_right; /*pad atoms to the right*/ + int quote_style; +}; + struct ref_array_item { unsigned char objectname[20]; int flag; -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html