spike
spike

Reputation: 10004

Replace region with result of calling a function on region

How would I write an interactive function that takes a function and replaces the currently selected region with the result of calling that function on the region.

I see this answer: https://stackoverflow.com/a/6539916/625365

But that's calling the function once per line, not giving it the region as an argument, and it seems like a lot of code.

Upvotes: 5

Views: 1418

Answers (2)

Diego Sevilla
Diego Sevilla

Reputation: 29021

I think you could do some trickery around filter-buffer-substring, but that seems like an obscure function, at least to me. On the other hand, doing so in Emacs Lisp directly doesn't seem complicate:

(defun apply-function-to-region (fn)   
  (interactive "XFunction to apply to region: ")   
  (save-excursion
    (let* ((beg (region-beginning))
           (end (region-end))
           (resulting-text 
            (funcall 
             fn 
             (buffer-substring-no-properties beg end))))
      (kill-region beg end)
      (insert resulting-text))))

Then you can use a function that accepts and produces text (say capitalize), and capitalize the region. The function will ask for a function to apply. Finally, the deleted text is saved in the kill ring.

Upvotes: 8

Daimrod
Daimrod

Reputation: 5020

(defun apply-to-region (func)
  (unless (use-region-p)
    (error "need an active region"))
  (delete-region (region-beginning) (region-end))
  (insert (funcall func)))

(defun foo ()
  ""
  "foobar")

(defun my/test ()
  (interactive)
  (apply-to-region 'foo))

To test it, select some text and run M-xmy/testRET.

Upvotes: 5

Related Questions