nicferrier / emacs-noflet

noflet - nic's overriding flet, for fleting functions for the purpose of decorating them
72 stars 17 forks source link

= noflet - Local function decoration =

{{{noflet}}} is dynamic, local, advice for Emacs-Lisp code.

{{{noflet}}} also has an Emacs indentation function for {{{flet}}} like macros.

It's great for test code when you need to mock another function.

This is useful for definining functions that overide a base definition in some way. You get access to the original (before you re-defined it) function through a different name.

Use it like this:

{{{ (noflet ((find-file-noselect (file-name) (if (string-match-p "^#." file-name) (this-fn "/tmp/mytest") (this-fn file-name))) (expand-file-name (file-name &optional thing) (if (string-match-p "^#." file-name) (concat "/tmp" (file-name-as-directory (substring file-name 1))) (funcall this-fn file-name thing)))) (expand-file-name "#/thing")) }}}

This specifies that two functions should be overridden:

In both cases {{{this-fn}}} is used to access the original function definition of these common Emacs functions.

=== Decorating results ===

{{{noflet}}} can also be used to decorate results, just like {{{around-advice}}}:

{{{ (noflet ((find-file (file-name &optional wildcards) (let ((result (funcall this-fn file-name wildcards))) (with-current-buffer result (setq some-buffer-local "special")) result))) (with-current-buffer (find-file "~/some-file") (message "buffer local var is: %s" some-buffer-local))) }}}

This overrides {{{find-file}}} to set a local variable. There are surely better ways to do it than this but it illustrates the point.

=== Lexical version ===

Because we include a good indenting function we also include a lexical {{{flet}}}. It's just a wrapper for {{{cl-flet}}}.