vimrcファイルを折りたたむベストプラクティスはありますか


21

私は最近、自分のvimrc長さが400行を超えていることに気付きました(これはIMOで長すぎて削減しようとします)。私は知らなかった)

  • 折り畳み方法を設定しようとしましたindentが、結果が好きではありませんでした(ほとんどが私のvimrcインデントされていないため、面倒でした)。
  • 私はまた、設定しようfoldmethodexprしてsyntaxますが、私は適切に何を折り畳むことができませんでした。
  • ここではdiff、折り畳み方法として使用することは適切ではないようです。(または、使用方法がわからなかった場合)
  • だから今のところ、ファイル内で「うるさい」とわかったマーカーとマーカーのmarkerために、私を完全に満足させない方法を使用しています。"{{{"}}}

だから私は適切に折り畳むことに関するベストプラクティスまたは一般的なガイドラインがあるかどうかを知りたいvimrcです。

注1:私たちは皆知っているように、SOはフォーラムではなく、個人的な意見を収集するように作られていません。それは私が探しているものではありません:もちろん、いくつかの人々が好みを持っていると思いますが、なぜ使用するのか知りたいですマーカー(たとえば)は、インデントを使用するよりも読みやすくします。

注2:また、私の主な目標は、自分vimrcをできる限り明確にすることですvimrc

編集1:vimrcはすでにセクション(および場合によってはサブセクション)にすでに細分化されていることを正確にすべきでした。

  • 一般的なオプション
  • プラグイン(各プラグインとその構成のサブセクションを含む)
  • マッピング
  • ナビゲーション(サブセクションも含む)
  • 等...

そして、それが折り畳みのことを考えさせたのはこの構造です。ある時点で興味のあるセクションだけを出力できるのは、とても便利なことだと思います。

編集2:vimrcいくつかのファイルのサブディビジョンに言及した回答は有効ですが、個人的な好みとして、ドットファイルを含むgitリポジトリで1つのファイルのみを維持する方が簡単だと思うので、折り畳みを使用します。それは個人的な好みに過ぎず、このアプローチも使用できることは承知していますが、折りたたみを使用したいと思います。


私が使って考える"{{{物事のやり方で最も「のような、Vimは」solarizedプラグインはこれを使用しているし、それはあなたのマニュアル折り目を設定する最も標準的な方法を提供しますNOISYそれがあるかもしれませんが
icc97

回答:


22

tabularvimrcの作者であるgodlygeekからコピーした以下のモードラインが下部にあります。

"" vim:fdm=expr:fdl=0
"" vim:fde=getline(v\:lnum)=~'^""'?'>'.(matchend(getline(v\:lnum),'""*')-2)\:'='

これにより、2から始まる行はすべて"折り畳まれます。が多い"ほど、折り目は深くなります。これにより、必要に応じてセクションを分割できます。


私は今それをテストすることはできませんが、それは私にとって理想的な解決策のようです!共有してくれてありがとう!
statox

いくつかのExplain:getline(v:lnum)は、行番号(v:lnum)で指定された行の文字列を返します。=〜は正規表現の一致を意味します。'^ ""'は、すべての行が2つの "sで始まることを意味します。matchend(getline(v:lnum)、 '" "*')-2は、" "の余分な数をカウントします。 "" "はレベル2で折りたたまれます。getline(v:lnum)=〜 '^" "'は、2つの"または "で始まるv:lnum行に応じてtrueまたはfalseを返します。trueの場合、FDEがに設定されている>extra number of "(この行で<後数で座っているレベルを開始)または'='(前の行のレベルを使用)、意味はで見つけることができますfold-expr
アベル・バン

最近のvimアップデート8.1.1517の後、この構成で「モードラインの処理中にエラーが検出されました」と表示されます
apollo

9

.vimrc(サブリストとサブサブリストのリストのように)最初に独自のカテゴリを定義し、すべてのプラグイン/設定/機能をそれぞれのカテゴリに追加することをお勧めします。カスタマイズされた折り畳みと組み合わせると、これは非常に効果的です:

例

上記の例は、カテゴリを構成するのに役立つと思われるカテゴリを示しています.vimrc。次のカスタマイズされた折り畳み設定を使用します。

""""""""""""""""""""""""
"  THIS IS A CATEGORY  "
""""""""""""""""""""""""
"" Autofolding .vimrc
" see http://vimcasts.org/episodes/writing-a-custom-fold-expression/
""" defines a foldlevel for each line of code
function! VimFolds(lnum)
  let s:thisline = getline(a:lnum)
  if match(s:thisline, '^"" ') >= 0
    return '>2'
  endif
  if match(s:thisline, '^""" ') >= 0
    return '>3'
  endif
  let s:two_following_lines = 0
  if line(a:lnum) + 2 <= line('$')
    let s:line_1_after = getline(a:lnum+1)
    let s:line_2_after = getline(a:lnum+2)
    let s:two_following_lines = 1
  endif
  if !s:two_following_lines
      return '='
    endif
  else
    if (match(s:thisline, '^"""""') >= 0) &&
       \ (match(s:line_1_after, '^"  ') >= 0) &&
       \ (match(s:line_2_after, '^""""') >= 0)
      return '>1'
    else
      return '='
    endif
  endif
