Могу ли я соединить строки запятой (или другим символом)?


19

Я знаю, что могу объединять строки в Vim с Jнесколькими вариантами ( gJи т. Д.); Jбудет «Удалить отступ и вставить до двух пробелов» .

Но есть ли простой способ вставить другой символ вместо двух пробелов? Например, запятая ( ,) или запятая и пробел ( ,)?

Данный:

8
9
10
32

Я хотел бы закончить с:

8, 9, 10, 32

или:

8,9,10,32

Вам также может понравиться github.com/sk1418/Join (не проверено).
VanLaser

Ответы:


5

Я написал плагин Join, может делать то, что вы хотите, и многое другое.

За исключением всех функций, предоставляемых командой build-in: join, Join может:

  • Объединить строки с разделителем (строка)
  • Объединить строки с или без обрезки начальных / конечных пробелов
  • Соединение строк с отрицательным счетом (обратное соединение)
  • Соединять линии в обратном порядке
  • Объединяйте строки и сохраняйте соединенные линии (не удаляя соединенные линии)
  • Объединяйте строки с любыми комбинациями вышеуказанных опций

подробнее и скриншоты:

https://github.com/sk1418/Join


23

Простой способ заключается в следующем: просто выберите ваши строки (все, кроме последней) - или используйте %- и запустите:

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

или

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

(где, конечно, '<,'>часть уже была вставлена ​​после :Vim, чтобы предназначаться для выбора)


(2-е) Обновление:

Основываясь на вышеизложенном (и комментарии Сато Кацуры ), вот возможная реализация "интерактивного соединения" с подсчетом и дополнительной поддержкой повторов:

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

И фактическое отображение:

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

Это что-то вроде (*) J, но интерактивное - оно запросит строку-разделитель. Строка по умолчанию - это пробел, поэтому, например, чтобы соединить строки без разделителя, нажмите, Backspaceкогда будет предложено, удалить символ пробела по умолчанию и Enterпринять (теперь) пустой разделитель. Граф, например 3J, тоже работает. Если tpope/vim-repeatплагин установлен, повторите с '.' также будет работать, повторно используя последний разделитель и (если не изменился - например 10.) последний счетчик или диапазон визуальной линии.


(*) Хотя это не совсем так J: хотя он удалит отступ, он не будет проверять .!?(конец фразы) вставку 2 пробелов вместо одного или вставку пробела только в случае его отсутствия (трудно сделать что-то вроде это, так как строка-разделитель теперь может быть чем угодно). Это также удалит завершающие пробелы (имеет больше смысла).

Я думаю, что это может быть хорошим способом перегрузить ограниченное пространство букв операторов :)

Ну, технически Jэто не совсем оператор, но он близок к одному - например, вы не можете Jawприсоединиться к «слову».

(предложения приветствуются)

введите описание изображения здесь


2
Еще лучше: :'<,'>-1s/\n/, /для отмеченных строк или :1,$-1s/\n/, /для всего файла.
Сато Кацура

Действительно, это даже лучше :)
VanLaser

@SatoKatsura вы можете объяснить -1?
alxndr

1
@alxndr - используется для пропуска последней строки в диапазоне / файле: например, в примере с OP вам не нужна запятая после 32, а также вы не хотите присоединять ее к следующей строке, если она существует , Вы можете даже использовать '<,'>-s/\n/, /или 1,$-s/\n/, /так -же, как -1.
VanLaser

1
Если l:sepесть &, то ваша замена будет работать неправильно, так как &это волшебство в замене. Возможно, лучше использовать \=буквальную строку let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- вместо того, чтобы пытаться обработать экранирование.
Jamessan

3

Вот пример использования внешней команды:

:%!paste -sd,

где %!заменяет текущий буфер (содержимое файла) командой: paste -sd,(параметры -sиспользуются для объединения нескольких строк и -dустановки символа разделителя ,).


3

На всякий случай, если кому-то не нравится вводить Regex и запоминать больше команд Plugin Ex:

Визуальный блок Добавить

Visual-block Append доступен в режиме Visual Block ( <C-v>) и может делать блок A ppend (и блок I nsert для prepend). (ссылка: :help v_b_A, :help v_b_I)

И если последним движением в блочном визуальном режиме является $, добавление будет сделано в конце всех выборов; или же пробелы будут вставлены перед добавленным вами текстом (представьте выравнивание закрытия )в конце нескольких вызовов метода в коде).

С образцом текста ниже и курсором 8:

8
9
10
12

<C-v>}$A,<C-c>, После возврата в нормальный режим, мы видим ,, добавляется ко всем выбранным строкам. (Попробуй без $)

Затем gvснова выберите область и Jили gJ. У нас есть трейлинг ,: 8,9,10,12,и $xмы закончили.

Используйте Вставку для Трейлинга ,

Давайте отменим наш текст (будь то uu..uпричудливый :ea 1d<cr>:lat 1) и попробуем Visual Insert:

j<C-v>}I, <C-c>и тогда мы можем соединить строки gJбез пробелов.

Подождите, подождите, подождите, что-то не хватает. Как повторно выбрать весь «массив»? На этот раз мы не выбрали первую строку ... так gvчто не помогает.

- Или это может помочь, gvokповторно выбрать ( gv), oугол pposite и kвверх.

PS Мой мизинец не быстрый и точный достаточно набрать /\для /\n, так что я , как объединение Vim встроенные операций и движения , чтобы избежать использования Regex. Однако, если я делаю это достаточно часто, использую отображение - возможно, те, которые отображаются на плагины, должны быть лучше.


1

Гораздо более простой способ без плагинов или внешних команд переназначить join ( J) из пробела на любой символ, который вам нравится. Например, для объединения с запятой и пробелом:

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

Для ввода символа новой строки в конце ( ^M) нажмите, Ctrl-Vа затем нажмите Return / Enter. То же самое происходит, если вы хотите заменить на tab ( ^I), введите Ctrl-Iзатем Tab.

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

Что это делает, это заменяет новую строку на вкладку в текущей строке и переназначает это поведение на символ J.

Это также работает с комбинациями, например, 4Jчтобы соединить следующие 4 строки.


0

Вы можете записать макрос для объединения строк с запятой. Это полезно, если это редкая или одноразовая задача, и вы не можете вспомнить, как написать замещающую команду и регулярное выражение для выполнения задачи, но вы помните, как записывать и запускать макрос.

Чтобы объединить строки с запятой, введите qjgJi,Escqзапись макроса в регистр j. Затем вы можете запустить макрос с @j. Вы можете перезапустить макрос с помощью @@, что экономит при наборе текста при запуске его несколько раз подряд - вы даже можете просто удерживать, @пока не дойдете до конца строк, к которым хотите присоединиться. Вы также можете использовать числовой префикс @jили @@повторять его определенное количество раз. Это оставляет начальные и конечные пробелы нетронутыми, поэтому пробелы будут до или после запятой, если в вашем исходном тексте были пробелы.

Чтобы объединить запятую и пробел, вставьте Spaceмежду ,и Escпри записи макроса.

Вы также можете использовать Jвместо gJзаписи макрос, который обычно объединяет строки с запятой и пробелом. Однако, если текущая строка имеет конечные пробелы, запятая будет отображаться после пробела без пробела после нее. Кроме того , она не включает в себя пространство , если следующая строка начинается с ), и это ставит два пробела после запятой , если joinspacesустановлено и текущие концы линии с ., !или ?. Эти предостережения описаны ниже :help J.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.