4

Я некоторое время играл с bash autocomplete, но не смог найти решение своей проблемы. У меня есть каталог проекта с подпапками, как это:

  • Проекты / рубин / project1
  • Проекты / рубин / project2
  • Проекты / рельсы / project3
  • проекты / html / проекта4

Теперь я хочу иметь команду, назовите ее cdproject где я могу cd в любой подпапке в моих проектах dir и subdirs. И эта команда должна предоставить функцию автозаполнения, где я могу набрать cdproject pr --> TAB TAB и затем получить список вроде ruby/project1 , ruby/project2 , rails/project3 ...

Моя проблема в том, как обращаться с подкаталогами. Программа cdproject выглядит так

#!/bin/bash
cd $1

cdproject-autocompletion.bash выглядит так

_cdproject()
{
  local cur prev opts
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  prev="${COMP_WORDS[COMP_CWORD-1]}"
  opts=$(ls ~/Dropbox/projects)
  COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  return 0
}
complete -o default -o nospace -F _o  o

И внутри моего .bash_profile я cdproject-autocompletion.bash с

source ~/cdproject-autocompletion.bash

Так что у кого есть идея, как этого добиться? Может быть, opts должен возвращать структуру подкаталога ruby/project1 но тогда автодополнение должно работать только на последнюю часть, фактического название проекта. И я понятия не имею, как это возможно.

2 ответа2

4

Глубоко изучая вопрос, вы ищете более плавные способы навигации по дереву файлов из командной строки.

Вариант 1: использовать CDPATH

Например, CDPATH=".:~:~/projects/ruby:~/projects/rail:~/projects/html"

Примечание: некоторые люди считают его полезным включить .. в CDPATH

К сожалению CDPATH не (всегда) поддержка автодополнения.  Для этого есть способы расширить bash.  Google с терминами "CDPATH" и "автозаполнение".

По общему признанию это немного неуклюже.  Если вы используете небольшой набор родительских каталогов, это не так уж плохо.

Вы можете добиться большего успеха с dirs , pushd и popd . Это займет некоторое время, чтобы освоиться. Обратите внимание, что pushd и popd могут принимать числовой параметр.

Также:
cd - возвращает вас в предыдущий каталог. Повторение команды переключает между двумя последними каталогами.
____________
Много документов (включая справочные страницы) показывают . (точка; т. е. текущий каталог) как компонент в CDPATH .  Однако, по крайней мере, некоторые оболочки работают так, как будто CDPATH заканчивается на :., поэтому, если вы скажете cd foo , вы получите ./foo если какой-либо другой родительский каталог, указанный в вашем CDPATH содержит foo .  YMMV.

Примечание редактора: Cygwin поддерживает CDPATH из коробки» (работает bash версии «4.1.17 (9)-release»).

0

Это кажется до смешного сложным, но это решение, которое я придумал:

function gcd {
  cd $HOME/git/firefly/$1
}

function _gcdcomplete()
{
  local cmd curb cur opts

  # base dir
  git=$HOME/git/firefly/

  # last arg so far
  cur="${COMP_WORDS[COMP_CWORD]}"

  # dirname-esque, but makes "xyz/" => "xyz/" not "."
  curb=$(echo $cur | sed 's,[^/]*$,,')

  # get list of directories (use commened out line for dirs and files)
  # append '/' to directories
  # cmd="find $git$curb -maxdepth 1 -type d -printf %p/\n , -type f -print "
  cmd="find $git$curb -maxdepth 1 -type d -printf %p/\n "

  # remove base dir from list and remove extra trailing /s
  opts=$($cmd | sed s:$git:: | sed s://*$:/:)

  # generate list of completions
  COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  return 0;
}
complete -o nospace -F _gcdcomplete gcd

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .