chapters/48.markdown @ 495eedad2b77

Proof 12-16
author Steve Losh <steve@stevelosh.com>
date Sat, 10 Nov 2012 17:36:05 -0500
parents 121fb4ea289b
children 3a16b2131235
Basic Folding
=============

If you've never used code folding in Vim, you don't know what you're missing.
Read `:help usr_28` and spend some time playing around with it in your normal
work.  Come back to this chapter once you've got it in your fingers.

Types of Folding
----------------

Vim supports six different ways of defining how your text should be folded.

### Manual

You create the folds by hand and they're stored in RAM by Vim.  When you close
Vim they go away and you have to recreate them the next time you edit the file.

This method can be handy if you combine it with some custom mappings to make it
easy to create folds.  We won't do that in this book, but keep it in the back
of your mind in case you run across a case where it could be handy.

### Marker

Vim folds your code based on characters in the actual text.

Usually these characters are put in comments (like `// {{{`), but in some
languages you can get away with using something in the language's syntax itself,
like `{` and `}` in Javascript files.

It may seem ugly to clutter up your code with comments that are purely for your
text editor, but the advantage is that it lets you hand-craft folds for
a specific file.  This can be really nice if you're working with a large file
that you want to organize in a very specific way.

### Diff

A special folding mode used when diff'ing files.  We won't talk about this one
at all because Vim automatically handles it.

### Expr

This lets you use a custom piece of Vimscript to define where folds occur.  It's
the most powerful method, but also requires the most work.  We'll talk about
this in the next chapter.

### Indent

Vim uses your code's indentation to determine folds.  Lines at the same
indentation level fold together, and lines with only whitespace (and blank
lines) are simply folded with their neighbors.

This is essentially free to use because your code is already indented; all you
have to do is turn it on.  This will be our first method of adding folding to
Potion files.

Potion Folding
--------------

Let's take a look at our sample Potion file once again:

    :::text
    factorial = (n):
        total = 1
        n to 1 (i):
            total *= i.
        total.

    10 times (i):
        i string print
        '! is: ' print
        factorial (i) string print
        "\n" print.

The bodies of the function and loop are both indented.  This means we can get
some basic folding with very little effort by using indent folding.

Before we start, go ahead and add a comment above the `total *= i.` line so we
have a nice multiple-line inner block to test with.  You'll learn why we need to
do this when you do the exercises, but for now just trust me.  The file should
now look like this:

    :::text
    factorial = (n):
        total = 1
        n to 1 (i):
            # Multiply the running total.
            total *= i.
        total.

    10 times (i):
        i string print
        '! is: ' print
        factorial (i) string print
        "\n" print.

Create an `ftplugin` folder in your Potion plugin's repository, and create
a `potion` folder inside that.  Finally, create a `folding.vim` file inside of
*that*.

Remember that Vim will run the code in this file whenever it sets a buffer's
`filetype` to `potion` (because it's in a folder named `potion`).

Putting all folding-related code into its own file is generally a good idea and
will help us keep the various functionality of our plugin organized.

Add the following line to this file:

    :::vim
    setlocal foldmethod=indent

Close Vim and open the `factorial.pn` file again.  Play around with the new
folding with `zR`, `zM`, and `za`.

One line of Vimscript gave us some useful folding!  That's pretty cool!

You might notice that the lines inside the inner loop of the `factorial`
function aren't folded even though they're indented.  What's going on?

It turns out that by default Vim will ignore lines beginning with a `#`
character when using `indent` folding.  This works great when editing C files
(where `#` signals a preprocessor directive) but isn't very helpful when you're
editing other types of files.

Let's add one more line to the `ftplugin/potion/folding.vim` file to fix this:

    :::vim
    setlocal foldmethod=indent
    setlocal foldignore=

Close and reopen `factorial.pn` and now the inner block will be folded properly.

Exercises
---------

Read `:help foldmethod`.

Read `:help fold-manual`.

Read `:help fold-marker` and `:help foldmarker`.

Read `:help fold-indent`.

Read `:help fdl` and `:help foldlevelstart`.

Read `:help foldminlines`.

Read `:help foldignore`.