Why are some (often long) commands garbled in bash & zsh?

Your prompt string probably has incorrectly escaped nonprinting characters. If you have anything like color changes in your prompt, you need to put \[ and \] around the terminal escape sequences so bash can tell that they don't take up space on screen — otherwise it miscalculates where the actual command is on screen, and updates it in the wrong place. See this section from TLDP. In zsh, put %{ and %} around escape sequences.