Đặt tùy chọn dán, nhưng chỉ cho một lần chèn


16

Tôi muốn có một cách nhanh chóng để thiết lập 'paste'tùy chọn Vim , chèn một số văn bản và trở lại giá trị trước đó 'paste'.

Một trường hợp sử dụng thông thường chèn nội dung clipboard của hệ điều hành theo nghĩa đen, bất kể chế độ chèn nào có thể đang hoạt động, chẳng hạn như thụt lề tự động và không thay đổi trạng thái của Vim. Một trường hợp sử dụng khác là cho phép một tính năng macro của hệ điều hành đưa tổ hợp phím vào Vim và để chúng được hiểu là văn bản bằng chữ.

Điều này rõ ràng khái quát cho các tùy chọn khác - ý tưởng chung là đặt một số tùy chọn nhưng chỉ trong thời gian của một chuyến đi thông qua chế độ chèn.

Về cơ bản tôi muốn liên kết một chuỗi khóa (nói _i) với một macro thực hiện điều này

:set paste
i…<Esc>
:set nopaste

trong đó i…<Esc>tôi có nghĩa là chuyển sang chế độ chèn (như với ilệnh) và tiếp tục macro khi trở về chế độ lệnh, ngoại trừ việc tôi muốn kết thúc với chế độ 'paste'vẫn hoạt động nếu nó được kích hoạt trước đó. Tôi có thể làm cái này như thế nào?

Lưu ý: Nội dung của bảng tạm hệ điều hành được ánh xạ tới thanh "*ghi . Khi nó hoạt động, 'paste'tùy chọn không hữu ích. Kịch bản thúc đẩy cho câu hỏi này là vào những thời điểm khi các điều kiện "*hỗ trợ đăng ký không được đáp ứng - Vim không được biên dịch với +xterm_clipboardtính năng này hoặc nó đang chạy trong một thiết bị đầu cuối như Màn hình hoặc qua SSH để cách ly nó khỏi máy chủ X xung quanh.


1
Tôi thích câu hỏi của bạn (tôi đã từng đến đó nhiều lần). Tuy nhiên, không dễ dàng hơn để dán từ +hoặc *đăng ký?
yo '

@yo ' Chỉ khi họ làm việc . Mà, đối với việc sử dụng Vim của tôi, thường không phải là trường hợp.
Gilles 'SO- ngừng trở thành ác quỷ'

Câu trả lời:


15

Hãy thử xem:

function! Paste_Func()
    let s:inPaste = &paste
    if !s:inPaste
        set paste
    endif

    echom s:inPaste
    augroup paste_callback
        autocmd!
        autocmd InsertLeave <buffer> call Paste_End()
    augroup END

    startinsert
endfunction

function! Paste_End()
    augroup paste_callback
        autocmd!
    augroup END
    augroup! paste_callback

    if !s:inPaste
        set nopaste
    endif
endfunction

map _i :call Paste_Func()<cr>

Nó lưu trạng thái dán hiện tại của bạn trong biến inPaste và đặt dán nếu nó chưa được đặt. Sau đó, nó sẽ thiết lập autocmd khi bạn rời khỏi chế độ chèn và sau đó đưa bạn vào chế độ chèn.

Khi bạn rời khỏi chế độ chèn, nó sẽ chạy autocmd, đầu tiên sẽ xóa autocmd (vì vậy nó sẽ không chạy khi bạn rời chế độ chèn theo bất kỳ cách nào khác), và cuối cùng đặt nopaste nếu ban đầu bạn không ở chế độ dán.

Ngoài ra, nếu bạn đang sử dụng vim trong thiết bị đầu cuối, bạn có thể muốn xem vim-ngoặced-paste , sử dụng tính năng chế độ dán khung được cung cấp bởi một số trình giả lập thiết bị đầu cuối để phát hiện nếu bạn dán và tự động đặt chế độ.

Chỉnh sửa: đã sửa tập lệnh


Điều này có vẻ như đang đi đúng hướng (đặc biệt, tôi không có ý tưởng làm thế nào để khung ngoặc cứng Một đoạn chèn bằng các lệnh thế giới thông thường). Cảm ơn. Tuy nhiên, điều đó không hoàn toàn đúng và tôi không thấy vấn đề ở đâu: sau đó _i, pastetùy chọn bị tắt, ngay cả khi nó đã được bật trước đó.
Gilles 'SO- ngừng trở nên xấu xa'

Bạn đúng rồi! Tôi khá chắc chắn rằng tôi đã thử nghiệm điều đó, nhưng tôi phải thay đổi một cái gì đó. Tôi đã cập nhật kịch bản trong bài viết, xem nó có hoạt động với bạn không.
Chad

4

ngoại trừ việc tôi muốn kết thúc với 'paste'hoạt động vẫn còn nếu nó đã hoạt động trước đó.

