Tắt tự động thụt lề khi dán văn bản vào vim


1186

Tôi đang nỗ lực để học Vim.

Khi tôi dán mã vào tài liệu của mình từ bảng ghi tạm, tôi sẽ có thêm khoảng trắng ở đầu mỗi dòng mới:

line
  line
    line

Tôi biết bạn có thể tắt thụt lề tự động nhưng tôi không thể làm cho nó hoạt động được vì tôi có một số cài đặt khác xung đột hoặc một cái gì đó (có vẻ khá rõ ràng trong .vimrc của tôi nhưng dường như không quan trọng khi tôi gỡ chúng ra).

Làm cách nào để tắt tự động thụt lề khi tôi dán mã nhưng vẫn có thụt lề tự động vim khi tôi đang viết mã? Đây là .vimrctập tin của tôi :

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  

4
FWIW, vim 8.0.210 thêm hỗ trợ riêng cho dán khung, vì vậy nó sẽ tránh thụt lề văn bản dán.
sh1

Đối với các tệp mới để tránh thay đổi với dán / nopaste của vim, bạn có thể cat > mynewfile.txtnhấn Enter , dán văn bản của mình, nhấn Enter lần nữa và sau đó Ctr + D để lưu. Các tập tin đã được tạo và bạn có thể chỉnh sửa nó với vim mynewfile.txt.
ccpizza

Câu trả lời:


2065

Cập nhật: Trả lời tốt hơn tại đây: https://stackoverflow.com/a/38258720/62202

Để tắt chế độ tự động khi bạn dán mã, có chế độ "dán" đặc biệt.

Kiểu

:set paste

Sau đó dán mã của bạn. Lưu ý rằng văn bản trong tooltip bây giờ nói -- INSERT (paste) --.

Sau khi bạn dán mã của mình, hãy tắt chế độ dán, để tự động thụt lề khi bạn nhập lại hoạt động chính xác.

:set nopaste

Tuy nhiên, tôi luôn thấy rằng cồng kềnh. Đó là lý do tại sao tôi ánh xạ <F3>sao cho nó có thể chuyển đổi giữa chế độ dán và chế độ nopaste trong khi chỉnh sửa văn bản! Tôi thêm cái này vào.vimrc

set pastetoggle=<F3>

38
Điều này không dễ dàng hơn :set noaitiếp theo :set ai. Đề nghị :r! catlà ngắn hơn.
Leopd

68
Tôi nghĩ set pastelà dễ dàng hơn, chắc chắn. Nó có nhiều ngữ nghĩa hơn noaihoặc thậm chí noautoindent, điều này quan trọng hơn khi gõ "noai" và "paste" chiếm khoảng thời gian không đáng kể khi bạn đủ thành thạo như một người đánh máy cảm ứng.
Victor Zamanian

52
:set noaikhông phải lúc nào cũng hoạt động, tùy thuộc vào cách các cài đặt liên quan đến thụt lề khác được định cấu hình theo OP. :set pastedường như là một tốc ký cho một vài cài đặt cùng một lúc.
MarkHu

13
Đến bữa tiệc muộn, nhưng set copyindentsẽ chăm sóc điều này cho bạn một cách liền mạch.
Matt Ryan

33
:set pastecũng vô hiệu hóa các tính năng khác như hoàn thành niềng răng, điều này cũng không mong muốn khi dán mã.
Manuel Faux

263

Để tránh các hiệu ứng không mong muốn trong khi dán, có một tùy chọn cần được đặt:

set paste

Một lệnh hữu ích cần có trong .vimrc của bạn là set pastetoggle=<F10>hoặc một số nút khác, để dễ dàng chuyển đổi giữa dán và nopaste.


13
Cuối cùng! Tôi cứ gõ: set paste /: set nopaste, ngu thế nào! Cám ơn.
imwilsonxu

4
từ một quan điểm thực tế, câu trả lời của bạn là có ích hơn là câu trả lời được chấp nhận
Lynob

