Vim: tự động nhận xét trong dòng mới


9

Vim tự động chèn một nhận xét khi tôi bắt đầu một dòng mới từ một dòng nhận xét, bởi vì tôi đã đặt formatoptions=tcroql. Ví dụ: (con trỏ là *):

// this is a comment*

và sau khi nhấn <Enter>(chế độ chèn) hoặc o(chế độ bình thường) tôi còn lại với:

// this is a comment
// *

Tính năng này rất tiện dụng khi viết bình luận nhiều dòng dài, nhưng thường thì tôi chỉ muốn một bình luận một dòng. Bây giờ nếu tôi muốn kết thúc loạt bình luận, tôi có một vài lựa chọn:

  • đánh <Esc>S
  • đánh <BS>ba lần

Cả hai đều có ba tổ hợp phím, được thực hiện cùng với <Enter>điều này có nghĩa là bốn tổ hợp phím cho một dòng mới, mà tôi nghĩ là quá nhiều. Lý tưởng nhất, tôi muốn chỉ đánh <Enter>lần thứ hai để được:

// this is a comment
*

Điều quan trọng là giải pháp cũng sẽ hoạt động với các mức độ thụt khác nhau, tức là

int main(void) {
    // this is a comment*
}

đánh <Enter>

int main(void) {
    // this is a comment
    // *
}

đánh <Enter>

int main(void) {
    // this is a comment
    *
}

Tôi nghĩ rằng tôi đã thấy tính năng này trong một số trình soạn thảo văn bản một vài năm trước nhưng tôi không nhớ đó là tính năng nào. Có ai biết một giải pháp sẽ làm điều này cho tôi trong Vim không? Con trỏ đi đúng hướng về cách cuộn giải pháp của riêng tôi cũng rất đáng hoan nghênh.


3
Bạn có thể sử dụng ctrl-u trong chế độ chèn để xóa các đánh dấu nhận xét được chèn tự động trong một hợp âm.
Etan Reisner

1
@EtanReisner điều đó thực sự tốt hơn, nhưng vẫn là một tổ hợp phím quá nhiều đối với tôi vì đây là trường hợp sử dụng phổ biến như vậy :)
Patrick Oscarity

Bạn đề nghị rằng bạn muốn có thể nhấn enter lần nữa để có được hành vi bạn muốn nhưng ctrl-u có quá nhiều không? Bạn có thể thử ánh xạ <enter> <enter> trong chế độ chèn để tự động thực hiện ctrl-u cho bạn nhưng điều đó sẽ gây ra độ trễ nếu bạn nhấn <enter> chỉ một lần (mà không cần nhấn bất cứ điều gì khác).
Etan Reisner

Ngoài ra, nó chỉ nên kích hoạt nếu dòng bình luận trống. Một độ trễ đáng chú ý khi nhấn <Enter> cũng không được chấp nhận.
Patrick Oscarity

Tôi sẽ chỉ trì hoãn nếu bạn không nhấn bất kỳ phím nào khác mà tôi tin vì vim sẽ phải chờ để đảm bảo bạn vẫn không định nhấn phím khác. Bạn có thể sử dụng một chức năng để thực hiện kiểm tra đó tôi nghĩ mặc dù nó có thể không đặc biệt đơn giản để làm.
Etan Reisner

Câu trả lời:


4

Thử đi:

function! EnterEnter()
  if getline(".") =~ '^\s*\(//\|#\|"\)\s*$'
    return "\<C-u>"
  else
    return "\<CR>"
  endif
endfunction

imap <expr> <CR> EnterEnter()

Cảm ơn trông rất tuyệt! Sẽ cố gắng khi tôi về nhà. Bạn có biết một cách để mở rộng regex để khớp ngôn ngữ đánh dấu nhận xét một cách độc lập không? Thông tin nên có trong các tệp cú pháp hoặc một cái gì đó. Có lẽ tôi có thể tận dụng tính năng cú pháp cho việc này ...
Patrick Oscarity

Ý tôi là trong C, nó phải khớp với // và / * và * (bình luận đa dòng) và trong ruby ​​#, v.v.
Patrick Oscarity

Rõ ràng, chức năng này hoàn toàn không chung chung. Xem :h 'comment':h format-comment'.
romainl

Chức năng được sửa đổi để làm việc với #ruby và "vimscript ngoài cổ điển //. Thật không có ý nghĩa gì khi làm bất cứ điều gì cho các *bình luận đa tuyến kiểu C vì dù sao nó cũng phải kết thúc bằng cách */nào.
romainl

Hmm, có lẽ có <CR><CR>thể được sử dụng để kết thúc bình luận đa dòng ...
romainl

3

Tôi đã mở rộng câu trả lời của @ romainl để làm việc với các ngôn ngữ tùy ý bằng cách tạo regex từ Vim's &commentstring:

function! s:IsOnlyComment(getlineArg)
  let commentRegex='^\s*'.substitute(&commentstring,'%s','\\s*','').'$'
  return strlen(matchstr(getline(a:getlineArg), commentRegex)) > 0
endfunction

function! SmartEnter()
  if s:IsOnlyComment('.')
    return "\<Esc>S"
  else
    return "\<CR>"
  endif
endfunction

inoremap <expr> <CR> SmartEnter()

Tuy nhiên, tôi dường như không thể ánh xạ lại <CR>chút nào, điều này sẽ không hoạt động. Hiện tại, tôi sử dụng <CR><CR>cho đến khi vấn đề này được giải quyết.


1
Tại sao <Esc>S? <C-u>làm tương tự mà không để lại chế độ chèn. Dù sao, tôi đã có một chức năng tùy chỉnh đã thực hiện một loạt các điều trên <CR>và đổi tên thành SmartEnter()chỉ ngày hôm qua sau khi tôi đăng câu trả lời của mình ;-). Ngoài ra, tôi không chắc chắn &commentstringlà lựa chọn đúng vì nó thường chỉ chứa một hình thức và nó có thể là "linewise" hoặc "blockwise" ( /*%s*/trong C, //%strong Javascript, v.v.).
romainl

2

Xóa r khỏi 'định dạng. Đó là những gì lựa chọn đó làm. Tắt nó đi có nghĩa là bạn không bao giờ nhận được vim làm điều đó cho bạn, điều đó có nghĩa là bạn sẽ cần thêm các dấu nhận xét hàng đầu khi bạn thực sự muốn chúng nhưng đó là sự đánh đổi.


2
Tôi thực sự muốn Vim thêm các đánh dấu nhận xét cho tôi, tôi thích điều này. Nhưng tôi cũng muốn một cách nhanh chóng để thoát khỏi bình luận. Cảm ơn câu trả lời của bạn mặc dù.
Patrick Oscarity
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.