justanhduc / task-spooler

A scheduler for GPU/CPU tasks
https://justanhduc.github.io/2021/02/03/Task-Spooler.html
GNU General Public License v2.0
281 stars 24 forks source link

Add bash-completion #63

Open straxhaber opened 3 months ago

straxhaber commented 3 months ago

I have a feature request. Right now, ts doesn't provide any bash completion. This would be super helpful!

I'll post some initial thoughts in a separate comment. If I find some time, I may follow up with some proposed code (it would be my first time writing a bash completion script, though, so no promises it would be good!).

straxhaber commented 3 months ago

Some quick comments.

-t | -c | -p | -o | -s | -r | -w | -k | -u | -i | -D could return available job IDs with a helper function: ts | cut -f1 -d' ' | tail -n '+2' | sort -n

-L | -S could have no auto-completion, since the args are custom text.

-U could either have no auto-completion (easiest) or properly auto-complete job IDs in the "id-id" pairs.

Otherwise, the first option that pops up is interpreted to be a command (e.g., find or ./path/to/exec) and then auto-completes that command's args, similar to the way sudo auto-completes.

straxhaber commented 3 months ago

This is a first draft. I put it together quite roughly. Some things that are missing:

  1. -U is not implemented (probably not too hard)
  2. Directories aren't auto-completing the way I'd expect (e.g., "./dir" will match "./dir1" as "./dir1 " with a space rather than "./dir1/", so you have to delete the space to continue adding sub-paths. I'm not sure how to fix this.
  3. I didn't implement the auto-completion for the command being called. I think the best approach here would be to copy the method used by another command like sudo or exec.
  4. There may be other errors since I am new to creating these and put this together quite quickly.
function _ts_complete_ids {
    ts | cut -f1 -d' ' | tail -n '+2' | sort -n
}

function _ts_complete {

    # Define the options
    local opts_taskid="-t -c -p -o -s -r -w -k -u -i -D"
    local opts_noauto="-L -S"
    local opts_twoids="-U"
    local opts_simple="-K -C -l -h -V -n -f -g -m -d"

    local all_opts="${opts_taskid} ${opts_noauto} ${opts_twoids} ${opts_simple}"

    local this="${COMP_WORDS[COMP_CWORD]}"
    local prev="${COMP_WORDS[COMP_CWORD-1]}"

    if false; then
        ## FIXME: should use command's auto-completion if has command
        false

    elif [[ ${COMP_CWORD} -eq 1 && "${this}" == '' ]]; then
        ## first arg shouldn't auto-complete if not started
        true

    elif [[ "${this}" =~ "-" ]]; then
        COMPREPLY=($(compgen -W "${all_opts}" -- "${this}"))

    else
        case "${prev}" in
            ## auto-complete task IDs
            -t | -c | -p | -o | -s | -r | -w | -k | -u | -i | -D)
                ## despite many task IDs being optional, nothing else should come after
                COMPREPLY=($(compgen -W "$(_ts_complete_ids)" -- "${this}")) ;;

            ## label and parallelism don't auto-complete
                -L | -S) true ;; ## despite -S' arg being optional, nothing else should come after

            ## FIXME: not yet implemented (-U id-id)
                -U) false ;;

            ## auto-complete commants
                *) COMPREPLY=($(compgen -c -- "${this}")) ;;
            ## FIXME: directories should auto-complete with "/"
        esac
    fi
}; complete -F _ts_complete ts