sh icon indicating copy to clipboard operation
sh copied to clipboard

syntax: don't allow multiline commands to be "inline"

Open mvdan opened this issue 4 years ago • 4 comments

We allow complex commands like for to be a single line, as long as their inner command also fits in a single line:

$ echo 'for i in 1 2 3; do if true; then foo; fi; done' | shfmt
for i in 1 2 3; do if true; then foo; fi; done

However, we have broken edge cases. For example, if the inner if turns into multiple lines due to having two commands in its body, we still allow the whole if to be "inline", even though it doesn't take a single line:

$ echo 'for i in 1 2 3; do if true; then foo; bar; fi; done' | shfmt
for i in 1 2 3; do if true; then
	foo
	bar
fi; done

The correct behavior should be:

$ echo 'for i in 1 2 3; do if true; then foo; bar; fi; done' | shfmt
for i in 1 2 3; do
	if true; then
		foo
		bar
	fi
done

mvdan avatar Aug 16 '21 12:08 mvdan

I have a similar (?) problem. Given the following code:

RUN_CMD=("$(foo)" \
  "bar")

When I format it with shfmt I get:

RUN_CMD=("$(foo)"
"bar")

The backslash is removed at the end (which is OK), but the second line is not intended. This only occurs when there is the $( as the first value in the array, with ( the issue does not occur.

Is this an issue related to this issue or shall I add a new issue (or is it no issue at all)?

michix avatar Feb 10 '22 14:02 michix

@michix that sounds like a separate issue, could you please file it? It also seems to me like removing the backslash is wrong, as it turns one command into two.

mvdan avatar Feb 14 '22 22:02 mvdan

@mvdan, I created a separate issue (#811), many thanks!

michix avatar Feb 15 '22 08:02 michix

Thanks! I misread your bit of code - removing the backslash is indeed OK, but you're right that the indentation gets mangled.

mvdan avatar Feb 19 '22 16:02 mvdan