]> git.eshelyaron.com Git - emacs.git/commitdiff
(elisp-create-defun): New command
authorEshel Yaron <me@eshelyaron.com>
Mon, 20 Jan 2025 07:56:46 +0000 (08:56 +0100)
committerEshel Yaron <me@eshelyaron.com>
Mon, 20 Jan 2025 07:56:46 +0000 (08:56 +0100)
lisp/progmodes/elisp-mode.el

index 6161400751095cd5b972a1ca10e6ccc12c1a8514..f9cbc1023fce87946428ad192189717d772bee42 100644 (file)
@@ -2532,6 +2532,38 @@ interactively, this is the prefix argument."
   "C-n" #'elisp-next-occurrence
   "C-p" #'elisp-prev-occurrence)
 
+(defun elisp-create-defun (fun-name arg-names)
+  "Insert a new (defun FUN-NAME ARG-NAMES) form below the current defun.
+
+FUN-NAME is a string and ARG-NAMES is a list of strings.
+
+Push a mark before moving point, and leave point inside the new form
+where the body of the defun should go.
+
+Interactively, if point is in a list (FUN . ARGS), then FUN-NAME is the
+name of FUN and ARG-NAMES is a list with placeholder argument names, one
+for each element of ARGS."
+  (interactive
+   (save-excursion
+     (named-let rec ((ps (reverse (nth 9 (syntax-ppss)))))
+       (if (null ps)
+           (user-error "No function call at point")
+         (goto-char (car ps))
+         (pcase (read (current-buffer))
+           (`(,(and head (pred symbolp)) . ,tail)
+            (list (symbol-name head)
+                  (mapcar (compose
+                           (apply-partially #'concat "arg")
+                           #'number-to-string)
+                          (number-sequence 1 (length tail)))))
+           (_ (rec (cdr ps)))))))
+   emacs-lisp-mode)
+  (push-mark)
+  (beginning-of-defun-raw)
+  (goto-char (scan-sexps (point) 1))
+  (insert "\n\n(defun " fun-name " (" (string-join arg-names " ") "))")
+  (backward-char))
+
 (defvar avy-action)
 
 (defvar elisp-extract-local-variable-name-history nil)