28

Code folding in Emacs

Sometimes I want to fold a block of text. In Vim you have easy folding without fuzz. Without to add any special characters like "markers" or specific regex like {{{. I would like to select a region and fold it, without messing with the structure.

When looking around, it seems there were already questions about code folding in Emacs. Someone said that there was "no perfect solution". For example, I created a clip of simple codefolding in Vim:

Vim plain folding

enter image description here

+ Fairly simple, select a region and fold it.
+ It's persistent. When you kill the buffer/close Vim. And reopen the file, the folds are still there.
+ You get a highlight bar, to easily see what's folded.

There are many other folding configurations for Vim. I'm happy with Emacs, but this is one thing that I miss. Other alternatives that I tried, for example HideShow:

HideShow

enter image description here

Evil's alternative with hide-show minor mode. I found it unusable:

- I'm not able to select a region and folding it. It folds on code blocks.

- There's no higlihgting bar or something, to attend you it's folded. You could easily miss it.

- It's not persistent. If you reopen the file, the folds are gone.

There is another package, Fold this:

Fold this

enter image description here

- It's a pretty alternative. However, it mess with the indentation, because the text under the fold gets placed next to the fold... (?).

- It's able to just visually select the region and fold it. But it breaks the indendation, so the overview gets messed up. Not very handy.

- There is no higlihgting bar or something, to attend you it's folded. You could easily miss it.

What's the issue?

I would like to replicate how Vim does folding. But when I searched around, it seems it's very hard to do that in Emacs. So I wonder if there something in emacs or its architecture that makes it difficult to replicate this? What are the limits?

16
  • 2
    I felt the question was too broad, so I voted to close on that basis. I would recommend that the original poster pick a couple of libraries that provide some of the features sought, and then combine/modify them as desired. If the O.P. runs into trouble implement/modifying a particular feature, then post a specific question limited to that one issue. The O.P. can probably achieve the desired visual effects, but should be prepared to make it an ongoing project to be worked on over time. – lawlist Aug 16 '15 at 1:53
  • 3
    Could you please explain what folding features you want? As a rule, you can't expect people on this site to know how Vim code folding works, and anyway you should tell us which features you want specifically. The only information you provide about what you want is an animation which only shows one example, and anyway I have no idea what it illustrates: they don't show what commands you used, why you moved the cursor to this or that spot, etc. Plus in a typical browser they play on a loop and it's impossible to tell when a repeat starts. – Gilles 'SO- stop being evil' Aug 16 '15 at 10:03
  • 3
    the hold should be removed from this question. as it currently stands it is reasonably specific. not having an answer to the question is not a good reason to close it. – Ista Aug 17 '15 at 13:12
  • 2
    ar-hide-region-atpt, ar-show-region-atpt from ‘thing-at-point-utils.el’, github.com/andreas-roehler/thing-at-point-utils - please un-block so that might be a regular answer. – Andreas Röhler Aug 17 '15 at 13:51
  • 2
    The question, as I understand it, is basically: "Someone: Please write an entire library for Emacs that will provide the exact code-folding features found in Vim." I see from some of the comments and up-votes that there are enough people who would like to see this become a reality. However, I don't see how this could reasonably fit into answer -- the proposed new library will need to be maintained, with issues and bug-fixes. I too wouldn't mind someone writing up an entire library with cool new features for code folding. – lawlist Sep 6 '15 at 19:04
18
+50

Try out vimish-fold.

Features

  • batteries included: activate minor mode, bind a couple of commands and everything will just work;

  • it works on regions you select;

  • it's persistent: when you close file your folds don't disappear;

  • in addition to being persistent, it scales well, you can work on hundreds of files with lots of folds without adverse effects;

  • it's obvious which parts of text are folded;

  • it doesn't break indentation or something;

  • it can refold just unfolded folds (oh, my);

  • for fans of avy package: you can use avy to fold text with minimal number of key strokes!

Usage

Create binding for some of/all these functions:

  • vimish-fold — basic folding of selected region;

  • vimish-fold-unfold — you don't really need to bind this, just use C-g when point is placed on header representing folded text;

  • vimish-fold-unfold-all — nevertheless this may be useful;

  • vimish-fold-refold — yes, you can fold it back;

  • vimish-fold-avy — use avy to fold your text!

You can turn vimish-fold-mode selectively for modes where you want to have persistent folding, or simply activate it everywhere:

(vimish-fold-global-mode 1)
9
  • do you have any suggested key bindings? What bindings do you use when you're in C++ mode? C mode? Python mode? Lisp mode? ELisp mode? JavaScript mode? – Reb.Cabin Sep 7 '15 at 14:25
  • 1
    @Reb.Cabin, this is not mode-specific package, so global key bindings is the best choice. I'm using key bindings that don't involve key-chords and most people would consider them a bit strange, currently I have: menu v fvimish-fold, menu v avimish-fold-avy, menu v uvimish-fold-unfold-all, menu v vvimish-fold-refold. Most my keybinds are like this, this is my config. – Mark Karpov Sep 7 '15 at 14:33
  • Does this integrate with evil motions and textobjects? – PythonNut Sep 8 '15 at 4:14
  • 1
    Hm... I'll start work on a PR. – PythonNut Sep 8 '15 at 13:44
  • 1
    I, for one, find vimish-fold completely unusable. Maybe it's intuitive to those already familiar with code-folding in vim... I don't know. Also, I don't understand why folding in org-mode works so well, but Emacs does not yet have good code-folding... – kjo Jul 23 '16 at 12:47
2

I like and use vimish-fold with evil-vimish-fold (and avy):

  ;; Optional use of avy
  (use-package avy
    :bind ("C-c J" . avy-goto-line)
    :commands avy-goto-line
    :init
    (setq-default
     ;; the unpredictability of this (when enabled) makes it a poor default
     avy-single-candidate-jump nil
     avy-background nil 
     avy-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
     avy-style 'at-full))

  ;; This does the heavy lifting
  (use-package vimish-fold
    :after evil)

  ;; This gives us evil integration, i.e., key bindings
  (use-package evil-vimish-fold
    :after evil vimish-fold
    :init
    (setq evil-vimish-fold-target-modes '(prog-mode markdown-mode conf-mode text-mode))
    :config
    (evil-vimish-fold-mode 1))

If you use package.el to get your packages then you can add an

:ensure

form to the use-package form.

Adjust the evil-vimish-fold-target-modes to include any that you wish to use folding in. Note that prog-mode is the parent mode of most programming modes, so it is sort of a catch all.

Note that this will give you many of the usual vim folding key bindings. Here are some that I use often:

z f Create a fold after first highlighting a region (or use a prefix count like vim).

z o Open existing fold at point.

z d Delete an existing fold.

z R Open all folds in the buffer.

z c Close existing fold at point.

z j Next fold.

z k Previous fold.

Etc.

As Mark Karpov, the creator of vimish-fold, mentioned in his answer, you can use M-x vimish-fold-avy which will fold everything between point and the location you choose via the avy interface that it presents.

An example of using a count prefix would be:

4 z f f

to create a fold from point to 4 lines down.

1

I wrote foldout.el years ago, so if your file can be “outlined” then it can be folded without needing additional markers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.