Skip to content

Add an option to define sorting methods for both string and numeric completions. #95

@tur1ngb0x

Description

@tur1ngb0x

Details

  • Distro: Fedora 43
  • Bash: version 5.3.0(1)-release (x86_64-redhat-linux-gnu)
  • Docker: dannyben/completely:latest, 8a990fc39eb8

Issue

Tab completion lists number arguments using lexicographic sort. I want completions to show using numerical sort.

# Current Behaviour
$ ddcutil.sh [TAB Key]
0    10   100  20   30   40   50   60   70   80   90
# Expected Behaviour
$ ddcutil.sh [TAB Key]
0   10   20   30   40   50   60   70   80   90   100

Proposal

completely_options:
  complete_options: -o <sort_type>
<sort_type>
lexsort : lexicographical (default) 
nosort  : no sorting (already implemented)
humsort : human sort
numsort : numeric sort
ransort : random sort
revsort : reverse sort
versort : version sort

Code

$ cat ~/scripts/ddcutil.sh
#!/usr/bin/env bash

if [[ -n "${1}" ]]; then
    ddcutil setvcp 10 "${1}"
else
    H=$(date +%H)
    if (( 10#${H} >= 6 && 10#${H} < 18 )); then
        ddcutil setvcp 10 100
    else
        ddcutil setvcp 10 10
    fi
fi
$ cat ~/completely/ddcutil.sh.yaml
ddcutil.sh:
- '0'
- '10'
- '20'
- '30'
- '40'
- '50'
- '60'
- '70'
- '80'
- '90'
- '100'
$ cat ~/.local/share/bash-completion/completions/ddcutil.sh
# ddcutil.sh completion                                    -*- shell-script -*-

# This bash completions script was generated by
# completely (https://github.com/bashly-framework/completely)
# Modifying it manually is not recommended

_ddcutil.sh_completions_filter() {
  local words="$1"
  local cur=${COMP_WORDS[COMP_CWORD]}
  local result=()

  # words the user already typed (excluding the command itself)
  local used=()
  if ((COMP_CWORD > 1)); then
    used=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
  fi

  if [[ "${cur:0:1}" == "-" ]]; then
    # Completing an option: offer everything (including options)
    echo "$words"

  else
    # Completing a non-option: offer only non-options,
    # and don't re-offer ones already used earlier in the line.
    for word in $words; do
      [[ "${word:0:1}" == "-" ]] && continue

      local seen=0
      for u in "${used[@]}"; do
        if [[ "$u" == "$word" ]]; then
          seen=1
          break
        fi
      done
      ((!seen)) && result+=("$word")
    done

    echo "${result[*]}"
  fi
}

_ddcutil.sh_completions() {
  local cur=${COMP_WORDS[COMP_CWORD]}
  local compwords=()
  if ((COMP_CWORD > 0)); then
    compwords=("${COMP_WORDS[@]:1:$((COMP_CWORD - 1))}")
  fi
  local compline="${compwords[*]}"

  COMPREPLY=()

  case "$compline" in
    *)
      while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_ddcutil.sh_completions_filter "0 10 20 30 40 50 60 70 80 90 100")" -- "$cur")
      ;;

  esac
} &&
  complete -F _ddcutil.sh_completions ddcutil.sh

# ex: filetype=sh

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions