从Fish Shell

时间:2017-03-06 19:45:05

标签: fish

我有多个像这样的目录

~/project/foo/Debug
~/project/bar/Debug
... and so on

文件夹projectDebug是常量。

我在调试目录中,foobar是项目名称。当我在~/project/bar/Debug时,是否可以将变量设置为字符串bar,当我在目录~/project/xxxxx/Debug中时,将该变量设置为xxxxx?< / p>

2 个答案:

答案 0 :(得分:3)

当前目录可通过PWD变量获取,因此您可以测试:

set -g string # define variable globally
if test $PWD = ~/project/foo/Debug
     set string foo
else if test $PWD = ~/project/bar/Debug
     set string bar
end

当然,如果有超过三个项目,或者列表随时间变化,那么这将变得难以处理,因此您可以使用fish的内置string工具来执行匹配和替换在它上面。

set -g string
if string match -q '/projects/*/Debug'
     set string (string replace -r '.*/projects/([^/]+)/Debug' '$1' -- $PWD)
end

我怀疑你真正想要的是在你的提示中显示你的项目名称来代替工作目录。如果是这样并且你使用git,你可以使用这个

function prompt_pwd --description 'Print the current working directory, shortened to fit the prompt'
    set -q argv[1]; and switch $argv[1]
        case -h --help
            __fish_print_help prompt_pwd
            return 0
    end

    # This allows overriding fish_prompt_pwd_dir_length from the outside (global or universal) without leaking it
    set -q fish_prompt_pwd_dir_length; or set -l fish_prompt_pwd_dir_length 1

    set -l tmp
    set -l gitdir
    # Replace everything up to the vcs root with [rootname]
    # under the assumption that that is the name of the "project".
    # TODO: On my machine, it seems that the last two components are the safer bet, e.g.
    # kwin/tiling
    # exercism/cli (go)
    # elves/elvish (go)
    # new/exa-git (aur)
    # dev/fish-shell
    #
    # Either that, or a more robust system of abbreviations,
    # a non-hacky solution for which needs dictionaries.
    if set gitdir (git rev-parse --show-toplevel ^/dev/null)
        set tmp (string replace -- $gitdir '' $PWD)
        # Underline the "project name"
        # FIXME: The coloring here will leak, but I can't see a way to just undo underlining.
        set gitdir \[(set_color -u)(string replace -r '.*/' '' -- $gitdir)(set_color normal; set_color $fish_color_cwd)\]
    else
        # Replace $HOME with "~"
        # Only if we're not in a gitdir, otherwise $HOME/dev/$HOME would give weird results.
        set realhome ~
        # FIXME: This will give weird results if any special regex chars are in $HOME,
        # but it should be a regex match because we only want it replaced at the beginning of the string.
        set tmp (string replace -r '^'"$realhome"'($|/)' '~$1' $PWD)
    end
    # The test will return false if $fish_... is non-numerical,
    # and the replace will not replace anything, so the PWD will be unshortened.
    # This is okay.
    if [ $fish_prompt_pwd_dir_length -eq 0 ]
        echo -s $gitdir $tmp
    else
        # Shorten to at most $fish_prompt_pwd_dir_length characters per directory
        # but only after the gitdir
        echo "$gitdir"(string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp)
    end
end

也可以适用于例如mercurial或类似的,虽然根据我的经验,mercurial启动相当缓慢,因此不是每个提示都要发生的事情。

将其保存在〜/ .config / fish / functions / prompt_pwd.fish中。

答案 1 :(得分:3)

正如faho在他的回答中指出的那样,如果效率至关重要,最近添加的string内置可用于此。但是,在这种情况下,我可能会使用传统的解决方案,因为它的清晰度和简洁性:

set var (basename (dirname $PWD))

如果您不想支付两个非常便宜的外部命令的费用,我会这样做,而不是使用正则表达式:

set components (string split -- / $PWD)
set var $components[-2]

您甚至可以在一个声明中执行此操作:

set var (string split -- / $PWD)[-2]