在zsh中回显所有的别名

7

你是否可以强制zsh在使用别名时输出所有别名所引用的实际命令?

例如,假设我设置了以下别名:

# List direcory contents
alias lsa='ls -lah'
alias l='ls -la'
alias ll='ls -l'

当我执行它们时,我希望能看到每个命令实际执行的内容。例如,我想看到以下内容:
$ ll
executing: 'ls -l'
total 0
-rw-r--r--  1 person  staff  0 Feb 15 13:46 cool.txt
-rw-r--r--  1 person  staff  0 Feb 15 13:46 sweet.html
-rw-r--r--  1 person  staff  0 Feb 15 13:46 test.md

不是以下这种方式:

$ ll
total 0
-rw-r--r--  1 person  staff  0 Feb 15 13:46 cool.txt
-rw-r--r--  1 person  staff  0 Feb 15 13:46 sweet.html
-rw-r--r--  1 person  staff  0 Feb 15 13:46 test.md

有没有一条命令可以添加到我的zshrc文件中,使得所有别名都能实现这个功能?我不想修改每个别名。


set -vx;myAlias args; set+vx 这样做并不能得到你想要的结果(不包括“执行:”前缀)。祝好运。 - shellter
很遗憾,我正在寻找一种可以设置一次并适用于所有别名的方法,而不与它们耦合。即使我为每个别名都这样做了,它仍然会倾倒大量关于别名和函数的信息,以创建我的自定义zsh提示。谢谢您的评论!我非常感激您的帮助。 - Aaron Massey
2个回答

9
如果你希望在命令行中显示别名,可以尝试将以下代码放入你的 .zshrc 文件中:
_-accept-line () {
    emulate -L zsh
    local -a WORDS
    WORDS=( ${(z)BUFFER} )
    # Unfortunately ${${(z)BUFFER}[1]} works only for at least two words,
    # thus I had to use additional variable WORDS here.
    local -r FIRSTWORD=${WORDS[1]}
    local -r GREEN=$'\e[32m' RESET_COLORS=$'\e[0m'
    [[ "$(whence -w $FIRSTWORD 2>/dev/null)" == "${FIRSTWORD}: alias" ]] &&
        echo -nE $'\n'"${GREEN}Executing $(whence $FIRSTWORD)${RESET_COLORS}"
    zle .accept-line
}
zle -N accept-line _-accept-line

描述(省略了一些琐碎的东西):

emulate -L zsh # Reset some options to zsh defaults (locally).
               # Makes function immune to user setup.

local -a WORDS # Declare WORDS as an array local to function

${(z)VARNAME}  # Split VARNAME using command-line parser.
               # Things like “"first word" "second word"” get split into 2 words:
               # “"first word"” “"second word"”

$BUFFER        # Variable containing the whole command-line. Can be modified

local -r V     # Declare variable “V” as read-only

$'\e[32m'      # Escape code for green foreground color in most terminals
$'\e[0m'       # Sequence that being echoed to terminal clears out color information

whence -w cmd  # Display type of the command in format “cmd: type”
whence cmd     # If “cmd” is an alias, then this command outputs alias value

zle .accept-line # Call internal zle “accept-line” widget. This must be done or 
               # every command will turn to no-op. You can, of course, replace
               # this with “eval $BUFFER” but I can’t say what will break in this case

zle -N accept-line _-accept-line # Associate widget “accept-line” with function
               # “_-accept-line”. This makes this function responsible for accepting
               # lines.

更多信息请参见man zshbuiltinsemulatewhencelocal),man zshzlezle$BUFFER),man zshparam${(z)})。


干得好!我已经将这个作为答案接受了,但是如果您能够向我解释一下,我会非常感激。我不确定您是如何完成的,但我很想学习。无论如何,谢谢! - Aaron Massey
这非常非常有帮助。感谢您的解释!非常感激。 :-) - Aaron Massey

1

感谢ZyX。我修改了他的答案,使其也适用于函数。这是代码:

_-accept-line () {
    emulate -L zsh
    local -a WORDS
    WORDS=( ${(z)BUFFER} )
    # Unfortunately ${${(z)BUFFER}[1]} works only for at least two words,
    # thus I had to use additional variable WORDS here.
    local -r FIRSTWORD=${WORDS[1]}
    local -r GREEN=$'\e[32m' RESET_COLORS=$'\e[0m'
    [[ "$(whence -w $FIRSTWORD 2>/dev/null)" == "${FIRSTWORD}: alias" ]] &&
        echo -nE $'\n'"${GREEN}Executing -> ${$(which $FIRSTWORD)//"$FIRSTWORD: aliased to "/""}${RESET_COLORS}"
    [[ "$(whence -w $FIRSTWORD 2>/dev/null)" == "${FIRSTWORD}: function" ]] &&
        echo -nE $'\n'"${GREEN}Executing -> ${$(which $FIRSTWORD)//"$FIRSTWORD () {
    "/""}${RESET_COLORS}"
    zle .accept-line
}
zle -N accept-line _-accept-line

PS:这是在紧急情况下开发的。当然,它可以得到改进。


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