Posso unire le linee con una virgola (o un altro carattere)?


19

So di poter unire le linee in Vim con Je diverse varianti ( gJ, ecc.); Jsarà "Rimuovere il trattino e inserire fino a due spazi" .

Ma c'è anche un modo semplice per inserire un altro personaggio al posto dei due spazi? Ad esempio una virgola ( ,) o virgola e spazio ( ,)?

Dato:

8
9
10
32

Vorrei finire con:

8, 9, 10, 32

o:

8,9,10,32

Potresti anche provare github.com/sk1418/Join (non testato).
VanLaser

Risposte:


5

Ho scritto un plug-in Join, posso fare quello che vuoi e molto altro.

Ad eccezione di tutte le funzionalità fornite dal comando build-in: join, Join può:

  • Unisci linee con separatore (stringa)
  • Unisci le linee con o senza tagliare gli spazi bianchi iniziali / finali
  • Linee di unione con conteggio negativo (unione all'indietro)
  • Unire le linee al contrario
  • Unisci linee e mantieni le linee unite (senza rimuovere le linee unite)
  • Unisci le linee con qualsiasi combinazione delle opzioni sopra

maggiori dettagli e schermate:

https://github.com/sk1418/Join


23

Un modo semplice è questo: seleziona semplicemente le tue linee (tutte tranne l'ultima) - oppure usa %- ed esegui:

:'<,'>s/\n/,/

o

:'<,'>s/\n/, /

(dove, ovviamente, la '<,'>parte era già stata inserita dopo :da Vim, per indirizzare la selezione)


(2 °) Aggiornamento:

Partendo da quanto sopra (e dal commento di Sato Katsura ), ecco una possibile implementazione di "join interattivo", con conteggio e supporto ripetizione opzionale:

" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
    if (a:use_last_sep == 0) "interactive, ask for separator to use
        call inputsave()
        echohl Question
        let l:sep = input("Separator:", g:last_join_separator)
        echohl None
        call inputrestore()
        redraw!
        let g:last_join_separator = l:sep "update last separator value
    else "non-interactive (when repeating with '.')
        let l:sep = g:last_join_separator
    endif
    if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
        let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
    else " don't remove indentation or trailing spaces (act like 'gJ')
        let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
    endif
    if a:firstline < a:lastline "join given range
        execute a:firstline . ',' . (a:lastline - 1) . l:subst
        let l:count = a:lastline - a:firstline + 1 "default count for repeat
    else "or join only with next line
        execute l:subst
        let l:count = 1 "default count for repeat
    endif
    "make command repeatable
    "(with the tpope/vim-repeat plugin: optional, recommended)
    if (a:0 == 0)
        silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
    else
        silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
    endif
endfunction

noremap <silent> <Plug>(interactiveJoin)  :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin)       :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin)      :call <SID>interactiveJoin(1,'g')<CR>

E una vera mappatura:

"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)

Questo è un po '(*) simile J, ma interattivo - richiederà la stringa di separazione. La stringa predefinita è uno spazio, quindi, ad esempio, per unire le linee senza separatore, premere Backspacequando richiesto, rimuovere il carattere di spazio predefinito e Enteraccettare il separatore (ora) vuoto. Il conteggio, ad esempio 3J, funziona anche. Se il tpope/vim-repeatplugin è installato, ripetendo con '.' funzionerà anche riutilizzando l'ultimo separatore e (se non modificato - ad es. 10.) l'ultimo conteggio o l'intervallo della linea visiva.


(*) Non è esattamente come J, però: mentre rimuoverà il rientro, non cercherà .!?(fine della frase) di inserire 2 spazi invece di uno, o inserire uno spazio solo se manca (è difficile fare qualcosa come questo, poiché la stringa di separazione può essere qualsiasi cosa ora). Rimuoverà anche gli spazi finali (ha più senso).

Penso che questo potrebbe essere un buon modo per sovraccaricare lo spazio lettere limitato degli operatori :)

Beh, tecnicamente Jnon è proprio un operatore, ma vicino a uno - per esempio, non puoi fare Jaw, unire "una parola".

(suggerimenti sono ben accetti)

inserisci qui la descrizione dell'immagine


2
Meglio ancora: :'<,'>-1s/\n/, /per le linee segnate o :1,$-1s/\n/, /per l'intero file.
Sato Katsura,

Anzi, è ancora meglio :)
VanLaser,

@SatoKatsura puoi spiegarmi il -1?
alxndr,

1
@alxndr - è usato per saltare l'ultima riga nell'intervallo / file: ad es. nell'esempio OP, non vuoi una virgola dopo 32, e non vuoi unirti alla riga successiva, se esiste . Puoi persino usare '<,'>-s/\n/, /o 1,$-s/\n/, /come -è uguale a -1.
VanLaser,

