~gpanders/wk

84a6a0c5a20a4881db65bcddda6adf9212dce522 — Greg Anders 2 months ago 39a73d2
Improve shell completion files

Bash completions now match anywhere in the string, not just at the
prefix. This means you can enter something like

  zet o 'substring of filename'<TAB>

And it will expand to the full filename (this is also how fish
completion works by default and it's much better).
2 files changed, 28 insertions(+), 14 deletions(-)

M completions/bash/zet
M completions/fish/zet.fish
M completions/bash/zet => completions/bash/zet +27 -13
@@ 1,13 1,9 @@
#!/usr/bin/env bash

_zet () {
    if [ "${#COMP_WORDS[@]}" -gt 3 ]; then
        return
    fi

    : "${ZETTEL_DIR:=${XDG_DATA_HOME:-$HOME/.local/share}/zet}"

    if [ -d "$ZETTEL_DIR" ]; then
    if [ ! -d "$ZETTEL_DIR" ]; then
        return
    fi



@@ 16,24 12,42 @@ _zet () {
    commands="backlinks show open list search sync new tags help preview"

    if [ "$COMP_CWORD" -eq 1 ]; then
        COMPREPLY=($(compgen -W "$commands" -- "$cur"))
        while read -r line; do COMPREPLY+=("$line"); done < <(compgen -W "$commands" -- "$cur")
        return 0
    fi

    local zettels=()
    for zettel in "$ZETTEL_DIR"/*; do
        zettels+=($(basename -- "${zettel%.*}"))
    done
    local zettels
    zettels=$(compgen -f "$ZETTEL_DIR/" | sed -E -e 's/.*\///g' -e '/^[0-9]{14}/!d' -e 's/\..*$//')

    case "${COMP_WORDS[1]}" in
        bl|backlinks|sh|show|o|open|p|pre|prev|preview)
            COMPREPLY=($(compgen -W "${zettels[*]}" -- "${COMP_WORDS[2]}"))
            # compgen only returns prefix-matches, but we want to return
            # matches anywhere in the substring, so use grep to generate the
            # results
            while IFS='' read -r line; do
                COMPREPLY+=("$line")
            done < <(printf '%s\n' "$zettels" | grep -iF "$cur")
            ;;
        l|ls|list|s|search|sync|t|tags|n|new|h|help)
        t|tag|tags)
            # Prioritize prefix matches but if none exist, fallback to matching
            # any substring
            local tags
            tags=$(awk '/^tags:/ {$1=""; print}' "$ZETTEL_DIR"/* | tr ',' '\n' | awk '{$1=$1}1' | sort -u)

            matches=$(printf '%s\n' "$tags" | grep -i "^$cur")
            if [ -z "$matches" ]; then
                matches=$(printf '%s\n' "$tags" | grep -iF "$cur")
            fi

            while IFS='' read -r line; do
                COMPREPLY+=("$line")
            done < <(printf '%s\n' "$matches")
            ;;
        l|ls|list|s|search|sync|n|new|h|help)
            return
            ;;
        *)
            COMPREPLY=($(compgen -W "$commands" -- "$cur"))
            return
            ;;
    esac
} &&

M completions/fish/zet.fish => completions/fish/zet.fish +1 -1
@@ 13,7 13,7 @@ end

function __fish_complete_zettel_tags
    set -q ZETTEL_DIR; or set -l ZETTEL_DIR (__zettel_dir)
    awk -- '/^tags:/ {$1=""; sub("^ *", ""); print}' $ZETTEL_DIR/* | tr ',' '\n' | sort -u
    awk -- '/^tags:/ {$1=""; print}' $ZETTEL_DIR/* | tr ',' '\n' | awk '{$1=$1}1' | sort -u
end

complete -k -x -c zet -n '__fish_seen_subcommand_from bl backlinks' -a '(__fish_complete_zettels)'