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.
    – mikeserv
    Sep 6, 2014 at 18:17
  • 1
    The canonical way is to write lines that are longer than 80 characters. 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.
    – user
    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)
    – Adaephon
    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/ /)
    – PythonNut
    Sep 9, 2014 at 19:36
  • @PythonNut, good point. See the edit for an alternative that addresses those. Sep 9, 2014 at 20:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .