Folding sections of Markdown in Vim
Tags: vim, writing, productivity, markdown
Published: 2020-05-25 07:22:45

**TIL:** Vim is able to fold sections or Markdown on their headings 💡

Modern version of [Vim](https://www.vim.org/) and [Neovim](https://neovim.io/) support folding `.md` [Markdown](https://en.wikipedia.org/wiki/Markdown) documents on their section headings `#`, `##`, `###` etc. out of the box, even without installing the additional [vim-markdown-folding](https://github.com/masukomi/vim-markdown-folding) plugin.

## What is folding 🤔

Vimʼs documentation describes _“folding”_ as:

```
Folding is used to show a range of lines in the buffer as a single line on the
screen.  Like a piece of paper which is folded to make it shorter:

	+------------------------+
	| line 1		 |
	| line 2		 |
	| line 3		 |
	|_______________________ |
	\			 \
	 \________________________\
	 / folded lines		  /
	/________________________/
	| line 12		 |
	| line 13		 |
	| line 14		 |
	+------------------------+

The text is still in the buffer, unchanged.  Only the way lines are displayed
is affected by folding.

The advantage of folding is that you can get a better overview of the
structure of text, by folding lines of a section and replacing it with a line
that indicates that there is a section.
```

When editing large documents, I personally find it handy to temporarily fold and _“hide away”_ certain parts I currently donʼt care about.

## Folding Markdown 🗂

Out of the box, Vim and Neovim currently wonʼt know _“how”_ to fold Markdown sections. Their included default [vim-markdown](https://github.com/tpope/vim-markdown) filetype and syntax plugin however offers an undocumented setting to enable just this:

```
let g:markdown_folding = 1
```

There is an [open pull request](https://github.com/tpope/vim-markdown/pull/135) include this in the official documentation, but it is not merged yet.

Flicking this switch turns my `.md` buffers into something like this:

```
+--- 32 lines: ## What is folding 🤔···········································
+--- 23 lines: ## Folding Markdown 🗂···········································
```

Pressing `zR` will recursively unfold all sections again. From there on you may continue to happily fold and unfold. [Drew Neil](https://twitter.com/nelstrom) from [Vimcasts](http://vimcasts.org) put together a nice and short [overview](http://vimcasts.org/episodes/how-to-fold/) over the most important folding commands:

| command | effect                              |
| ------- | ----------------------------------- |
| `zo`    | open current fold                   |
| `zO`    | recursively open current fold       |
| `zc`    | close current fold                  |
| `zC`    | recursively close current fold      |
| `za`    | toggle current fold                 |
| `zA`    | recursively open/close current fold |
| `zm`    | reduce `foldlevel` by one           |
| `zM`    | close all folds                     |
| `zr`    | increase `foldlevel` by one         |
| `zR`    | open all folds                      |

### First look 👀

With Markdown-folding enabled, Vim will default to the fully _“folded”_ view when opening a Markdown buffer. I personally prefer to start with the _“full”_ document though. According to [this Stackoverflow thread](https://stackoverflow.com/questions/8316139/how-to-set-the-default-to-unfolded-when-you-open-a-file) there are a few ways out of this behavior.

I went for setting a custom `foldlevelstart` value in my configuration. It instructs Vim how or if a buffer should be folded when one starts editing:

```
'foldlevelstart' 'fdls'	number (default: -1)
			global
	Sets 'foldlevel' when starting to edit another buffer in a window.
	Useful to always start editing with all folds closed (value zero),
	some folds closed (one) or no folds closed (99).
	This is done before reading any modeline, thus a setting in a modeline
	overrules this option.  Starting to edit a file for |diff-mode| also
	ignores this option and closes all folds.
	It is also done before BufReadPre autocommands, to allow an autocmd to
	overrule the 'foldlevel' value for specific files.
	When the value is negative, it is not used.
```

I went for starting with all folds open in Markdown buffers:

```
au FileType markdown setlocal foldlevel=99
```

**Happy folding 🗺**