endfunction

""" defines a foldtext
function! VimFoldText()
  " handle special case of normal comment first
  let s:info = '('.string(v:foldend-v:foldstart).' l)'
  if v:foldlevel == 1
    let s:line = ' ◇ '.getline(v:foldstart+1)[3:-2]
  elseif v:foldlevel == 2
    let s:line = '   ●  '.getline(v:foldstart)[3:]
  elseif v:foldlevel == 3
    let s:line = '     ▪ '.getline(v:foldstart)[4:]
  endif
  if strwidth(s:line) > 80 - len(s:info) - 3
    return s:line[:79-len(s:info)-3+len(s:line)-strwidth(s:line)].'...'.s:info
  else
    return s:line.repeat(' ', 80 - strwidth(s:line) - len(s:info)).s:info
  endif
endfunction

""" set foldsettings automatically for vim files
augroup fold_vimrc
  autocmd!
  autocmd FileType vim 
                   \ setlocal foldmethod=expr |
                   \ setlocal foldexpr=VimFolds(v:lnum) |
                   \ setlocal foldtext=VimFoldText() |
     "              \ set foldcolumn=2 foldminlines=2
augroup END

独自のカテゴリとサブカテゴリを定義するには、次の構文を使用します。

""""""""""""""
"  Category  "
""""""""""""""
"" Subcategory
""" Subsubcategory
" Just a comment, gets ignored no matter where

vim-snippetsを使用する場合(たとえばUltiSnipsを使用)、最上位のカテゴリを非常に簡単に作成できます。vim -snippetsが提供する、boxまたはbboxスニペットを展開するだけです(書き込みトリガーboxまたはbbox展開トリガーを押します)。

スペースを2回押して、折り畳みの開閉をさらに高速に切り替えるには:

let mapleader = "\<space>"
" Toggle folds
nnoremap <silent> <leader><Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
vnoremap <leader><space> zf

そうすれば、.vimrc簡単にナビゲートできる適切に構造化されたものができます。


素敵なアニメーションGIFの+1 :)好奇心が強い、タイプされたキーを表示するために何を使用しましたか?
mMontu

@mMontu:screenkeyを使用してキーを表示し、gtk-recordmydesktopを使用して記録しました(どちらもDebianリポジトリにあります)。5fpsでは、45秒のクリップはMiB未満です。次に、それをオンラインでgifに変換しました(画質が完璧になる前に歪みが生じた場所です)。
cbaumhardt

7

私はプライマリvimrcを他のいくつかの分類されたファイルへのリンクとして使用します。たとえば、あるファイルのVimオプション、別のファイルのプラグイン設定など、それぞれが進むにつれてソースになります。

"--- Vim Options
source ~/.vim/config/vim_options.vim

"--- Here Be Functions!
" (need to be sourced before stuff that uses 'em)
runtime! functions/*.vim

"--- Key Mapping
source ~/.vim/config/key_mapping.vim

"--- Folding
source ~/.vim/config/folding.vim

"--- Autocmds
source ~/.vim/config/autocmds.vim

"--- We Are Plugged In!
source ~/.vim/config/plugins.vim

" vim: ft=vim fdm=marker

OPの質問に対するより直接的な答えとして、マーカーメソッドを使用しますが、ほとんどの場合、右側よりも間隔を空けて、個々よりも多くのカテゴリを使用します。ただし、各プラグインは個別に実行します。


私は自分の質問でそれを正確に忘れていました:私はvimrc(IMO)が複雑さを増し、維持するのをより難しくするので、異なるファイルの「分離」のファンではありません。折り畳みについては、「間隔を空けて右側へ」とはどういう意味ですか?
statox

私は" {{{あなたと同じくらい多くのスペースがあるtextwidthので、マーカーは右端の近くにあります。また、folding.vimファイルにはパーソナライズされたFoldText関数があります。私のgitリポジトリがコミットごとに1つの特定のタイプのmodだけになるように、個別のファイルを好みます。
コメットソング

7

あなたは「ベストプラクティス」は非常に意見の問題だと言うことができます:)しかし、2つのアプローチがあります。およびサブセクション(または、勇気がある場合はさらに深く)、構成をいくつかの小さなファイルに分割し、:sourceそれらを-ingします。

個人的には、折り畳むことを好みます。これにより、アクセスしやすくなりますが、階層を取得できるからです。関数とautocmdsを最も内側のレベルで折り畳むことも良い考えです。これらは「自然な」論理ユニットを作るからです。 marker論理階層は必ずしもインデントレベルや構文の強調表示に反映されないため、折り畳みはこれらすべてにとって最も理にかなっています。またfoldcolumn、を増やすことで、自分がどこにいるかの視覚的なヒントが得られます。

# vim: filetype=vim foldmethod=marker foldlevel=0 foldcolumn=3

補足として、このfoldtext関数(IIRCのDrew Neilによる同様の関数の修正)は、デフォルトよりも意味があります。

function! MyFoldText()
    let line = getline(v:foldstart)

    let nucolwidth = &foldcolumn + &number * &numberwidth
    let windowwidth = winwidth(0) - nucolwidth - 3
    let foldedlinecount = v:foldend - v:foldstart

    " expand tabs into spaces
    let chunks = split(line, "\t", 1)
    let line = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - strwidth(v:val) % &tabstop)'), '') . chunks[-1]

    let line = strpart(line, 0, windowwidth - 2 - len(foldedlinecount))
    let fillcharcount = windowwidth - len(line) - len(foldedlinecount) - 1
    return line . '...' . repeat(' ', fillcharcount) . foldedlinecount . ' '
endfunction
set foldtext=MyFoldText()

ファイルを分割するもう1つのアプローチでは、主な問題は物を見つけることと、あるファイルから別のファイルに切り替えることです。両方に対処する非常に良い方法は、CtrlSFCtrlPなどのプラグインを使用することです。とにかく、あなたはおそらくそれらのいずれかをすでに使用しています。


だからあなたは一緒に行きますmarker。実際、カスタマイズすることfoldcolumnは良いことです。どの値が私のニーズに最も合うかを見ていきます。また、分割ファイルに関するあなたの見解を共有しますがCtrlSF、私はかなり満足していても、それを見てみるとは知りませんでしたCtrlP
statox

また、カスタム折りたたみ方法の使用方法を説明してください。私は、設定しようとしたfdmfoldtextしてMyFoldText()いますが、それを使用する正しい方法ではないように思えます。
statox

@statox CtrlSFは、agまたはackで最適に機能します。ag またはackは、本質的にの特殊バージョンですgrepfoldtextはカスタムの折りたたみ方法ではなく、折りたたみテキストの外観を変更する関数です。スニペットの最後の行は、その使用方法を示していますset foldtext=MyFoldText()
lcd047

2

基本的なベストプラクティス:

  • セクションに分割する:

    • プラグイン
    • 設定
    • 再バインド
  • 各セクションのコメント/再バインド

  • (バックアップし.vimrcたり_vimrcのGithub上)

ただ私の個人的な好み。たぶんあまり助けにはなりません。


私は個人的に折り畳みを使用しません、そして、あなたはそうする必要はありません。vimrcを整理するだけで、すべてうまくいくはずです。
グスタフブロムクヴィスト

私のvimrcはすでにセクション(一般オプション、プラグイン、マッピング、ナビゲーション、色など)に整理されています。セクション(またはサブセクション)を折りたたむことができるという事実は、実際に編集/探しているものに集中するのに適しています。
statox

はい。悪い答えでごめんなさい。
グスタフブロムクヴィスト

それは悪い答えではなく、詳細な十分な質問をしていないことにも罪悪感があり、申し訳ありません;-)
statox

2

@PeterRinckerの回答に触発されて、ATXスタイルのヘッダーを使用するために以下を作成しました。あなたの最後に追加します.vimrc

"# Folding

" Fold with ATX style headers - "# is H1, "## is H2, and so on
" vim:fdm=expr:fdl=0
" vim:fde=getline(v\:lnum)=~'^"#'?'>'.(matchend(getline(v\:lnum),'"#*')-1)\:'='

1

私のような大きな関数がある場合、これを使用して関数を折りたたむことができます。

fun! MyFoldLevel(linenum)
    if ! exists('w:nextline')
        let w:nextline = 0
        let w:insideafun = 0
    endif

    if w:nextline == 1
        let w:nextline = 0
        let w:insideafun = 0
    endif

    let l:line = getline(a:linenum)

    if l:line =~# '^[[:space:]]*fun'
        let w:insideafun = 1
        return '>1'
    elseif l:line =~# '^[[:space:]]*endf'
        let w:nextline = 1
        return '<1'
    endif

    if w:insideafun == 1
        return 1
    else
        return 0
    endif
endfun

そして、このモードラインをvimrcに追加します:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:

0

@Peter Rinckerと@ go2nullのアイデアを拡大します。Vimモードラインで折りたたみオプションを設定したくない場合。次のautocmdを使用して、折りたたみ方法と折りたたみ式を設定できます。

augroup vim_folding
    autocmd!
    autocmd FileType vim set foldmethod=expr foldlevel=0
    " note that double quote in foldexpr has to be escaped with backslash
    autocmd FileType vim set foldexpr=getline(v:lnum)=~'^\"#'?'>'.(matchend(getline(v:lnum),'\"#*')-1):'='
augroup END

元の答えが通常のvimコマンドとして機能するように小さな変更を加えました(コロンをエスケープする必要はありませんが、二重引用符はエスケープする必要があります)。

長いfoldexpr文字列が気に入らない場合は、そのための関数を定義できます。

function! VimFolds(lnum)
    let s:cur_line = getline(a:lnum)

    if s:cur_line =~ '^"#'
        return '>' . (matchend(s:cur_line, '"#*')-1)
    else
        return '='
    endif

endfunction

次に、autocmd行foldexpr

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.