"C-c C-b" #'elisp-byte-compile-buffer
"C-M-q" #'indent-pp-sexp
"C-c M-e" #'macrostep-expand
+ "C-c C-x" #'elisp-extract
"C-c C-n" #'elisp-next-occurrence
"C-c C-p" #'elisp-prev-occurrence)
"C-n" #'elisp-next-occurrence
"C-p" #'elisp-prev-occurrence)
+(defun elisp-extract (beg end new)
+ "Extract region from BEG to END into NEW function."
+ ;; FIXME:
+ ;; - Check that region is a valid form.
+ ;; - Handle Local function bindings (e.g. `named-let').
+ ;; - Group buffer changes together.
+ ;; - Order bound variables by their binding positions.
+ (interactive
+ (if (use-region-p)
+ (list (use-region-beginning)
+ (use-region-end)
+ (let ((def (when-let ((d (which-function))) (concat d "-1"))))
+ (read-string (format-prompt "Function name" def) nil nil def)))
+ (user-error "No region selected"))
+ emacs-lisp-mode)
+ (let* (bound-vars)
+ (save-excursion
+ (goto-char beg)
+ (beginning-of-defun)
+ (scope (lambda (_type sbeg len bin)
+ (and (<= beg sbeg (+ sbeg len) end) (numberp bin) (< bin beg)
+ (cl-pushnew (intern (buffer-substring sbeg (+ sbeg len)))
+ bound-vars))))
+ (insert "\n\n(defun " new " (" (mapconcat #'symbol-name bound-vars " ") ")" "\n")
+ (indent-according-to-mode)
+ (push-mark nil t)
+ (insert (string-trim (buffer-substring beg end)) ")")
+ (prog-indent-sexp 'defun)
+ (goto-char beg)
+ (delete-region beg end)
+ (insert "(" new " " (mapconcat #'symbol-name bound-vars " ") ")")
+ (prog-indent-sexp 'defun))))
+
\f
(put 'read-symbol-shorthands 'safe-local-variable #'consp)
(throw 'var-def
(list (propertize
(buffer-substring-no-properties beg (+ beg len))
- 'pos beg)))))
- (current-buffer))
+ 'pos beg))))))
nil)))))
(cl-defmethod refactor-backend-rename-edits
(scope (lambda (_type beg len bin)
(when (<= beg pos (+ beg len))
(setq dec bin))
- (when bin (push (list beg len bin) all)))
- (current-buffer)))
+ (when bin (push (list beg len bin) all)))))
(list
(cons (current-buffer)
(let (res)
(scope (lambda (_type beg len bin)
(when (<= beg pos (+ beg len))
(setq dec bin))
- (when bin (push (list beg len bin) all)))
- (current-buffer)))
+ (when bin (push (list beg len bin) all)))))
(when dec
(let (res)
(pcase-dolist (`(,beg ,len ,bin) all)
It calls them sequentially, and if any returns non-nil,
`which-function' uses that name and stops looking for the name.")
+;;;###autoload
(defun which-function ()
"Return current function name based on point.
Uses `which-func-functions', `add-log-current-defun'.