Subject: Re: [PATCH] pretty-print: de-tabify indented logs to make things line up properly

From: Junio C Hamano <[email-masked]>
Date: Wed, 16 Mar 2016 12:32:36 -0700

Linus Torvalds <[email-masked]> writes:

> On Wed, Mar 16, 2016 at 11:01 AM, Junio C Hamano <[email-masked]> wrote:
>>
>>  (1) if turning your "preparation; do { ... } while()" into
>>      "while () { }" would make the result a bit easier to read;
>
> So it's probably partly taste, but I will also disagree with your
> "easier to read", because of the way the code is logically structured.
>
> In particular, the "no TAB" case is actually *fundamentally* different
> from the "no TAB at the end" case. The return value is different, and
> the caller does very different things - the code tries to make it very
> clear that that "no TAB" situation is very different from "we found a
> TAB".
>
> So it's not "preparation + do-while".
>
> It's "preparation + handle the no-TAB case differently", and then the
> "do-while" is very natural because by the time we get to the "ok, we
> are now going to need to do something about the line" stage, we
> already know we have a tab.

OK, I agree with that viewpoint; retracted.

>>  (2) if we can somehow eliminate duplication of "tab + 1" (spelled
>>      differently on the previous line as "1+tab"), the end result
>>      may get easier to follow.
>
> Yeah, I considered that. Either by just doing "tab++" before (so the
> +1" would come from that in both cases), or by introducing a new
> variable like
>
>     ptrdiff_t bytes_used;
>     ...
>     bytes_used = 1 + tab - line;
>
> and then just doing
>
>     line += bytes_used;
>     linelen -= bytes_used;
>
> and the code I wrote just didn't do any of those temporary updates,
> and instead just did the "+1" by hand in both cases.

The above is most likely what I would have written if I were doing
this patch.  I could squash it to save a round-trip, but let me run
the testsuite first to see if we need adjustments to existing tests.

Also your idea:

> But the code *could* be made to just always do the whole
> "strbuf_add()", and not return a return value at all, and the no-tab
> case wouldn't be explicitly written to be different.

may give us a better structure if we are going to give users a knob
to disable this tab expansion, i.e. move the addition of 4 spaces to
the caller, name the body of such a function strbuf_expand_add(),
and then make the caller do something like this perhaps?

@@ -1723,10 +1711,14 @@ void pp_remainder(struct pretty_print_context *pp,
 
 		strbuf_grow(sb, linelen + indent + 20);
 		if (indent) {
-			if (pp_handle_indent(sb, indent, line, linelen))
-				linelen = 0;
+			strbuf_addchars(sb, ' ', indent);
+			if (pp->fmt == CMIT_FMT_EXPAND_TABS)
+				strbuf_expand_add(sb, line, linelen);
+			else
+				strbuf_add(sb, line, linelen);
+		} else {
+			strbuf_add(sb, line, linelen);
 		}
-		strbuf_add(sb, line, linelen);
 		strbuf_addch(sb, '\n');
 	}
 }