(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 в паре пустых скобок - удаляются обе. В случае если выделен какой-то текст, то он обрамляется в скобки.
У меня почему-то работает только для двойных кавычек и для прямых скобок (GNU Emacs 23.2.1).
ReplyDeleteP.S. А вообще спасибо за макрос!
Это может быть связанно с тем, что текущий режим переопределяет действие. Можно попробовать добавить это хуком, например как-то так:
ReplyDelete(defun my-some-mode-hook ()
(parentheses insert-parentheses "(" ")")
(parentheses insert-square-parentheses "[" "]")
(parentheses insert-braces-parentheses "{" "}")
(parentheses insert-quote-parentheses "\"" "\"")
(global-set-key (kbd "") 'backspace))
(add-hook 'some-mode-hook 'my-some-mode-hook)
Правда в таком случае необходимо сперва заменить в макросе строку:
(global-set-key ,open (quote ,name))))
На
(local-set-key ,open (quote ,name))))
И в принципе всё должно заработать.