# Vim Fold Settings Not Working - Fix Folding Configuration Issues

You've set up folding in your .vimrc, expecting nested functions and code blocks to collapse neatly, but instead nothing folds. Or folds appear in the wrong places, collapsing your carefully structured code into confusing blobs. Folding is one of Vim's most useful features for navigating large files, but its configuration has many interacting parts that can fail silently.

Understanding Vim's Folding Methods

Vim supports six folding methods, controlled by the foldmethod option:

vim
:set foldmethod?

The methods are:

  1. 1.manual - Folds created manually with zf commands (default)
  2. 2.indent - Folds based on indentation levels
  3. 3.syntax - Folds defined by syntax highlighting rules
  4. 4.expr - Folds defined by a custom expression
  5. 5.marker - Folds defined by text markers like {{{ and }}}
  6. 6.diff - Folds for diff mode (automatic)

If folding isn't working, the first step is to verify which method is active.

Enabling Folding

Folding must be explicitly enabled. Check the fold column:

vim
:set foldcolumn?

A value of 0 means the fold column is hidden. Set it to see the fold indicators:

vim
:set foldcolumn=4

This shows a 4-character column on the left displaying fold status: - for open folds, + for closed folds, and | for fold levels.

Common Problem: Method Set But No Folds

You set foldmethod=indent but see no folds. This usually means:

No Fold Level Set

The foldlevel determines how many folds are open by default:

vim
:set foldlevel?

If it's 0, all folds are closed. Set it higher:

vim
:set foldlevel=99    " Open all folds by default
:set foldlevelstart=99    " Start with all folds open

Start_foldlevel Setting

There's also foldlevelstart which sets the fold level when opening a new buffer:

vim
:set foldlevelstart=99

Minimum Fold Lines

Folds might be too small to display:

vim
:set foldminlines?

Default is usually 1. Increase if you want to hide small folds:

vim
:set foldminlines=3    " Only fold if 3+ lines

Indent Folding Problems

Indent folding is popular for Python and other indentation-sensitive languages:

vim
:set foldmethod=indent

If this doesn't work:

Check Indentation

The file might not have consistent indentation:

vim
:set list

This shows tabs and trailing spaces. You'll see ^I for tabs. For Python, you typically want:

vim
:set foldmethod=indent
:set foldlevel=99
:set noexpandtab    " Or expandtab, depending on your style
:set shiftwidth=4
:set tabstop=4

Fold Level Calculation

Vim calculates fold level from indentation. Each level of indentation creates a new fold level:

python
def function():          # Level 0
    if True:             # Level 1 (one indent)
        print("Hello")   # Level 2 (two indents)

To see the computed fold levels:

vim
:set foldlevel=0
zR    " Open all folds
zM    " Close all folds

Syntax Folding Problems

Syntax folding depends on syntax files defining fold regions:

vim
:set foldmethod=syntax

If folds don't appear:

Syntax Not Defining Folds

Not all syntax files define fold regions. Check if your syntax file supports folding:

vim
:syntax

Look for lines containing fold. For example, in a C file, you should see syntax region ... fold.

If the syntax file doesn't define folds, you can add them:

vim
" For JavaScript
syntax region jsFold start=/\v\{/ end=/\v\}/ transparent fold

Filetype Not Detected

Check if the filetype is set:

vim
:set filetype?

If empty, the syntax file didn't load:

vim
:set filetype=javascript

Enable filetype detection in your .vimrc:

vim
filetype plugin indent on

Expression Folding Problems

Expression folding is the most flexible but requires correct setup:

vim
:set foldmethod=expr
:set foldexpr=MyFoldLevel(v:lnum)

If your expression isn't working:

Check Expression Return Values

The function must return a string, not a number:

vim
function! MyFoldLevel(lnum)
    let line = getline(a:lnum)
    if line =~ '^\s*$'
        return '-1'    " Use fold level from previous line
    elseif line =~ '^\s*def '
        return '>1'    " Start fold level 1
    else
        return '='    " Same fold level as previous line
    endif
