Come avvolgere un determinato testo nella regione


11

Spesso ho una situazione in cui devo applicare del testo in una regione. Per HTML e casi semplici ci sono già librerie per questo. Ma per quanto riguarda il caso generale? Vorrei chiedermi cosa inserirò all'inizio e alla fine della regione.


Vuoi usarlo per inserire contenuti arbitrari una volta, o una manciata di coppie, molte volte? In quest'ultimo caso, librerie come smartparens potrebbero rivelarsi utili e possono essere estese con coppie personalizzate. Ad esempio, potresti aggiungere una coppia <?php... ?>, e quindi, quando selezioni una regione e digiti <?php(o un keybinding), la includi nella coppia. Tuttavia, non esiste un modo semplice per utilizzare queste librerie se si hanno molte coppie one-shot.
T. Verron,

@ T.Verron: so che esistono. Ma per quei momenti in cui c'è un bisogno unico di esaminare il codice e contrassegnare le cose come una singola funzione generale, riutilizzabile si adatta meglio
nperson325681

Risposte:


6

Ho cercato su Google e ho trovato questo post di John D. Cook . Dimostra come creare una semplice funzione interattiva per ottenere facilmente tag HTML / XML nella regione. Da quello ho modificato la funzione per chiedere due volte.

(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)))))

Ancora più importante, questa funzione può essere utilizzata anche come strumento ausiliario, ad esempio quando si desidera associare i tasti per mappare alcuni bit specifici di testo.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))

A proposito, il modo in cui gestisce alcuni casi limite non è ottimale; la ricerca dell'inizio a volte può fallire e lasciare entrambi i tag alla fine. Potrebbe essere evilche io uso che interferisce qui. Forse una funzione di tipo ha interactive "r" funzionato in modo più efficace?
nperson325681,

4

Suggerirei un approccio diverso. Quando c'è una regione, per definizione pointdeve essere all'inizio (o alla fine) della regione e marksarà alla fine (o all'inizio). Ciò significa che è possibile inserire il testo desiderato in un punto, quindi utilizzare exchange-point-and-mark, ad esempio C-x C-x, per passare all'altra estremità della regione. Inserisci la seconda metà del wrapper e il gioco è fatto.

Non ti viene chiesto esplicitamente di inserire il testo di inserimento, ma non riesco a immaginare che ci sarebbe un modo per realizzare la stessa cosa con meno sforzo.


Se il testo iniziale e finale è lo stesso, mi chiedo se qualcosa di simile multiple-cursorspotrebbe essere modificato per inserire il testo simultaneamente all'inizio e alla fine della regione attiva.
glucas,

Sembra il modo manuale che gli utenti degli editor minori sono costretti a fare comunque. Comunque ho letto l'uso delle macro come sottotesto dalla tua risposta, devo dire. Mi piace il tuo stile
nperson325681

1
@progo - Grazie :) Sembra un approccio più manuale, ma in realtà utilizza un numero di tasti inferiore rispetto alla tua alternativa. Con questo approccio, oltre al testo a capo, hai solo bisogno C-x C-x. Con la tua risposta, devi chiamare la tua funzione ( C-c something) e devi anche premere returndopo ogni voce. Quindi, qualunque cosa tu faccia, hai altre due battiture. Detto questo, non aiuta se vuoi qualcosa da chiamare da elisp.
Tyler,

3

Solo per motivi di varietà:

Un altro modo per farlo con un testo di inizio e fine arbitrario sarebbe quello di usare replace-regexpsulla regione: abbina .+e sostituisci con before \& after, o qualunque testo tu voglia usare per beforee after.

Potresti scrivere un comando do a questo, ma sto pensando a un caso in cui in un determinato file vuoi applicare lo stesso testo iniziale / finale in più punti. Puoi registrare una macro o semplicemente usare la cronologia del minibuffer per ripetere su un'altra regione.

Ovviamente se il testo che vuoi avvolgere può essere espresso come un'espressione regolare, allora non dovrai nemmeno selezionare una regione e puoi fare un query-replace-regexpbuffer, ma presumibilmente il testo che vuoi avvolgere non è così coerente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.