Skip to content

Instantly share code, notes, and snippets.

@jorgenschaefer
Created November 17, 2012 15:42
Show Gist options
  • Select an option

  • Save jorgenschaefer/4096909 to your computer and use it in GitHub Desktop.

Select an option

Save jorgenschaefer/4096909 to your computer and use it in GitHub Desktop.
Better electric-pair-mode
(defun electric-pair-post-self-insert-function ()
(let* ((syntax (and (eq (char-before) last-command-event) ; Sanity check.
(electric-pair-syntax last-command-event)))
;; FIXME: when inserting the closer, we should maybe use
;; self-insert-command, although it may prove tricky running
;; post-self-insert-hook recursively, and we wouldn't want to trigger
;; blink-matching-open.
(closer (if (eq syntax ?\()
(cdr (or (assq last-command-event electric-pair-pairs)
(aref (syntax-table) last-command-event)))
last-command-event)))
(cond
;; Wrap a pair around the active region.
((and (memq syntax '(?\( ?\" ?\$)) (use-region-p))
(if (> (mark) (point))
(goto-char (mark))
;; We already inserted the open-paren but at the end of the
;; region, so we have to remove it and start over.
(delete-char -1)
(save-excursion
(goto-char (mark))
;; Do not insert after `save-excursion' marker (Bug#11520).
(insert-before-markers last-command-event)))
(insert closer))
;; Backslash-escaped: no pairing, no skipping.
((save-excursion
(goto-char (1- (point)))
(not (zerop (% (skip-syntax-backward "\\") 2))))
nil)
;; Skip self.
((and (memq syntax '(?\) ?\" ?\$))
electric-pair-skip-self
(looking-at (concat "\\s-*"
(regexp-quote
(make-string 1 last-command-event))))
;; (eq (char-after) last-command-event)
)
;; This is too late: rather than insert&delete we'd want to only skip (or
;; insert in overwrite mode). The difference is in what goes in the
;; undo-log and in the intermediate state which might be visible to other
;; post-self-insert-hook. We'll just have to live with it for now.
;; (delete-char 1)
(replace-match "")
)
;; Insert matching pair.
((not (or (not (memq syntax `(?\( ?\" ?\$)))
overwrite-mode
;; I find it more often preferable not to pair when the
;; same char is next.
(eq last-command-event (char-after))
(eq last-command-event (char-before (1- (point))))
;; I also find it often preferable not to pair next to a word.
(eq (char-syntax (following-char)) ?w)))
(save-excursion (insert closer))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment