Existe uma prática recomendada para dobrar um arquivo vimrc

21

Recentemente, percebi que vimrcagora tenho mais de 400 linhas (que a IMO é demais, tentarei reduzir) e, para facilitar a navegação, a leitura e a edição, decidi investigar o conceito de dobrar no vim (que Eu não estava familiarizado com) .

  • Tentei definir o método de dobrar, indentmas não gostei do resultado (era muito confuso, principalmente porque grande parte do meu vimrcnão é realmente recuado).
  • Eu também tentou definir foldmethoda expre syntaxmas eu não era capaz de dobrar qualquer coisa corretamente.
  • Aqui, usar diffcomo método de dobra não parece relevante. (Ou, se não entendi como usá-lo)
  • Então, por enquanto, estou usando o markermétodo que não me satisfaz totalmente por causa dos marcadores "{{{e "}}}que achei "barulhentos" no arquivo.

Então, eu gostaria de saber se existem práticas recomendadas ou diretrizes comuns sobre como dobrar corretamente avimrc .

Nota 1: Como todos sabemos, SO não é um fórum e não é feito para coletar opiniões pessoais e não é isso que estou procurando: é claro que acho que algumas pessoas têm suas preferências, mas gostaria de saber por que usar marcadores (por exemplo) melhoram mais a legibilidade do que usar recuo.

Nota 2: também meu principal objetivo é tornar o vimrcmais claro possível, de modo que, se houver outras práticas recomendadas para criar um bom interesse, fique vimrccurioso.

Edit 1: Eu deveria ter precisado que meu vimrcjá está subdividido em seções (e algumas vezes subseção) as principais sendo

  • opções gerais
  • plug-ins (contendo uma subseção para cada plug-in e sua configuração)
  • mapeamentos
  • navegação (também contendo subseção)
  • cor
  • etc ...

E é essa estrutura que me fez pensar em desistir: sinto que ser capaz de produzir apenas a seção em que estou interessado em um determinado momento é algo bastante conveniente.

Edit 2: A resposta mencionando subdivisões do vimrcarquivo em vários arquivos é válida, mas como uma preferência pessoal, eu prefiro usar o fold, porque acho que é mais fácil manter apenas um arquivo no repositório git que contém meus dotfiles. Essa é apenas uma preferência pessoal e estou ciente de que também é possível usar essa abordagem, mas eu preferiria usar a dobradura.

statox
fonte
Acho que usando o "{{{é o 'vim como' mais maneira de fazer as coisas, o plugin solarized usa isso e embora possa ser barulhento dá-lhe a forma mais padrão de configuração dobras manuais
icc97

Respostas:

22

Eu tenho as seguintes modelines na parte inferior da minha vimrcque copiei de godlygeek, o autor do tabular :

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

Isso fará com que qualquer linha iniciada com 2+ seja "uma dobra. Quanto mais "profunda a dobra. Isso permite subdividir seções, se necessário.

Peter Rincker
fonte
Não posso testá-lo agora, mas essa parece ser a solução ideal para mim! Obrigado por compartilhar!
Statox
Alguns explicam: getline (v: lnum) retorna a string da linha fornecida pelo número da linha (v: lnum); = ~ significa correspondência de expressão regular; '^ ""' significa que todas as linhas começam com dois "s; matchend (getline (v: lnum), '" "*') - 2 conta o número extra de", significa que "" "será dobrado no nível 1" "" "dobrará com o nível 2 e assim por diante; getline (v: lnum) = ~ '^" "' retorna verdadeiro ou falso, dependendo do início da linha v: lnum com dois" ou não; se true, o fde é definido como >extra number of "(nível inicial que é o número após <nesta linha) ou '='(usa o nível da linha anterior), o significado pode ser encontrado emfold-expr
van abel
após a recente atualização do vim 8.1.1517), estou recebendo "" Erro detectado ao processar modelos "com esta configuração.
apollo
9

É uma boa idéia primeiro definir suas próprias categorias em sua .vimrc(como uma lista com sublistas e sub-listas) e adicionar todos os seus plugins / configurações / funções às respectivas categorias. Combinado com dobragem personalizada, isso pode funcionar muito bem:

Exemplo

O exemplo acima mostra as possíveis categorias que acho úteis para estruturar o meu .vimrc. Ele usa as seguintes configurações de dobra personalizadas:

""""""""""""""""""""""""
"  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

Para definir suas próprias categorias e subcategorias, use a seguinte sintaxe:

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

A categoria de nível superior pode ser criada com muita facilidade se você usar o vim-snippets (por exemplo, com o UltiSnips ): Basta expandir o boxou bboxtrecho fornecido pelo vim-snippets (escreva boxou bboxpressione o gatilho de expansão).

Para alternar dobras abertas e fechadas ainda mais rápido, pressionando o espaço duas vezes:

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

Dessa forma, você tem um bem estruturado .vimrcque pode ser navegado facilmente.

cbaumhardt
fonte
+1 para o bom gif animado :) Apenas curioso, o que você costumava exibir as teclas digitadas?
MMontu
@ mMontu: Eu usei o screenkey para exibir as chaves e o gtk-recordmydesktop para gravá-lo (ambos nos repositórios Debian). Com 5fps, um clipe de 45 segundos é menor que um MiB. Em seguida, converteu-o on-line para um gif (é aí que as distorções ocorreram, antes que a qualidade da imagem fosse perfeita).
cbaumhardt
7

Eu uso o meu primário vimrccomo um link para vários outros arquivos categorizados, fornecendo cada um à medida que avança, por exemplo, opções do Vim em um arquivo, configurações de plug-in em outro.

"--- 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

Como resposta mais direta à pergunta do OP, eu uso o método do marcador, mas no lado direito, com espaçamento e em torno de mais categorias do que individuais, na maior parte. Eu faço cada plugin separadamente embora.

Cometsong
fonte
Esqueci-me de precisar isso na minha pergunta: não sou fã de "separar" os vimrcarquivos diferentes porque (IMO) aumenta a complexidade e dificulta a manutenção. Sobre a dobra, o que você quer dizer com "fora para o lado direito com espaçamento"?
Statox
Quero dizer, " {{{com tantos espaços quanto o seu textwidthpara que os marcadores fiquem perto das bordas direitas. Eu também tenho uma função FoldText personalizada no arquivo fold.vim. Eu prefiro arquivos separados para que meu git repo apenas um tipo específico de mod por commit.
Cometsong 03/07/2015
7

Você poderia dizer que a "melhor prática" é preeminentemente uma questão de opinião :), mas há duas abordagens que (1) fazem sentido óbvio e (2) podem ser aplicadas a todos os arquivos de configuração, não apenas ao Vim: dobrando por seções lógicas e subseções (ou até mais, se você se sentir corajoso), e dividir sua configuração em vários arquivos menores e :sourceinseri-los.

Pessoalmente, prefiro desistir porque facilita o acesso às coisas, enquanto ainda me fornece uma hierarquia. Dobrar funções autocmdes nos níveis mais internos também é uma boa idéia, pois elas produzem unidades lógicas "naturais". markerdobrar faz mais sentido para tudo isso, porque hierarquias lógicas não são necessariamente refletidas nos níveis de recuo ou no realce da sintaxe. Também aumento foldcolumn, o que me dá uma dica visual de onde estou:

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

Em uma nota lateral, esta foldtextfunção (uma modificação de uma função semelhante por Drew Neil, IIRC) faz mais sentido para mim do que o padrão:

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()

Com a outra abordagem, os arquivos divididos, os principais problemas são encontrar coisas e alternar de um arquivo para outro. Uma maneira muito agradável de abordar ambos é usar um plug-in como CtrlSF , CtrlP ou similar. Mas você provavelmente já está usando um desses de qualquer maneira.

lcd047
fonte
Então você vai com marker. Na verdade, personalizar foldcolumné uma coisa boa a se fazer, vou ver qual valor se encaixa melhor na minha necessidade. Também compartilho sua opinião sobre os arquivos divididos, mas não sabia CtrlSFque vou dar uma olhada, mesmo que esteja muito feliz CtrlP.
statox
Além disso, você poderia explicar como usar o método de dobra personalizado, por favor? Tentei definir fdma foldtexte MyFoldText()mas parece que não é a maneira correta de usá-lo.
Statox
O @statox CtrlSFfunciona melhor com ag ou ack , que são versões essencialmente especializadas do grep. foldtextnão é um método de dobra personalizado, mas uma função para alterar a aparência do texto dobrado. A última linha em meus shows trecho de como ele é usado: set foldtext=MyFoldText().
Lcd047 03/07/2015
2

Práticas recomendadas básicas:

  • Divida em seções:

    • Plugins
    • Configurações
    • Rebinds
  • Comente cada seção / religue

  • (faça backup do seu .vimrcou _vimrcno Github)

Apenas minha preferência pessoal. Talvez não seja de muita ajuda.

Gustav Blomqvist
fonte
Eu pessoalmente não uso dobrável, e você não precisa. Apenas organize seu vimrc e tudo deve ser bom.
Gustav Blomqvist
Meu vimrc já está organizado na seção (opções gerais, plugins, mapeamentos, navegação, cor, etc ...). O fato de poder dobrar uma seção (ou subseção) é realmente bom para focar no que você está editando / procurando.
Statox
OK. Desculpe pela resposta ruim.
Gustav Blomqvist
Isso não é uma resposta ruim e eu também sou culpado por não dar pergunta bastante detailled, não há necessidade de se arrepender ;-)
statox
2

Inspirado na resposta de @ PeterRincker, criei o seguinte para usar os cabeçalhos de estilo ATX. Adicione-o ao final do seu.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)\:'='
go2null
fonte
1

Se você possui funções grandes como eu, pode usar isso para dobrar suas funções:

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

E adicione esta modelagem ao seu vimrc:

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

Expandindo a idéia de Peter Rincker e @ go2null. Se você não deseja definir as opções de dobra na modelagem do Vim. Você pode usar o seguinte autocmd para definir o método de dobra e a expressão de dobra.

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

Fiz pequenas modificações para fazer a resposta original e fazê-lo funcionar como um comando vim regular (não é necessário escapar do cólon, mas é necessário fazer uma aspas duplas).

Se você não gosta da foldexprstring longa , podemos definir uma função para isso:

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

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

endfunction

Em seguida, substitua a linha autocmd prestes foldexpra

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
jdhao
fonte