不同目录的 Bash 自动完成

不同目录的 Bash 自动完成

我已经使用 bash 自动完成功能一段时间了,但找不到解决问题的方法。我有一个项目目录,其中包含如下子文件夹:

  • 项目/ruby/project1
  • 项目/ruby/project2
  • 项目/rails/project3
  • 项目/html/project4

现在我想要一个命令,cdproject可以cd在我的项目目录和子目录中的任何子文件夹中调用它。并且此命令应提供自动完成功能,我可以在其中键入cdproject pr --> TAB TAB然后获取一个列表,例如ruby/project1,,...ruby/project2rails/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,但自动完成功能应该只对最后一部分(即实际项目名称)起作用。我不知道这是如何实现的。

答案1

深入阅读这个问题,您正在寻找从命令行浏览文件树的更流畅的方法。

选项 1:使用CDPATH

例如, CDPATH=".:~:~/projects/ruby:~/projects/rail:~/projects/html"

注意:有些人认为包含以下内容很有用..CDPATH

不幸的是,CDPATH并不(总是)支持自动完成。有多种方法可以扩展 bash 来实现这一点。使用术语“CDPATH”和“自动完成”在 Google 上搜索。

不可否认,这有点笨重。如果您使用的父目录数量很少,那么这还不算太糟。

您可能更适合使用dirspushdpopd。这些需要花些时间才能掌握。请注意pushdpopd可以采用数字参数。

另外:
cd -返回上一个目录。重复该命令可在两个最近的目录之间切换。____________

许多文档(包括手册页)显示. (点;即当前目录)作为 中的一个组成部分CDPATH。然而,至少有些 shell 似乎认为CDPATH:.,所以,如果你说cd foo,你将得到,./foo除非你列出的其他父目录CDPATH包含foo。YMMV。

编者注:Cygwin 似乎支持CDPATH开箱即用的自动完成功能(运行 bash 版本“4.1.17(9)-release”)。

答案2

这看起来非常复杂,但这是我想出的解决方案:

函数 gcd {
  cd $HOME/git/firefly/$1
}

函数 _gcdcomplete()
{
  本地命令 curb cur 选择

  # 基本目录
  git=$HOME/git/firefly/

  # 到目前为止的最后一个参数
  cur="${COMP_WORDS[COMP_CWORD]}"

  # dirname-esque,但是使 "xyz/" => "xyz/" 而不是 "."
  curb=$(echo $cur | sed 's,[^/]*$,,')

  # 获取目录列表(使用注释行列出目录和文件)
  # 将“/”附加到目录
  # cmd="find $git$curb -maxdepth 1 -type d -printf %p/\n , -type f -print "
  cmd="查找$git$curb -maxdepth 1 -type d -printf %p/\n"

  # 从列表中删除基本目录并删除多余的尾随 /s
  opts=$($cmd | sed s:$git:: | sed s://*$:/:)

  # 生成完成列表
  COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  返回0;
}
完成 -o 无空间 -F _gcdcomplete gcd

相关内容