Comment envelopper le texte donné autour de la région

11

J'ai souvent une situation où j'ai besoin d'appliquer du texte autour d'une région. Pour HTML et les cas simples, il existe déjà des bibliothèques pour cela. Mais qu'en est-il du cas général? J'aimerais qu'on me demande ce que je vais insérer au début et à la fin de la région.

nperson325681
la source
Voulez-vous l'utiliser pour insérer du contenu arbitraire une fois, ou une poignée de paires, plusieurs fois? Dans ce dernier cas, des bibliothèques telles que les smartparens pourraient s'avérer utiles et elles peuvent être étendues avec des paires personnalisées. Par exemple, vous pouvez ajouter une paire <?php... ?>, puis, lorsque vous sélectionnez une région et un type <?php(ou une liaison de touches), la placer dans la paire. Mais afaik, il n'y a pas de moyen facile d'utiliser ces bibliothèques si vous avez plusieurs paires à un coup.
T. Verron
@ T.Verron: Je sais que ceux-ci existent. Mais pour les moments où il y a un besoin unique de parcourir le code et de marquer les choses, une seule fonction générale et réutilisable convient le mieux
nperson325681

Réponses:

6

Je suis allé sur Google et j'ai trouvé ce post de John D. Cook . Il montre comment créer une fonction interactive simple pour obtenir facilement des balises HTML / XML dans la région. De là, j'ai modifié la fonction pour demander deux fois.

(defun tag-word-or-region (text-begin text-end)
  "Surround current word or region with given text."
  (interactive "sStart tag: \nsEnd tag: ")
  (let (pos1 pos2 bds)
    (if (and transient-mark-mode mark-active)
        (progn
          (goto-char (region-end))
          (insert text-end)
          (goto-char (region-beginning))
          (insert text-begin))
      (progn
        (setq bds (bounds-of-thing-at-point 'symbol))
        (goto-char (cdr bds))
        (insert text-end)
        (goto-char (car bds))
        (insert text-begin)))))

Plus important encore, cette fonction peut également être utilisée comme un outil auxiliaire, par exemple lorsque vous souhaitez lier des clés pour mapper des bits de texte spécifiques.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))
nperson325681
la source
En fait, la façon dont cela gère certains cas limites n'est pas optimale; la recherche du début peut parfois échouer et laisser les deux balises à la fin. Il se peut evilque j'utilise cela interfère ici. Peut-être qu'une fonction de type interactive "r" fonctionnait de manière plus robuste?
nperson325681
4

Je proposerais une approche différente. Lorsqu'il y a une région, par définition, elle pointdoit être au début (ou à la fin) de la région, et marksera à la fin (ou au début). Ce qui signifie que vous pouvez entrer le texte que vous voulez au point, puis utiliser exchange-point-and-mark, c'est C-x C-x-à- dire , pour sauter à l'autre extrémité de la région. Entrez la seconde moitié de votre emballage et vous avez terminé.

Vous n'êtes pas explicitement invité à entrer le texte d'insertion, mais je ne peux pas imaginer qu'il y aurait un moyen d'accomplir la même chose avec moins d'effort.

Tyler
la source
Si le texte de début et de fin est le même, je me demande si quelque chose comme multiple-cursorspourrait être modifié pour insérer du texte simultanément au début et à la fin de la région active.
glucas
Cela ressemble à la manière manuelle que les utilisateurs de petits éditeurs sont obligés de faire de toute façon. Quoi qu'il en soit, j'ai lu l'utilisation des macros comme sous-texte de votre réponse, je dois dire. J'aime ton style
nperson325681
1
@progo - Merci :) Cela ressemble à une approche plus manuelle, mais il utilise en fait moins de frappes que votre alternative. Avec cette approche, autre que le texte d'habillage, vous n'avez besoin que C-x C-x. Avec votre réponse, vous devez appeler votre fonction ( C-c something), et vous devez également frapper returnaprès chaque entrée. Peu importe ce que vous faites, vous disposez de deux touches supplémentaires. Cela dit, cela n'aide pas si vous voulez que quelque chose appelle elisp.
Tyler
3

Juste pour la variété:

Une autre façon de le faire avec un texte de début et de fin arbitraire serait d'utiliser replace-regexpsur la région: faire correspondre .+et remplacer par before \& after, ou tout texte que vous souhaitez utiliser pour beforeet after.

Vous pouvez écrire une commande pour cela, mais je pense à un cas où, dans un fichier donné, vous souhaitez appliquer le même texte de début / fin à plusieurs endroits. Vous pouvez enregistrer une macro ou simplement utiliser l'historique du mini-tampon pour répéter sur une autre région.

Bien sûr, si le texte que vous souhaitez encapsuler peut être exprimé sous la forme d'une expression régulière, vous n'aurez même pas besoin de sélectionner une région et de le faire query-replace-regexpsur le tampon, mais le texte que vous souhaitez encapsuler n'est probablement pas cohérent.

glucas
la source