Tôi có thể nối các dòng bằng dấu phẩy (hoặc ký tự khác) không?


19

Tôi biết tôi có thể tham gia các dòng trong Vim với Jvà một số biến thể của chúng ( gJ, v.v.); Jsẽ "Xóa thụt lề và chèn tối đa hai khoảng trắng" .

Nhưng cũng có một cách đơn giản để chèn một ký tự khác thay vì hai khoảng trắng? Ví dụ: dấu phẩy ( ,) hoặc dấu phẩy & dấu cách ( ,)?

Được:

8
9
10
32

Tôi muốn kết thúc với:

8, 9, 10, 32

hoặc là:

8,9,10,32

Bạn cũng có thể thích github.com/sk1418/Join (chưa được kiểm tra).
VanLaser

Câu trả lời:


5

Tôi đã viết một plugin Tham gia, có thể làm những gì bạn muốn và nhiều hơn nữa.

Ngoại trừ tất cả các tính năng được cung cấp bởi lệnh tích hợp: tham gia, Tham gia có thể:

  • Nối các dòng với dấu phân cách (chuỗi)
  • Tham gia các dòng có hoặc không cắt bớt các khoảng trắng hàng đầu / dấu
  • Tham gia các dòng có số âm (tham gia ngược)
  • Nối các đường ngược lại
  • Nối các dòng và giữ các dòng đã tham gia (không xóa các dòng đã tham gia)
  • Tham gia các dòng với bất kỳ kết hợp các tùy chọn trên

biết thêm chi tiết và ảnh chụp màn hình:

https://github.com/sk1418/Join


23

Một cách đơn giản là thế này: chỉ cần chọn các dòng của bạn (tất cả trừ dòng cuối cùng) - hoặc sử dụng %- và chạy:

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

hoặc là

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

(tất nhiên, '<,'>phần đã được :Vim chèn vào sau , để nhắm mục tiêu lựa chọn)


(2) Cập nhật:

Dựa trên nhận xét trên (và nhận xét của Sato Katsura ), đây là một triển khai "tham gia tương tác" có thể, với số lượng và hỗ trợ lặp lại tùy chọn:

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

Và một bản đồ thực tế:

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

Đây là loại (*) thích J, nhưng tương tác - nó sẽ nhắc cho chuỗi phân tách. Chuỗi mặc định là một khoảng trắng - vì vậy, ví dụ, để nối các dòng không có dấu phân cách, nhấn Backspacekhi được nhắc, để xóa ký tự Enterkhoảng trắng mặc định và chấp nhận dấu phân cách trống (bây giờ). Đếm, ví dụ 3J, cũng hoạt động. Nếu tpope/vim-repeatplugin được cài đặt, lặp lại với '.' cũng sẽ hoạt động, sử dụng lại dấu phân cách cuối cùng và (nếu không thay đổi - ví dụ 10.) số đếm hoặc phạm vi dòng trực quan cuối cùng.


(*) Đó là không chính xác như J, mặc dù: trong khi nó sẽ loại bỏ thụt đầu dòng, nó sẽ không kiểm tra .!?(cuối cụm từ) để chèn 2 không gian thay vì một, hoặc chèn một không gian chỉ khi nó còn thiếu (thật khó để làm điều gì đó như này, vì chuỗi phân cách có thể là bất cứ điều gì bây giờ). Nó cũng sẽ loại bỏ các dấu cách (có ý nghĩa hơn).

Tôi nghĩ rằng đây có thể là một cách hay để quá tải không gian thư của nhà khai thác hạn chế :)

Chà, về mặt kỹ thuật Jkhông hoàn toàn là một nhà điều hành, nhưng gần với một nhà điều hành - ví dụ, bạn không thể làm gì Jaw, để tham gia "một từ".

(đề nghị được chào đón)

nhập mô tả hình ảnh ở đây


2
Tốt hơn nữa: :'<,'>-1s/\n/, /cho các dòng được đánh dấu, hoặc :1,$-1s/\n/, /cho toàn bộ tệp.
Sato Katsura

Thật vậy, điều đó thậm chí còn tốt hơn :)
VanLaser

@SatoKatsura bạn có thể giải thích -1?
alxndr

1
@alxndr - được sử dụng để bỏ qua dòng cuối cùng trong phạm vi / tệp: ví dụ: trong ví dụ OP, bạn không muốn có dấu phẩy sau 32 và bạn cũng không muốn tham gia dòng đó với dòng tiếp theo, nếu nó tồn tại . Bạn thậm chí có thể sử dụng '<,'>-s/\n/, /hoặc 1,$-s/\n/, /như -là giống như -1.
VanLaser

1
Nếu l:seplà một &, thì sự thay thế của bạn sẽ hoạt động không chính xác, vì đó &là phép thuật trong sự thay thế. Có thể tốt hơn để sử dụng \=để sử dụng một chuỗi ký tự - let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"- thay vì cố gắng xử lý thoát.
jamessan

3

Dưới đây là ví dụ sử dụng lệnh bên ngoài:

:%!paste -sd,

