2012-03-14 27 views
5

Tôi không hiểu tại sao các lệnh này lại làm những việc khác nhau.Vim: thoát khỏi "thanh" nối các lệnh Ex

dán trong tập tin vimrc, kích hoạt bằng cách nhấn t trong bình thường:

nnoremap t :call search('\m\(a\|b\)', 'W')<CR> 
nnoremap t :call search('\m\(a\\|b\)', 'W')<CR> 

Typed trực tiếp vào dòng lệnh:

:call search('\m\(a\|b\)', 'W') 
:call search('\m\(a\\|b\)', 'W') 

Để cụ thể: Các "dự định" hành vi đòi hỏi một \\| trong Ví dụ nnoremap, nhưng nó yêu cầu \| trong ví dụ tìm kiếm call.

Tôi biết rằng việc xử lý đặc biệt thanh (:help :bar) là một trong những bẫy mà Vim đã đặt ra cho tôi, nhưng nó vẫn không có ý nghĩa. Các tài liệu rõ ràng nói "danh sách các lệnh này sẽ thấy thanh như là một phần của đối số của họ" nhưng không ai trong số những trường hợp ngoại lệ áp dụng ở đây. Tất cả các lệnh liên quan trong ví dụ này xử lý thanh như một ký tự meta ghép. Cũng trong tình huống này, thanh nằm bên trong một chuỗi và (tôi nghĩ?) Đang được phân tích cú pháp như là một phần của chuỗi được ưu tiên hơn cú pháp meta ghép.

Trả lời

11

Thật vậy, vấn đề là do điều trị đặc biệt của ký tự thanh theo lệnh tạo bản đồ.

Cơ chế ánh xạ khóa trong Vim là cách tạo chuỗi các phím bấm để được hiểu là một chuỗi khóa khác; không có cách diễn giải ngữ nghĩa của Ngôn ngữ Vim-script được thực hiện ở cấp độ này. Kể từ khi tạo bản đồ, cần để tách cả hai đối số chuỗi khóa để nêu rõ ánh xạ giữa các lệnh của số :map -gia đình bằng cách xác định ranh giới của hai đối số này. Để sử dụng các ký tự có thể can thiệp vào quy trình này trong ánh xạ, người dùng phải sử dụng cú pháp thoát được cung cấp cho các ký tự đó (trong đó có ký tự trả về, dấu cách, dấu gạch chéo ngược và thanh).

Vì ký tự thanh có thể được sử dụng để phân tách lệnh ánh xạ từ lệnh Ex tiếp theo và do đó, để xác định ranh giới kết thúc của bên phải của ánh xạ, nó không thể được sử dụng như trong một chuỗi khóa. Theo :help map_bar, tùy thuộc vào thiết lập này, một nhân vật có thể thanh thoát như <bar>, \|, hoặc ^V| (nơi ^V biểu thị đen Ctrl +V mã chủ chốt).

Giữ ý nghĩ đó, chúng ta hãy làm theo các ánh xạ trong câu hỏi (khoảng một phần \|/\\|) cách chúng được giải thích theo cấu hình mặc định. Trong ánh xạ đầu tiên, chuỗi \| được coi là một ký tự | duy nhất. Do đó, sau đó lệnh lập bản đồ được thực thi, nhấn t sẽ là giống như gõ

:call search('\m\(a|b\)', 'W')Nhập

Khi lệnh lập bản đồ thứ hai là chạy, chuỗi \\| được hiểu như là một ký tự gạch chéo ngược (không cần phải thoát khỏi \ trong các ánh xạ bên phải , trừ các lồng nhau) theo sau là \| chỉ định đại diện cho một ký tự thanh. Vì vậy, lệnh này bản đồ t đến sau:

:call search('\m\(a\|b\)', 'W')Nhập

Tuy nhiên, khi một loại tìm kiếm ánh xạ gọi trong chế độ dòng lệnh, không giống như trình tự quan trọng trong việc ánh xạ, họ được hiểu là lệnh Ex ngay lập tức. Các ký tự thanh này xảy ra theo chuỗi ký tự, vì vậy không có khả năng là giải thích sai chúng dưới dạng dấu tách cho lệnh Ex. Khi gõ trực tiếp, các lệnh được gửi đến thực thi khi chúng được viết. Do đó, sự khác biệt trong công việc giữa chúng là do ý nghĩa của cụm từ thông dụng \m\(a\|b\)\m\(a\\|b\), không phải do một số hành vi thoát.

+0

Cảm ơn bạn đã xóa thanh toán này. Tôi chắc chắn đã bỏ qua cách các lệnh 'map' phải phân tích các đối số của chúng mà không cần nhìn vào nội dung của chúng. – Ein

7

Khi bạn sử dụng vim của *mapcommand lệnh, động cơ vimscript không giải thích các lệnh - nó lưu nó như là, như là một chuỗi tổ hợp phím (trong trường hợp *map) hoặc như là một chuỗi (trong trường hợp command). Lệnh này chỉ được diễn giải khi bạn sử dụng nó.

Do đó, khi bạn ánh xạ lệnh, vim không thực sự biết ký tự ống của bạn nằm bên trong một chuỗi, bởi vì anh ấy không biết hoặc quan tâm nếu có chuỗi trong lệnh của bạn, ít nhất không phải trong giai đoạn đó .

Nếu bạn muốn sử dụng | trong một số *map, bạn cần sử dụng <bar> để thay thế.

Các vấn đề liên quan