'paste'nên hoạt động trong thời gian càng ngắn càng tốt. Nó vô hiệu hóa rất nhiều chức năng (bao gồm cả bản đồ), vì mục đích duy nhất của nó là để tránh hiểu sai văn bản đang được dán. Vì vậy, tôi nghĩ rằng yêu cầu được trích dẫn không thực sự cần thiết.

Điều đó đang được nói, nó thực sự khá dễ dàng để dán mà không cần phải thiết lập 'paste'. Nếu bạn đang chạy gvim hoặc có +xterm_clipboardtrong vim console, bạn chỉ cần sử dụng "+pđể dán từ bảng tạm của hệ điều hành.

Vấn đề thụt tự động trong khi dán chỉ thực sự xảy ra trong hai kịch bản. Chèn nội dung của thanh ghi trong khi ở chế độ chèn ( <C-r>+) hoặc dán giữa chuột bằng chuột.

Thay vì chèn nội dung của thanh ghi trong khi ở chế độ chèn, dán từ thanh ghi ở chế độ bình thường sẽ tránh được vấn đề định dạng lại.

Nếu bạn muốn nhấp chuột giữa dán bằng chuột, sau đó sử dụng 'mouse'tùy chọn để cho Vim, thay vì thiết bị đầu cuối, xử lý nhấp chuột giữa. Vim sau đó sẽ chèn nội dung theo nghĩa đen thay vì diễn giải văn bản đến như được gõ.


2
Không ai trong số này trả lời câu hỏi của tôi. Tôi đưa ra yêu cầu rõ ràng cho một lý do! Thường thì 'paste'thực sự không hoạt động trước, nhưng tôi không muốn phải suy nghĩ về điều này. Tôi thường làm việc trong một Vim không có quyền truy cập vào bảng tạm hoặc chuột X, vì bản dựng Vim của tôi không có xterm_clipboardtính năng này hoặc do tôi đang làm việc trong một phiên Màn hình hiện đang được gắn vào một Thiết bị đầu cuối X.
Gilles 'SO- ngừng trở thành ác quỷ'

@Gilles Sau đó, bạn có thể giải thích cách bạn dán? Đó là thông tin liên quan để có thể đưa ra câu trả lời có thể bao bọc hành động đó với những gì bạn muốn làm.
jamessan 4/2/2015

1
Trường hợp sử dụng cơ bản của tôi là dán bằng nút chuột giữa hoặc bằng Shift + Chèn. Mặc dù điều đó không thực sự phù hợp: cốt lõi của câu hỏi là làm thế nào để thiết lập tùy chọn, chuyển sang chế độ chèn (với i, tôi không hỏi làm thế nào để tham số hóa điều này) và khôi phục giá trị của tùy chọn khi trở về từ chế độ chèn.
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles Cốt lõi của câu hỏi của bạn như được nêu trong nhận xét này rõ ràng hơn nhiều so với câu hỏi ban đầu của bạn. Cảm ơn.
jamessan 4/2/2015

1
@Gilles Nó không liên quan đến bạn , nhưng nó có thể liên quan đến khách truy cập trong tương lai. Do đó, bạn có thể tự đặt câu hỏi ("Tôi biết tôi có thể sử dụng "*phoặc "+pdán từ bảng ghi, nhưng tôi sẽ không sử dụng khả năng dán của hệ thống") và sau đó câu trả lời này là không cần thiết. Hoặc bạn không, và sau đó tôi nghĩ rằng câu trả lời này có vị trí của nó ở đây.
yo '

4

Cá nhân, tôi sử dụng yokeybinding từ plugin vim-unimpaired tuyệt vời của Tim Pope vì lý do này chính xác. Từ tài liệu của mì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 yohoặ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'.

Có thể là quá mức cần thiết để cài đặt plugin chỉ đơn giản cho câu hỏi của bạn, nhưng tôi thấy nó cũng cung cấp rất nhiều khóa phím hữu ích khác (thêm thông tin trong README ).


1

Với Vim 8+ trên Linux hoặc Mac, giờ đây bạn có thể chỉ cần sử dụng dán gốc của thiết bị đầu cuối (ví dụ: nút chuột giữa, ctrl+shift+Vtrong Gnome, cmd+Vtrên Mac) nếu thiết bị đầu cuối hỗ trợ dán khung. Không nhấn icho Chế độ chèn.

Nó sẽ dán nội dung của bảng tạm hệ điều hành của bạn, giữ nguyên các khoảng trắng và các tab mà không cần thêm tự động. Nó tương đương với cái cũ :set paste, i, ctrl+shift+V, esc, :set nopastephương pháp.

Bạn thậm chí không cần các tính năng +clipboardhoặc +xterm_clipboardvim được cài đặt nữa. Tính năng này được gọi là "dán khung". Để biết thêm chi tiết, hãy xem /programming/2514445/turn-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

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.