@@ -2767,6 +2767,67 @@ With a numeric prefix argument the let is introduced N lists up."
27672767 (interactive )
27682768 (clojure--move-to-let-internal (read-from-minibuffer " Name of bound symbol: " )))
27692769
2770+ ; ;; Shorthand fn conversion
2771+ (defun clojure--gather-shorthand-args ()
2772+ " Return a cons cell (ARITY . VARARG)
2773+ ARITY is number of arguments in the function,
2774+ VARARG is a boolean of whether it takes a variable argument %&."
2775+ (save-excursion
2776+ (let ((end (save-excursion (clojure-forward-logical-sexp) (point )))
2777+ (rgx (rx symbol-start " %" (group (? (or " &" (+ (in " 0-9" ))))) symbol-end))
2778+ (arity 0 )
2779+ (vararg nil ))
2780+ (while (re-search-forward rgx end 'noerror )
2781+ (when (not (or (clojure--in-comment-p) (clojure--in-string-p)))
2782+ (let ((s (match-string 1 )))
2783+ (if (string= s " &" )
2784+ (setq vararg t )
2785+ (setq arity
2786+ (max arity
2787+ (if (string= s " " ) 1
2788+ (string-to-number s))))))))
2789+ (cons arity vararg))))
2790+
2791+ (defun clojure--substitute-shorthand-arg (arg sub end )
2792+ " ARG is either a number or the symbol '&.
2793+ SUB is a string to substitute with, and
2794+ END marks the end of the fn expression"
2795+ (save-excursion
2796+ (let ((rgx (format " \\ _<%%%s \\ _>" (if (eq arg 1 ) " 1?" arg))))
2797+ (while (re-search-forward rgx end 'noerror )
2798+ (when (and (not (clojure--in-comment-p))
2799+ (not (clojure--in-string-p)))
2800+ (replace-match sub))))))
2801+
2802+ (defun clojure-convert-shorthand-fn ()
2803+ " Convert a #(...) function into (fn [...] ...), prompting for the argument names."
2804+ (interactive )
2805+ (when-let (beg (clojure-string-start))
2806+ (goto-char beg))
2807+ (if (or (looking-at-p " #(" )
2808+ (forward-char 1 )
2809+ (re-search-backward " #(" (save-excursion (beginning-of-defun ) (point )) 'noerror ))
2810+ (let* ((end (save-excursion (clojure-forward-logical-sexp) (point-marker )))
2811+ (argspec (clojure--gather-shorthand-args))
2812+ (arity (car argspec))
2813+ (vararg (cdr argspec)))
2814+ (delete-char 1 )
2815+ (save-excursion (forward-sexp 1 ) (insert " )" ))
2816+ (save-excursion
2817+ (insert " (fn [] " )
2818+ (backward-char 2 )
2819+ (mapc (lambda (n )
2820+ (let ((name (read-string (format " Name of argument %d : " n))))
2821+ (when (/= n 1 ) (insert " " ))
2822+ (insert name)
2823+ (clojure--substitute-shorthand-arg n name end)))
2824+ (number-sequence 1 arity))
2825+ (when vararg
2826+ (insert " & " )
2827+ (let ((name (read-string " Name of variadic argument: " )))
2828+ (insert name)
2829+ (clojure--substitute-shorthand-arg '& name end)))))
2830+ (user-error " No #() shorthand at point!" )))
27702831
27712832; ;; Renaming ns aliases
27722833
0 commit comments