8

Is there a better alternative to this function I use to remove parens around a region? I'm looking for an Emacs builtin, or something better written, something that will remove any pairs around the selected region (ex: brackets, curly brackets, double quotes, single quotes)

(defun my-delete-surrounded-parens ()
  (interactive)
  ;; save where region begins & ends                                                                            
  (let ((beginning (region-beginning))
        (end (region-end)))
    (cond ((not (eq (char-after beginning) ?\())
           ;; if region not begins by (, trigger error                                                          
           (error "Char at region-begin not an open-parens"))
          ((not (eq (char-before end) ?\)))
           ;; if region not ends by ), trigger error                                                            
           (error "Char at region-end not a close-parens"))
          ;; save mark, pt, current buffer & execute body                                                       
          ((save-excursion
             (goto-char beginning)
             (forward-sexp)
             (not (eq (point) end)))
           ;; if parens are not balanced, trigger error                                                         
           (error "parens not balanced"))
          (t (save-excursion
               (goto-char end)
               (delete-char -1)
               (goto-char beginning)
               (delete-char 1)))))) 

2 Answers 2

8

If you install smartparens, then you can use the function sp-splice-sexp, which does exactly what you are asking for. It works on all valid types of braces and quotes, according to the current major mode. See the docs for more details.

Edit: The principal advantage of smartparens over paredit (see rekado's answer) is that smartparens has better support for languages other than lisp. It also allows multi-character delimiters such as triple-quotes in python or tags in XML/HTML.

7

There's paredit which has a function paredit-splice-sexp, which might do what you want.

In this example | indicates point:

(hello world "no |way")  ; run paredit-splice-sexp
(hello world no way)

Here's another example:

(let ((a b))
  (fo|rmat #t "meh")) ; run paredit-splice-sexp

(let ((a b))
  format #t "meh")

It does not work on the top level, however, because that would result in an invalid s-expression. It also does not operate on a region but on s-expressions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.