Wednesday, 7 April 2010

Emacs небольшое рассширение для скобок.

После того как познакомился с Pharo, начал испытывать неудобство с ручным проставлением парных скобок и кавычек. Как результат в мой .emacs файл добавился следующий код:

(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 в паре пустых скобок - удаляются обе. В случае если выделен какой-то текст, то он обрамляется в скобки.

2 comments:

  1. У меня почему-то работает только для двойных кавычек и для прямых скобок (GNU Emacs 23.2.1).

    P.S. А вообще спасибо за макрос!

    ReplyDelete
  2. Это может быть связанно с тем, что текущий режим переопределяет действие. Можно попробовать добавить это хуком, например как-то так:

    (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))))

    И в принципе всё должно заработать.

    ReplyDelete