Как расширить завершение bash в другом каталоге?

Я изучаю завершение bash. Я могу перечислить содержимое только текущего каталога. Вот мой код:

   _foo()
   {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"

       opts="push pull"
       OUTPUT=" $(ls) "

      case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=( $(compgen -W "$OUTPUT" -- ${cur}) )
              return 0
              ;;
      esac

        COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
        return 0
  }
  complete -F _foo foo

Его вывод:

$ foo push --in[TAB]
file1.txt file2.txt foo  ;; content of pwd

Но когда я делаю это:

$ foo push --in ~[TAB]

Это не работает. Итак, я хочу знать, как выполнить завершение bash в другом каталоге (не только в pwd)? Спасибо.


person rishi kant    schedule 09.07.2016    source источник
comment
О, их на самом деле нет в сценарии. Это только из-за редактора Vim. И я скопировал этот скрипт оттуда, поэтому номер строки также скопировал.   -  person rishi kant    schedule 09.07.2016


Ответы (1)


Вы можете использовать -f для сопоставления имен файлов:

#!/bin/bash
_foo()    {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"
       opts="push pull"

       case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=( $(compgen -f ${cur}) )
              return 0
              ;;
      esac

      COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
      return 0   
}

complete -F _foo foo

Однако кажется, что это не работает только для ~, но $ foo push --in ~/[TAB] работает и для всех других каталогов. Это решение не будет включать косую черту для поиска файла в каталоге: $ foo push --in /etc[TAB] даст foo push --in /etc , а не foo push --in /etc/

Следующий пост решает эту проблему, используя режим по умолчанию:
Заставить compgen включать косые черты в каталогах при поиске файлов

По умолчанию

Используйте завершение имени файла Readline по умолчанию, если compspec не создает совпадений.

Итак, вы можете использовать:

#!/bin/bash
_foo()
   {
       local cur prev opts
       COMPREPLY=()
       cur="${COMP_WORDS[COMP_CWORD]}"
       prev="${COMP_WORDS[COMP_CWORD-1]}"

       opts="push pull"
       OUTPUT=" $(ls) "

      case "${prev}" in
          push)
              COMPREPLY=( $(compgen -W "--in --out" -- ${cur}) )
              return 0
              ;;
          --in)
              COMPREPLY=()
              return 0
              ;;
          --port)
              COMPREPLY=("")
              return 0
              ;;
      esac

        COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
        return 0
  }
  complete -o default -F _foo foo

Или установите режим по умолчанию, когда вам нужно лайкнуть этот пост: https://unix.stackexchange.com/a/149398/146783

person Bertrand Martel    schedule 10.07.2016
comment
Это хорошо. Но что, если я не хочу ничего делать в конкретном случае. Допустим есть аргумент --port, И я хочу взять его с клавиатуры. Так должно быть $ foo push --port[TAB] ;; Автодополнение должно остановиться, результата нет. Это указывает пользователю передать значение --port с клавиатуры. Но судя по вашему ответу, будет $ foo push --port[TAB] ;; содержимое pwd Итак, есть ли способ указать, что в этих случаях мы не используем результат по умолчанию? - person rishi kant; 10.07.2016
comment
Но это не работает. $ foo push --in[TAB] bash: compopt: command not found Это сообщение об ошибке, которое я получил. - person rishi kant; 10.07.2016
comment
Вы использовали файл в bash_completion.d? попробуйте добавить #!/bin/bash вверху, чтобы убедиться, что он использует правильный bash. Если ваш bash не находится в /bin/bash, замените его правильным расположением bash (which bash) - person Bertrand Martel; 10.07.2016
comment
это не будет включать косую черту для поиска подкаталогов, если вы это сделаете - person Bertrand Martel; 10.07.2016
comment
Давайте продолжим это обсуждение в чате. - person rishi kant; 10.07.2016