views:

2944

answers:

7

Whats the best way to do achieve something like code folding, or the type of cycling that org-mode uses. What would be the best solution in elisp to create this type of behavior?

EDIT: I'm sorry I was not clear. I want to program something in elisp that does things very similar to code folding, or actually most like org-mode with the hierarchy that can be expanded. I am wondering the best way to achieve this affect. I think I have heard emacs overlays are a good solution, but I dont know.

As far as folding I just use the builtin set-selective-display

EDIT NUMBER 2:

Thanks for the answers but I think I am asking the wrong question so let me try to be more clear on what I am trying to do. I would like to create the following

When you put your point on a function and call this elisp function it will put the function definition from wherever it is (I am thinking of just using find-tag for this) and unfold it in the current buffer. The idea is if you have to jump to a different buffer to read the function definition I feel like its a context switch to another file. So I would like it to behave like code folding only it pulls in code external from the buffer. This presents some problems as it can not acutally paste the code into the buffer or if someone saves it it will save the pulled in code. So I am wondering if there is a way to create an area inside a buffer that is also not part of the buffer. I think that makes sense.

Again sorry for not being very clear before.

+5  A: 

Apparently there is no perfect solution, but I think the best one is this:

http://www.emacswiki.org/emacs/FoldingMode

freitass
+4  A: 

I use the outline minor mode to fold my python code. Instead of needing to place {{{ and }}} as in folding mode, it uses where the block is defined.

http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html http://www.emacswiki.org/emacs/OutlineMinorMode

I am pretty sure that it comes with emacs. I then add this to my .emacs

;;======= Code folding =======
(add-hook 'python-mode-hook 'my-python-outline-hook)
; this gets called by outline to deteremine the level. Just use the length of the whitespace
(defun py-outline-level ()
  (let (buffer-invisibility-spec)
    (save-excursion
      (skip-chars-forward "    ")
      (current-column))))
; this get called after python mode is enabled
(defun my-python-outline-hook ()
  ; outline uses this regexp to find headers. I match lines with no indent and indented "class"
  ; and "def" lines.
  (setq outline-regexp "[^ \t]\\|[ \t]*\\(def\\|class\\) ")
  ; enable our level computation
  (setq outline-level 'py-outline-level)
  ; do not use their \C-c@ prefix, too hard to type. Note this overides some bindings.
  (setq outline-minor-mode-prefix "\C-t")
  ; turn on outline mode
  (outline-minor-mode t)
  ; initially hide all but the headers
  ;(hide-body)
  ; make paren matches visible
  (show-paren-mode 1)
)
Nikwin
+1  A: 

You can also get code folding by using CEDET with following code in init file:

(global-semantic-folding-mode t)

After evaluation of this code, the small triangle will appear in fringle area, so you will able to fold & unfold code using it. This method is more precise, as it uses syntactic information, extracted from source code

Alex Ott
+4  A: 

hide-show mode (hs-minor-mode) with default keybinding C-c @ C-c to trigger the folding.

dmckee
+4  A: 

Folding is generally unnecessary with emacs, as it has tools that explicitly implement the actions people do manually when folding code.

Most people have good success with simple incremental searches. See "foo" mentioned somewhere? Type C-s foo, find the definition, press enter, read it, and then press C-x x to go back to where you were. Simple and very useful.

Most modes support imenu. M-x imenu will let you jump to a function definition (etc.) by name. You can also bind it to a mouse click to get a menu of functions (or add it to the menubar; see the Info page for more detail). It provides data for which-function-mode, which will let you see which function you are currently inside in the modeline. (Why are your functions this long, though?)

There is also speedbar, which displays the imenu information (and other things) graphically.

If you want to get an overview of your file, try "M-x occur". Given a regex, it will create a new buffer with each match in the current buffer. You can search for "(defun" to get an overview of the functions the current file implements. Clicking on the result will move you to that position in the file.

So anyway, think about what you really want to achieve, and Emacs probably implements that. Don't fight with imperfect tools that make you fold and unfold things constantly.

jrockway
M-x occur is excellent!
cschreiner
Seconded re: M-x occur
Dan
Thirded re: M-x occur
MDCore
A: 

emacs comes with hs-minor-mode which fascilitates code folding between balanced expressions http://www.emacswiki.org/emacs/HideShow

eunikorn
+1  A: 

I believe that your comparison of your "project" to folding is not quite good, because folding is about changing the appearance while keeping the buffer contents intact (the text). Your project would involve showing extra text while keeping the buffer contents intact, AFAIU. So. it's not implementable as a composition of text-insertion and folding (then, the buffer contents would be changed).

But perhaps, it's indeed possible with the same mechanism as folding is done with -- "overlays"... Consider the "before-string" and "after-string" overlay properties; perhaps, you could put your function definitions into these strings belonging to a zero-length overlay at the point. Look at outline-flag-region function to see how overlays are used in the outline mode.

imz