Vim Markdown Folding?

后端 未结 12 1399
梦毁少年i
梦毁少年i 2020-12-08 07:10

I just realized that VIM 7.3 has built-in support for highlighting Markdown files. Excellent. However, it doesn\'t fold on the headings.

Can any offer suggestions on

相关标签:
12条回答
  • 2020-12-08 07:30

    VOoM : Vim two-pane outliner is worth checking it out.

    Not only does it provide basic folding, but it also provides outline navigation via a 2nd outline view pane (similar to document map in MS Word). And it supports a large number of markup languages including others mentioned in other answers - Markdown, viki, reStructuredText, vimwiki, org, and many others.

    For more info see the screenshots and the help page.

    0 讨论(0)
  • 2020-12-08 07:33

    The only way how I get folding to work in markdown, was't very elegant, :set fdm=marker and use html comment tag

     <!-- My folding {{{1 -->
    

    more help :help folding

    0 讨论(0)
  • 2020-12-08 07:35

    As of Vim 8 it is included by default (via Tim Pope's markdown plugin). Just add this to .vimrc:

    let g:markdown_folding=1
    

    To make sure you have this plugin loaded you can run

    :showscripts
    

    and look for

    vim80/syntax/markdown.vim
    
    0 讨论(0)
  • 2020-12-08 07:36

    When I use markdown I only use the hash-style headings with space separating hashes and text. This makes the folding task a lot simpler.

    I'm pretty new to Vim, so use the following at your own risk. I added the following code to my vimrc and it folds headings based on number of hashes, and it retains the syntax colouring.

    function! MarkdownLevel()
        if getline(v:lnum) =~ '^# .*$'
            return ">1"
        endif
        if getline(v:lnum) =~ '^## .*$'
            return ">2"
        endif
        if getline(v:lnum) =~ '^### .*$'
            return ">3"
        endif
        if getline(v:lnum) =~ '^#### .*$'
            return ">4"
        endif
        if getline(v:lnum) =~ '^##### .*$'
            return ">5"
        endif
        if getline(v:lnum) =~ '^###### .*$'
            return ">6"
        endif
        return "=" 
    endfunction
    au BufEnter *.md setlocal foldexpr=MarkdownLevel()  
    au BufEnter *.md setlocal foldmethod=expr     
    
    0 讨论(0)
  • 2020-12-08 07:36

    Working from @Omar comment to this answer, I coded a fold method to languages which comment with //, like JS. Add following to ~/.vimrc:

    autocmd FileType javascript setlocal foldmethod=expr foldcolumn=6 
    autocmd FileType javascript setlocal foldexpr=JSFolds()
    
    " Level of a folding:
        "// #: level 1
        "// ##: level 2
        "// ###: level 3
    function! JSFolds()
        " Option 1: // and no space and hashes:
            "if getline(v:lnum) =~ '^//#'
        " Option 2: // and 1 space and hashes:
            "if getline(v:lnum) =~ '^//\+ #'
        " Option 3: spaces/tabs/nothing  and // and 1 space and hashes:
        if getline(v:lnum) =~ '^\s*//\+ #'
        " Option 4: anything and // and 1 space and hashes:
        " DANEGROUS! Potential conflict with code. E.g. print("// # Title");
        " if getline(v:lnum) =~ '//\+ #'
    
            " Number of hashs # in line that success previous condition (if)
            " determine the fold level
           let repeatHash = len(matchstr(getline(v:lnum), '#\+'))
           return ">" . repeatHash
        endif
        return "=" 
    endfunction
    

    Examples. Note on the left the fold levels ("|" and "-"):

    -     // # ** Fold style recommended **
    -     // #       1  easy case
    |-    // ##      2  easy case
    ||-   // ###     3  easy case
    |||   //            Comment inside level 3
    |||-  // ####    4  easy case
    ||||  //            Comment inside level 4
    |-        // ##  2  easy case (indents are OK with Option 3)
    ||    /####     error (JS comment needs 2 slashes)
    ||  
    -     // # ** Fold of just 1 line **
    |--   // ###    3  easy case
    ||-   // ###    =  same fold level as previous line, thus previous line folds just itself ?!? (not concerns this fold function) 
    |||   
    -     // # ** Space needed before, BUT not needed after hash/-es **
    |-    // ##Fold Level   changed Because no space after hashes is OK:    '// # ' vs '// #NoSpace'. NoSpace could even be a return carriage (enter). 
    ||    //## Fold Level Unchanged Because no space after pair of slashes: '// #' vs '//#'
    ||    //     ##txt    Unchanged Because too much space after slashes
    ||    //     ## txt   Unchanged Because too much space after slashes
    ||    
    -     // # ** Odds vs Even slashes **
    -     /// #     1  overrides typo 3 slash instead of just 2 (/// vs //)
    -     ///// #   1  overrides typo 5 slash instead of just 4 (///// vs ////). Read Recommenting Comments notes.
    |-    // ## ** As long as the pattern is at least '// # ', further previous slashes are ok  **
    -     // #            1  easy case
    |--   // ###          3  ok (and recommended fold style)
    ||-   ///// ###       3  ok (recommented + typo)
    ||-   ////// ###      3  ok (re-recommented)
    ||-   /// ###         3  ok (typo)
    ||-   //// ###        3  ok (recommented)
    ||-   ///////// ###   3  ok (who cares? it works!)
    |||   
    -     // # ** Recommenting Comments **
    -     // #      1  easy case
    |     //           Comment inside level 1
    -     //// #    1  recommented a comment
    |     ////         Comment inside level 1
    -     ///// #   1  re-re-recomment
    |     /////        Comment inside level 1
    |     
    -     // # ** Recommenting Comments adding text **
    |--   // ### //// #    3  changing fold level on purpose of a recommented a comment
    |||   //               Comment inside level 3
    |||   // text  // ##         2  (recommented a comment adding text)
    |||   // text#text  // ##    2  right   {recommented a comment adding initial text, as long as this text has no hash just after '// ' (2*slash + space) would be ok }
    -     // #text#text  // ##   2  wrongly {recommented a comment adding initial text, as long as this text has no hash just after '// ' (2*slash + space) would be ok }
    -     // # changeFoldIntentionally // ##     1  clear intention to change fold level of comments
    -     // #changeFoldIntentionally // ##      1  clear intention to change fold level of comments (previousi example, with space after hash would be clearer)
    |--   // ### changeFoldIntentionally // ##   3  clear intention to change fold level of comments
    |||   
    

    PD: totally open to critics and improvements of the code. Actually I'm a beginner with vimscript.

    0 讨论(0)
  • 2020-12-08 07:38

    Here is a try at a recursive header folding rule. It doesn't include the underline style of Markdown header, but I'm guessing those would be awkward for your purposes anyway.

    Put the following code into your .vimrc:

    au FileType markdown syn region myMkdHeaderFold
            \ start="\v^\s*\z(\#{1,6})"
            \ skip="\v(\n\s*\z1\#)\@="
            \ end="\v\n(\s*\#)\@="ms=s-1,me=s-1
            \ fold contains=myMkdHeaderFold
    
    au FileType markdown syn sync fromstart
    au FileType markdown set foldmethod=syntax
    
    0 讨论(0)
提交回复
热议问题