7

I recently encountered a line of zsh code

ls_colors_parsed=${${(@s.:.)LS_COLORS}/(#m)\**=[0-9;]#/${${MATCH/(#m)[0-9;]##/$MATCH=$MATCH=04;$MATCH}/\*/'=(#b)($PREFIX:t)(?)*'}}

Not only does this burn my eyballs, it's far, far over the 80 char limit. Unfortunately, I don't see any clear way to shorten it. I have many lines like this (made of ridiculously complicated substitutions that can't be cut into pieces). What is the canonical way of handling lines like these if I want them to be <80 chars long.

2
  • 2
    You do \\n anywhere. Commented Sep 6, 2014 at 18:17
  • 1
    The canonical way is to write lines that are longer than 80 characters. Commented Sep 6, 2014 at 22:41

2 Answers 2

2

You can break long lines by escaped newlines, that is \ immediatelly followed by a newline:

ls_colors_parsed=${${(@s.:.)LS_COLORS}/(#m)\**=[0-\
9;]#/${${MATCH/(#m)[0-9;]##/$MATCH=$MATCH=04;$MATC\
H}/\*/'=(#b)($PREFIX:t)(?)*'}}

WARNING

While you can break a line that way nearly everywhere, there are exceptions. It will not work inside single quoted text or after the \ of an escape sequence (\n, \x40, ...). Some other shell constructs may break, too: If you put try to break between ($PREFIX and :t) in your example, it will not work correctly.

2
  • And if you are using indentation, it might not work exactly like you expect in some situations. Commented Sep 9, 2014 at 20:32
  • @MichaelKjörling That's right. Indentations are essentially just a bunch of spaces. So you can indent only in places where you could write the same amount of spaces in the single line version of the code: between words (as recognized By the shell) Commented Sep 9, 2014 at 22:17
1

You could do something like:

setopt extendedglob
alias 'verbose{{=read -rd "" -u9 _code 9<<-"}}";\
  eval "${_code//[[:space:]]#$'\''\n'\''[[:space:]]#}"'

verbose{{
  ls_colors_parsed=${
    ${(@s.:.)LS_COLORS}
      /(#m)\**=[0-9;]#
      /${
          ${MATCH
            /(#m)[0-9;]##
            /$MATCH=$MATCH=04;$MATCH
          }
            /\*
            /'=(#b)($PREFIX:t)(?)*'
      }
  }
}}

The newlines surrounded by spacing characters are removed before being passed to eval for interpretation.

2
  • Thanks, this could be useful, but has two shortcomings: 1. It's slower (uses a subprocess) and 2. It breaks substitutions that actually use whitespace (like ${param/ /) Commented Sep 9, 2014 at 19:36
  • @PythonNut, good point. See the edit for an alternative that addresses those. Commented Sep 9, 2014 at 20:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.