viernes, noviembre 21, 2008

Poor man's code folding for F#

Code folding is one of those "features" that I practically never use. The reason is that in some tools the feature doesn't play well with the incremental search. More important is that there's some kind of people that think that a 3000 thousand lines file folded into methods, properties and constants is "nicer". (Trust me they exist)

Some days ago I got some kind of Emacs-fever thanks to the Emacs wiki. I set-up the jabber client, fixed that nasty behaviour with the clipboard and discovered the outline-minor-mode.

The outline-minor-mode is basically a mode for hierarchical text folding. I'm not going to spend my time giving an explanation having this

The mechanism behind this mode is so simple but yet so powerful. Is just a regex.. The hierarchy of the folding depends on the size of the regex match.

Let's imagine this simple example:
module Search =

type IQueue<'c,'a> =
{ makeQueue: 'a list -> 'c
empty: 'c -> bool
first: 'c -> 'a
removeFirst: 'c -> ('a * 'c)
insertAll: ('a list * 'c) -> 'c
}


Using something as simple as this:
(setq outline-regexp " *\\(let ..\\|type .\\|module\\)")

We are able to fold the code in different ways:
module Search =

type IQueue...
module Search... 

But also... We can fold every let definition!
For example:
    let treeSearch<'c,'a> 
(succesors: 'a -> 'a list)
(queue: IQueue<'c,'a>)
(goal: 'a -> bool)
(i0: 'a ) =
let rec explore (fringe: 'c) =
if queue.empty fringe then
failwith "Not Found"
else
let (first, fringe) = queue.removeFirst fringe
if goal first then
first
else explore (queue.insertAll (succesors first, fringe))
explore (queue.makeQueue [i0])

Can fold into this:
    let treeSearch<'c,'a> 
(succesors: 'a -> 'a list)
(queue: IQueue<'c,'a>)
(goal: 'a -> bool)
(i0: 'a ) =
let ...
explore (queue.makeQueue [i0])

The best thing is that it plays perfectly good with C-s and C-y. The regex can be extended to manage any computation expression builder, if-then-else, while, for, match-with blocks.

If you want too hook it to the F# mode...
(setq inferior-fsharp-program "~/lib/fsharp/fsi.sh")
(setq fsharp-compiler "~/lib/fsharp/fsc.sh")
(add-hook 'fsharp-mode-hook
(lambda () (outline-minor-mode)
(setq outline-regexp " *\\(let ..\\|type .\\|module\\)")))

3 comentarios:

fengfk2008 dijo...
Este blog ha sido eliminado por un administrador de blog.
fengfk2008 dijo...
Este blog ha sido eliminado por un administrador de blog.
fengfk2008 dijo...
Este blog ha sido eliminado por un administrador de blog.