将 'out' 个变量传递给函数

Passing 'out' variables to function

我试图让我的 fish_prompt 更漂亮,方法是让我的用户名和主机的颜色根据它们是什么而变化。但是,如果此尝试失败,我宁愿将颜色保留为默认值 $fish_color_[host|user] 到目前为止,这是有效的:

function fish_prompt
    # …
    set -l color_host $fish_color_host
    if command -qs shasum
        set color_host (colorize (prompt_hostname))
    end
    # …
    echo -n -s \
        (set_color --bold $color_user)      "$USER" \
        (set_color normal)                  @ \
        (set_color $color_host)             (prompt_hostname) \
        ' ' \
        (set_color --bold $color_cwd)       (prompt_pwd) \
        (set_color normal)                  " $suffix "
end

function colorize
    echo -n (printf "$argv" | shasum -ta 256 - | cut -c 59-64 | tr -d '\n')
end

在这一点上,我认为如果 shasum 检查在 colorize 中而不是在 fish_prompt 中重复,这看起来会更清晰。然后我尝试了这个,认为如果我单引号我可以传递变量名:

function fish_prompt
    # …
    set -l color_user $fish_color_user
    colorize_more 'color_user' "$USER"
    # …
end

function colorize_more -a what -a whence
    if command -qs shasum
        set "$what" (printf "$whence" | shasum -ta 256 - | cut -c 59-64 | tr -d '\n')
    end
end

但是,fish_prompt 中的 $color_user 似乎没有改变。我怀疑这是因为 colorize_more 中的 set 无法修改 fish_prompt 中的变量的局部变量,因为 应该 出现的颜色colorize_more 中的黄色而不是我从 $fish_color_user 中得到的绿色。

我如何重组我的 fish_prompt 和辅助函数,以便我有一个 colorize 函数,仅在它能够时将变量设置为某个值?

这里有多种可能性。

一个是 function

的“--no-scope-shadowing”标志
function colorize_more -a what -a whence --no-scope-shadowing

这将使外部局部作用域保持可见。这不适用于例如$argv,如果你需要任何变量,它们可能会覆盖外部定义的变量,所以要小心使用。

另一种方法是将变量定义为全局变量 - 这样做的缺点是它们将保持定义状态并且会与任何同名的全局变量发生冲突。

另一种是输出值而不是赋值

例如

function colorize_more -a whence
    if command -qs shasum
        echo (printf "$whence" | shasum -ta 256 - | cut -c 59-64 | tr -d '\n')
    end
end

set -l color_user (colorize_more $USER)
set -q color_user[1]; or set color_user $fish_color_user
# or you could let colorize_more output $fish_color_user if it wouldn't output anything else

受到 faho 对 "Another is to output the value instead of assigning it" 的评论的启发,我最终这样做了:

function fish_prompt --description 'Write out the prompt'
    # …

    set -l color_host (colorize (prompt_hostname) "$fish_color_host")
    set -l color_user (colorize "$USER"           "$fish_color_user")

    # …
end


function colorize -a what -a default -d 'Outputs a hex color for a string or, failing that, a default'
    if command -qs shasum
        echo -n (printf "$what" | shasum -ta 256 - | cut -c 59-64 | tr -d '\n')
    else
        echo "$default"
    end
end