Code folding for emacs?

I’m using julia-mode.el, but I’m by no means an emacs wizard

Is there a way to do code folding? I.e. I place the cursor at the start of a function, press some key combo, and it becomes one line… and then another key combo brings it back?

I tried looking at outline-minor-mode and hideshow mode, on the emacs wiki, but could not figure them out… (maybe I should just bite the bullet and learn LISP, sigh).

thanks

I’m using outshine, like this:

(use-package outshine
  :init
  (progn
    (add-hook 'outline-minor-mode-hook 'outshine-mode)
    (add-hook 'c-mode-common-hook 'outline-minor-mode)
    (add-hook 'sh-mode-common-hook 'outline-minor-mode)
    (add-hook 'julia-mode-hook 'outline-minor-mode)))

It does not let me fold functions, but I can add small Org-like headers in comments, like this:

# * First section

first_function(x) = 30x

# * Second section

second_function(x) =  80x

# ** Subsection

third_function(x,y) = cos(x)*sin(y)

and then I can hide an entire section by setting the cursor on the line of the header and pressing <Tab> (or C-i).

3 Likes

Just add the following to your .emacs file:

(global-set-key (kbd "<C-f5>") 'set-selective-display-dlw)

(defun set-selective-display-dlw (&optional level)
"Fold text indented same of more than the cursor.
If level is set, set the indent level to LEVEL.
If 'selective-display' is already set to LEVEL, clicking
F5 again will unset 'selective-display' by setting it to 0."
  (interactive "P")
  (if (eq selective-display (1+ (current-column)))
      (set-selective-display 0)
    (set-selective-display (or level (1+ (current-column))))))

Then put the cursor at the beginning of a block (any block: functions, loops, etc…) and press Ctrl+F5 to toggle folding at that level.

Further info here: elisp - How to achieve code folding effects in Emacs? - Stack Overflow

4 Likes

That’s very nice!

I’d like to add that the rationale they quote in the StackOverflow post you linked is why I never bothered with proper function folding; using e.g. ivy it’s very easy to find your way around a large file. However, sometimes I do wish to hide a large block of the file, and that’s when I use the outshine trick above; basically, I order my functions by theme and then it’s very easy to navigate the file on a high level as well.

1 Like

Thats awesome! thanks!

However, for me it seams to collapse all the functions at the same time…(which makes sense, since its indent based). Is there a way to only have it collapse the current function? I.e. could Ctrl+, mark a region, and then press CTRL-F6 or something? Even cooler if it could recognize julia End statements…

Maybe this is what you’re looking for:
https://github.com/magnars/fold-this.el

but you’ll need to select the region you wish to fold, i.e. it can’t (AFAIK) fold a block up to the end statement. I used it for a while, then turned back to the indent-based folding.

The reason is that a block depth is related to a “scope” (in all case I could think of, not just Julia source code). In order to focus on a “scope” I typically want to hide the “minor details” (i.e. deeper blocks). At the same time I don’t need text on the same scope to be hidden since it would typically be outside my scrolling window (unless the file is very, very short…). Hence an indent-based folding fits perfectly my workflow.

On the other hand, a region-based folding would possibly lead to an excessive number of fold-this, unfold-that activities, that I wish to avoid. Just my 2 cents… :wink:

1 Like

thanks! thats a very simple and useful emacs extension.

it looks like (by same author)
https://github.com/magnars/expand-region.el
is more advanced, and people have already added Ruby, Erlang, etc syntax, so I’ll attempt to add some Julia constructs, and see what I get.

1 Like

I would love to have support for expand-region in Julia. I use it a lot in other languages and it is awesome!

I had saved this reply to test this package (outshine). I’ve tested it right now and I’m happy it works here, going to incorporate it into my emacs workflow. This reminds me that I should periodically take a look here for tips like this one :laughing: