Skip to content

Commit

Permalink
Improve "xf" for Clojure
Browse files Browse the repository at this point in the history
* le-clojure.el (lispy-flatten--clojure-loaded): New defvar.
(lispy-flatten--clojure-load): New defun.
(lispy-flatten--clojure): Update.

The code now can distinguish macros and use `macroexpand' for them.
Otherwise, some custom Clojure code will be used to flatten.

"xf" should work on this:

    (filter odd? [1 2 3 4 5])

After "xfM" you get:

    (let [pred odd? coll [1 2 3 4 5]
          ]
      (lazy-seq (when-let [s (seq coll)
                           ]
                  (if (chunked-seq? s)
                    (let [c (chunk-first s)
                          size (count c)
                          b (chunk-buffer size)
                          ]
                      (dotimes [i size]
                        (when (pred (.nth c i))
                          (chunk-append b (.nth c i))))
                      (chunk-cons (chunk b)
                                  (filter pred (chunk-rest s))))
                    (let [f (first s)
                          r (rest s)
                          ]
                      (if (pred f)
                        (cons f (filter pred r))
                        (filter pred r)))))))

Re purcell#54.
  • Loading branch information
abo-abo committed Mar 13, 2015
1 parent fceccc3 commit 526ee85
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions le-clojure.el
Expand Up @@ -210,6 +210,34 @@ Besides functions, handles specials, keywords, maps, vectors and sets."
(format "(:macro (meta #'%s))" symbol))
"true"))

(defvar lispy-flatten--clojure-loaded nil
"Nil if the custom Clojure code wasn't loaded yet.")

(defun lispy-flatten--clojure-load ()
"Load the custom Clojure flattening code."
(unless lispy-flatten--clojure-loaded
(lispy--eval-clojure
"
(require 'clojure.repl)
(defn le-symbol-function [sym]
(read-string
(clojure.repl/source-fn
sym)))
(defn le-flatten [expr]
(let [func (first expr)
args (rest expr)
func-def (symbol-function func)
func-body (nth func-def 4)
func-args (first func-body)
func-impl (rest func-body)]
(cons 'let
(cons (vec (interleave func-args args))
func-impl))))")
(setq lispy-flatten--clojure-loaded t)))


(defun lispy-flatten--clojure (arg)
"Inline a Clojure function at the point of its call."
(let* ((begp (if (looking-at lispy-left)
Expand All @@ -220,9 +248,15 @@ Besides functions, handles specials, keywords, maps, vectors and sets."
(lispy-left 1))))
(bnd (lispy--bounds-list))
(str (lispy--string-dwim bnd))
(expr (lispy--read str))
(result
(lispy--eval-clojure
(format "(macroexpand '%s)" str))))
(if (and (symbolp (car expr))
(lispy--clojure-macrop (symbol-name (car expr))))
(lispy--eval-clojure
(format "(macroexpand '%s)" str))
(lispy-flatten--clojure-load)
(lispy--eval-clojure
(format "(le-flatten '%s)" str)))))
(goto-char (car bnd))
(delete-region (car bnd) (cdr bnd))
(insert result)
Expand Down

0 comments on commit 526ee85

Please sign in to comment.