(defmacro parentheses (name open close) `(progn (defun ,name() (interactive) (if (and transient-mark-mode mark-active) (let ((b (region-beginning)) (e (region-end))) (goto-char (min b e)) (insert ,open) (goto-char (1+ (max b e))) (insert ,close)) (progn (insert ,open) (insert ,close) (backward-char 1)))) (global-set-key ,open (quote ,name)))) (parentheses insert-parentheses "(" ")") (parentheses insert-square-parentheses "[" "]") (parentheses insert-braces-parentheses "{" "}") (parentheses insert-quote-parentheses "\"" "\"") (defun backspace () (interactive) (setq p (point)) (goto-char (- p 1)) (if (or (search-forward "()" (+ p 1) t 1) (search-forward "[]" (+ p 1) t 1) (search-forward "\"\"" (+ p 1) t 1) (search-forward "{}" (+ p 1) t 1)) (replace-match "" nil t) (progn (goto-char p) (backward-delete-char-untabify 1)))) (global-set-key (kbd "<backspace>") 'backspace)
Делает примерно следующее: при нажатие открытия любой из скобок или двойной кавычки - вставляется пара, курсор между ними. При нажатие backspace в паре пустых скобок - удаляются обе. В случае если выделен какой-то текст, то он обрамляется в скобки.