noflet - nic's overriding flet, for fleting functions for the purpose of decorating them
Emacs Lisp
Latest commit 7ae84dc Nov 2, 2014 @nicferrier bump the version
Permalink
Failed to load latest commit information.
README.creole Remove cl-style arglists from TODO section Aug 27, 2014
let-while-tests.el add tests for let-while. Jun 12, 2013
noflet.el bump the version Nov 2, 2014

README.creole

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:

  • find-file-noselect is changed so that if the file-name begins with # a different file-name altogether is opened
  • expand-file-name is changed so that if the file-name begins with # it's resolved via /tmp

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.