从历史记录中提取的多行zsh命令中插入换行符

44
有时我在zsh中使用多行命令:
❯ echo \
> a \
> multiline \
> command

从历史搜索中拉取命令后进行编辑时,我可以更改单个行的内容。但是,我不知道如何插入另一行:

# I want to insert another line after "multiline"...echo \
> a \
> multiline \  # but hitting <return> here just runs the command, even though there's a backslash at the end of the line
> command

我怎样在从历史记录中取出的多行命令的中间插入一个换行符?


http://unix.stackexchange.com/questions/6620/how-to-edit-command-line-in-full-screen-editor-in-zsh - chepner
@chepner 太棒了,非常好。请写一个答案,解释得更详细一些,这样我就可以接受它了。 - Sean Mackesey
7个回答

55
你可以使用ESC-Return
顺便说一下,我在Debian Jessie、zsh 5.0.7上测试过,那里可行。

44
您可以使用self-insert-unmetaAlt+Return绑定到插入文字换行,而不接受命令:
bindkey '^[^M' self-insert-unmeta

使用您的示例:在光标位置(#)按下Alt+Return键。
% echo \
a \
multiline \#
command

将会给您带来以下内容:

% echo \
a \
multiline \
#
command

这不仅适用于修改历史命令,也适用于输入命令。因此,您可以像脚本一样准备多个命令,并通过单个 Return 键接受它们。

例如,在此示例中按下 Alt+Return 而不是 #:

% echo command 1#
echo command 2#
echo command 3

执行命令 echo command 1; echo command 2; echo command 3 会产生与此相同的输出:

command 1
command 2
command 3

3
我知道在 Stack Overflow 上不应该感谢别人,但我还是想表达我的感激。谢谢 :D 现在我可以创建一个带有 here document 的多行命令并对其进行执行时更改,而不会打印出 heredoc> 并阻止我编辑它,方法如下:bindkey -s "^[t" 'sh <<EOF ^[^Mecho "compilation step 1 (optional)"; ^[^Mecho "compilation step 2 (mandatory)" ^[^MEOF^[[A^[[A^[[H' - Sridhar Sarnobat
由于某种原因,在我的情况下,这已经可以正常工作了,而无需进行任何操作。(使用Ubuntu 18.04+oh-my-zsh) - Michael
1
对于我来说,在MacOS 10.12.6和iTerm 3.2.7beta4上,这并没有起作用。 - JamieJag
当使用 Oh-My-Zsh 的 Zsh-vi-mode 插件时,在我的启动文件中设置的这个绑定似乎被覆盖或删除了。(在启动新终端后,它不会出现在 bindkey 中,但如果我直接在命令行中键入 bindkey '^[^M' self-insert-unmeta,它仍然有效。)一个解决方法是只在 vi 插入模式键映射中提供此键绑定:bindkey -M viins '^[^M' self-insert-unmeta。@adaephon,感谢您让我完成了 90% 的工作。 - Jonathan Wheeler

7

(摘自https://unix.stackexchange.com/questions/6620/how-to-edit-command-line-in-full-screen-editor-in-zsh的回答总结)

zsh 自带一个函数,可以用来在您喜欢的编辑器中打开当前命令行。将以下行添加到您的 .zshrc 文件中:

autoload -z edit-command-line
zle -N edit-command-line
bindkey "^X^E" edit-command-line

第一行加载函数。第二行从同名函数中为Z Shell行编辑器(zle)创建一个新的小部件。第三行将该小部件绑定到 Control-X Control-E。如果您使用的是vi绑定而不是emacs键绑定,请使用类似以下内容的命令:

bindkey -M vicmd v edit-command-line

而是使用 vicmd 模式下将小部件绑定到 v 键。


你的回答非常好,但是我必须更改已接受的答案,因为@Adaephon的回答更直接。 - Sean Mackesey
这个命令完全搞乱了我的终端。请提供如何撤销这些设置的命令? - saumilsdk
@saumilsdk,当您的终端出现混乱的能力时,您可以随时使用“stty sane”。我相信它可能会解决您的问题。 - Diti
这里不会影响终端设置。这只是zsh行编辑器的配置。 - chepner

4

如果使用bindkey -v模式,您也可以使用默认的o/O命令从vicmd模式添加一个新行,并在当前行上方或下方进入insert模式。


2

请注意,如果您想在多行命令中添加注释,可以使用以下方法:

❯ echo `#first comment` \
 a `#second comment` \
 multiline \
 command

0

Windows/WSL 按下 CTRL + Enter (回车) Mac 按下 CTRL +X CTRL+E

根据下面的评论进行了编辑


1
在我的MacOS上实际有效的是 Ctr+X Ctr+E - 因此按住 Ctr 按下 X 键,然后再按下 E 键。 - vasigorc

-1

听起来使用一个 shell 脚本文件是一个合适的地方,不是吗?

#!/bin/zsh
my
commands
here
I can even add a new line at a later time.

谢谢,但我不同意。如果您正在运行具有复杂命令行界面的程序的多个变体,则Shell的历史搜索提供了一种通过以前的运行进行搜索和分叉的绝佳方式。如果您将每个配置存储在文件中,则无法获得此功能。 - Sean Mackesey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接