Cách nhanh hơn để di chuyển một khối văn bản


25

Đây là cách tôi thường sao chép một khối văn bản hoặc mã:

  1. Chọn khối với chế độ Visual ( V) và xóa nó bằng d; hoặc nếu nó chỉ là một dòng duy nhất, chỉ cần sử dụng dd.
  2. Đi đến nơi tôi muốn văn bản trở thành, tôi quá ngu ngốc để nhớ sự khác biệt giữa pP, vì vậy tôi nhận được điều này đúng khoảng 50% thời gian. (nếu tôi hiểu sai: hoàn tác thử lại).
  3. Đôi khi, thụt đầu dòng cần điều chỉnh, vì vậy tôi chuyển sang chế độ Visual Vmột lần nữa và chọn lại cùng một khối, và sử dụng >hoặc <để sửa nó.

Có cách nào dễ hơn không? Trong một số trình soạn thảo tôi đã thấy rằng bạn có thể "nhặt" một khối văn bản, như nó đã được, và di chuyển nó xung quanh; đây là một ví dụ từ Emacs (nhưng tôi cũng đã thấy điều này trong các trình soạn thảo khác):

Emacs

Hoặc có lẽ có một cách khác (thậm chí tốt hơn)?


Về vấn đề thụt đầu dòng bạn có thể giải quyết nó bằng cách dán với ]phoặc [phơn phoặc P. Bằng cách này, khối mà bạn dán sẽ được tự động.
Gonçalo Ribeiro

Bạn có thể muốn xem đoạn phim ngắn của Drew Neil Bubling Text khuyến nghị sử dụng vim-unimpaired .
Hotschke

Câu trả lời:


13

Có một plugin cho điều đó: dragvisuals.vim .

Nó không ràng buộc bất kỳ khóa nào theo mặc định, vì vậy bạn sẽ phải tự làm điều đó. Tôi thích ánh xạ chúng tới Control+ Arrow key:

xmap <expr> <C-Left> DVB_Drag('left')
xmap <expr> <C-Right> DVB_Drag('right')
xmap <expr> <C-Down> DVB_Drag('down')
xmap <expr> <C-Up> DVB_Drag('up')

Nó cũng đi kèm với một khóa thưởng để nhân đôi lựa chọn hiện tại:

xmap <expr> D DVB_Duplicate()

Ưu điểm của plugin này so với các câu trả lời khác:

  • Không làm cho bất kỳ văn bản nào biến mất nếu bạn cố gắng di chuyển xa hơn dòng đầu tiên.
  • Nó sẽ mở rộng tập tin nếu bạn di chuyển bên dưới dòng cuối cùng.
  • Di chuyển sang trái / phải hoạt động tốt hơn một chút.

Một mẹo hữu ích khác để bổ sung cho điều này, đó là các keybinds:

xnoremap > >gv
xnoremap < <gv

Thao tác này sẽ chọn lại lựa chọn hình ảnh cuối cùng sau khi bạn sử dụng >khi ở chế độ Visual, do đó bạn có thể điều chỉnh căn chỉnh dễ dàng hơn (bạn cũng có thể sử dụng các phím mũi tên, nhưng điều này sẽ di chuyển nó theo một ký tự chứ không phải một ký tự shiftwidth).


1
Có một plugin khác cho điều này mà tác giả của plugin gợi ý của tôi mô tả là "việc làm lại được cải thiện rất nhiều về dragvisuals.vim của tôi": github.com/zirrostig/vim-schlepp
Jay Thompson

8

Đối với bước 3, bạn có thể sử dụng gv=thay thế ( =có nghĩa là thụt lề và gvcó nghĩa là "chọn lại lựa chọn hình ảnh cuối cùng").

Đối với hành vi của Emacs, việc thêm một số ánh xạ vào .vimrc của bạn sẽ khá đơn giản.

vnoremap <down> dpV`]
vnoremap <up> dkPV`]

Sau đó, bạn có thể sử dụng các phím mũi tên lên và xuống để di chuyển xung quanh lựa chọn đường trực quan. (Tất nhiên, bạn cũng có thể ánh xạ tới các phím khác nhau nếu bạn ghét mũi tên.)

(Bạn có thể làm điều này với các lựa chọn hình ảnh bình thường và di chuyển chúng sang trái và phải: vnoremap <left> dhPgvhohovnoremap <right> dpgvlolo.)


gvđi đến lựa chọn hình ảnh cuối cùng, trong trường hợp này sẽ là đoạn đã bị xóa. Tôi đang thiếu gì?
Robert Smith

