¿Cómo transponer argumentos de línea de comando con combinaciones de teclas de emacs?

¿Cómo transponer argumentos de línea de comando con combinaciones de teclas de emacs?

Usando Bash, con las combinaciones de teclas de emacs configuradas, la combinación de teclas transpose-words ( M-t) no transpone argumentos, sino "palabras" (según su propia definición de palabras).

Entonces si tengo esto:

vimdiff project-number-One/Vagrantfile project-number-Two/Vagrantfile.old

y mi cursor está entre el primer y segundo argumento cuando entro optiont, en lugar de eso termino con

vimdiff project-number-One/project Vagrantfile-number-Two/Vagrantfile.old

que obviamente no es lo que quiero. ¿Cómo puedo transponer argumentos?

Respuesta1

En bash, diferentes comandos tienen diferentes nociones de palabras.C-welimina el espacio en blanco anterior, pero la mayoría de los demás comandos, incluidos, M-tutilizan palabras delimitadas por puntuación.

Con el cursor entre el primer y segundo argumento, C-w C-e SPC C-yse transpondrán las dos palabras.

Si desea vincular una clave para transponer palabras delimitadas por espacios en blanco, es más complicado. Vercomportamiento confuso de las combinaciones de teclas estilo emacs en bash. Aquí hay un código mínimamente probado.

transpose_whitespace_words () {
  local prefix=${READLINE_LINE:0:$READLINE_POINT} suffix=${READLINE_LINE:$READLINE_POINT}
  if [[ $suffix =~ ^[^[:space:]] ]] && [[ $prefix =~ [^[:space:]]+$ ]]; then
    prefix=${prefix%${BASH_REMATCH[0]}}
    suffix=${BASH_REMATCH[0]}${suffix}
  fi
  if [[ $suffix =~ ^[[:space:]]+ ]]; then
    prefix=${prefix}${BASH_REMATCH[0]}
    suffix=${suffix#${BASH_REMATCH[0]}}
  fi
  if [[ $prefix =~ ([^[:space:]]+)([[:space:]]+)$ ]]; then
    local word1=${BASH_REMATCH[1]} space=${BASH_REMATCH[2]}
    prefix=${prefix%${BASH_REMATCH[0]}}
    if [[ $suffix =~ [^[:space:]]+ ]]; then
      suffix=${suffix#${BASH_REMATCH[0]}}
      READLINE_LINE=${prefix}${BASH_REMATCH[0]}$space$word1$suffix
      READLINE_POINT=$((${#READLINE_LINE} - ${#suffix}))
    fi
  fi
}
bind -x '"\e\C-t": transpose_whitespace_words'

Todo esto es más fácil en zsh…

Respuesta2

Si tu cursor está allí:

vimdiff projectOne/Vagrantfile projectTwo/Vagrantfile
                              ^

Presione Alt + BTTBBTFTBBTT


O simple:

Presione Ctrl+ W, Ctrl+ E, inserte un espacio en blanco y presione Ctrl+Y

Respuesta3

Para obtener una solución rápida y sencilla, agregue esto a su inputrc (elija las claves adecuadas para usted):

"\e\C-b": shell-backward-kill-word
"\eh": shell-backward-word
"\e\C-f": shell-forward-word
# Swap the preceding two arguments (control + alt + t)
"\e\C-t": "\e\C-b\eh\C-y"
# Swap the preceding argument with the next (control + alt + p)
"\e\C-p": "\e\C-b\e\C-f\C-y"

En el caso de shell-*versiones de estas funcioneslas palabras están delimitadas por metacaracteres de shell sin comillas.

metacarácter

Carácter que, cuando no está entre comillas, separa palabras. Un metacarácter es un espacio, una tabulación, una nueva línea o uno de los siguientes caracteres: '|', '&', ';', '(', ')', '<' o '>'.

Nota: El cursor debe estar después del segundo argumento antes de presionar Ctrl+ Alt+ t, por lo que efectivamente empuja el argumento antes del cursor hacia el principio de la línea.

$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
                                                             ^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
                                     ^
$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
                         ^

Nota: El cursor debe estar después del primer argumento antes de presionar Ctrl+ Alt+ p, por lo que efectivamente arrastra el argumento antes del cursor hacia el final de la línea.

$ true "too/too far.away" foo/bar.xyz even/without\ quotes.ok
                         ^
$ true foo/bar.xyz "too/too far.away" even/without\ quotes.ok
                                     ^
$ true foo/bar.xyz even/without\ quotes.ok "too/too far.away"
                                                             ^

Respuesta4

Debes presionar BTTBBTen lugar de uno solo T.

información relacionada