elves / elvish

Powerful scripting language & versatile interactive shell
https://elv.sh/
BSD 2-Clause "Simplified" License
5.67k stars 299 forks source link

Add a way to disable indentation of multi-line commands #1834

Open occivink opened 1 month ago

occivink commented 1 month ago

What new feature should Elvish have?

The editor currently indents multi-line such that they're all aligned with the end of the prompt, like this:

~ my-nice-prompt > some-really-long-com
                   mand --with-long-arg
                   uments --which-cause
                   -wrapping

This is visually pleasing, but makes it inconvenient to copy-paste the command (or parts of it) since a lot of whitespace will be introduced. It would be nice to have an option to enable/disable this behavior, as in my opinion the indentation is not worth the copying troubles.

For info, other shells don't seem to do this kind of indentation.

Output of "elvish -version"

0.20.0-dev.0.20230826021805-1c0cffbfed89

Code of Conduct

xiaq commented 3 days ago

Spent a bit of time looking into this while I'm rewriting the TUI.

It's relatively easy to add an API for disabling indentation. But there's a more tricky issue - Elvish also manages line breaks itself instead of using the terminal's own soft line breaks. This means that in the example above:

~ my-nice-prompt > some-really-long-com
                   mand --with-long-arg
                   uments --which-cause
                   -wrapping

The line breaks at the end of each line is actually a hard line break; so even if we get rid of the indentation, you still have those line breaks to deal with.

Preserving soft line breaks is not exactly straightforward, especially in shells with more interactive features. Zsh seems to get this wrong: on my macOS machine using iTerm 2 with zsh 5.9 (arm64-apple-darwin24.0), if I type a long single-line command that spans multiple lines and then copy the command line, I get hard line breaks in between. Bash and Fish do get this correct, to their credits.

It's definitely still possible, but probably not something I'll work on at the moment.

On the other hand, I thought that the following workaround should work:

# Run this in a mini-buffer, or in a keybinding:
edit:notify $edit:current-command

This does get rid of the indentation, but unfortunately it still doesn't get rid of the hard line breaks. I'll push a fix that makes this workaround work soon, though.