Mettre une marque à sa valeur précédente

9

Parfois, j'utilise des repères pour naviguer facilement dans différents fichiers en utilisant mA, mB... et 'A, 'B...

Et parfois (plus souvent que je ne l'admets) à cause de l'inattention ou pour quelque raison que ce soit, j'utilise m[LETTER]avec une marque déjà existante qui efface sa valeur précédente lorsque je ne le veux pas. La plupart du temps, lorsque je le fais, je n'ai pas ouvert le fichier initialement pointé par la marque.

Dans ce cas, lorsque je me suis rendu compte immédiatement que j'avais fait une erreur, est-il possible d'obtenir la valeur précédente de ma marque autrement que de me rappeler où elle pointait, de naviguer vers cet emplacement et de la redéfinir?

Je n'ai pas trouvé de commande comme celle-ci dans le document, donc si elle n'existe pas, y a-t-il une solution intelligente que certains d'entre vous utilisent dans cette situation?

statox
la source
1
Vous pouvez également consulter cet article pour plus d'informations: superuser.com/questions/687441/…
nobe4
@ Nobe4 merci pour votre lien je ne l'ai pas trouvé mais cela semble confirmer qu'il n'est pas vraiment possible de le faire facilement.
statox
Utilisez les commandes de saut ( ctrl-o, ctrl-iet :jumps) avec votre propre mémoire personnelle :)
VanLaser

Réponses:

5

Voici quelques VimScript de base qui font à peu près ce que vous voulez.

Nous remplaçons les mapar mzcorrespondances pour stocker la valeur actuelle g:previous_marksavant d' appeler l'original mde mettre effectivement la marque. Nous définissons également à <Leader>matravers <Leader>mzpour afficher l'historique de ladite marque.

Vous voudrez probablement stocker les informations de g:previous_marksmanière plus organisée et ajouter la possibilité de restaurer rapidement une marque (plutôt que de simplement voir les emplacements), mais cet exemple montre comment cela peut être fait, d'autres ajustements sont laissés en exercice au lecteur ;-)

let g:previous_marks = {}
fun! MyMark(mark)
    let l:marks = ''
    redir => l:marks
        try
            silent! execute 'marks ' . a:mark
        catch
        endtry
    redir END

    if l:marks != ''
        if !has_key(g:previous_marks, a:mark)
            let g:previous_marks[a:mark] = []
        endif
        call add(g:previous_marks[a:mark], split(l:marks, "\n")[1])
    endif

    execute 'normal! m' . a:mark
endfun

fun! ShowHistory(mark)
    if !has_key(g:previous_marks, a:mark)
        echoerr 'No history for ' . a:mark
        return
    endif

    for l:line in g:previous_marks[a:mark]
        echo l:line
    endfor
endfun

fun! MakeMappings()
    for l:char in range(97, 122)
        let l:char = nr2char(l:char)

        execute 'nnoremap <silent> m' . l:char . ' :call MyMark("' . l:char . '")<CR>'
        execute 'nnoremap <silent> <Leader>m' . l:char . ' :call ShowHistory("' . l:char . '")<CR>'
    endfor
endfun

call MakeMappings()
Martin Tournoij
la source
Wow comme d'habitude réponse incroyable! Je vais essayer de prendre le temps ce week-end pour mettre en œuvre l'exercice pour le lecteur;)
statox
2

Pas exactement ce que vous voulez, mais peut-être plus utile: le plugin de signature . Il montre les marques actuelles sous forme de signes dans la marge de la gouttière et dispose de raccourcis simples pour les modifier. Il peut également mettre la liste des panneaux dans une liste d'emplacement pour un accès rapide.

Sato Katsura
la source
Je ne suis pas un grand fan de la marque visible sur la marge, mais il semble avoir des fonctionnalités intéressantes, je vais y jeter un œil.
statox
@statox Dans la même veine, il y a aussi des repères . Il affiche littéralement toutes les marques (le plugin ci-dessus ne traite que les marques alphabétiques) et peut être basculé avec une clé. Je le trouve utile de temps en temps.
Sato Katsura du
Oui, j'utilise les showmarks depuis un certain temps (contrairement à la signature) c'est pourquoi j'ai dit que je ne suis pas fan des marques en marge mais j'essaie la signature en ce moment pour voir si je l'aime :-)
statox
2

Étant donné que le problème réel semble être la navigation entre plusieurs fichiers / positions, je suggère cette solution simple, basée sur le plugin Unite :

:Unite jump -auto-preview

Cette commande (qui peut être mappée à quelque chose comme <leader>jpar exemple) affichera la liste de sauts, avec un aperçu: chaque fois que vous parcourez la liste avec j/ k, plusieurs lignes autour de la position du curseur dans ce fichier seront affichées.

entrez la description de l'image ici


Alternative:

Les marques par défaut sont si faciles à remplacer: des signets nommés pourraient peut-être mieux correspondre à votre cas d'utilisation, par exemple avec le plugin simple_bookmarks .

VanLaser
la source
Je ne peux pas vraiment dire que le problème est ce type de navigation car j'utilise ces marques de temps en temps et la plupart du temps je navigue différemment dans mes fichiers. Néanmoins, je pense depuis longtemps que je devrais utiliser la liste de sauts plus souvent, ce qui semble être une bonne façon de le faire!
statox
Même si elles peuvent être enregistrées entre les sessions vim, il est trop facile d'écraser les marques. J'ai ajouté une solution alternative.
VanLaser
En effet, votre solution alternative semble valoir la peine d'être essayée, merci beaucoup!
statox