2013-07-29 20 views
6

spesso incollare gli elementi separati da capo o linea alimenta in un buffer di Emacs conseguente ciascun elemento residente su una linea diversa simili:Emacs: convertire gli elementi su linee separate per un elenco separato da virgole

one 
two 
three 
four 

Molto spesso io in realtà voglio un elenco di valori separati da virgola in questo modo:

"one", "two", "three", "four" 

sarebbe bello per essere in grado di fare una conversione one-touch da linee da elencare. Immagino di poterlo convertire usando una regex, ma sembra il tipo di operazione comunemente usata che potrebbe già avere una funzione Emacs integrata. Qualcuno può suggerirne uno?

risposta

4

M-q sostituisce interruzioni di riga con spazi (in elenchi ragionevolmente brevi di parole brevi) ma non aggiunge virgolette e virgole. Oppure, forse M-^ molte volte, finché non li avrai tutti sulla stessa linea. Oltre a questo, nulla viene in mente.

Ovviamente, una macro di tastiera è un buon candidato per questo.

Ma un modo più veloce, che non crea molti annullamento dei passaggi sarebbero qualcosa in queste righe:

(defun lines-to-cslist (start end &optional arg) 
    (interactive "r\nP") 
    (let ((insertion 
     (mapconcat 
      (lambda (x) (format "\"%s\"" x)) 
      (split-string (buffer-substring start end)) ", "))) 
    (delete-region start end) 
    (insert insertion) 
    (when arg (forward-char (length insertion))))) 
+0

Il cursore deve essere posizionato subito dopo l'ultima riga nell'elenco per consentire a questa funzione di funzionare come previsto, ma probabilmente è il posto naturale del cursore se si è appena incollato qualcosa nel buffer. Questo funziona per me - grazie. Edit: E questo, per inciso, se mi piace Emacs! – SlowLearner

+0

@SlowLearner L'ho modificato per utilizzare l'argomento universale come un'istruzione per passare al punto dopo l'inserimento, quindi se si chiama 'M-x lines-to-cslist', il punto si sposterà alla fine della stringa inserita. –

4

Edit: Io faccio vedere siete alla ricerca di una funzione di ... ma dal momento che l'unica risposta è semplicemente scrivere la tua (cioè non esiste uno built-in), ho pensato di inserire la regex come, poiché altri potrebbero inciampare su questo e apprezzare un'alternativa alla scrittura del funzione e inserendolo in .emacs.


Si tratta di due passi, ma solo perché voleva il testo citato:

Come incollato in Emacs *scratch* tampone (aggiunto five six per dimostrare che funziona con più parole per riga, se questo è di interesse):

one 
two 
three 
four 
five six 

In primo luogo, sostituire individuale word con "word":

M-x replace-regexp RET \(.*\) RET "\1" RET produce:

"one" 
"two" 
"three" 
"four" 
"five six" 

Ora, sostituire ogni ritorno a capo (in Emacs, C-q C-j) con una ,:

M-x replace-regexp RET C-q C-j RET , RET produce:

"one", "two", "three", "four", "five six" 
1

Ho scritto una soluzione per questo al lavoro oggi. Di seguito sono riportate le funzioni per convertire da linee a csv e da csv a linee, con un separatore in grado di specificare l'utente. Questa funzione opera sulla regione attualmente evidenziata.

(defun lines-to-csv (separator) 
    "Converts the current region lines to a single line, CSV value, separated by the provided separator string." 
    (interactive "sEnter separator character: ") 
    (setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end))) 
    (insert 
    (mapconcat 'identity 
       (split-string current-region-string "\n") 
       separator))) 

(defun csv-to-lines (separator) 
    "Converts the current region line, as a csv string, to a set of independent lines, splitting the string based on the provided separator." 
    (interactive "sEnter separator character: ") 
    (setq current-region-string (buffer-substring-no-properties (region-beginning) (region-end))) 
    (insert 
    (mapconcat 'identity 
       (split-string current-region-string separator) 
       "\n"))) 

Per utilizzare questo, evidenziare la regione che si desidera modificare, quindi fare M-x e specificare il separatore da utilizzare.

0

Solitamente eseguo questo tipo di attività utilizzando le macro. M-X kmacro-start-macro e M-x kmacro-end-or-call-macro, che è quindi possibile ripetere più volte.

Problemi correlati