Comment puis-je faire avancer 'n' même si j'ai commencé à chercher avec '?' ou '#'?

19

Vim a (au moins) deux ensembles de commandes qui recherchent dans des directions opposées. Taper /puis un motif recherchera le motif dans le document; en tapant ?, puis un motif cherchera en arrière. La même relation existe entre les commandes *et #.

Ce que je n'aime pas, c'est que ces commandes définissent également la direction de recherche pour les commandes net N. Après utilisation /, navance dans le document et Nrecule; après utilisation ?, nrecule et Navance. (En d'autres termes, nva toujours dans le même sens que la recherche d'origine et Nva toujours dans l'autre sens.)

Comment puis-je navancer dans le document et Nrevenir en arrière, quelle que soit la direction dans laquelle j'ai commencé la recherche?

bdesham
la source

Réponses:

29

Vous pouvez modifier le comportement de net Neffectuer une recherche cohérente vers le bas / vers le haut en utilisant les éléments suivants:

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

Mise à jour: comment ça marche?

Cela utilise expression-maps, qui mappe les lhs de la carte à une expression qui sera évaluée, chaque fois que le lhs est rencontré. Voir :h map-expressiondans l'aide.

Ce qui se passe, c'est que la variable v: searchforward (qui détermine l'état interne de la direction de la dernière recherche, voir :h v:searchforward) est utilisée comme index pour la chaîne en face d'elle. Donc, dans le cas de la première carte, si la dernière direction de recherche était en avant, le n sera mappé sur 'n' (index de 1, signifiant retourner le deuxième caractère) et s'il était en arrière, le 'n' sera mappé sur 'N' (car la variable v: searchforward est 0 et donc le 'N' sera retourné.

Une autre façon d'écrire ces cartes serait (ce qui pourrait être plus clair):

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

Il existe également certains plugins qui font cela (c'est-à-dire le plugin SearchRepeat et peut-être d'autres également).

Christian Brabandt
la source
Merci d'avoir mentionné mon plugin; J'étais sur le point de recommander cela comme alternative :-)
Ingo Karkat
2
Utilisation intelligente de l'indice!
wchargin
6
Pourriez-vous s'il vous plaît ajouter une explication? Je n'ai jamais vu cette syntaxe auparavant, et j'aimerais savoir comment cela fonctionne.
EvergreenTree
1
@EvergreenTree: Ajout de quelques explications supplémentaires
Christian Brabandt
2
@ChristianBrabandt C'est très intelligent. Je n'ai jamais pensé que vous utilisiez v:searchforwardun index.
EvergreenTree
1

Sur la base de la solution de Christian Brabandt, j'ai trouvé

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

Ces mappings obéissent également au foldopenparamètre

Naumann
la source
0

J'utilise le plugin SearchIndex . Pour utiliser la réponse de Christian Brabandt mais garder la fonctionnalité du plugin d'afficher le numéro de correspondance chaque fois que je tape nou N, je mets ceci dans mon vimrc:

nnoremap <silent><expr> n (v:searchforward ? 'n' : 'N') . ":SearchIndex<CR>"
nnoremap <silent><expr> N (v:searchforward ? 'N' : 'n') . ":SearchIndex<CR>"
bdesham
la source