2008-09-26 13 views
13

Emacs tiene un útil comando transpose-words que le permite a uno intercambiar la palabra antes del cursor con la palabra después del cursor, preservando la puntuación.¿Cómo emular las palabras de transposición de Emacs en Vim?

Por ejemplo, 'stack |overflow' + M-t = 'overflow stack|' ('|' es la posición del cursor).

<a>|<p> se convierte en <p><a|>.

¿Es posible emularlo en Vim? Sé que puedo usar dwwP, pero no funciona bien con la puntuación.

Actualización: No, dwwP es realmente no una solución. Imagínese:

SOME_BOOST_PP_BLACK_MAGIC((a)(b)(c)) 
//    with cursor here^

Emacs’ M-t habría cambiado b y c, resultando en (a)(c)(b).

Lo que funciona es /\w yiwNviwpnviwgp. Pero estropea "" y "/. ¿Hay una solución más limpia?

Update²:

Resuelto

:nmap gn :s,\v(\w+)(\W*%#\W*)(\w+),\3\2\1\r,<CR>kgJ:nohl<CR> 

imperfecta, pero funciona.

Gracias Camflan por traer el elemento %# a mi atención. Por supuesto, todo está en el wiki, pero no me di cuenta de que podría resolver el problema de exacta (Emacs lo hizo completamente bien) duplicación de la función transpose-words.

+0

Estoy teniendo dificultades para buscar en Google "% #". ¿Qué significan aquí? –

+0

Use la ayuda de Vim incorporada:: h/\% # –

Respuesta

7

Estos son de mi .vimrc y funcionan bien para mí.

" swap two words 
:vnoremap <C-X> <Esc>`.``gvP``P 
" Swap word with next word 
nmap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l> *N* 
+0

Gracias, me gusta mucho el mapa visual. Sin embargo, hay que tener cuidado de que dado que el número de columna de una marca no cambia, si las dos palabras que está intercambiando están en la misma línea, entonces * debe * comenzar con la eliminación de la primera palabra de la izquierda y luego . segunda palabra de la izquierda, no al revés (la excepción a la excepción es cuando las dos palabras son en realidad de la misma longitud). –

5

Dependiendo de la situación, puede usar los comandos W o B, como en dWwP. Las versiones "capitales" saltan al espacio siguiente/anterior, incluida la puntuación. Los comandos f y t también pueden ayudar a especificar el final del rango eliminado.

También hay un debate sobre el Vim Tips Wiki sobre diversas técnicas de intercambio.

5

En medio de una línea, vaya a la primera letra de la primera palabra, y luego hacer

dw wP 

Al final de una línea (es decir, las dos últimas palabras de la línea), vaya a la el espacio entre las palabras y hacer

2dw bhP 

De la mano Equivalence of VIM & Emacs commands


Se podría añadir teclas de acceso directo para aquellos añadiendo algo como lo siguiente a su archivo vimrc:

map L dwwP 
map M 2dwbhP 

En ese caso, SHIFT-L (en modo comando) sería cambiar las palabras en el medio de la línea y SHIFT-M lo haría al final.

NB: Funciona mejor con palabras separadas por espacios y no maneja muy bien el caso específico del OP.

0

Puede utilizar dwwP o dWwP como Mark y CapnNefarious han dicho, pero tengo algunas notas de mi propia:

  • Si el cursor está en la primera letra de la segunda palabra, como en el ejemplo que diste, puedes usar dwbP (o dWbP para manejar la puntuación);
  • Si el cursor está en el medio de la palabra, puede usar dawbP/daWbP.
2

Hay un consejo en http://vim.wikia.com/wiki/VimTip10. Pero elijo rodar el mío. Mi fragmento tiene dos ventajas obvias sobre el método mencionado en el consejo: 1) funciona cuando el cursor no está en una palabra. 2) no iluminará toda la pantalla.

Funciona casi como 'transpose-words' de emacs, excepto que cuando la transposición es imposible, no hace nada. (Las palabras de transposición de emacs parpadearán y cambiarán la posición del cursor al comienzo de la palabra actual.)

"transpose words (like emacs `transpose-words') 
function! TransposeWords() 
    if search('\w\+\%#\w*\W\+\w\+') 
    elseif search('\w\+\W\+\%#\W*\w\+') 
    endif 
    let l:pos = getpos('.') 
    exec 'silent! :s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/' 
    call setpos('.', l:pos) 
    let l:_ = search('\(\%#\w\+\W\+\)\@<=\w\+') 
    normal el 
endfunction 

nmap <silent> <M-right> :call TransposeWords()<CR> 
imap <silent> <M-right> <C-O>:call TransposeWords()<CR> 
Cuestiones relacionadas