¿Cómo puedo hacer que 'n' avance incluso si comencé a buscar con '?' o '#'?

19

Vim tiene (al menos) dos conjuntos de comandos que buscan en direcciones opuestas. Al escribir /y luego un patrón, se buscará el patrón en el documento; escribiendo ?y luego un patrón buscará hacia atrás. La misma relación existe entre los comandos *y #.

Lo que no me gusta es que estos comandos también establecen la dirección de búsqueda de los comandos ny N. Después de usar /, navanza por el documento y Nretrocede; después de usar ?, nretrocede y Navanza. (En otras palabras, nsiempre va en la misma dirección que la búsqueda original y Nsiempre va en la otra dirección).

¿Cómo puedo navanzar por el documento y Nretroceder, independientemente de en qué dirección comencé a buscar?

Bdesham
fuente

Respuestas:

29

Puede cambiar el comportamiento ny Nbuscar constantemente hacia abajo / hacia arriba utilizando lo siguiente:

nnoremap <expr> n 'Nn'[v:searchforward]
nnoremap <expr> N 'nN'[v:searchforward]

Actualización: ¿Cómo funciona?

Esto utiliza mapas de expresión, que mapean las lhs del mapa a una expresión que se evaluará, cada vez que se encuentre la lhs. Ver :h map-expressionen la ayuda.

Lo que sucede es que la variable v: searchforward (que determina el estado interno de la dirección en la que se realizó la última búsqueda, ver :h v:searchforward) se usa como índice para la cadena que se encuentra frente a ella. Entonces, en el caso del primer mapa, si la última dirección de búsqueda fue hacia adelante, la n se asignará a 'n' (índice de 1, lo que significa devolver el segundo carácter) y si estaba hacia atrás, la 'n' se asignará a 'N' (porque la variable v: searchforward es 0 y, por lo tanto, se devolverá la 'N'.

Una forma alternativa de escribir esos mapas sería (que podría ser más claro):

nnoremap <expr> n (v:searchforward ? 'n' : 'N')
nnoremap <expr> N (v:searchforward ? 'N' : 'n')

También hay algunos complementos que hacen eso (es decir, el complemento SearchRepeat y posiblemente otros también).

Christian Brabandt
fuente
Gracias por mencionar mi complemento; Estaba a punto de recomendar eso como una alternativa :-)
Ingo Karkat
2
Uso inteligente de suscripciones!
wchargin
66
¿Podría por favor agregar una explicación? No he visto esta sintaxis antes, y me gustaría saber cómo funciona.
EvergreenTree
1
@EvergreenTree: se agregó una explicación más
Christian Brabandt
2
@ChristianBrabandt Eso es muy inteligente. Nunca pensé en ti usando v:searchforwardcomo índice.
EvergreenTree
1

Basado en la solución de Christian Brabandt se me ocurrió

nnoremap <expr> n 'Nn'[v:searchforward].(&fdo=~'search\\|all'?'zv':'')
nnoremap <expr> N 'nN'[v:searchforward].(&fdo=~'search\\|all'?'zv':'')

Estas asignaciones también obedecen a la foldopenconfiguración

Naumann
fuente
0

Estoy usando el complemento SearchIndex . Para usar la respuesta de Christian Brabandt, pero mantener la funcionalidad del complemento de mostrar el número de coincidencia cada vez que escribo no Npongo esto en mi vimrc:

nnoremap <silent><expr> n (v:searchforward ? 'n' : 'N') . ":SearchIndex<CR>"
nnoremap <silent><expr> N (v:searchforward ? 'N' : 'n') . ":SearchIndex<CR>"
Bdesham
fuente