4

Bạn có thể sắp xếp lại một số phím để di chuyển các dòng xung quanh. Ví dụ, mũi tên lên và xuống nếu bạn được sử dụng để di chuyển qua hjkl.

Ví dụ: trên .vimrc

nnoremap <down> :m .+1<CR>==
nnoremap <up> :m .-2<CR>==
vnoremap <down> :m '>+1<CR>gv=gv
vnoremap <up> :m '<-2<CR>gv=gv

:m, lệnh bình thường để di chuyển một dòng

+1hoặc -2để chỉ ra một dòng lên hoặc xuống (-1 giữ dòng trên cùng một vị trí)

gvđể chọn lại cùng một văn bản trong VISUALchế độ

Giải pháp này không can thiệp vào các thanh ghi, vì vậy mọi văn bản được sao chép sẽ vẫn có sẵn, cũng như định dạng lại mã để đặt thụt lề thích hợp, v.v.


Điều này là tốt, nhưng đối với tôi, vì tôi không thích sử dụng =(nó thường thay đổi quá nhiều định dạng không liên quan đến tôi).
Martin Tournoij


3

Có một vài plugin cho việc này nhưng tôi thích vim-unimpaired ( github ) của Tim Pope (Ingo Karkat LineJuggler cũng tương tự).

Bạn trực quan chọn khối văn bản của bạn sau đó làm ]e(e để trao đổi) để di chuyển khối xuống ( [eđối với hướng khác). Sử dụng .để lặp lại hành động (Bạn đã cài đặt lại.vim không phải bạn). Nếu bạn đi quá xa thì chỉ cần hoàn tác qua u.

Bây giờ cá nhân tôi nghĩ pPlà những lệnh phổ biến đến mức tốt nhất nên tìm hiểu chúng trước khi tạo thói quen xấu. Sau đó, bạn có thể sử dụng ]pđể dán tại cùng một vết lõm. Nếu bạn đang sử dụng không có kinh nghiệm, bạn có thể làm >pđể dán mức độ ấn định sâu hơn hoặc =pđể dán và định dạng lại.

Nếu bạn gặp khó khăn trong việc ghi nhớ pPsau đó nó có thể giúp bạn nghĩ về chúng theo các lệnh oOlệnh là một loại đối xứng.

Như những người khác đã lưu ý, bạn có thể sử dụng gvđể chọn lại một lựa chọn trực quan. Tuy nhiên nếu bạn chỉ đặt / dán văn bản, bạn sẽ mất lựa chọn hình ảnh của mình. Đừng băn khoăn vì mọi thay đổi (và yanks!) Sẽ được đặt '[']xung quanh khu vực đã thay đổi. Vì vậy, bạn có thể thụt lề thông qua >'](đọc: dịch chuyển sang phải cho đến khi kết thúc thay đổi cuối cùng) và sử dụng .để lặp lại chỉ định cho đến khi bạn có văn bản ở đúng vị trí.

Để được trợ giúp thêm xem:

:h p
:h P
:h ]p
:h o
:h O
:h .
:h u
:h >
:h ']
:h gv

2

Nếu bạn biết số dòng mà bạn muốn di chuyển khối văn bản sang, thì bạn có thể sử dụng một phạm vi hoặc lựa chọn trực quan với :movelệnh để di chuyển khối đến đó.

Ví dụ: nếu tôi có tệp sau:

1 aaa
2 bbb
3 ccc
4 ddd

và tôi muốn di chuyển dòng của a đến sau dòng của c, tôi đặt con trỏ trên dòng của a và nhập :m3, và dòng sau đó được dịch chuyển.

Điều này cũng hoạt động với +/- offset. Trong ví dụ trên, kết quả tương tự có thể được thực hiện với :m+2việc di chuyển dòng 2 xuống.

Đối với các khối văn bản, sự khác biệt duy nhất là thêm vào một phạm vi hoặc lựa chọn. Để di chuyển các dòng aaa và bbb đến cuối tệp, sử dụng lệnh như :1,2m$($ = dòng cuối) hoặc chọn trực quan các dòng và :m$.


1
Để biết thêm mẹo về :movexem thêm vim.wikia.com/wiki/Moving_lines_up_or_down hoặc Mẹo 29 Sao chép hoặc Di chuyển các dòng bằng cách sử dụng ': t' và ': m' Các lệnh trong Sách thực hành Vim của D. Neil.
Hotschke

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.