Puis-je joindre des lignes avec une virgule (ou un autre caractère)?

19

Je sais que je peux joindre des lignes dans Vim avec Jet plusieurs variantes de celles-ci ( gJ, etc.); Jva "Supprimer le retrait et insérer jusqu'à deux espaces" .

Mais existe-t-il également un moyen simple d'insérer un autre caractère au lieu des deux espaces? Par exemple, une virgule ( ,) ou une virgule et un espace ( ,)?

Donné:

8
9
10
32

J'aimerais finir avec:

8, 9, 10, 32

ou:

8,9,10,32
Martin Tournoij
la source
Vous pourriez également aimer github.com/sk1418/Join (non testé).
VanLaser

Réponses:

5

J'ai écrit un plugin Join, je peux faire ce que tu veux et bien plus encore.

À l'exception de toutes les fonctionnalités fournies par la commande build-in: join, Join peut:

  • Joindre des lignes avec séparateur (chaîne)
  • Joindre des lignes avec ou sans rogner les espaces blancs avant / arrière
  • Rejoignez les lignes avec un nombre négatif (jointure arrière)
  • Joignez les lignes en sens inverse
  • Joindre des lignes et conserver des lignes jointes (sans supprimer les lignes jointes)
  • Joignez des lignes avec toutes les combinaisons d'options ci-dessus

plus de détails et captures d'écran:

https://github.com/sk1418/Join

Kent
la source
23

Un moyen simple est le suivant: sélectionnez simplement vos lignes (toutes sauf la dernière) - ou utilisez %- et exécutez:

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

ou

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

(où, bien sûr, la '<,'>partie a déjà été insérée :par Vim, pour cibler la sélection)


(2e) Mise à jour:

Sur la base de ce qui précède (et du commentaire de Sato Katsura ), voici une implémentation possible de "jointure interactive", avec comptage et prise en charge répétée facultative:

" ================ 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>

Et une cartographie réelle:

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

C'est un peu comme (*) J, mais interactif - il vous demandera la chaîne de séparation. La chaîne par défaut est un espace - donc, par exemple, pour joindre des lignes sans séparateur, appuyez sur Backspacelorsque vous y êtes invité, pour supprimer le caractère d'espace par défaut et Enterpour accepter le séparateur (maintenant) vide. Count, par exemple 3J, fonctionne également. Si le tpope/vim-repeatplugin est installé, répétez avec '.' fonctionnera également, en réutilisant le dernier séparateur et (s'il n'est pas modifié - par exemple 10.) le dernier décompte ou la plage de ligne visuelle.


(*) Ce n'est pas exactement comme ça J, cependant: alors qu'il supprimera l'indentation, il ne vérifiera pas .!?(fin de la phrase) pour insérer 2 espaces au lieu d'un, ou insérer un espace uniquement s'il est manquant (il est difficile de faire quelque chose comme cela, puisque la chaîne de séparation peut être n'importe quoi maintenant). Il supprimera également les espaces de fin (plus logique).

Je pense que cela pourrait être un bon moyen de surcharger l'espace limité des lettres des opérateurs :)

Eh bien, techniquement, ce Jn'est pas tout à fait un opérateur, mais proche de celui-ci - par exemple, vous ne pouvez pas Jaw, pour rejoindre "un mot".

(les suggestions sont les bienvenues)

entrez la description de l'image ici

VanLaser
la source
2
Mieux encore: :'<,'>-1s/\n/, /pour les lignes marquées ou :1,$-1s/\n/, /pour l'ensemble du fichier.
Sato Katsura
En effet, c'est encore mieux :)
VanLaser
@SatoKatsura pouvez-vous expliquer le -1?
alxndr
1
@alxndr - il est utilisé pour ignorer la dernière ligne de la plage / du fichier: par exemple, dans l'exemple OP, vous ne voulez pas de virgule après 32, et vous ne voulez pas non plus la joindre à la ligne suivante, si elle existe . Vous pouvez même utiliser '<,'>-s/\n/, /ou 1,$-s/\n/, /comme -c'est le même que -1.
VanLaser
1
Si l:sepc'est un &, alors votre remplaçant ne fonctionnera pas correctement, car &c'est magique dans le remplacement. Il pourrait être préférable d'utiliser le \=pour utiliser une chaîne littérale - let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- au lieu d'essayer de gérer l'échappement.
jamessan
3

Voici un exemple utilisant une commande externe:

:%!paste -sd,

%!remplace le tampon actuel (contenu du fichier) par la commande: paste -sd,(les paramètres -ssont utilisés pour joindre plusieurs lignes et -ddéfinissent le caractère délimiteur sur ,).

