mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
6.97k stars 332 forks source link

Unexpected reformatting of multi-line commands #1045

Open AxelKrypton opened 7 months ago

AxelKrypton commented 7 months ago

A bash command split on multiple lines without a space before \ gets reformatted.

$ printf 'my_command\\\n    split\n'
my_command\
    split
$ shfmt -ln bash -i 4 < <(printf 'my_command\\\n    split\n')
my_command split
$ shfmt -ln bash -i 4 < <(printf 'my_command \\\n    split\n')
my_command \
    split

I am not sure whether this is an expected behaviour, but I was surely surprised by this. I also did not find an answer in existing issues or discussions.

To give some context, I read about the (many) discussions asking for having a maximum length option (e.g. #80). In projects where there is a maximum line length enforcement, we split lines by hand using \ and I'd like shfmt not to change that, especially because then lines would often exceed the maximum length.

Is this behaviour intended?

AxelKrypton commented 7 months ago

In the description above my_command was e.g. any possible user function. For some builtins like printf the behaviour is different1.

$ shfmt -ln bash -i 4 < <(printf '%s\\\n    %s\n' "printf '%s\n'" 'My string')
printf '%s\n' \
    My string
$ shfmt -ln bash -i 4 < <(printf '%s \\\n    %s\n' "printf '%s\n'" 'My string')
printf '%s\n' \
    My string

Maybe someone can shed some light on this. It might well be that I am missing something here. 🤔

1Sorry for the process substitution brain-gymnastic, it is definitely not something I would use in a real script, but it was the most compact way to offer something to play with in a terminal.