trong đó %!thay thế bộ đệm hiện tại (nội dung của tệp) bằng lệnh: paste -sd,(tham số -sđược sử dụng để nối nhiều dòng và -dđặt ký tự phân cách thành ,).


3

Chỉ trong trường hợp ai đó không thích gõ Regex và ghi nhớ thêm Lệnh Ex Lệnh:

Chặn trực quan

Visual-block Append có sẵn trong chế độ Visual Block ( <C-v>) và có thể thực hiện một khối A ppend (và khối I nsert để trả trước). (tham khảo : :help v_b_A, :help v_b_I)

Và nếu chuyển động cuối cùng trong Block Visual Mode là $, phần bổ sung sẽ được thực hiện ở cuối tất cả các lựa chọn; hoặc các khoảng trắng khác sẽ được chèn trước khi văn bản bạn nối thêm (hãy tưởng tượng việc căn chỉnh đóng )ở cuối một số cuộc gọi phương thức trong mã).

Với văn bản mẫu bên dưới và con trỏ trên 8:

8
9
10
12

<C-v>}$A,<C-c>. Sau khi trở lại chế độ bình thường, chúng ta có thể thấy ,được gắn vào tất cả các dòng được chọn. (Thử mà không có $)

Sau đó làm gvđể chọn lại khu vực và Jhoặc gJ. Chúng tôi có một dấu vết ,: 8,9,10,12,$xchúng tôi đã hoàn thành.

Sử dụng Chèn cho Không Trailing ,

Hãy hoàn tác văn bản của chúng tôi (có thể là uu..umột thứ ưa thích :ea 1d<cr>:lat 1) và thử Visual Chèn:

j<C-v>}I, <C-c>và sau đó chúng ta có thể tham gia các dòng gJkhông có khoảng trắng.

Chờ đợi chờ đợi, thiếu một cái gì đó. Làm thế nào để chọn lại toàn bộ "mảng"? Lần này chúng tôi đã không chọn dòng đầu tiên ... vì vậy gvkhông có ích.

- Hoặc nó có thể giúp, gvokđược chọn lại ( gv), ogóc pposeite và klên.

PS của tôi hồng hào không phải là nhanh chóng và chính xác đủ để gõ /\cho /\n, vì vậy tôi giống như kết hợp Vim tích hợp trong các hoạt động và phong trào để tránh sử dụng Regex. Tuy nhiên, nếu tôi làm điều này đủ thường xuyên, sử dụng ánh xạ - có thể những ánh xạ tới plugin sẽ tốt hơn.


1

Một cách đơn giản hơn nhiều mà không cần plugin hoặc lệnh bên ngoài để ánh xạ lại phép nối ( J) từ khoảng trắng sang bất kỳ ký tự nào bạn thích. Ví dụ: để tham gia bằng dấu phẩy và dấu cách:

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

Đối với dòng mới ký tự đặc biệt ở cuối ( ^M) Ctrl-V, sau đó nhấn Return / Enter. Cũng vậy nếu bạn muốn thay thế bằng một tab ( ^I), gõ Ctrl-Isau đó Tab.

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

Điều này đang làm là thay thế một dòng mới bằng một tab trên dòng hiện tại và ánh xạ lại hành vi đó cho ký tự J.

Điều này cũng hoạt động với các kết hợp, như 4Jtham gia vào 4 dòng tiếp theo.


0

Bạn có thể ghi lại một macro để nối các dòng bằng dấu phẩy. Điều này hữu ích nếu đó là một tác vụ hiếm hoặc một lần và bạn không thể nhớ cách viết lệnh thay thế và biểu thức chính quy để thực hiện tác vụ, nhưng bạn nhớ cách ghi và chạy macro.

Để nối các dòng bằng dấu phẩy, hãy nhập qjgJi,Escqđể ghi macro trong thanh ghi j. Sau đó, bạn có thể chạy macro với @j. Bạn có thể chạy lại macro với @@, giúp tiết kiệm khi gõ khi chạy nó nhiều lần trong một hàng, bạn thậm chí có thể giữ @cho đến khi bạn đến gần cuối dòng bạn muốn tham gia. Bạn cũng có thể sử dụng tiền tố số trên @jhoặc @@lặp lại số lần đặt. Điều này để lại không gian hàng đầu và dấu còn nguyên vẹn, do đó sẽ có khoảng trắng trước hoặc sau dấu phẩy nếu văn bản gốc của bạn có khoảng trắng ở đó.

Để nối với dấu phẩy và dấu cách, hãy chèn Spacegiữa ,Esckhi ghi macro.

Bạn cũng có thể sử dụng Jthay vì gJkhi ghi macro, thường sẽ nối các dòng bằng dấu phẩy và dấu cách. Tuy nhiên, nếu dòng hiện tại có khoảng trắng ở cuối, dấu phẩy sẽ xuất hiện sau khoảng trắng mà không có khoảng trắng theo sau nó. Ngoài ra, nó không bao gồm các không gian nếu dòng tiếp theo bắt đầu với ), và nó đặt hai không gian sau dấu phẩy nếu joinspacesđược thiết lập và dòng hiện tại kết thúc với ., !hoặc ?. Những cảnh báo này được mô tả dưới đây :help J.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.