Principes de base des curseurs multiples

55

J'ai récemment appris à ce sujet multiple-cursors, et cela semble être un paquet très utile. J'ai parcouru la documentation sur le référentiel d'origine , mais les commandes me semblent toujours un peu obscures.

J'ai ensuite regardé la vidéo dans Emacs Rocks !, et la vidéo est excellente, mais elle se concentre principalement sur ce qui multiple-cursorsest capable de le faire, plutôt que sur la façon de le faire.

Existe-t-il des guides, des tutoriels ou des exemples illustrant ses fonctionnalités les plus élémentaires?

Amelio Vazquez-Reina
la source
4
J'ai pu multiple-cursorstrès vite me mettre à l'aise en lisant le fichier README. Ma recommandation est juste d'apprendre mc/mark-next-like-this. Essayez-le et familiarisez-vous avec ce qu'il fait. À partir de là, reportez-vous au fichier README chaque fois que vous avez une question commençant par "Je me demande si plusieurs curseurs peuvent le faire ..." Cela dit, je pense qu'une introduction plus fondamentale que celle d'Emacs! la vidéo serait utile pour les débutants.
nispio
Entièrement d'accord! Absolument pas clair comment l'utiliser. J'ai juste masqué les lignes puis fait mc / edit-lines avec KBD lié (pas via Mx comme indiqué sur Github) Ensuite, je vois plusieurs curseurs, mais ils disparaissent simplement après toute saisie de texte
Dima Fomin

Réponses:

19

Outre les utilisations décrites par @bastibe, j'utilise plusieurs curseurs pour ajouter ou supprimer du texte depuis le début / la fin d'un groupe de lignes:

  1. Déplacer le point au début ou à la fin de la zone d'intérêt
  2. appeler set-rectangular-region-anchor(lié à la clé que vous voulez, je pense que la suggestion de Magnars était H-space, si vous avez une hyper clé)
  3. Déplacez le point en avant ou en arrière par ligne ( C-net C-p) jusqu'à ce que vous ayez un curseur sur chaque ligne à modifier
  4. Insérez ou supprimez du texte si nécessaire, en vous déplaçant éventuellement en fin de ligne ( C-e) pour y apporter des modifications.

Vous pouvez utiliser forward-word, forward sentenceetc. pour vous déplacer dans les lignes, ce qui vous permet d’éditer le quatrième mot de chaque ligne, même si le texte de chaque ligne n’est pas identique.

Par exemple, je fais ce genre de travail tout le temps:

  • C-u M-!ls / test-dat / pp5 / * fsaRETURN

    Ceci insère le contenu du répertoire pp5 dans le tampon. Je place un point !au début de la liste:

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa
/test-dat/pp5/QCJB-22-5_Frag#90.fsa
/test-dat/pp5/ONGL-1-5_Frag#102.fsa
/test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • Ajouter des curseurs à chaque ligne avec H-space, C-nx 4
  • dupliquer chaque ligne avec C-k C-y space C-y C-a

!/test-dat/pp5/ONAB-6-5_Frag#89.fsa /test-dat/pp5/ONAB-6-5_Frag#89.fsa
!/test-dat/pp5/QCJB-22-5_Frag#90.fsa /test-dat/pp5/QCJB-22-5_Frag#90.fsa
!/test-dat/pp5/ONGL-1-5_Frag#102.fsa /test-dat/pp5/ONGL-1-5_Frag#102.fsa
!/test-dat/pp5/ONGL-1-5_Frag#78.fsa /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • découper la première section en noms de variables avec M-dx 3 C-d C-fx3 M-dx3 <-

ONAB-6-5 <-! /test-dat/pp5/ONAB-6-5_Frag#89.fsa
QCJB-22-5 <-! /test-dat/pp5/QCJB-22-5_Frag#90.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#102.fsa
ONGL-1-5 <-! /test-dat/pp5/ONGL-1-5_Frag#78.fsa
  • puis enveloppez le nom de fichier dans la fonction pour le charger: read.file ( C-d" C-e")RETURN

ONAB-6-5 <- read.file("/test-dat/pp5/ONAB-6-5_Frag#89.fsa")
QCJB-22-5 <- read.file("/test-dat/pp5/QCJB-22-5_Frag#90.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#102.fsa")
ONGL-1-5 <- read.file("/test-dat/pp5/ONGL-1-5_Frag#78.fsa")

Et voila, vous avez converti une liste de fichiers en code pour lire cette liste. C'est en fait beaucoup plus difficile à décrire que de le faire!

Tyler
la source
3
Si vous faites souvent la même chose, vous pouvez l'envelopper dans une macro de clavier. Les macros du clavier et multiple-cursorspeuvent faire une combinaison très puissante.
nispio
@nispio d'accord! Parfois, je répète le même processus et une macro serait utile. Souvent, cependant, il existe de petites différences au milieu du flux de travail qui nécessitent de légers changements qui «casseraient» une macro.
Tyler
1
Vous pouvez souvent décrire avec précision l’emplacement auquel vous souhaitez que le curseur accède à l’aide d’une expression rationnelle. Dans de tels cas, utiliser phi-searchpeut être plus robuste que de naviguer avec des commandes telles queM-f (x3)
nispio
@nispio bien sûr, cela dépend de la situation. Avec des noms toujours structurés, il est facile de se déplacer par mot. Je n'avais pas utilisé la recherche dans plusieurs curseurs car les commandes de recherche intégrées emacs sont fragiles avec mc. Je ne savais pas phi-search, ça a l'air super!
Tyler
22