endfunction

The return values are:

  • '0' - No fold
  • '1', '2', etc. - Fold level
  • '>1' - Start a fold at level 1
  • '<1' - End a fold
  • '=' - Same level as previous
  • '-1' - Use previous line's level

Test your function:

vim
:echo MyFoldLevel(1)
:echo MyFoldLevel(5)

Debug Fold Expression

Set foldexpr to see what it returns:

vim
:echo foldlevel(10)    " Show fold level at line 10

Or check every line:

vim
:g/^/echo line('.') . ':' . foldlevel(line('.'))

Marker Folding Problems

Marker folding uses special text markers:

vim
:set foldmethod=marker
:set foldmarker={{{,}}}

If markers don't work:

Check Marker Characters

Verify the markers are correct:

vim
:set foldmarker?

Your file must contain the exact markers:

bash
// {{{
function code() {
    ...
}
// }}}

Nested Markers

Markers must be properly nested:

bash
// {{{ outer
    // {{{ inner
    // }}}
// }}}

Mismatched markers break folding. Use % to jump between matching braces/brackets if your markers are {{{ and }}}.

Fold Commands Not Working

If you can't open/close folds:

Check Fold Commands

Basic fold commands:

vim
zo    " Open fold
zc    " Close fold
za    " Toggle fold
zR    " Open all folds
zM    " Close all folds
zr    " Reduce folding (open some)
zm    " More folding (close some)

If za does nothing, there might not be a fold at the cursor position. Check with:

vim
:echo foldclosed('.')

Returns -1 if the current line is not in a closed fold, or the first line of the fold if it is.

Check for Conflicting Mappings

vim
:map zo
:map zc
:map za

If any show results, a plugin has remapped these keys.

Common Configuration Issues

Config Not Loading

Your .vimrc settings might not be loading. Check:

vim
:scriptnames

Look for your .vimrc in the list. Verify it loaded:

vim
:echo $MYVIMRC

Config Overwritten by Plugins

A plugin might set folding options after your .vimrc. Check when options were set:

vim
:verbose set foldmethod?
:verbose set foldlevel?

This shows the last script to set the option.

Wrong Filetype-specific Settings

Filetype plugins might override your settings. Check:

vim
:verbose set foldmethod?

If it shows a file in after/ftplugin/, that's overriding your settings. Create your own after-plugin:

vim
" Create: ~/.vim/after/ftplugin/python.vim
setlocal foldmethod=indent
setlocal foldlevel=99

Complete Folding Configuration

A robust folding setup in .vimrc:

```vim " Enable folding set foldenable

" Set default method set foldmethod=indent

" Open most folds by default set foldlevelstart=99

" Show fold column set foldcolumn=4

" Don't fold small blocks set foldminlines=3

" Fold settings by filetype augroup Folding autocmd! autocmd FileType python setlocal foldmethod=indent autocmd FileType javascript setlocal foldmethod=syntax autocmd FileType vim setlocal foldmethod=marker autocmd FileType markdown setlocal foldmethod=expr \ foldexpr=getline(v:lnum)=~'^\\s*$'?'-1': \ getline(v:lnum)=~'^#'?'<'.matchstr(getline(v:lnum),'#*'): \ '=' augroup END ```

Testing Your Folds

Open a file and test:

vim
zM    " Close all folds - should see code collapse
zR    " Open all folds - should see code expand
zc    " Close fold under cursor
zo    " Open fold under cursor
za    " Toggle fold under cursor

Use the fold column to navigate: click + to open, - to close, or use the keyboard commands.

Folding is incredibly useful once configured correctly. The key is to ensure foldmethod is set, foldlevel starts high enough that folds are open by default, and that your specific filetype has appropriate fold definitions. Use :verbose set foldmethod? to debug when settings don't seem to take effect.