Ánh xạ với chuyển động


12

Tôi đang cố gắng hiểu làm thế nào tôi có thể sử dụng toán tử với chuyển động tiếp theo bên trong ánh xạ. Ví dụ:

nmap /c c{here we pending for a motion}/<C-r>"<CR>

Bản đồ nên làm như sau:

  1. Kích hoạt ctoán tử và lắng nghe chuyển động tiếp theo;
  2. Ví dụ, tôi có thể gõ vào đây t,để thay đổi mọi thứ trước dấu phẩy tiếp theo;
  3. Chuyển đến chế độ chèn xóa mọi thứ giữa con trỏ và dấu phẩy;
  4. Văn bản đã xóa được tự động tìm kiếm dưới dạng mẫu

Vì vậy, để đơn giản, sau khi xóa văn bản chuyển động, tôi được chuyển sang chế độ chèn với các lần xuất hiện được tô sáng của văn bản đã xóa. Tôi sẽ rất biết ơn nếu ai đó giúp tôi giải quyết vụ án này.

CẬP NHẬT

Các câu trả lời gần như những gì tôi muốn. Nhưng! Khi tôi nhấn /cw, gõ một cái gì đó thay vì từ, sau đó nhấn <Esc>. Sau khi tôi mong đợi để làm điều tương tự với các lần xuất hiện tiếp theo. Nhưng sau khi đặt trước n(đi đến lần xuất hiện tiếp theo) và .(lặp lại lệnh cuối cùng), nó chỉ thêm vào văn bản đã gõ cuối cùng thay vì thay thế nó. Mục tiêu chính của ánh xạ là sử dụng nó n/N.lặp lại. Tôi đã bỏ lỡ một cái gì đó?

Câu trả lời:


9

vim hỗ trợ ánh xạ toán tử :h map-operator.

Những gì bạn cần là một operatorfunc, và một bản đồ. cho nhu cầu của bạn, các mã sau đây hoạt động. Vâng, nó chỉ là một ví dụ, bạn tinh chỉnh thêm.

nmap  <silent> /c :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
    silent exec 'normal! `[v`]d'    
    silent exec 'let @/=@"' 
    startinsert
endfunction

Lưu ý rằng exec 'let @/=@"'chỉ để làm nổi bật các mã trong bộ đệm. Nếu bạn không muốn xem phần tô sáng ngay lập tức, bạn có thể chỉ cầnlet @/=@"


Tôi đã cập nhật câu hỏi của mình. Có vẻ như câu trả lời của bạn là câu hỏi gần nhất với nhu cầu của tôi, nhưng nó không làm như vậy với lần xuất hiện tiếp theo, vì vậy tôi đã giải thích khoảnh khắc đó trong câu hỏi.
Timur Fayzrakhmanov

Bạn có hai toán tử ( /ci) vim .chỉ lặp lại cái cuối cùng. Nếu bạn muốn mở rộng nó, hãy kiểm tra repeatplugin. @TimurFayzrakhmanov cũng có :g:scác lệnh, cũng có thể giúp bạn.
Kent

"mã lẻ trong mã của bạn 'let @/=@""'? Tôi nghĩ rằng có thể, ví dụ silent exec 'normal! [v ]c', bởi vì ctoán tử thực hiện những gì tôi mong đợi, ngoại trừ việc nó không thêm văn bản đã thay đổi vào mẫu tìm kiếm.
Timur Fayzrakhmanov

1
@TimurFayzrakhmanov "" là một lỗi đánh máy .. tôi cũng đã nghĩ ra c, tuy nhiên nó đã thêm một khoảng trắng , bởi vì có sự thay đổi chế độ n-i-n-itôi đoán ... làm một số thử nghiệm bạn sẽ thấy.
Kent

@TimurFayzrakhmanov bạn có thể làm cho nó lặp lại mà không cần bất kỳ plugin bằng cách thay đổi dđể ystartinsertđể call feedkeys("cgn", 'n')(xem câu trả lời của tôi dưới đây)
Jerome Dalbert

4

Việc thực hiện (và ghi lại) các ánh xạ phức tạp sẽ dễ dàng hơn bằng cách sử dụng các hàm:

function! DoMagic()
   execute "normal! d".input("enter motion: ")
   let @/=@"
   startinsert
endfunction

Sau đó thực hiện chức năng ánh xạ của bạn gọi chức năng đó:

nmap /c :call DoMagic()<CR>

Biên tập:

Nếu ý định của bạn là thực hiện tìm kiếm & thay thế ở một số lượng lớn địa điểm, bạn nên thử lệnh thay thế : :s. Bạn có thể thay đổi ánh xạ của mình để sao chép lựa chọn trực quan vào mẫu tìm kiếm:

function! DoMagic2()
   normal! gv"ay
   return @a
endfunction

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>

1
điều này thậm chí với giao diện người dùng "đẹp", hoạt động theo nhu cầu của OP và có thể "nhiều hơn" so với dự kiến, tùy thuộc vào nội dung bạn nhập. Ví dụ: khi một người nhìn thấy enter motion:, anh ta đã đưa ra: t,ggVGJZZ ^ _ ^ Đó là một vấn đề phổ biến đối với việc ghép lệnh
Kent

Đó gần như là những gì tôi muốn. Vd: Tôi nhấn /cwrồi gõ một cái gì đó thay vì từ, sau đó nhấn <Esc>. Sau khi tôi muốn làm tương tự với lần xuất hiện tiếp theo. Nhưng sau khi đặt trước n(đi đến lần xuất hiện tiếp theo) và .(lặp lại lệnh cuối cùng), nó chỉ thêm vào văn bản đã gõ cuối cùng thay vì thay thế nó. Mục tiêu chính của ánh xạ là sử dụng nó n/N.lặp lại. Tôi đã bỏ lỡ một cái gì đó?
Timur Fayzrakhmanov

1
Chức năng này là để làm rõ ý tưởng sử dụng các chức năng khi bạn gặp rắc rối với ánh xạ phức tạp. Bạn nên thay đổi nó để đáp ứng nhu cầu của bạn; hãy thử làm theo lời khuyên của Kent để thực hiện .lại lệnh của bạn.
mMontu

Cảm ơn bạn đã trả lời. Đó là hữu ích quá, nhưng tôi chấp nhận một trong những 's @Kent, bởi vì nó làm chuyển động ngay lập tức sau khi tôi gõ họ (không cấp phát <CR>từ input()).
Timur Fayzrakhmanov

1
@TimurFayzrakhmanov bạn cũng có thể thử thay thế, như được giải thích trong bản cập nhật.
mMontu

1

Giải pháp này hoạt động với "lặp lại lệnh cuối" (aka .):

nmap <silent> /c :set opfunc=ChangeOccurence<CR>g@

function! ChangeOccurence(type)
  exec 'normal! `[v`]y'
  let @/ = @"
  call feedkeys('cgn', 'n')
endfunction

Khi lặp lại, bạn thậm chí không cần sử dụng n, bạn chỉ có thể sử dụng .để trực tiếp tìm nạp và thay thế lần xuất hiện tiếp theo nếu bạn muốn đi nhanh hơn.

Tùy chọn, nếu bạn muốn có các từ nổi bật của các từ phù hợp, bạn có thể thay thế 'cgn'bằng 'n``cgn'.

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.