Wednesday, September 30, 2009

Emacs Tip #33: paredit

I recently found paredit. It is a mode which allows you to edit s-expressions (sexps) in a structured way.

Essentially it forces you to maintain balanced parentheses by always inserting/deleting matched pairs. It is very easy to modify the current sexp to: enclose (wrap) the next element, to merge it up one level (aka splice, i.e. remove a set of parentheses), to split the current sexp, etc.

It works with round parens (), square brackets [], curly braces {}, and angle braces <>. It also handles string quotes " the same way.

Deleting and killing of text also works nicely. For example, C-k is bound to 'paredit-kill which has the following behavior (note: | represents the cursor position):

(foo bar)|     ; Useless comment!
->
(foo bar)|

(|foo bar) ; Useful comment!
->
(|) ; Useful comment!

|(foo bar) ; Useless line!
->
|

(foo "|bar baz"
quux)
->
(foo "|"
quux)
It's taking a little getting used to, but I'm finding myself thinking less about where the current block of code ends than I used to. The parentheses just take care of themselves...

This is how I enabled it:


(defun turn-on-paredit-mode ()
(paredit-mode +1))

;; I didn't like C-j being overridden, I want it to still work the old way in lisp-interaction
(eval-after-load "paredit"
'(progn
(define-key paredit-mode-map (read-kbd-macro "C-j") nil)))

(add-hook 'emacs-lisp-mode-hook 'turn-on-paredit-mode)

The cheat sheet is probably the best way to get an idea of what is possible. Check it out here. Also, the command documentation is very complete (see the above which was grabbed right from the C-k documentation, so it's easy to remind yourself what is possible.

About the only problem I've had is when I've yanked code that has unbalanced parens. So I wrote a little advice which at least warns you and allows you to abort if the yanked text is unbalanced. It's not perfect, but it is a reasonable first implementation:

(defun paredit-check-region-for-yank ()
"run after yank and yank-pop to verify balanced parens"
(when paredit-mode
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(condition-case nil
(check-parens)
(error
(if (not (y-or-n-p "The text inserted has unbalanced parentheses, continue? "))
(delete-region (point-min) (point-max)))))))))

(defadvice yank (after yank-check-parens activate)
(paredit-check-region-for-yank))
(defadvice yank-pop (after yank-pop-check-parens activate)
(paredit-check-region-for-yank))

6 comments:

Dave Roberts said...

Paredit rocks.

Went said...

Paredit is great! Thanks for the cheat sheet link, I didn't know about that.

pbsl said...

thanks for sharing this site. there are various kinds of ebooks available from here

http://feboook.blogspot.com

araceliscowman said...

援交友留言,視訊聊天室,成人貼圖站,情色視訊,情色論壇,美女圖片,080視訊聊天室,正妹牆qk176,18sxe成人影城,080視訊聊天室,免費交友,情色a片,台灣成人網,情色a片,聊天交友,台灣情色,情人貼圖,上班族聊天室f1,成人網,正妹交友,成人視訊,彰化人聊天室,台灣情色網,免費聊天,美女交友,丁字褲美女寫真,情色,免費視訊聊天室,777成人區,哈啦聊天室,0401視訊美女,免費色情影片,成人視訊,免費視訊,正妹牆自拍, ut聊天室,免費視訊,免費視訊g,八國聯軍成人,聊天室ut,

Brandon said...

So, I'm assuming that you know this, but in case other people have trouble `C-q )' will do a literal insert and get you around the fact that paredit only wants you to work with matched parens.

In case you yank something unbalanced I mean.

Thanks for pointing this out to me, it's pretty great.

Anonymous said...

Brandon, that is a great tip!