J'ai essentiellement deux cas d'utilisation fréquente pour multiple-cursors:

  • Remplace une ficelle. Marquez une instance d'une chaîne, puis utilisez mc/mark-next-like-thiset mc/mark-previous-like-thispour marquer plusieurs instances de celle-ci. J'ai alors immédiatement frappé C-wpour supprimer chaque instance et écrire une nouvelle chaîne à la place. J'utilise souvent cela pour renommer une variable en code.
  • Éditez plusieurs endroits simultanément. Soit vous marquez plusieurs occurrences d’une chaîne comme précédemment, mais vous annulez immédiatement la sélection (mais pas les curseurs) C-g, ou vous placez un repère dans la même colonne de lignes différentes et mc/edit-linesvous obtenez un curseur par ligne. Vous pouvez maintenant utiliser les commandes d'édition habituelles qui agissent sur chacun de ces curseurs.

Le premier cas d'utilisation est particulièrement utile avec expand-region. Je suis er/expand-regionlié à C-j, et mc/mark-next-like-thiset mc/mark-previous-like-thisà C->et C-<. Avec cela, je peux facilement sélectionner le mot point et marquer instantanément l’occurrence suivante / précédente de ce mot.

Le deuxième cas d'utilisation a remplacé la plupart des utilisations de macros pour moi. Au lieu d'enregistrer une macro et de l'appliquer à plusieurs endroits, je placerais un curseur sur chaque endroit et effectuerais l'opération à la fois.

bastibe
la source
Merci @Bastibe. Toute liaison particulière que vous multiple-cursors recommandez ou recommandez, par exemple, mark-next-like-this& mark-previous-like-this?
Amelio Vazquez-Reina
@ user815423426 comme indiqué dans le post, j'utilise C->et C-<pour mark-next-like-thiset mark-previous-like-this.
Bastibe
pourquoi ne pas utiliser standart M-% pour rechercher et remplacer ?
Dima Fomin
6

J'aimerais ajouter quelques extras que j'utilise parfois avec multiple-cursors.

J'ai trouvé ce qui suit utile:

iy-go-to-char

Parfois, vous vous rendez compte que vous avez besoin de passer au suivant #ou au prochain ,délimiteur. Ceci est particulièrement utile lorsque vous devez vous déplacer sur différents nombres de mots pour chaque curseur. Il fournit les fonctions iy-go-to-charet iy-go-to-char-backward, que vous pouvez lier et utiliser facilement.

élargir la région

Ceci est vraiment utile pour des raisons similaires iy- lorsque vous avez des lignes légèrement différentes sous chaque curseur et que vous souhaitez peut-être sélectionner la chaîne entre guillemets sous le point ou similaire.

trucs personnalisés

Ce sont des choses qui sont juste elisp dans ma config, mais je trouve utile. Probablement pas écrit par moi.

Invite à la saisie
J'ai reçu celle-ci de Magnars en réponse à une demande de mise d'une chaîne différente sous chaque curseur. Le code est simple, mais le lier à quelque chose et utiliser plusieurs curseurs est un moyen pratique d'insérer des éléments légèrement différents à chaque endroit.

(defun prompt-for-insert ()
  (interactive)
  (insert (read-string "Insert: ")))

Incrément numéro au point
Cela vient soit de SO, ou emacswiki. Je ne sais pas lequel. C'est très utile en soi, et aussi lorsqu'il est utilisé en combinaison avecmc/insert-numbers

(defun my-increment-number-decimal (&optional arg)
  "Increment the number forward from point by 'arg'."
  (interactive "p*")
  (save-excursion
    (save-match-data
      (let (inc-by field-width answer)
        (setq inc-by (if arg arg 1))
        (skip-chars-backward "0123456789")
        (when (re-search-forward "[0-9]+" nil t)
          (setq field-width (- (match-end 0) (match-beginning 0)))
          (setq answer (+ (string-to-number (match-string 0) 10) inc-by))
          (when (< answer 0)
            (setq answer (+ (expt 10 field-width) answer)))
          (replace-match (format (concat "%0" (int-to-string field-width) "d")
                                 answer)))))))

eval-and-replace
C'est super puissant, et permet quelques morceaux vraiment utiles. Il évalue le sexe derrière le curseur et insère le résultat de son évaluation.
Combinez-le avec, multiple-cursors-numberspar exemple, pour insérer des puissances de deux ou une série qui 0 1 2 0 1 2 0 1 2traverse chaque ligne ou quelque chose. (J'ai fait ces deux s.elchoses utilement) ou utilisez-le avec pour écrire ces fastidieuses configurations Java avec des choses par défaut. Vous écrivez chacun CONFIG_VALUE_VARIABLE, puis transformez cela en CONFIG_VALUE_VARIABLE = "configValueVariable"exécution s-camel-case.

(defun eval-and-replace ()
  (interactive)
  (let ((value (eval (preceding-sexp))))
    (kill-sexp -1)
    (insert (format "%s" value))))
Calmement
la source
iy-go-to-char est super utile. Exactement ce que je cherchais.
Heinrich Hartmann
1
  1. Allez à la fin * de ce que vous voulez sélectionner.
  2. Appuyez sur C-S-bou M-S-bpour sélectionner en arrière jusqu'à ce qu'une partie soit sélectionnée. Vous pouvez également utiliser la touche Maj gauche.
  3. Ensuite, appuyez sur C->(appuyez sur la touche Maj si la touche se >trouve en haut de la touche de votre clavier) jusqu'à ce que plusieurs éléments soient sélectionnés.

* Il est important de sélectionner en arrière ou la première sélection placera le curseur dans la mauvaise position.

morishi
la source