8
Một tùy chọn khác là thêm một macro vào vimrc của bạn:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris

Đề xuất hay @Chris - chuỗi phím đơn để dán mà không có vấn đề thụt lề!
RichVel

Nếu tôi không bao giờ muốn ở chế độ dán thì sao? Có cách nào để vô hiệu hóa vĩnh viễn?
maxwell

132

Tôi thường sử dụng :r! catvà sau đó dán ( shift + insert )nội dung, và CTRL+D.

Không cần phải bật và tắt, sử dụng trực tiếp.


Tôi thích tùy chọn sử dụng trực tiếp này. Tôi vẫn đang học cách đọc cú pháp vim trên các trang web. Bước của bạn có ý nghĩa gì? Cụ thể, giả sử tôi có một cái gì đó trong bảng tạm hệ thống, tôi nhấn gì để dán nó vào tài liệu trong vim?
jvriesem 4/11/2015

9
Câu trả lời này sẽ hữu ích hơn với thông tin về lý do và cách thức :r! cathoạt động.
K Erlandsson

11
@KErlandsson, :rchèn nội dung của tệp vào tài liệu hiện tại. !catnói, chạy cat về cơ bản mở stdin (* nix shell) (shift + insert)hoặc đối với một số thiết bị đầu cuối, nhấp chuột phải sẽ dán nội dung của bảng tạm vào thiết bị đầu cuối CTRL+Dlà cuối tệp, vì vậy nó đóng :r !catphiên.
Daniel

Đây có phải là 'trực tiếp' không? Hơn thiết lập một tùy chọn pasteđược thực hiện chỉ cho mục đích này? @jvriesem Đây không phải là một lựa chọn 'trực tiếp', nếu những gì tôi cho là sự hiểu biết của bạn về từ đó là chính xác.
0xc0de

Bạn cũng có thể sử dụng :r! catsau đó CTRL+SHIFT+Vđể dán vào thiết bị đầu cuối (sau đó CTRL+D).
Paul Rougieux

86

Nếu bạn đang làm việc cục bộ, bạn có thể dán từ bảng tạm hệ thống với chuỗi khóa:

"+p

Đây là một lệnh vim thích hợp, vì vậy không cần phải lo lắng về việc nhập chế độ chèn hoặc tắt tự động trước.

Tất nhiên, nếu bạn đang làm việc từ xa (ví dụ như bảng điều khiển qua SSH) thì điều này sẽ không hoạt động và bạn nên chuyển sang :set noai, chế độ chèn, dán vào bảng điều khiển, để lại mã chèn, :set aiđịnh tuyến như được mô tả ở nơi khác.


10
Tôi viết câu trả lời này từ lâu. Ngày nay tôi sử dụng :set paste:set nopastethay vào đó bởi vì mặc dù dài hơn, nó dễ nhớ hơn và tôi không phải tìm kiếm nó mỗi lần!
thomasrutter

6
Trong một số hệ thống nhúng (chủ yếu dựa trên busybox) :set pastekhông được triển khai, do đó :set noainên được sử dụng thay thế.
jcarballo

Khi bạn có một văn bản lớn để sao chép, thay vào đó, sử dụng thanh ghi + sẽ nhanh hơn?
pedromanoel

1
@pedromanoel chỉ hoạt động khi làm việc tại địa phương. Chẳng hạn, nó sẽ không hoạt động khi truy cập vim qua SSH, nếu bạn đã sao chép một cái gì đó cục bộ và muốn dán nó vào vim trong phiên SSH của bạn.
thomasrutter

1
@thomasrutter nhưng tôi đã ánh xạ nó tới <leader>p.. rất hữu ích!
Dane

51

Mặc dù cài đặt chế độ dán paste/nopaste/pastetogglehoàn toàn tốt, bạn vẫn phải bật chế độ dán thủ công trước khi dán và tắt chế độ dán sau khi dán. Là người lười biếng mà tôi là, dưới đây là giải pháp tốt nhất mà tôi đã tìm thấy cho đến nay, nó tự động bật chế độ dán khi bạn dán.

