![¿Es posible configurar la forma en que bash completa los nombres de los directorios?](https://rvso.com/image/1288703/%C2%BFEs%20posible%20configurar%20la%20forma%20en%20que%20bash%20completa%20los%20nombres%20de%20los%20directorios%3F.png)
Me gustaría indicarle a bash que use un método especial para completar ciertos nombres de directorio. Por ejemplo, bash llamaría a un programa mío para realizar la finalización si una ruta comienza con "$$" y, en caso contrario, realizaría la finalización normalmente.
¿Es esto posible? ¿Cómo lo implementarías?
Generosidad: Realmente agradecería una respuesta a esa pregunta. El objetivo es permitirsalto automáticopara completar las rutas de todos los comandos cuando el usuario los inicia con un prefijo determinado. Entonces, por ejemplo, al copiar un archivo desde un directorio lejano, puede escribir:
cp $$patern + <Tab>
y el autojump se completaría
cp /home/user/CompliCatedDireCTOry/long/path/bla/bla
y solo tendrías que agregar dónde quieres poner el archivo. Por supuesto que puedo usar el comentario de Ott para agregarlo a algunos comandos específicos, pero si alguien tiene una idea mejor, estaría muy agradecido.
Respuesta1
Puede hacerlo anulando el enlace predeterminado para TAB(^i). Primero debe anular el enlace TAB, luego debe crear una función que llame a su comando y, por último, debe tomar el resultado de ese comando y actualizar la variable que contiene la línea de comando actual.
Esta función toma la línea de comando actual y cambia los dos últimos caracteres a 'huugs'.
function my_awesome_tab_completion_function () {
set -- $READLINE_LINE
command="$1"
shift
argument="$*"
argument_length=$(echo -n $argument | wc -c)
if echo $argument | grep '^$$' >/dev/null 2>&1; then
new_argument=$(echo $argument | sed 's/..$/huugs/') # put your autojump here
else
new_argument=$(compgen -d $argument)
fi
new_argument_length=$(echo -n $new_argument | wc -c)
READLINE_POINT=$(( $new_argument_length - $argument_length + $READLINE_POINT ))
READLINE_LINE="$command $new_argument"
}
Para su ejemplo, probablemente desee cambiar la línea new_argument para que se vea así:
new_argument=$(autojump $argument)
Ahora anule el enlace ^i:
$ bind -x '"\C-i"':'my_awesome_tab_completion_function'
Ahora prueba que funciona:
$ cd /ro<TAB>
changes my command to:
$ cd /root
por lo que la finalización normal todavía funciona, puedes probar la parte $$ haciendo cd $$... etc.
Si tiene problemas, active el modo detallado:
$ set -x
Imprimirá todo lo que está haciendo la función.
Probé esto en Ubuntu 11 usando la versión bash 4.2.8(1) (la predeterminada).
Respuesta2
La rutina de finalización de bash se puede programar como un script de shell.
A continuación se muestra un ejemplo de un script de shell que reemplazará cualquier parámetro $$[Tab]
por my replacement string
, pero solo para el comando específico mycommand
y solo si el parámetro es exactamente "$$":
_mycomplete()
{
if [ ${COMP_WORDS[COMP_CWORD]} == \$\$ ]
then
COMPREPLY='my replacement string'
fi
}
complete -o default -o bashdefault -F _mycomplete mycommand
Debe obtener el script a través del cual ejecutar source <file-name>
(o el comando punto) para que comience a funcionar y luego:
mycommand $$[Tab] -> mycommand my replacement string
mycommand $$$[Tab] -> mycommand $$$ (beep)
mycommand whatever[Tab] -> (will complete "whatever" in the normal bash manner)
Para que siempre funcione para algunos o todos los usuarios, inclúyalo en uno de losrutinas de perfil bash.
El problema con el complete
comando es que funcionará solo para uno o más nombres de comandos, que se especifican como parámetros. Uno podría simplemente darle la lista de todos los comandos que los usuarios podrían usar o, en casos desesperados, expandirla /bin/* /usr/bin/* ~/bin/*
.
Probado en CentOS 5.5.
Este script simple se basa en las fuentes que enumeré en mi otra respuesta, la que fue eliminada por el moderador studiohack. Si está interesado, pídale que lo recupere.