ánh xạ để bao quanh biểu tượng dưới con trỏ với một biểu thức có chứa biểu tượng


7

Đã đọc các bài viết kịch bản vim trong một giờ, nhưng tôi sợ rằng tôi không có kỹ năng để áp dụng các bài đăng này cho vấn đề của mình. Chỉnh sửa toán học trong tài liệu latex, tôi thường muốn thay thế các ký hiệu toán học như +, -, = bằng \ Pad {+}, \ Pad {-}, \ Pad {=}, trong đó \ Pad là macro latex I ' đã xác định để đặt không gian xung quanh biểu tượng. Tôi muốn có thể đặt con trỏ của mình vào một biểu tượng như vậy, nhập một vài chữ cái, nói ;Pvà có hành động này thay thế biểu tượng bằng

\Pad{whatever the symbol under the cursor is}

Bất kỳ trợ giúp sẽ được đánh giá cao nhất!

`

Câu trả lời:


5
function! s:PadMacro(type) abort
    if a:type ==# 'char'
        normal! `[v`]d
    elseif a:type ==# 'line'
        normal! '[V']d
    elseif a:type ==# 'v'
        normal! `<v`>d
    else
        return
    endif
    let string = '\Pad{' . @" . '}'
    silent execute "normal! i\<c-r>=string\r"
endfunction
nnoremap <silent> ;P :set operatorfunc=<sid>PadMacro<cr>g@
vnoremap <silent> ;P :<c-u>call <sid>PadMacro(visualmode())<cr>

Nếu bạn đặt mã trước đó vào vimrc của mình, nó sẽ làm những gì bạn muốn.

Để sử dụng nó, nhấn ;P{motion}PadMacro()chức năng nên kèm theo các nhân vật được bao phủ bởi {motion}với \Pad{}.

Ví dụ sử dụng:

  • ;Plđể đặt ký tự bên dưới con trỏ (vì llà một chuyển động bao phủ ký tự dưới con trỏ)
  • ;Piwđể đặt từ dưới con trỏ (vì iwlà một đối tượng văn bản bao gồm tất cả các ký tự bên trong từ bên dưới con trỏ)
  • ;Pisđể đặt câu trong đó con trỏ là (vì islà một đối tượng văn bản bao gồm tất cả các ký tự bên trong câu)
  • ;P$ để bao quanh các ký tự giữa con trỏ của bạn và cuối dòng
  • ;P để bao quanh các nhân vật được lựa chọn trực quan

Tất cả mọi thứ được thực hiện bởi PadMacro()chức năng này được coi là một phiên bản duy nhất có nghĩa là nó có thể lặp lại.
Nói cách khác, nếu bạn có một số phần văn bản tương tự để gửi kèm theo \Pad{}thì không cần phải chạm vào ánh xạ mỗi lần, chỉ lần đầu tiên (sau đó bạn có thể nhấn .để lặp lại phiên bản cuối cùng của mình).

Để biết danh sách đầy đủ các đối tượng văn bản mà bạn có thể áp dụng bao vây của mình, hãy xem :
:help text-objects.


Tuyệt vời, cảm ơn rất nhiều @saginaw. Tôi thực sự có một vài lệnh khoảng cách khác nhau mà tôi sử dụng, như \ pad, \ ppad, ngoài Pad. Rõ ràng là tôi có thể nhân đôi macro cho từng loại này, nhưng với mục đích hướng dẫn, tôi cho rằng có một cách để truyền đối số cho macro, sửa đổi dòng "let string" để chèn đối số thay vì Pad, sau đó xác định một sơ đồ khác đối với mỗi tùy chọn, ví dụ: p sẽ chèn \ pad ,; pp sẽ chèn \ ppad? Cảm ơn một lần nữa!
Leo Simon

@LeoSimon Bạn có thể xác định toàn bộ nhóm ánh xạ với một forvòng lặp và :executelệnh. Xem ở đây để biết ví dụ: github.com/romainl/dotvim/blob/master/vimrc#L307-L312 Không khó để làm điều tương tự cho ánh xạ của bạn. Tuy nhiên, tôi không biết cách chuyển "pad", "ppad", ... làm đối số cho hàm. Tôi có một ý tưởng (sau khi đọc :h g@, có vẻ như bạn có thể thêm một nhóm đối số tùy chọn ...và truy cập đối số đầu tiên của nhóm này với a:1), nhưng tôi đã không thành công trong việc viết một hàm làm việc. Nếu tôi có thể, tôi sẽ cho bạn biết.
saginaw

Cảm ơn @saginaw, tôi đã bắt đầu vào vòng lặp for, nhưng thật đáng buồn, không thể vượt qua cơ sở đầu tiên. Tôi đã thử làm như sau một bước khởi đầu: trong phạm vi vĩ mô của bạn,
Leo Simon

@LeoSimon Tôi hy vọng tên PadMacronày không quá sai lệch, bởi vì nó chỉ là một chức năng vimscript. Tôi gọi nó như thế bởi vì bạn nói \Pad{}đã được hiểu là một macro latex. Nhưng nếu bạn thích, bạn có thể gọi nó là bất cứ điều gì khác ( PadEnclosureví dụ). Đối với các ánh xạ, giả sử bạn có 3 chức năng MyFunctionA, MyFunctionBMyFunctionC, mỗi người áp dụng một biến đổi nhất định trên văn bản của bạn. Và bạn muốn ánh xạ chúng đến ;Pa, ;Pb;Pc. Sau đó, đoạn mã sau sẽ có thể làm điều đó cho bạn: paste.debian.net/plain3536949 Không được kiểm tra, vì vậy tôi không chắc nó hoạt động.
Saginaw

Cảm ơn! @saginaw. PadMacro là hoàn toàn tốt. Vòng lặp của bạn hoạt động rất đẹp. Mọi thứ sẽ thanh lịch hơn một chút nếu tôi có thể bao gồm chức năng tập lệnh thực tế trong vòng lặp. Thật dễ dàng để sửa đổi dòng \let string = để nó chấp nhận một mục danh sách thay vì Pad; phần vấn đề là xác định tên macro là một mục danh sách thay vì một chuỗi ký tự, nghĩa là, phần sau không hoạt động (không đáng ngạc nhiên) function! s: . func_name . (type) abort. Có lẽ có một số cách tạo hàm với một tên chung, sau đó trong vòng lặp sao chép hàm chung vào func_name?
Leo Simon

5

Ý tưởng rất đơn giản:

  1. bạn cắt văn bản bạn muốn bao quanh và vào chế độ chèn,
  2. bạn chèn phần đầu tiên
  3. bạn chèn nội dung của thanh ghi không tên
  4. bạn chèn phần cuối cùng
  5. bạn thoát khỏi chế độ chèn.

Ví dụ của bạn, bạn sẽ làm:

s\Pad{<C-r>"}<Esc>

Mà có thể được ánh xạ để thuận tiện cho bạn:

" normal mode, for single characters
nnoremap ;P s\Pad{<C-r>"}<Esc>

" visual mode, for multiple characters
xnoremap ;P s\Pad{<C-r>"}<Esc>

Lưu ý rằng có thể sử dụng một thanh ghi khác nếu bạn không muốn làm lộn xộn thanh ghi không tên. Ở đây tôi sử dụng zđăng ký:

"zs\Pad{<C-r>z}<Esc>

3

Chỉ một giải pháp nữa cho trường hợp khi bao quanh không chỉ một biểu tượng (mẫu từ cấu hình của tôi để bao quanh với "[" & "]"

vmap Q[ O<Esc>i[<Esc>gvo<Esc>la]<Esc>
nnoremap Q[ veO<Esc>i[<Esc>gvo<Esc>la]<Esc>

Điều quan trọng là sử dụng "o" & "O" để di chuyển đến bắt đầu / kết thúc lựa chọn

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.