Đây là một mẹo nhỏ sử dụng chế độ dán có dấu ngoặc của thiết bị đầu cuối để tự động đặt / hủy đặt chế độ dán của Vim khi bạn dán. Đặt sau trong .vimrc của bạn:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

Bây giờ bạn có thể dán mà không bật / tắt chế độ dán rõ ràng - nó được xử lý tự động cho bạn.

Nguồn: Mã hóa

Lưu ý: Giải pháp này không hoạt động trong WSL (Hệ thống con Windows 10 cho Linux). Nếu bất cứ ai có giải pháp cho WSL, vui lòng cập nhật câu trả lời này hoặc thêm nó vào phần bình luận.

Tmux Nếu sử dụng tmux, thì các khai báo cần phải được thoát gấp đôi. Mã cho điều này cũng có trong Coderwall


Điều này là sáng chói. Một điều mặc dù ... Với mỗi lần dán, tôi nhận được một ký tự "0" (không) khi bắt đầu mỗi lần dán. Bất kỳ lời khuyên cho điều đó?
Julius Š.

cũng lưu ý trong nếu sử dụng tmux thì bạn cần phải thoát gấp đôi. Mã cho điều này nằm trong liên kết Coderwall trong câu trả lời
Daithí

1
Nếu bạn thậm chí còn lười hơn và sao chép mã ở trên vào .vimrc của bạn, hãy chú ý đến việc thụt lề của hàm XTermPasteBegin ().
k1133