Kenorb
la source
3

Juste au cas où quelqu'un n'aime pas taper Regex et mémoriser plus de commandes Plugin Ex:

Ajout d'un bloc visuel

Visual-block Append est disponible en mode Visual Block ( <C-v>) et peut faire un bloc A ppend (et bloquer I nsert pour prepend). (ref: :help v_b_A, :help v_b_I)

Et si le dernier mouvement en mode bloc visuel est $, l'ajout sera fait à la fin de toutes les sélections; ou bien des espaces seront insérés avant le texte que vous avez ajouté (imaginez aligner la fermeture )à la fin de plusieurs appels de méthode dans le code).

Avec un exemple de texte ci-dessous et le curseur sur 8:

8
9
10
12

<C-v>}$A,<C-c>. Après être revenu au mode normal, nous pouvons voir qu'il ,est ajouté à toutes les lignes sélectionnées. (Essayez sans $)

Effectuez ensuite gvune nouvelle sélection de la zone et Jou gJ. Nous avons une fuite ,: 8,9,10,12,et $xnous avons terminé.

Utiliser l'insertion pour aucun suivi ,

Annulons notre texte (que ce uu..usoit ou une fantaisie :ea 1d<cr>:lat 1), et essayons Visual Insert:

j<C-v>}I, <C-c>puis nous pouvons joindre les lignes avec gJpour aucun espace.

Attendez, attendez, il manque quelque chose. Comment resélectionner l'ensemble du "tableau"? Cette fois, nous n'avons pas sélectionné la première ligne ... alors gvça n'aide pas.

- Ou cela peut aider, gvokest re-sélectionner ( gv), ocoin opposé et kvers le haut.

PS Mon petit doigt est pas assez rapide et précis à taper /\pour /\n, donc je aime combiner Vim intégré dans les opérations et les mouvements pour éviter d' utiliser Regex. Cependant, si je le fais assez souvent, utiliser un mappage - peut-être que ceux qui mappent sur des plugins devraient être meilleurs.

Sunny Pun
la source
1

Une manière beaucoup plus simple, sans plugins ni commandes externes, de remapper join ( J) à partir d'un espace vers le personnage de votre choix. Par exemple, pour joindre une virgule et un espace:

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

Pour la nouvelle ligne de caractère spécial à la fin ( ^M), appuyez sur Ctrl-Vpuis sur Retour / Entrée. Il en va de même si vous souhaitez remplacer par un onglet ( ^I), tapez Ctrl-Ialors Tab.

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

Ce que cela fait est de remplacer une nouvelle ligne par un onglet sur la ligne actuelle et de remapper ce comportement au caractère J.

Cela fonctionne également avec des combinaisons, comme 4Jpour joindre les 4 lignes suivantes.

Modes Wes
la source
0

Vous pouvez enregistrer une macro pour joindre des lignes avec une virgule. Ceci est utile s'il s'agit d'une tâche rare ou ponctuelle, et que vous ne vous souvenez pas comment écrire une commande de substitution et une expression régulière pour effectuer la tâche, mais vous vous souvenez comment enregistrer et exécuter une macro.

Pour joindre des lignes avec une virgule, tapez qjgJi,Escqpour enregistrer la macro dans le registre j. Ensuite, vous pouvez exécuter la macro avec @j. Vous pouvez réexécuter la macro avec @@, ce qui vous évite de taper lorsque vous l'exécutez plusieurs fois de suite - vous pouvez même maintenir enfoncée @jusqu'à ce que vous arriviez à la fin des lignes que vous souhaitez joindre. Vous pouvez également utiliser un préfixe numérique sur @jou @@pour le répéter un nombre défini de fois. Cela laisse intacts les espaces de début et de fin, il y aura donc des espaces avant ou après la virgule si votre texte d'origine contenait des espaces.

Pour joindre une virgule et un espace, insérez Spaceentre le ,et Esclors de l'enregistrement de la macro.

Vous pouvez également utiliser à la Jplace de gJlors de l'enregistrement de la macro, qui joint généralement les lignes avec une virgule et un espace. Cependant, si la ligne actuelle comporte des espaces de fin, la virgule apparaît après les espaces sans espace après. En outre, il ne comprend pas l'espace si la ligne suivante commence avec ), et il met deux espaces après la virgule si joinspacesest réglé et les extrémités de la ligne en cours avec ., !ou ?. Ces mises en garde sont décrites ci-dessous :help J.

Lithis
la source