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"
let (first, fringe) = queue.removeFirst fringe
if goal first then
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/")
(setq fsharp-compiler "~/lib/fsharp/")
(add-hook 'fsharp-mode-hook
(lambda () (outline-minor-mode)
(setq outline-regexp " *\\(let ..\\|type .\\|module\\)")))

martes, noviembre 11, 2008

Copy to Html

I was going to write something completely different but I had some troubles copying the source code to my blog. I Usually use a little script from Steve Yegge for copying the highlighted text from Emacs to Html.

It had some strange trouble converting the RGB colors and it was not setting the values of the default font.

Here is the code: (using the highlighter :D)

(defun html-string-color (face key)
(mapconcat (lambda (x) (format "%.2x" (/ x 256)))
( color-values (face-attribute
(make-face face) key)) ""))

(defun syntax-highlight-region (start end)
"Adds <font> tags into the region that correspond to the
current color of the text. Throws the result into a temp
buffer, so you don't dork the original."

(interactive "r")
(let ((text (buffer-substring start end)))
(with-output-to-temp-buffer "*html-syntax*"
(set-buffer standard-output)
(insert (format "<div style=\"color:#%s; background:#%s\" ><pre>"
(html-string-color 'default :foreground)
(html-string-color 'default :background)))
(save-excursion (insert text))
(save-excursion (syntax-html-escape-text))
(while (not (eobp))
(let ((plist (text-properties-at (point)))
(or (next-single-property-change
(point) 'face (current-buffer))
(syntax-add-font-tags (point) next-change)
(goto-char next-change)))
(insert "\n</pre></div>"))))

(defun syntax-add-font-tags (start end)
"Puts <font> tag around text between START and END."
(let (face color rgb name r g b)
(setq face (get-text-property start 'face))
(or (if (listp face) (setq face (car face))) t)
(setq color (face-attribute face :foreground))
(setq rgb (assoc (downcase color) color-name-rgb-alist))
(destructuring-bind (name r g b) rgb
(let ((text (buffer-substring-no-properties start end)))
(delete-region start end)
(insert (format "<font color=#%.2x%.2x%.2x>"
(/ r 256) (/ g 256) (/ b 256)))
(insert text)
(insert "</font>"))))))

(defun syntax-html-escape-text ()
"HTML-escapes all the text in the current buffer,
starting at (point)."

(save-excursion (replace-string "<" "<"))
(save-excursion (replace-string ">" ">")))

BTW there's some minor issue with the greater than symbol inside of the strings.

Change in the language... For good?

After thinking about it carefully I have decided to start writing my "Programming" blog in English. I don't think I'm going to lose any of the current readers (Is there any reader out there???) but instead, this can be the perfect exercise for improving my horrible English.

It would be really nice if you can point out any nasty grammatical mistake or misuse in the words (I have a really a bad time with some phrasal verbs)