Tôi tò mò làm thế nào nó hoạt động, và vì vậy tôi đã tìm kiếm Paste ngoặc và tìm thấy gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing giải thích rằng các biến t_SIt_EIcho phép dán ngoặc và vô hiệu hóa nó. Khi dán dấu ngoặc được bật, văn bản được dán có tiền tố esc[200~và theo sau esc[201~.
PatS

37

Người dùng Mac có thể tránh định dạng tự động bằng cách đọc trực tiếp từ bảng điều khiển với:

:r !pbpaste

3
Đây là một phản ứng tuyệt vời. Tuy nhiên, khi tôi làm điều này, nó sẽ ẩn tài liệu (có vẻ như tôi đã quay lại dòng lệnh), nhưng có văn bản trên bảng ghi tạm của tôi. Nó nhắc tôi nhấn enter, vì vậy tôi làm và nó đưa tôi trở lại tài liệu của mình mà không có bất kỳ thay đổi nào. Điều gì đã xảy ra, và làm thế nào để tôi làm những gì bạn đang nói?
jvriesem 04/11/2015

Nếu bạn chỉ cần gõ :.!pbpaste, điều này sẽ hoạt động bằng cách thay thế dòng hiện tại bằng đầu ra của bộ đệm dán. Nói chung, vim cho phép bạn chuyển dữ liệu trong tệp hiện tại của mình sang chương trình khác và thay thế văn bản bằng đầu ra của lệnh. Vì vậy, :1,3!pbpastethay thế ba dòng đầu tiên của tệp của bạn bằng bộ đệm dán. Tôi sử dụng :.!ppjsonđể lấy một chuỗi JSON rất dài (không được định dạng) và định dạng nó và thay thế chuỗi dài bằng định dạng tương đương. ppjson chỉ là một tập lệnh bash chạy python -m json.tool.
PatS

19

Đây là một bài đăng của một người đã tìm ra cách ánh xạ lại sự kiện dán để tự động bật chế độ dán và sau đó tắt. Hoạt động với tôi trong tmux / iTerm trên MacOSX.


1
Cảm ơn vì tiền hỗ trợ. Tôi cũng đã theo dõi một plugin nơi người đó đã tích hợp chức năng tương tự - stackoverflow.com/a/36512548/255961 .
studgeek

Điều này dường như gây ra một chuỗi 'eeeeeee' khi tôi chèn một đoạn văn bản từ bảng ghi tạm của mình.
John Jiang

16

Thêm phần này vào của bạn ~/.vimrcvà bạn sẽ chỉ phải nhấn F2 trước và sau khi dán:

set pastetoggle=<F2>

12

Tôi chỉ cần đặt set clipboard=unnamed .vimrc của tôi. Điều đó làm cho bản đồ bộ đệm dán mặc định vào bảng tạm của X.

Vì vậy, nếu tôi đánh dấu một chút văn bản trong một thiết bị đầu cuối, tôi chỉ cần nhấn pđể dán nó vào vim. Tương tự, tôi có thể kéo mọi thứ trong vim (ví dụ: YYkéo dòng hiện tại vào bộ đệm) và nhấp vào giữa trong bất kỳ cửa sổ nào để dán nó.

Không biết. Tôi thấy nó siêu tiện lợi.


IMHO, đây là câu trả lời tốt nhất, không cần chuyển đổi với F11 (được cấu hình sẵn theo mặc định trong vim). Điều này hoạt động trong hệ thống OSX mac, tôi không biết về những người khác.
Lightman

9

Khi làm việc bên trong thiết bị đầu cuối, vim-ngoặc-dán vim plugin sẽ tự động xử lý các loại bột nhão mà không cần bất kỳ tổ hợp phím nào trước hoặc sau khi dán.

Nó hoạt động bằng cách phát hiện chế độ dán có dấu ngoặc là một chuỗi thoát được gửi bởi các thiết bị đầu cuối tương thích x "hiện đại" như iTerm2, gnome-terminal và các thiết bị đầu cuối khác bằng libvte. Là một phần thưởng bổ sung, nó cũng hoạt động cho các phiên tmux. Tôi đang sử dụng thành công với iTerm2 trên máy Mac kết nối với máy chủ linux và sử dụng tmux.


Cảnh giác với những gì nó cũng lưu ý thêm: Thật không may, điều này có nghĩa là họ cũng sẽ chạy nội dung của bộ đệm đầu vào nếu có một dòng mới trong bất cứ thứ gì bạn dán vào thiết bị đầu cuối.
0xc0de

1
@ 0xc0de, trích dẫn đó không liên quan ở đây. Đó là nói về những gì một shell sẽ làm khi nó không hỗ trợ chế độ dán ngoặc. Đó là điểm trong chế độ dán khung - để ngăn điều đó xảy ra.
sh1

Điều này làm việc tốt hơn cho tôi so với các giải pháp khác. Cảm ơn.
jjj

8

Dán cái này vào ~ / .vimrc của bạn và vui mừng:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'

Chỉnh sửa: về sự phản chiếu, :r !catlà một cách tiếp cận tốt hơn nhiều vì nó ngắn, ngữ nghĩa và không yêu cầu vimrc tùy chỉnh. Sử dụng thay thế!


5

Mặc dù :pastetogglehay :paste:nopastenên làm việc tốt (nếu được thực hiện - họ không phải lúc nào cũng như chúng ta có thể nhìn thấy từ các cuộc thảo luận) tôi rất recomment dán sử dụng phương pháp trực tiếp "+phoặc "*pvà đọc với "+rhoặc "*r:

Vim có tới mười loại thanh ghi ( :help registers) và người hỏi quan tâm đến quotestarquoteplustừ phần

  1. Lựa chọn và thả thanh ghi "*, "+và "~

Sử dụng các thanh ghi này để lưu trữ và truy xuất văn bản đã chọn cho GUI. Xem quotestarquoteplus . Khi bảng tạm không có sẵn hoặc không hoạt động, thay vào đó, thanh ghi không tên được sử dụng. Đối với các hệ thống Unix, bảng tạm chỉ khả dụng khi có tính năng + xterm_clipboard. {không ở Vi}

Lưu ý rằng chỉ có sự phân biệt giữa "* và" + cho các hệ thống X11.

:help x11-selectionlàm rõ thêm sự khác biệt của *+:

                                                  quoteplus quote+

Có ba lựa chọn X được ghi lại: PRIMARY (dự kiến ​​sẽ đại diện cho lựa chọn hình ảnh hiện tại - như trong chế độ Trực quan của Vim), THỨ HAI (được xác định sai) và CLIPBOARD (dự kiến ​​sẽ được sử dụng để cắt, sao chép và dán ).

Trong số ba, Vim sử dụng PRIMARY khi đọc và viết thanh ghi "* (do đó khi có sẵn các lựa chọn X11, Vim đặt giá trị mặc định cho 'clipboard' của" autoselect ") và CLIPBOARD khi đọc và ghi thanh ghi" +. Vim không truy cập vào lựa chọn THỨ HAI.

Ví dụ: (giả sử các giá trị tùy chọn mặc định)

  • Chọn một URL trong chế độ Visual trong Vim. Chuyển đến trình duyệt của bạn và nhấp vào nút chuột giữa trong trường văn bản URL. Văn bản đã chọn sẽ được chèn vào (hy vọng!). Lưu ý: trong Firefox, bạn có thể đặt tùy chọn middlemouse.contentLoadURL thành true trong about: config, sau đó URL được chọn sẽ được sử dụng khi nhấn nút chuột giữa ở hầu hết các vị trí trong cửa sổ.

  • Chọn một số văn bản trong trình duyệt của bạn bằng cách kéo bằng chuột. Chuyển đến Vim và nhấn nút chuột giữa: Văn bản đã chọn được chèn.

  • Chọn một số văn bản trong Vim và thực hiện "+ y. Truy cập trình duyệt của bạn, chọn một số văn bản trong trường văn bản bằng cách kéo bằng chuột. Bây giờ sử dụng nút chuột phải và chọn" Dán "từ menu bật lên. Văn bản đã chọn được ghi đè bằng văn bản từ Vim. Lưu ý rằng văn bản trong thanh ghi "+ vẫn khả dụng khi thực hiện lựa chọn Visual, làm cho văn bản khác có sẵn trong thanh ghi" *. Điều đó cho phép ghi đè văn bản đã chọn.

Tôi đã nhận thấy bằng cách sử dụng nhấp chuột giữa trong vim dường như không gây ra sự thụt lề để đó có thể là một ý tưởng
Fuseteam

4

Điều này làm việc cho tôi (trường hợp cho + đăng ký, những gì tôi sử dụng như bộ đệm trao đổi giữa các aps):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>

2

Nếu bạn đang sử dụng máy mac, macvim dường như xử lý tốt mà không cần phải bật dán.

brew cài đặt macvim --override-system-vim


Đó có phải là trường hợp nếu bạn đưa các chỉ thị của OP vào .vimrctệp của mình không?
vẽ Noakes

2

Dán gốc / dán khung là cách tốt nhất và đơn giản nhất kể từ vim 8(phát hành năm 2016). Nó thậm chí hoạt động trên ssh! (Dán khung hoạt động trên Linux và Mac, nhưng không phải Windows Git Bash)

  1. Đảm bảo bạn có vim 8+ (bạn không cần +clipboardhoặc +xterm_clipboardtùy chọn).

    vim --version | head -1

  2. Chỉ cần sử dụng lệnh dán gốc của hệ điều hành (ví dụ ctrl+shift+Vhoặc cmd+V) trong Chế độ bình thường. Không nhấn icho Chế độ chèn.


Kiểm tra

  1. Sao chép ( ctrl+shift+Choặc cmd+C) đầu ra của điều này (2 dòng có thụt tab) vào bảng tạm hệ thống:

    echo -e '\ta\n\tb'

  2. Khởi chạy vim 8+ sạch với autoindent:

    vim -u NONE --noplugin -c 'set autoindent'

  3. Dán từ bảng tạm hệ thống ( ctrl+shift+Vhoặc cmd+V) ở Chế độ thường. Không nhấn icho Chế độ chèn. Các abnên được liên kết với một thụt lề tab duy nhất. Bạn thậm chí có thể làm điều này trong khi ssh-ing đến một máy từ xa (máy từ xa sẽ cần vim 8+).

  4. Bây giờ hãy thử cách cũ, cách này sẽ tự động tạo dòng thứ hai bằng một tab phụ: Nhấn icho Chế độ chèn. Sau đó dán bằng ctrl+shift+Vhoặc cmd+V. Hiện tại abđang bị điều chỉnh sai.


Cài đặt Vim 8


1
cách tốt nhất và đơn giản nhất! Ngoài ra, Google đã đề xuất nó trong Featured snippettìm kiếm của tôi 'dán nội dung không có tab vim', có thể bởi vì, tôi đã sử dụng từ khóa 'tab', chỉ trong câu trả lời này được đề cập :)
David


1

Cách nhanh nhất tôi biết để nhanh chóng đi đến dán-insert mode cho một dán one-shot là tpope của không yếu đuối , có tính năng yoyO, có lẽ việc nhớ mật khẩu cho “bạn mở”. Họ chỉ được ghi nhận trong vimdoc của mình, như:

Chuyển đổi không được cung cấp cho 'dán' vì trường hợp sử dụng điển hình của việc chèn một phần chèn đơn độc là rất lãng phí: Bạn chuyển đổi hai lần, nhưng bạn chỉ dán một lần (YOPO). Thay vào đó, nhấn yo hoặc yO để gọi o hoặc O với 'dán' đã được đặt. Tự động rời khỏi chế độ chèn sẽ đặt 'nopaste'.


1

Một cách khác để dán là thông qua <CR>và thả nội dung của thanh ghi (ở đây là thanh ghi toàn cầu). Xem: :h i_ctrl-rh i_CTRL-R_CTRL-O .

Từ tài liệu trợ giúp của vim:
Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse<MiddleMouse>. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

Vì vậy, để dán nội dung vào vim mà không cần thụt lề tự động, hãy sử dụng <CR><CO>*trong hầu hết các hệ thống unix.

Lưu ý: điều này chỉ hoạt động nếu vim được biên dịch với clipboard.



1

Một câu trả lời khác mà tôi không thấy cho đến bây giờ:

:se paste noai

0

Đáng buồn là tôi đã tìm thấy plugin vim được đề cập là không hoạt động với iTerm2 3.0.15 (công bằng mà tôi không biết nếu nó bị hỏng trên các phiên bản cũ hơn) - nhưng thay vào đó tôi đã tìm thấy bản hack này.

Ánh xạ lệnh-p để thực hiện dán và sử dụng các khóa vim iTerm2. Rõ ràng điều này chỉ hoạt động cho iTerm2.

Làm thế nào nó hoạt động. Tôi sử dụng "jk" để vào chế độ thoát vì vậy bạn cũng sẽ cần:

: inoremap jk

trong .vimrc của bạn.

Sau đó, nó chỉ gọi P để vào chế độ dán, "+ p để dán từ bảng ghi tạm và sau đó P để tắt chế độ dán. Hth.

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


1
Đợi đã, cái gì, bạn sử dụng 'jk' cho việc này?
0xc0de

Ồ vâng, tôi đã quên đề cập đến điều đó. Chỉ cần thêm ": inoremap jk <esc>" vào .vimrc của bạn. Về lý do tại sao tôi sử dụng jk, hãy hỏi Apple và tại sao họ cảm thấy cần phải di chuyển và thoát khỏi phím thoát vật lý. 8 (
Neil McGill

BTW cần một số đào tạo nhưng sau một thời gian jk cảm thấy nhanh hơn và tôi nghĩ rằng tôi thích nó hơn là thoát ... Dù sao cũng sẽ rất thú vị nếu biết iTerm2 có chấp nhận <ESC> ở đây không.
Neil McGill

Con đường để đi Apple!
0xc0de
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.