Con frecuencia uso el comando open -a
en Terminal para abrir aplicaciones a través de ssh. ¿Cómo hago que se complete automáticamente el nombre de una aplicación?
Con frecuencia uso el comando open -a
en Terminal para abrir aplicaciones a través de ssh. ¿Cómo hago que se complete automáticamente el nombre de una aplicación?
_complete_open() {
COMPREPLY=()
local cur="${COMP_WORDS[$COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
[[ "$cur" == -* || "$prev" != '-a' ]] && return
apps="$(mdfind kMDItemKind==Application -onlyin /Applications -onlyin ~/Applications -onlyin /Developer -onlyin ~/Developer | grep -v '/.*/.*/.*/.*/' | sed -E 's|.*/||g;s|\.app$||g' | uniq)"$'Finder\nArchive Utility\nCharacterPalette\nKeyboardViewer'
local IFS=$'\n'
if [[ "${cur:0:1}" = '"' || "${cur:0:1}" = "'" ]]; then
quote="${cur:0:1}"
cur="${cur:1}"
fi
local found="$(grep -i "^$cur" <<< "$apps")"
if [[ "$quote" == '"' ]]; then
found="$(sed "s|^|\"|g;s|$|\"|g" <<< "$found")"
elif [[ "$quote" == "'" ]]; then
found="$(sed "s|^|'|g;s|$|'|g" <<< "$found")"
else
found="$(sed 's| |\ |g' <<< "$found")"
fi
COMPREPLY=($found)
}
complete -o default -F _complete_open open
Tercera versión, que ahora debería distinguir entre mayúsculas y minúsculas y trabajar entre comillas.
Agregue lo siguiente a su .bash_profile
o .bashrc
e inicie una nueva sesión:
function _complete_open {
cur=$2
COMPREPLY=( );
[[ "$COMP_WORDS" = "open" ]] || return
[[ "${COMP_WORDS[ $(( $COMP_CWORD - 1 )) ]}" = "-a" ]] || return
OLDIFS="$IFS"
IFS=$'\n'
local _part="${COMP_WORDS[$COMP_CWORD]}"
if [[ "${_part:0:1}" = '"' || "${_part:0:1}" = "'" ]] ; then
COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' | sort -u )" -- $cur ) )
else
COMPREPLY=( $( compgen -W "$( mdfind kMDItemKind==Application | sed -e 's|.*/||g' -e 's|.app$||' -e 's| |\\ |g' | sort -u )" -- $cur ) )
fi
IFS="$OLDIFS"
}
complete -o default -F _complete_open open
No es necesario instalar nada. Esto funciona con bash
fuera de la caja.
Solo autocompletará los nombres de los programas si la opción anterior es -a
y, de lo contrario, mostrará el comportamiento predeterminado, por ejemplo. devuelva una lista de todos los archivos en el directorio actual o complete el prefijo de ruta actual.
Los resultados se generan a partir de system_profiler SPApplicationsDataType
, que es la forma más fácil de obtener todas las aplicaciones que se pueden iniciar de esta manera en su sistema de esa manera. La lista se procesa para devolver solo los nombres de los programas, que pueden contener espacios y pueden ser diferentes de los nombres de los paquetes (incluso cuando se ignoran .app
suffix)
Uso: Escriba open -a
, seguido de un espacio, seguido de presionar Tab
o Esc
(dos veces en mi sistema, no estoy seguro de si está en todas partes).
Ejemplo que muestra todas las aplicaciones de ayuda para mi escáner:
$ open -a Scan
Scan to E-mail Scan to Excel Scan to Folder Scan to Print Scan to Searchable PDF Scan to Word ScanSnap Manager
Inconvenientes y problemas de esta solución:
Hay toneladas de programas en tu sistema que quizás no conozcas, como todo en /System/Library/CoreServices
. Es posible que no desee enumerar todos ellos. OTOH, es muy fácil de ver y lanzar, por ejemplo. CharacterPalette
o KeyboardViewer
de esta manera. * Configure las llamadas mdfind
adecuadamente con el argumento -onlyin
.
Es un poco lento, debido a Ahora usa system_profiler SPApplicationsDataType
. Es posible que deba esperar uno o dos segundos antes de que aparezca la finalización. mdfind
para obtener los programas rápidamente. Gracias @Lri
Puede manejar espacios en los nombres de las aplicaciones y en los nombres de los programas incluidos entre comillas, pero es bastante intrépido. Requiere que la cita sea el primer carácter: mientras Scan" to "P
es válido en bash
, este programa no lo detectará. La finalización tampoco funciona después de un espacio de escape (por ejemplo, Scan\ to
), use comillas en tales casos ( "Scan to
). El soporte para espacios escapados solo es bueno para completar DVD
a DVD\ Player
.
Autocompletado programable al rescate! Sin embargo, se necesitaba una gran cantidad de copias de la página principal de finalización de Bash , que vale la pena instalar de todos modos por un montón de magia de autocompletado . Si lo hace, solo necesitará la última función ( _open
) y el comando de inicialización desde abajo.
Agregue lo siguiente a .bashrc
:
# taken from http://bash-completion.alioth.debian.org/
_compopt_o_filenames()
{
# We test for compopt availability first because directly invoking it on
# bash < 4 at this point may cause terminal echo to be turned off for some
# reason, see https://bugzilla.redhat.com/653669 for more info.
type compopt &>/dev/null && compopt -o filenames 2>/dev/null || \
compgen -f /non-existing-dir/ >/dev/null
}
_tilde() {
local result=0
# Does $1 start with tilde (~) and doesn't contain slash (/)?
if [[ ${1:0:1} == "~" && $1 == ${1//\/} ]]; then
_compopt_o_filenames
# Try generate username completions
COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
result=${#COMPREPLY[@]}
fi
return $result
}
_quote_readline_by_ref()
{
if [[ ${1:0:1} == "'" ]]; then
if [[ ${BASH_VERSINFO[0]} -ge 4 ]]; then
# Leave out first character
printf -v $2 %s "${1:1}"
else
# Quote word, leaving out first character
printf -v $2 %q "${1:1}"
# Double-quote word (bash-3)
printf -v $2 %q ${!2}
fi
elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
printf -v $2 %q "${1:1}"
else
printf -v $2 %q "$1"
fi
# If result becomes quoted like this: $'string', re-evaluate in order to
# drop the additional quoting. See also: http://www.mail-archive.com/
# [email protected]/msg01942.html
[[ ${!2:0:1} == '$' ]] && eval $2=${!2}
} # _quote_readline_by_ref()
_filedir()
{
local i IFS=$'\n' xspec
_tilde "$cur" || return 0
local -a toks
local quoted tmp
_quote_readline_by_ref "$cur" quoted
toks=( ${toks[@]-} $(
compgen -d -- "$quoted" | {
while read -r tmp; do
printf '%s\n' $tmp
done
}
))
if [[ "$1" != -d ]]; then
# Munge xspec to contain uppercase version too
[[ ${BASH_VERSINFO[0]} -ge 4 ]] && \
xspec=${1:+"!*.@($1|${1^^})"} || \
xspec=${1:+"!*.@($1|$(printf %s $1 | tr '[:lower:]' '[:upper:]'))"}
toks=( ${toks[@]-} $( compgen -f -X "$xspec" -- $quoted) )
fi
[ ${#toks[@]} -ne 0 ] && _compopt_o_filenames
COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
} # _filedir()
# only the following is needed if bash-autocompletion is already installed
_open ()
{
local cur;
cur=$2;
COMPREPLY=();
if [ $COMP_CWORD -eq 2 ]; then
COMPREPLY=($(compgen -W "$(/bin/ls /Applications)" -- $cur ));
return 0
fi
_filedir
}
complete -F _open open
Lea otras preguntas en las etiquetas terminal auto-complete