Làm thế nào để gấp bình luận?


16

Cú pháp foldmethodrất hay, nhưng đôi khi tôi chỉ muốn gấp các bình luận trong một tệp nguồn.

Ngoài ra cú pháp gấp các bình luận chỉ hoạt động cho các bình luận C-Style như:

/*
 ...
 */

Nhưng không cho bình luận nồi hơi như:

//
//
// ...
//

Hoặc thậm chí cho các khối nhận xét bằng các ngôn ngữ không giống C như:

#
#
# ...
#

Làm thế nào tôi có thể cấu hình này với vim?


Bạn có muốn sử dụng cú pháp gấp nhận xét gấp? Hay chỉ bình luận gấp?
Martin Tournoij

@Carpetsmoker, cú pháp gấp + gấp bình luận sẽ ổn nếu người ta có thể nói 'mở tất cả các nếp gấp, ngoại trừ các bình luận'. Nếu không, bình luận gấp mà không cần cú pháp gấp cũng sẽ tốt.
maxschlepzig

Câu trả lời:


14

Chỉ gấp các ý kiến ​​là khá dễ dàng bằng cách sử dụng foldmethod=expr:

set foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*'.&commentstring[0]

Điều này chỉ đơn giản là kiểm tra xem dòng bắt đầu với bất kỳ khoảng trắng + ký tự nhận xét nào. Lưu ý rằng điều này khá ngây thơ và có thể không hoạt động đối với tất cả các ngôn ngữ. Vì vậy, bạn có thể muốn sử dụng autocmd để cụ thể hơn:

autocmd FileType c setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*//'
autocmd FileType python setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*#'

Để biết thêm thông tin về Fold-expr, xem:


Sử dụng cú pháp gấp nhận xét gấp có liên quan nhiều hơn; điều này sẽ yêu cầu sửa đổi tệp cú pháp /usr/share/vim/vim74/syntax/*.vimvà sẽ dành riêng cho ngôn ngữ bạn đang sử dụng.

Lưu ý rằng một số filetypes đã làm điều này! Ví dụ từ ruby.vim:

if !exists("ruby_no_comment_fold")
  syn region rubyMultilineComment start="\%(\%(^\s*#.*\n\)\@<!\%(^\s*#.*\n\)\)\%(\(^\s*#.*\n\)\{1,}\)\@=" end="\%(^\s*#.*\n\)\@<=\%(^\s*#.*\n\)\%(^\s*#\)\@!" contains=rubyC
  syn region rubyDocumentation    start="^=begin\ze\%(\s.*\)\=$" end="^=end\%(\s.*\)\=$" contains=rubySpaceError,rubyTodo,@Spell fold
else
  syn region rubyDocumentation    start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell
endif

2

Tôi thích gấp với thụt lề nhưng bao gồm các bình luận trong nếp gấp (ý tôi là mỗi bình luận có cùng mức độ gấp như dòng trước).

Thật không may, từ khóa Foldignore chỉ hoạt động cho một dòng bình luận. Vì vậy, tôi gấp với expr trong vimrc:

set foldmethod=expr
set foldexpr=FoldMethod(v:lnum)

function! FoldMethod(lnum)
  "get string of current line
  let crLine=getline(a:lnum)

  " check if empty line 
  if empty(crLine) "Empty line or end comment 
    return -1 " so same indent level as line before 
  endif 

  " check if comment 
  let a:data=join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )
  if a:data =~ ".*omment.*"
    return '='
  endif

  "Otherwise return foldlevel equal to indent /shiftwidth (like if
  "foldmethod=indent)
  else  "return indent base fold
    return indent(a:lnum)/&shiftwidth
endfunction

Khối cuối cùng:

indent(a:lnum)/&shiftwidth

Trả về một cơ sở Foldlevel trên thụt lề.

Và một cái khác:

join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )

Kiểm tra nếu ký tự đầu tiên của dòng được coi là một nhận xét với cú pháp. Vì vậy, đó là một cách tốt để hợp nhất thụt lề và cú pháp gấp với biểu thức, cách gấp tiên tiến nhất.

Lưu ý rằng bạn cũng có thể "đặt Foldtext" tùy thuộc vào cách bạn muốn kết quả trông như thế nào.


0

Bạn có thể trực quan chọn khối nhận xét với vacvà sau đó tạo một nếp gấp thủ công zf.

Đối tượng văn bản nhận xét có thể là phần mở rộng ngôn ngữ để thiết lập các đối tượng văn bản vim tiêu chuẩn. Đã thử nghiệm nó với cú pháp Go.


1
Thật vậy, ackhông phải là một nội dung. Nhưng với bình luận của tpope gclà một đối tượng văn bản. Vì vậy, giải pháp tốt hơn là zfac, zfgchoặc zfiptồi tệ nhất
D. Ben Knoble
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.