1
Se l:sepè un &, allora il tuo sostituto funzionerà in modo errato, poiché &è magico nel rimpiazzo. Potrebbe essere meglio usare il \=per usare una stringa letterale - let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- invece di provare a gestire la fuga.
Jamessan,

3

Ecco un esempio usando il comando esterno:

:%!paste -sd,

dove %!sostituisce il buffer corrente (contenuto del file) con il comando: paste -sd,(i parametri -svengono utilizzati per unire più righe e -dimpostare il carattere delimitatore su ,).


3

Nel caso in cui a qualcuno non piaccia digitare Regex e memorizzare altri Comandi Plugin Ex:

Append. Blocco visivo

L'aggiunta del blocco visivo è disponibile nella modalità Blocco visivo ( <C-v>) e può eseguire un blocco A ppend (e bloccare I nsert per prepend). (ref: :help v_b_A, :help v_b_I)

E se l'ultimo movimento in Block Visual Mode è $, l'appendice verrà eseguita alla fine di tutte le selezioni; altrimenti gli spazi verranno inseriti prima del testo che hai aggiunto (immagina di allineare la chiusura )alla fine di diverse chiamate di metodo nel codice).

Con il testo di esempio qui sotto e il cursore acceso 8:

8
9
10
12

<C-v>}$A,<C-c>. Dopo essere tornati alla modalità normale, possiamo vedere che ,viene aggiunto a tutte le linee selezionate. (Prova senza $)

Quindi eseguire gvnuovamente la selezione dell'area e Jo gJ. Abbiamo un finale ,: 8,9,10,12,e $xabbiamo finito.

Utilizzare Inserisci per Nessun trascinamento ,

Annulla il nostro testo (che sia uu..uo una fantasia :ea 1d<cr>:lat 1) e prova Visual Insert:

j<C-v>}I, <C-c>e quindi possiamo unire le linee gJsenza spazi.

Aspetta aspetta aspetta, manca qualcosa. Come riselezionare l'intero "array"? Questa volta non abbiamo selezionato la prima riga ... quindi gvnon aiuta.

- Oppure può essere d'aiuto, gvokè ri-selezionare ( gv), oangolo pposite e ksu.

PS Il mio mignolo non è rapida e precisa sufficiente digitare /\per /\n, quindi mi piace la combinazione Vim built-in operazioni e movimenti per evitare di utilizzare Regex. Tuttavia, se lo faccio abbastanza frequentemente, usando una mappatura, forse quelli che mappano sui plugin dovrebbero essere migliori.


1

Un modo molto più semplice senza plug-in o comandi esterni per rimappare join ( J) da uno spazio a qualunque personaggio ti piaccia. Ad esempio, per unire con una virgola e uno spazio:

:nmap J :s/\n/, /^M

Per il carattere speciale newline alla fine ( ^M) premere Ctrl-Ve quindi Return / Enter. Lo stesso vale se si desidera sostituire con una scheda ( ^I), digitare Ctrl-Iquindi Tab.

:nmap J :s/\n/^I/^M

Ciò che sta facendo è sostituire una nuova riga con una scheda sulla riga corrente e rimappare quel comportamento al carattere J.

Funziona anche con combinazioni, come in 4Jper unire le 4 righe successive.


0

È possibile registrare una macro per unire le linee con una virgola. Ciò è utile se si tratta di un'attività rara o una tantum e non ricordi come scrivere un comando sostitutivo e un'espressione regolare per eseguire l'attività, ma ti ricordi come registrare ed eseguire una macro.

Per unire le linee con una virgola, digitare qjgJi,Escqper registrare la macro nel registro j. Quindi è possibile eseguire la macro con @j. Puoi rieseguire la macro con @@, che risparmia sulla digitazione quando la esegui più volte di seguito: puoi anche semplicemente tenere premuto @fino a quando non ti avvicini alla fine delle linee che vuoi unire. Puoi anche utilizzare un prefisso numerico su @jo @@per ripeterlo un determinato numero di volte. Questo lascia intatto lo spazio iniziale e finale, quindi ci saranno spazi prima o dopo la virgola se il testo originale aveva spazi lì.

Per unire con una virgola e uno spazio, inserire Spacetra ,e Escdurante la registrazione della macro.

È inoltre possibile utilizzare Jinvece che gJdurante la registrazione della macro, che solitamente unisce le linee con una virgola e uno spazio. Tuttavia, se la riga corrente ha spazi vuoti finali, la virgola apparirà dopo lo spazio bianco senza uno spazio che la segue. Inoltre, non include lo spazio se la riga successiva inizia con ), e mette due spazi dopo la virgola se joinspacesè impostato e alla fine delle linee con ., !o ?. Queste avvertenze sono descritte sotto :help J.

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.