ubuntu 系统里设置 smug start 自动补全

文章目录

    我使用 ubuntu 系统,我希望在执行 smug start 命令时,按 tab 能自动列举 ~/work/config/smug/ 目录下的相关配置文件名,作为自动补全。同时去掉文件名后缀。这样做的好处是不用记录复制配置的文件名,毕竟太多单词我记不住。。。注:smug 的介绍参考:smug 一款用 go 实现的 tmux session manager

    Ubuntu 默认一般是 Bash。下面以 Bash 为例,给 smug start 增加 Tab 补全:从 ~/work/config/smug/ 读取 .yml / .yaml 文件,并去掉后缀补全。

    1. 创建 Bash 补全脚本

    mkdir -p ~/.local/share/bash-completion/completions
    
    cat > ~/.local/share/bash-completion/completions/smug <<'EOF'
    _smug_complete() {
        local cur cmd dir f base
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        cmd="${COMP_WORDS[1]:-}"
        dir="$HOME/work/config/smug"
    
        # 补全 smug 的子命令
        if [[ $COMP_CWORD -eq 1 ]]; then
            COMPREPLY=( $(compgen -W "start stop list edit" -- "$cur") )
            return 0
        fi
    
        # 只处理:smug start <TAB>
        if [[ "$cmd" == "start" && $COMP_CWORD -eq 2 ]]; then
            [[ -d "$dir" ]] || return 0
    
            while IFS= read -r -d '' f; do
                base="${f##*/}"
    
                # 去掉 .yml / .yaml 后缀
                case "$base" in
                    *.yml)  base="${base%.yml}" ;;
                    *.yaml) base="${base%.yaml}" ;;
                    *) continue ;;
                esac
    
                [[ "$base" == "$cur"* ]] && COMPREPLY+=("$base")
            done < <(find "$dir" -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) -print0)
    
            return 0
        fi
    }
    
    complete -F _smug_complete smug
    EOF
    

    2. 让补全生效

    source ~/.local/share/bash-completion/completions/smug
    

    如果新开终端后仍然不生效,可以把下面这行加到 ~/.bashrc:

    source ~/.local/share/bash-completion/completions/smug
    

    然后:

    source ~/.bashrc
    

    3. 测试

    smug start <TAB><TAB>
    

    如果 ~/work/config/smug/ 下有:

    foo.yml
    bar.yaml
    my-session.yml
    

    那么补全时显示:

    foo  bar  my-session
    

    而不是:

    foo.yml  bar.yaml  my-session.yml
    

    这样 smug start fo<TAB> 就会补成 smug start foo。

    zsh

    如果你使用的是 Zsh,而不是 Bash,可以用这个简版:

    # 加到 ~/.zshrc
    _smug() {
      local dir="$HOME/work/config/smug"
      local -a sessions
      local f base
    
      if (( CURRENT == 3 )) && [[ $words[2] == start ]]; then
        for f in "$dir"/*.yml(N) "$dir"/*.yaml(N); do
          base="${f:t}"
          base="${base%.yml}"
          base="${base%.yaml}"
          sessions+=("$base")
        done
        _describe 'smug session' sessions
      else
        _arguments '1:command:(start stop list edit)'
      fi
    }
    
    compdef _smug smug
    

    然后:

    source ~/.zshrc