let b:commentChar='//'
: Điều này tạo ra một biến trong vim. các b
đây đề cập đến phạm vi, mà trong trường hợp này được chứa vào bộ đệm, có nghĩa là tập tin hiện đang mở. Các ký tự nhận xét của bạn là các chuỗi và cần được gói trong dấu ngoặc kép, các trích dẫn không phải là một phần của những gì sẽ được thay thế khi bật các bình luận.
autocmd BufNewFile,BufReadPost *...
: Autocommands kích hoạt những thứ khác nhau, trong trường hợp này, đây là những kích hoạt khi một tệp mới hoặc tệp đọc kết thúc với một phần mở rộng nhất định. Sau khi được kích hoạt, thực thi lệnh sau, cho phép chúng ta thay đổi commentChar
tùy thuộc vào filetype. Có nhiều cách khác để làm điều này, nhưng chúng khó hiểu hơn đối với người mới (như tôi).
function! Docomment()
: Hàm được khai báo bằng cách bắt đầu bằng function
và kết thúc bằng endfunction
. Chức năng phải bắt đầu bằng một vốn. các !
Đảm bảo rằng chức năng này ghi đè bất kỳ chức năng trước đó định nghĩa là Docomment()
với phiên bản này của Docomment()
. Không có !
, tôi có lỗi, nhưng đó có thể là do tôi đang xác định các hàm mới thông qua dòng lệnh vim.
execute '''<,''>s/^\s*/&'.escape(b:commentChar, '\/').' /e'
: Thực thi cuộc gọi một lệnh. Trong trường hợp này, chúng tôi đang thực thi substitute
, có thể lấy một phạm vi (theo mặc định đây là dòng hiện tại) như %
cho toàn bộ bộ đệm hoặc '<,'>
cho phần được tô sáng. ^\s*
là regex để khớp với bắt đầu của một dòng theo sau bởi bất kỳ khoảng trắng nào, sau đó được thêm vào (do &
). Ở .
đây được sử dụng để nối chuỗi, vì escape()
không thể được gói trong dấu ngoặc kép. escape()
cho phép bạn thoát ký tự commentChar
phù hợp với các đối số (trong trường hợp này \
và /
) bằng cách thêm chúng vào a \
. Sau đó, chúng tôi nối lại một lần nữa với phần cuối của substitute
chuỗi, trong đó cóe
cờ. Cờ này cho phép chúng tôi thất bại trong âm thầm, có nghĩa là nếu chúng tôi không tìm thấy kết quả khớp trên một dòng nhất định, chúng tôi sẽ không hét lên về nó. Nhìn chung, dòng này cho phép chúng ta đặt một ký tự nhận xét theo sau là khoảng trắng ngay trước văn bản đầu tiên, nghĩa là chúng ta giữ mức thụt lề.
execute '''<,''>s/\v(^\s*)'.escape(b:commentChar, '\/').'\v\s*/\1/e'
: Điều này tương tự như lệnh dài lớn cuối cùng của chúng tôi. Duy nhất với cái này, chúng tôi có \v
, đảm bảo rằng chúng tôi không phải trốn thoát ()
, và 1
, đề cập đến nhóm chúng tôi đã thực hiện với chúng tôi ()
. Về cơ bản, chúng tôi khớp với một dòng bắt đầu với bất kỳ khoảng trắng nào và sau đó là ký tự nhận xét của chúng tôi theo sau bởi bất kỳ khoảng trắng nào và chúng tôi chỉ giữ bộ khoảng trắng đầu tiên. Một lần nữa, e
chúng ta hãy âm thầm thất bại nếu chúng ta không có một nhân vật bình luận trên dòng đó.
let l:line=getpos("'<")[1]
: điều này đặt một biến giống như chúng ta đã làm với ký tự nhận xét của mình, nhưng l
đề cập đến phạm vi cục bộ (cục bộ cho hàm này). getpos()
trong trường hợp này, bắt đầu đánh dấu của chúng tôi và [1]
có nghĩa là chúng tôi chỉ quan tâm đến số dòng, không phải những thứ khác như số cột.
if match(getline(l:line), '^\s*'.b:commentChar)>-1
: bạn biết cách làm if
việc match()
kiểm tra xem thứ đầu tiên có chứa thứ thứ hai không, vì vậy chúng tôi lấy dòng mà chúng tôi đã bắt đầu tô sáng và kiểm tra xem nó có bắt đầu bằng khoảng trắng theo sau là ký tự nhận xét của chúng tôi không. match()
trả về chỉ mục nơi điều này là đúng và -1
nếu không tìm thấy kết quả khớp nào. Vì if
đánh giá tất cả các số khác không là đúng, chúng tôi phải so sánh đầu ra của chúng tôi để xem nó có lớn hơn -1 không. So sánh vim
trả về 0 nếu sai và 1 nếu đúng, đó là điều if
muốn xem để đánh giá chính xác.
vnoremap <silent> <C-r> :<C-u>call Comment()<cr><cr>
: vnoremap
có nghĩa là ánh xạ lệnh sau trong chế độ trực quan, nhưng không ánh xạ đệ quy (có nghĩa là không thay đổi bất kỳ lệnh nào khác có thể sử dụng theo các cách khác). Về cơ bản, nếu bạn là người mới làm quen với vim, hãy luôn sử dụng noremap
để đảm bảo bạn không phá vỡ mọi thứ. <silent>
có nghĩa là "Tôi không muốn lời nói của bạn, chỉ là hành động của bạn" và bảo nó không được in bất cứ điều gì lên dòng lệnh. <C-r>
là thứ chúng tôi lập bản đồ, đó là ctrl + r trong trường hợp này (lưu ý rằng bạn vẫn có thể sử dụng Cr bình thường để "làm lại" trong chế độ bình thường với ánh xạ này). C-u
hơi khó hiểu, nhưng về cơ bản, nó đảm bảo bạn không bị mất dấu của việc làm nổi bật hình ảnh của bạn (theo câu trả lời này, nó làm cho lệnh của bạn bắt đầu với '<,'>
đó là những gì chúng ta muốn).call
Ở đây chỉ nói với vim để thực thi chức năng mà chúng ta đã đặt tên và <cr>
đề cập đến việc nhấn enter
nút. Chúng ta phải nhấn nó một lần để thực sự gọi hàm (nếu không chúng ta vừa gõ call function()
vào dòng lệnh, và chúng ta phải nhấn nó một lần nữa để thay thế chúng ta đi suốt (không thực sự chắc chắn tại sao, nhưng bất cứ điều gì).
Dù sao, hy vọng điều này sẽ giúp. Điều này sẽ lấy bất cứ điều gì được tô sáng bằng v
, V
hoặc C-v
, kiểm tra xem dòng đầu tiên có được nhận xét hay không, nếu có, cố gắng bỏ ghi chú tất cả các dòng được tô sáng và nếu không, hãy thêm một lớp ký tự nhận xét cho mỗi dòng. Đây là hành vi mong muốn của tôi; Tôi không chỉ muốn nó chuyển đổi xem mỗi dòng trong khối có được nhận xét hay không, vì vậy nó hoạt động hoàn hảo với tôi sau khi hỏi nhiều câu hỏi về chủ đề này.