EMACS: update autopair
This commit is contained in:
parent
b9eacfc709
commit
277854946f
1 changed files with 172 additions and 139 deletions
|
@ -101,7 +101,7 @@
|
||||||
;; For lisp-programming you might also like `autopair-skip-whitespace'.
|
;; For lisp-programming you might also like `autopair-skip-whitespace'.
|
||||||
;;
|
;;
|
||||||
;; For further customization have a look at `autopair-dont-pair',
|
;; For further customization have a look at `autopair-dont-pair',
|
||||||
;; `autopair-handle-action-fns' and `autopair-extra-pair'.
|
;; `autopair-handle-action-fns' and `autopair-extra-pairs'.
|
||||||
;;
|
;;
|
||||||
;; `autopair-dont-pair' lets you define special cases of characters
|
;; `autopair-dont-pair' lets you define special cases of characters
|
||||||
;; you don't want paired. Its default value skips pairing
|
;; you don't want paired. Its default value skips pairing
|
||||||
|
@ -195,7 +195,12 @@ criterious when skipping.")
|
||||||
syntax table.")
|
syntax table.")
|
||||||
|
|
||||||
(defvar autopair-dont-activate nil
|
(defvar autopair-dont-activate nil
|
||||||
"If non-nil `autopair-global-mode' does not activate in buffer")
|
"Control activation of `autopair-global-mode'.
|
||||||
|
|
||||||
|
Set this to a non-nil value to skip activation of `autopair-mode'
|
||||||
|
in certain contexts. If however the value satisfies `functionp'
|
||||||
|
and is a function of no arguments, the function is called and it is
|
||||||
|
the return value that decides.")
|
||||||
(make-variable-buffer-local 'autopair-dont-activate)
|
(make-variable-buffer-local 'autopair-dont-activate)
|
||||||
|
|
||||||
(defvar autopair-extra-pairs nil
|
(defvar autopair-extra-pairs nil
|
||||||
|
@ -263,7 +268,7 @@ three elements are (ACTION PAIR POS-BEFORE).
|
||||||
|
|
||||||
ACTION is one of `opening', `insert-quote', `skip-quote',
|
ACTION is one of `opening', `insert-quote', `skip-quote',
|
||||||
`backspace', `newline' or `paired-delimiter'. PAIR is the pair of
|
`backspace', `newline' or `paired-delimiter'. PAIR is the pair of
|
||||||
the `last-input-event' character, if applicable. POS-BEFORE is
|
the `autopair-inserted' character, if applicable. POS-BEFORE is
|
||||||
value of point before action command took place .")
|
value of point before action command took place .")
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,11 +311,26 @@ behaviour, be sure to include `autopair-default-handle-wrap-action' in
|
||||||
the list, or call it in your handlers.")
|
the list, or call it in your handlers.")
|
||||||
(make-variable-buffer-local 'autopair-handle-wrap-action-fns)
|
(make-variable-buffer-local 'autopair-handle-wrap-action-fns)
|
||||||
|
|
||||||
|
(defvar autopair-inserted nil
|
||||||
|
"Delimiter inserted by last interactive autopair command.
|
||||||
|
|
||||||
|
This is calculated with `autopair-calculate-inserted', which see.")
|
||||||
|
|
||||||
|
(defun autopair-calculate-inserted ()
|
||||||
|
"Attempts to guess the delimiter the current command is inserting.
|
||||||
|
|
||||||
|
For now, simply returns `last-command-event'"
|
||||||
|
last-command-event)
|
||||||
|
|
||||||
;; minor mode and global mode
|
;; minor mode and global mode
|
||||||
;;
|
;;
|
||||||
(define-globalized-minor-mode autopair-global-mode autopair-mode autopair-on)
|
(define-globalized-minor-mode autopair-global-mode autopair-mode autopair-on)
|
||||||
|
|
||||||
(defun autopair-on () (unless (or buffer-read-only autopair-dont-activate) (autopair-mode 1)))
|
(defun autopair-on () (unless (or buffer-read-only
|
||||||
|
(if (functionp autopair-dont-activate)
|
||||||
|
(funcall autopair-dont-activate)
|
||||||
|
autopair-dont-activate))
|
||||||
|
(autopair-mode 1)))
|
||||||
|
|
||||||
(define-minor-mode autopair-mode
|
(define-minor-mode autopair-mode
|
||||||
"Automagically pair braces and quotes like in TextMate."
|
"Automagically pair braces and quotes like in TextMate."
|
||||||
|
@ -324,9 +344,10 @@ the list, or call it in your handlers.")
|
||||||
(define-key map (kbd "<backspace>") 'autopair-backspace)
|
(define-key map (kbd "<backspace>") 'autopair-backspace)
|
||||||
(define-key map [backspace] 'autopair-backspace)
|
(define-key map [backspace] 'autopair-backspace)
|
||||||
(define-key map (kbd "DEL") 'autopair-backspace)
|
(define-key map (kbd "DEL") 'autopair-backspace)
|
||||||
|
(define-key map [return] 'autopair-newline)
|
||||||
(define-key map (kbd "RET") 'autopair-newline)
|
(define-key map (kbd "RET") 'autopair-newline)
|
||||||
(dotimes (char 256) ;; only searches the first 256 chars,
|
(dotimes (char 256) ;; only searches the first 256 chars,
|
||||||
;; TODO: is this enough/toomuch/stupid?
|
;; TODO: is this enough/toomuch/stupid?
|
||||||
(unless (member char
|
(unless (member char
|
||||||
(getf autopair-dont-pair :never))
|
(getf autopair-dont-pair :never))
|
||||||
(let* ((syntax-entry (aref (syntax-table) char))
|
(let* ((syntax-entry (aref (syntax-table) char))
|
||||||
|
@ -371,7 +392,7 @@ the list, or call it in your handlers.")
|
||||||
(setq autopair-action nil)
|
(setq autopair-action nil)
|
||||||
(setq autopair-wrap-action nil)
|
(setq autopair-wrap-action nil)
|
||||||
(add-hook 'emulation-mode-map-alists 'autopair-emulation-alist 'append)
|
(add-hook 'emulation-mode-map-alists 'autopair-emulation-alist 'append)
|
||||||
(add-hook 'post-command-hook 'autopair-post-command-handler 'append 'local))
|
(add-hook 'post-command-hook 'autopair-post-command-handler nil 'local))
|
||||||
(t
|
(t
|
||||||
(setq autopair-emulation-alist nil)
|
(setq autopair-emulation-alist nil)
|
||||||
(remove-hook 'emulation-mode-map-alists 'autopair-emulation-alist)
|
(remove-hook 'emulation-mode-map-alists 'autopair-emulation-alist)
|
||||||
|
@ -414,7 +435,7 @@ A list of four elements is returned:
|
||||||
:code
|
:code
|
||||||
quick-syntax-info)))))
|
quick-syntax-info)))))
|
||||||
|
|
||||||
(defun autopair-find-pair (delim)
|
(defun autopair-find-pair (delim &optional closing)
|
||||||
(when (and delim
|
(when (and delim
|
||||||
(integerp delim))
|
(integerp delim))
|
||||||
(let ((syntax-entry (aref (syntax-table) delim)))
|
(let ((syntax-entry (aref (syntax-table) delim)))
|
||||||
|
@ -423,7 +444,8 @@ A list of four elements is returned:
|
||||||
((or (eq (syntax-class syntax-entry) (car (string-to-syntax "\"")))
|
((or (eq (syntax-class syntax-entry) (car (string-to-syntax "\"")))
|
||||||
(eq (syntax-class syntax-entry) (car (string-to-syntax "$"))))
|
(eq (syntax-class syntax-entry) (car (string-to-syntax "$"))))
|
||||||
delim)
|
delim)
|
||||||
((eq (syntax-class syntax-entry) (car (string-to-syntax ")")))
|
((and (not closing)
|
||||||
|
(eq (syntax-class syntax-entry) (car (string-to-syntax ")"))))
|
||||||
(cdr syntax-entry))
|
(cdr syntax-entry))
|
||||||
(autopair-extra-pairs
|
(autopair-extra-pairs
|
||||||
(some #'(lambda (pair-list)
|
(some #'(lambda (pair-list)
|
||||||
|
@ -434,27 +456,33 @@ A list of four elements is returned:
|
||||||
(remove-if-not #'listp autopair-extra-pairs)))))))
|
(remove-if-not #'listp autopair-extra-pairs)))))))
|
||||||
|
|
||||||
(defun autopair-calculate-wrap-action ()
|
(defun autopair-calculate-wrap-action ()
|
||||||
(when (region-active-p)
|
(when (and transient-mark-mode mark-active)
|
||||||
|
(when (> (point) (mark))
|
||||||
|
(exchange-point-and-mark))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let* ((region-before (cons (region-beginning)
|
(let* ((region-before (cons (region-beginning)
|
||||||
(region-end)))
|
(region-end)))
|
||||||
(point-before (point))
|
(point-before (point))
|
||||||
(start-syntax (syntax-ppss (car region-before)))
|
(start-syntax (syntax-ppss (car region-before)))
|
||||||
(end-syntax (syntax-ppss (cdr region-before))))
|
(end-syntax (syntax-ppss (cdr region-before))))
|
||||||
(when (and (eq (nth 0 start-syntax) (nth 0 end-syntax))
|
(when (or (not (eq autopair-autowrap 'help-balance))
|
||||||
(eq (nth 3 start-syntax) (nth 3 end-syntax)))
|
(and (eq (nth 0 start-syntax) (nth 0 end-syntax))
|
||||||
|
(eq (nth 3 start-syntax) (nth 3 end-syntax))))
|
||||||
(list 'wrap (or (second autopair-action)
|
(list 'wrap (or (second autopair-action)
|
||||||
(autopair-find-pair last-input-event))
|
(autopair-find-pair autopair-inserted))
|
||||||
point-before
|
point-before
|
||||||
region-before))))))
|
region-before))))))
|
||||||
|
|
||||||
|
(defun autopair-original-binding ()
|
||||||
|
(or (key-binding `[,autopair-inserted])
|
||||||
|
(key-binding (this-single-command-keys))
|
||||||
|
(key-binding fallback-keys)))
|
||||||
|
|
||||||
(defun autopair-fallback (&optional fallback-keys)
|
(defun autopair-fallback (&optional fallback-keys)
|
||||||
(let* ((autopair-emulation-alist nil)
|
(let* ((autopair-emulation-alist nil)
|
||||||
(beyond-cua (let ((cua--keymap-alist nil))
|
(beyond-cua (let ((cua--keymap-alist nil))
|
||||||
(or (key-binding (this-single-command-keys))
|
(autopair-original-binding)))
|
||||||
(key-binding fallback-keys))))
|
(beyond-autopair (autopair-original-binding)))
|
||||||
(beyond-autopair (or (key-binding (this-single-command-keys))
|
|
||||||
(key-binding fallback-keys))))
|
|
||||||
(when autopair-autowrap
|
(when autopair-autowrap
|
||||||
(setq autopair-wrap-action (autopair-calculate-wrap-action)))
|
(setq autopair-wrap-action (autopair-calculate-wrap-action)))
|
||||||
|
|
||||||
|
@ -467,15 +495,16 @@ A list of four elements is returned:
|
||||||
(blink-matching-paren (not autopair-action)))
|
(blink-matching-paren (not autopair-action)))
|
||||||
(call-interactively beyond-autopair))))
|
(call-interactively beyond-autopair))))
|
||||||
|
|
||||||
(defvar autopair-autowrap nil
|
(defvar autopair-autowrap 'help-balance
|
||||||
"If non-nil autopair attempts to wrap the selected region.
|
"If non-nil autopair attempts to wrap the selected region.
|
||||||
|
|
||||||
This is also done in an optimistic \"try-to-balance\" fashion.")
|
This is also done in an optimistic \"try-to-balance\" fashion.
|
||||||
|
Set this to to 'help-balance to be more criterious when wrapping.")
|
||||||
|
|
||||||
(defvar autopair-skip-whitespace nil
|
(defvar autopair-skip-whitespace nil
|
||||||
"If non-nil also skip over whitespace when skipping closing delimiters.
|
"If non-nil also skip over whitespace when skipping closing delimiters.
|
||||||
|
|
||||||
This will be most useful in lisp-like languages where you want
|
If set to 'chomp, this will be most useful in lisp-like languages where you want
|
||||||
lots of )))))....")
|
lots of )))))....")
|
||||||
|
|
||||||
(defvar autopair-blink (if (boundp 'blink-matching-paren)
|
(defvar autopair-blink (if (boundp 'blink-matching-paren)
|
||||||
|
@ -504,7 +533,7 @@ original command as if autopair didn't exist"
|
||||||
(defun autopair-exception-p (where-sym exception-where-sym blacklist &optional fn)
|
(defun autopair-exception-p (where-sym exception-where-sym blacklist &optional fn)
|
||||||
(and (or (eq exception-where-sym :everywhere)
|
(and (or (eq exception-where-sym :everywhere)
|
||||||
(eq exception-where-sym where-sym))
|
(eq exception-where-sym where-sym))
|
||||||
(member last-input-event
|
(member autopair-inserted
|
||||||
(if fn
|
(if fn
|
||||||
(mapcar fn (getf blacklist exception-where-sym))
|
(mapcar fn (getf blacklist exception-where-sym))
|
||||||
(getf blacklist exception-where-sym)))))
|
(getf blacklist exception-where-sym)))))
|
||||||
|
@ -545,6 +574,7 @@ returned) and uplisting stops there."
|
||||||
;;
|
;;
|
||||||
(defun autopair-insert-or-skip-quote ()
|
(defun autopair-insert-or-skip-quote ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(let* ((syntax-triplet (autopair-syntax-ppss))
|
(let* ((syntax-triplet (autopair-syntax-ppss))
|
||||||
(syntax-info (first syntax-triplet))
|
(syntax-info (first syntax-triplet))
|
||||||
(where-sym (second syntax-triplet))
|
(where-sym (second syntax-triplet))
|
||||||
|
@ -559,22 +589,22 @@ returned) and uplisting stops there."
|
||||||
(cond (;; decides whether to skip the quote...
|
(cond (;; decides whether to skip the quote...
|
||||||
;;
|
;;
|
||||||
(and (not escaped-p)
|
(and (not escaped-p)
|
||||||
(eq last-input-event (char-after (point)))
|
(eq autopair-inserted (char-after (point)))
|
||||||
(or
|
(or
|
||||||
;; ... if we're already inside a string and the
|
;; ... if we're already inside a string and the
|
||||||
;; string starts with the character just inserted,
|
;; string starts with the character just inserted,
|
||||||
;; or it's a generically terminated string
|
;; or it's a generically terminated string
|
||||||
(and inside-string
|
(and inside-string
|
||||||
(or (eq inside-string t)
|
(or (eq inside-string t)
|
||||||
(eq last-input-event inside-string)))
|
(eq autopair-inserted inside-string)))
|
||||||
;; ... if we're in a comment and ending a string
|
;; ... if we're in a comment and ending a string
|
||||||
;; (the inside-string criteria does not work
|
;; (the inside-string criteria does not work
|
||||||
;; here...)
|
;; here...)
|
||||||
(and (eq where-sym :comment)
|
(and (eq where-sym :comment)
|
||||||
(condition-case nil
|
(condition-case nil
|
||||||
(eq last-input-event (char-after (scan-sexps (1+ (point)) -1)))
|
(eq autopair-inserted (char-after (scan-sexps (1+ (point)) -1)))
|
||||||
(error nil)))))
|
(error nil)))))
|
||||||
(setq autopair-action (list 'skip-quote last-input-event (point))))
|
(setq autopair-action (list 'skip-quote autopair-inserted (point))))
|
||||||
(;; decides whether to pair, i.e do *not* pair the quote if...
|
(;; decides whether to pair, i.e do *not* pair the quote if...
|
||||||
;;
|
;;
|
||||||
(not
|
(not
|
||||||
|
@ -598,26 +628,27 @@ returned) and uplisting stops there."
|
||||||
;; ... comment-disable or string-disable are true here.
|
;; ... comment-disable or string-disable are true here.
|
||||||
;; The latter is only useful if we're in a string
|
;; The latter is only useful if we're in a string
|
||||||
;; terminated by a character other than
|
;; terminated by a character other than
|
||||||
;; `last-input-event'.
|
;; `autopair-inserted'.
|
||||||
(some #'(lambda (sym)
|
(some #'(lambda (sym)
|
||||||
(autopair-exception-p where-sym sym autopair-dont-pair))
|
(autopair-exception-p where-sym sym autopair-dont-pair))
|
||||||
'(:comment :string))))
|
'(:comment :string))))
|
||||||
(setq autopair-action (list 'insert-quote last-input-event (point)))))
|
(setq autopair-action (list 'insert-quote autopair-inserted (point)))))
|
||||||
(autopair-fallback)))
|
(autopair-fallback)))
|
||||||
|
|
||||||
(put 'autopair-insert-or-skip-quote 'function-documentation
|
(put 'autopair-insert-or-skip-quote 'function-documentation
|
||||||
'(concat "Insert or possibly skip over a quoting character.\n\n"
|
'(concat "Insert or possibly skip over a quoting character.\n\n"
|
||||||
(autopair-document-bindings)))
|
(autopair-document-bindings)))
|
||||||
|
|
||||||
(defun autopair-in-unterminated-string-p (autopair-triplet)
|
(defun autopair-in-unterminated-string-p (autopair-triplet)
|
||||||
(and (eq last-input-event (fourth (third autopair-triplet)))
|
(and (eq autopair-inserted (fourth (third autopair-triplet)))
|
||||||
(condition-case nil (progn (scan-sexps (ninth (third autopair-triplet)) 1) nil) (error t))))
|
(condition-case nil (progn (scan-sexps (ninth (third autopair-triplet)) 1) nil) (error t))))
|
||||||
|
|
||||||
|
|
||||||
(defun autopair-insert-opening ()
|
(defun autopair-insert-opening ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(when (autopair-pair-p)
|
(when (autopair-pair-p)
|
||||||
(setq autopair-action (list 'opening (autopair-find-pair last-input-event) (point))))
|
(setq autopair-action (list 'opening (autopair-find-pair autopair-inserted) (point))))
|
||||||
(autopair-fallback))
|
(autopair-fallback))
|
||||||
(put 'autopair-insert-opening 'function-documentation
|
(put 'autopair-insert-opening 'function-documentation
|
||||||
'(concat "Insert opening delimiter and possibly automatically close it.\n\n"
|
'(concat "Insert opening delimiter and possibly automatically close it.\n\n"
|
||||||
|
@ -625,17 +656,19 @@ returned) and uplisting stops there."
|
||||||
|
|
||||||
(defun autopair-skip-close-maybe ()
|
(defun autopair-skip-close-maybe ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(when (autopair-skip-p)
|
(when (autopair-skip-p)
|
||||||
(setq autopair-action (list 'closing (autopair-find-pair last-input-event) (point))))
|
(setq autopair-action (list 'closing (autopair-find-pair autopair-inserted) (point))))
|
||||||
(autopair-fallback))
|
(autopair-fallback))
|
||||||
(put 'autopair-skip-close-maybe 'function-documentation
|
(put 'autopair-skip-close-maybe 'function-documentation
|
||||||
'(concat "Insert or possibly skip over a closing delimiter.\n\n"
|
'(concat "Insert or possibly skip over a closing delimiter.\n\n"
|
||||||
(autopair-document-bindings)))
|
(autopair-document-bindings)))
|
||||||
|
|
||||||
(defun autopair-backspace ()
|
(defun autopair-backspace ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(when (char-before)
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(setq autopair-action (list 'backspace (autopair-find-pair (char-before)) (point))))
|
(when (char-before)
|
||||||
|
(setq autopair-action (list 'backspace (autopair-find-pair (char-before) 'closing) (point))))
|
||||||
(autopair-fallback (kbd "DEL")))
|
(autopair-fallback (kbd "DEL")))
|
||||||
(put 'autopair-backspace 'function-documentation
|
(put 'autopair-backspace 'function-documentation
|
||||||
'(concat "Possibly delete a pair of paired delimiters.\n\n"
|
'(concat "Possibly delete a pair of paired delimiters.\n\n"
|
||||||
|
@ -643,22 +676,26 @@ returned) and uplisting stops there."
|
||||||
|
|
||||||
(defun autopair-newline ()
|
(defun autopair-newline ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(let ((pair (autopair-find-pair (char-before))))
|
(let ((pair (autopair-find-pair (char-before))))
|
||||||
(when (eq (char-after) pair)
|
(when (and pair
|
||||||
|
(eq (char-syntax pair) ?\))
|
||||||
|
(eq (char-after) pair))
|
||||||
(setq autopair-action (list 'newline pair (point))))
|
(setq autopair-action (list 'newline pair (point))))
|
||||||
(autopair-fallback (kbd "RET"))))
|
(autopair-fallback (kbd "RET"))))
|
||||||
(put 'autopair-newline 'function-documentation
|
(put 'autopair-newline 'function-documentation
|
||||||
'(concat "Possibly insert two newlines and place point after the first, indented.\n\n"
|
'(concat "Do a smart newline when right between parenthesis.\n
|
||||||
|
In other words, insert an extra newline along with the one inserted normally
|
||||||
|
by this command. Then place point after the first, indented.\n\n"
|
||||||
(autopair-document-bindings (kbd "RET"))))
|
(autopair-document-bindings (kbd "RET"))))
|
||||||
|
|
||||||
(defun autopair-skip-p ()
|
(defun autopair-skip-p ()
|
||||||
(interactive)
|
|
||||||
(let* ((syntax-triplet (autopair-syntax-ppss))
|
(let* ((syntax-triplet (autopair-syntax-ppss))
|
||||||
(syntax-info (first syntax-triplet))
|
(syntax-info (first syntax-triplet))
|
||||||
(orig-point (point)))
|
(orig-point (point)))
|
||||||
(cond ((eq autopair-skip-criteria 'help-balance)
|
(cond ((eq autopair-skip-criteria 'help-balance)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let ((pos-pair (autopair-up-list syntax-info last-input-event)))
|
(let ((pos-pair (autopair-up-list syntax-info autopair-inserted)))
|
||||||
;; if `autopair-up-list' returned something valid, we
|
;; if `autopair-up-list' returned something valid, we
|
||||||
;; probably want to skip but only if on of the following is true.
|
;; probably want to skip but only if on of the following is true.
|
||||||
;;
|
;;
|
||||||
|
@ -673,7 +710,7 @@ returned) and uplisting stops there."
|
||||||
(or (eq (car pos-pair) (cdr pos-pair))
|
(or (eq (car pos-pair) (cdr pos-pair))
|
||||||
(< orig-point (cdr pos-pair))
|
(< orig-point (cdr pos-pair))
|
||||||
(eq (char-after (car pos-pair))
|
(eq (char-after (car pos-pair))
|
||||||
(autopair-find-pair last-input-event)))))))
|
(autopair-find-pair autopair-inserted)))))))
|
||||||
((eq autopair-skip-criteria 'need-opening)
|
((eq autopair-skip-criteria 'need-opening)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(condition-case err
|
(condition-case err
|
||||||
|
@ -697,7 +734,7 @@ returned) and uplisting stops there."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let ((pos-pair (autopair-up-list syntax-info))
|
(let ((pos-pair (autopair-up-list syntax-info))
|
||||||
(prev-point (point-max))
|
(prev-point (point-max))
|
||||||
(expected-closing (autopair-find-pair last-input-event)))
|
(expected-closing (autopair-find-pair autopair-inserted)))
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(progn
|
(progn
|
||||||
(while (not (eq prev-point (point)))
|
(while (not (eq prev-point (point)))
|
||||||
|
@ -720,7 +757,7 @@ returned) and uplisting stops there."
|
||||||
;; autopair if we're in a mixed parens situation,
|
;; autopair if we're in a mixed parens situation,
|
||||||
;; i.e. the last list jumped over was started by
|
;; i.e. the last list jumped over was started by
|
||||||
;; the paren we're trying to match
|
;; the paren we're trying to match
|
||||||
;; (`last-input-event') and ended by a different
|
;; (`autopair-inserted') and ended by a different
|
||||||
;; parens, or the closing paren we stopped at is
|
;; parens, or the closing paren we stopped at is
|
||||||
;; also different from the expected. The second
|
;; also different from the expected. The second
|
||||||
;; `scan-lists' places point at the closing of the
|
;; `scan-lists' places point at the closing of the
|
||||||
|
@ -729,7 +766,7 @@ returned) and uplisting stops there."
|
||||||
(condition-case err
|
(condition-case err
|
||||||
(prog1
|
(prog1
|
||||||
(eq (char-after (scan-lists (point) -1 0))
|
(eq (char-after (scan-lists (point) -1 0))
|
||||||
last-input-event)
|
autopair-inserted)
|
||||||
(goto-char (scan-lists (point) -1 -1)))
|
(goto-char (scan-lists (point) -1 -1)))
|
||||||
(error t))
|
(error t))
|
||||||
|
|
||||||
|
@ -790,102 +827,91 @@ returned) and uplisting stops there."
|
||||||
|
|
||||||
(defun autopair-blink (&optional pos)
|
(defun autopair-blink (&optional pos)
|
||||||
(when autopair-blink
|
(when autopair-blink
|
||||||
(if pos
|
(if pos
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char pos)
|
(goto-char pos)
|
||||||
(sit-for autopair-blink-delay))
|
(sit-for autopair-blink-delay))
|
||||||
(sit-for autopair-blink-delay))))
|
(sit-for autopair-blink-delay))))
|
||||||
|
|
||||||
(defun autopair-default-handle-action (action pair pos-before)
|
(defun autopair-default-handle-action (action pair pos-before)
|
||||||
;;(message "action is %s" action)
|
;;(message "action is %s" action)
|
||||||
(cond (;; automatically insert closing delimiter
|
(condition-case err
|
||||||
(and (eq 'opening action)
|
(cond (;; automatically insert closing delimiter
|
||||||
(not (eq pair (char-before))))
|
(and (eq 'opening action)
|
||||||
(insert pair)
|
(not (eq pair (char-before))))
|
||||||
(autopair-blink)
|
(insert pair)
|
||||||
(backward-char 1))
|
(autopair-blink)
|
||||||
(;; automatically insert closing quote delimiter
|
(backward-char 1))
|
||||||
(eq 'insert-quote action)
|
(;; automatically insert closing quote delimiter
|
||||||
(insert pair)
|
(eq 'insert-quote action)
|
||||||
(autopair-blink)
|
(insert pair)
|
||||||
(backward-char 1))
|
(autopair-blink)
|
||||||
(;; automatically skip oper closer quote delimiter
|
(backward-char 1))
|
||||||
(and (eq 'skip-quote action)
|
(;; automatically skip oper closer quote delimiter
|
||||||
(eq pair (char-after (point))))
|
(and (eq 'skip-quote action)
|
||||||
(delete-char 1)
|
(eq pair (char-after (point))))
|
||||||
(autopair-blink-matching-open))
|
(delete-char 1)
|
||||||
(;; skip over newly-inserted-but-existing closing delimiter
|
(autopair-blink-matching-open))
|
||||||
;; (normal case)
|
(;; skip over newly-inserted-but-existing closing delimiter
|
||||||
(eq 'closing action)
|
;; (normal case)
|
||||||
(let ((skipped 0))
|
(eq 'closing action)
|
||||||
(when autopair-skip-whitespace
|
(let ((skipped 0))
|
||||||
(setq skipped (save-excursion (skip-chars-forward "\s\n\t"))))
|
(when autopair-skip-whitespace
|
||||||
(when (eq last-input-event (char-after (+ (point) skipped)))
|
(setq skipped (save-excursion (skip-chars-forward "\s\n\t"))))
|
||||||
(unless (zerop skipped) (autopair-blink (+ (point) skipped)))
|
(when (eq autopair-inserted (char-after (+ (point) skipped)))
|
||||||
(delete-char (1+ skipped))
|
(backward-delete-char 1)
|
||||||
(autopair-blink-matching-open))))
|
(unless (zerop skipped) (autopair-blink (+ (point) skipped)))
|
||||||
(;; autodelete closing delimiter
|
(if (eq autopair-skip-whitespace 'chomp)
|
||||||
(and (eq 'backspace action)
|
(delete-char skipped)
|
||||||
(eq pair (char-after (point))))
|
(forward-char skipped))
|
||||||
(delete-char 1))
|
(forward-char))
|
||||||
(;; opens an extra line after point, then indents
|
(autopair-blink-matching-open)))
|
||||||
(and (eq 'newline action)
|
(;; autodelete closing delimiter
|
||||||
(eq pair (char-after (point))))
|
(and (eq 'backspace action)
|
||||||
(save-excursion
|
(eq pair (char-after (point))))
|
||||||
(newline-and-indent))
|
(delete-char 1))
|
||||||
(indent-according-to-mode)
|
(;; opens an extra line after point, then indents
|
||||||
(when (or (and (boundp 'global-hl-line-mode)
|
(and (eq 'newline action)
|
||||||
global-hl-line-mode)
|
(eq pair (char-after (point))))
|
||||||
(and (boundp 'hl-line-mode)
|
(save-excursion
|
||||||
hl-line-mode))
|
(newline-and-indent))
|
||||||
(hl-line-unhighlight) (hl-line-highlight)))))
|
(indent-according-to-mode)
|
||||||
|
(when (or (and (boundp 'global-hl-line-mode)
|
||||||
|
global-hl-line-mode)
|
||||||
|
(and (boundp 'hl-line-mode)
|
||||||
|
hl-line-mode))
|
||||||
|
(hl-line-unhighlight) (hl-line-highlight))))
|
||||||
|
(error
|
||||||
|
(message "[autopair] Ignored error in `autopair-default-handle-action'"))))
|
||||||
|
|
||||||
(defun autopair-default-handle-wrap-action (action pair pos-before region-before)
|
(defun autopair-default-handle-wrap-action (action pair pos-before region-before)
|
||||||
"Default handler for the wrapping action in `autopair-wrap'"
|
"Default handler for the wrapping action in `autopair-wrap'"
|
||||||
(when (eq 'wrap action)
|
(condition-case err
|
||||||
(let ((reverse-selected (= (car region-before) pos-before)))
|
(when (eq 'wrap action)
|
||||||
(cond
|
(let ((delete-active-region nil))
|
||||||
((eq 'opening (first autopair-action))
|
(cond
|
||||||
;; (message "wrap-opening!")
|
((eq 'opening (first autopair-action))
|
||||||
(cond (reverse-selected
|
(goto-char (1+ (cdr region-before)))
|
||||||
(goto-char (1+ (cdr region-before)))
|
(insert pair)
|
||||||
(insert pair)
|
(autopair-blink)
|
||||||
(autopair-blink)
|
(goto-char (1+ (car region-before))))
|
||||||
(goto-char (1+ (car region-before))))
|
(;; wraps
|
||||||
(t
|
(eq 'closing (first autopair-action))
|
||||||
(delete-backward-char 1)
|
(delete-backward-char 1)
|
||||||
(insert pair)
|
(insert pair)
|
||||||
(goto-char (car region-before))
|
(goto-char (1+ (cdr region-before)))
|
||||||
(insert last-input-event)))
|
(insert autopair-inserted))
|
||||||
(setq autopair-action nil) )
|
((eq 'insert-quote (first autopair-action))
|
||||||
(;; wraps
|
(goto-char (1+ (cdr region-before)))
|
||||||
(eq 'closing (first autopair-action))
|
(insert pair)
|
||||||
;; (message "wrap-closing!")
|
(autopair-blink))
|
||||||
(cond (reverse-selected
|
(t
|
||||||
(delete-backward-char 1)
|
(delete-backward-char 1)
|
||||||
(insert pair)
|
(goto-char (cdr region-before))
|
||||||
(goto-char (1+ (cdr region-before)))
|
(insert autopair-inserted)))
|
||||||
(insert last-input-event))
|
(setq autopair-action nil)))
|
||||||
(t
|
(error
|
||||||
(goto-char (car region-before))
|
(message "[autopair] Ignored error in `autopair-default-handle-wrap-action'"))))
|
||||||
(insert pair)
|
|
||||||
(autopair-blink)
|
|
||||||
(goto-char (+ 2 (cdr region-before)))))
|
|
||||||
(setq autopair-action nil))
|
|
||||||
((eq 'insert-quote (first autopair-action))
|
|
||||||
(cond (reverse-selected
|
|
||||||
(goto-char (1+ (cdr region-before)))
|
|
||||||
(insert pair)
|
|
||||||
(autopair-blink))
|
|
||||||
(t
|
|
||||||
(goto-char (car region-before))
|
|
||||||
(insert last-input-event)
|
|
||||||
(autopair-blink)))
|
|
||||||
(setq autopair-action nil))
|
|
||||||
(reverse-selected
|
|
||||||
(delete-backward-char 1)
|
|
||||||
(goto-char (cdr region-before))
|
|
||||||
(insert last-input-event))))))
|
|
||||||
|
|
||||||
|
|
||||||
;; example python triple quote helper
|
;; example python triple quote helper
|
||||||
|
@ -917,10 +943,13 @@ returned) and uplisting stops there."
|
||||||
;; example latex paired-delimiter helper
|
;; example latex paired-delimiter helper
|
||||||
;;
|
;;
|
||||||
(defun autopair-latex-mode-paired-delimiter-action (action pair pos-before)
|
(defun autopair-latex-mode-paired-delimiter-action (action pair pos-before)
|
||||||
"Pair or skip latex's \"paired delimiter\" syntax in math mode."
|
"Pair or skip latex's \"paired delimiter\" syntax in math mode. Added AucText support, thanks Massimo Lauria"
|
||||||
(when (eq action 'paired-delimiter)
|
(when (eq action 'paired-delimiter)
|
||||||
(when (eq (char-before) pair)
|
(when (eq (char-before) pair)
|
||||||
(if (and (eq (get-text-property pos-before 'face) 'tex-math)
|
(if (and (or
|
||||||
|
(eq (get-text-property pos-before 'face) 'tex-math)
|
||||||
|
(eq (get-text-property (- pos-before 1) 'face) 'font-latex-math-face)
|
||||||
|
(member 'font-latex-math-face (get-text-property (- pos-before 1) 'face)))
|
||||||
(eq (char-after) pair))
|
(eq (char-after) pair))
|
||||||
(cond ((and (eq (char-after) pair)
|
(cond ((and (eq (char-after) pair)
|
||||||
(eq (char-after (1+ (point))) pair))
|
(eq (char-after (1+ (point))) pair))
|
||||||
|
@ -942,8 +971,9 @@ returned) and uplisting stops there."
|
||||||
|
|
||||||
(defun autopair-extra-insert-opening ()
|
(defun autopair-extra-insert-opening ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(when (autopair-extra-pair-p)
|
(when (autopair-extra-pair-p)
|
||||||
(setq autopair-action (list 'opening (autopair-find-pair last-input-event) (point))))
|
(setq autopair-action (list 'opening (autopair-find-pair autopair-inserted) (point))))
|
||||||
(autopair-fallback))
|
(autopair-fallback))
|
||||||
(put 'autopair-extra-insert-opening 'function-documentation
|
(put 'autopair-extra-insert-opening 'function-documentation
|
||||||
'(concat "Insert (an extra) opening delimiter and possibly automatically close it.\n\n"
|
'(concat "Insert (an extra) opening delimiter and possibly automatically close it.\n\n"
|
||||||
|
@ -951,8 +981,9 @@ returned) and uplisting stops there."
|
||||||
|
|
||||||
(defun autopair-extra-skip-close-maybe ()
|
(defun autopair-extra-skip-close-maybe ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
(when (autopair-extra-skip-p)
|
(when (autopair-extra-skip-p)
|
||||||
(setq autopair-action (list 'closing last-input-event (point))))
|
(setq autopair-action (list 'closing autopair-inserted (point))))
|
||||||
(autopair-fallback))
|
(autopair-fallback))
|
||||||
(put 'autopair-extra-skip-close-maybe 'function-documentation
|
(put 'autopair-extra-skip-close-maybe 'function-documentation
|
||||||
'(concat "Insert or possibly skip over a (and extra) closing delimiter.\n\n"
|
'(concat "Insert or possibly skip over a (and extra) closing delimiter.\n\n"
|
||||||
|
@ -971,7 +1002,7 @@ returned) and uplisting stops there."
|
||||||
(syntax-info (first syntax-triplet))
|
(syntax-info (first syntax-triplet))
|
||||||
(where-sym (second syntax-triplet))
|
(where-sym (second syntax-triplet))
|
||||||
(orig-point (point)))
|
(orig-point (point)))
|
||||||
(and (eq (char-after (point)) last-input-event)
|
(and (eq (char-after (point)) autopair-inserted)
|
||||||
(some #'(lambda (sym)
|
(some #'(lambda (sym)
|
||||||
(autopair-exception-p where-sym sym autopair-extra-pairs #'cdr))
|
(autopair-exception-p where-sym sym autopair-extra-pairs #'cdr))
|
||||||
'(:comment :string :code :everywhere))
|
'(:comment :string :code :everywhere))
|
||||||
|
@ -980,7 +1011,7 @@ returned) and uplisting stops there."
|
||||||
(backward-sexp (point-max))
|
(backward-sexp (point-max))
|
||||||
(error
|
(error
|
||||||
(goto-char (third err))))
|
(goto-char (third err))))
|
||||||
(search-forward (make-string 1 (autopair-find-pair last-input-event))
|
(search-forward (make-string 1 (autopair-find-pair autopair-inserted))
|
||||||
orig-point
|
orig-point
|
||||||
'noerror)))))
|
'noerror)))))
|
||||||
|
|
||||||
|
@ -990,7 +1021,8 @@ returned) and uplisting stops there."
|
||||||
(defun autopair-insert-or-skip-paired-delimiter ()
|
(defun autopair-insert-or-skip-paired-delimiter ()
|
||||||
" insert or skip a character paired delimiter"
|
" insert or skip a character paired delimiter"
|
||||||
(interactive)
|
(interactive)
|
||||||
(setq autopair-action (list 'paired-delimiter last-input-event (point)))
|
(setq autopair-inserted (autopair-calculate-inserted))
|
||||||
|
(setq autopair-action (list 'paired-delimiter autopair-inserted (point)))
|
||||||
(autopair-fallback))
|
(autopair-fallback))
|
||||||
|
|
||||||
(put 'autopair-insert-or-skip-paired-delimiter 'function-documentation
|
(put 'autopair-insert-or-skip-paired-delimiter 'function-documentation
|
||||||
|
@ -1005,7 +1037,8 @@ returned) and uplisting stops there."
|
||||||
;; 'delete-selection properties of the autopair commands. The function
|
;; 'delete-selection properties of the autopair commands. The function
|
||||||
;; would return non-nil when no wrapping should/could be performed.
|
;; would return non-nil when no wrapping should/could be performed.
|
||||||
;;
|
;;
|
||||||
;; Until then use some `defadvice' i.e. monkey-patching
|
;; Until then use some `defadvice' i.e. monkey-patching, which relies
|
||||||
|
;; on these features' implementation details.
|
||||||
;;
|
;;
|
||||||
(put 'autopair-insert-opening 'delete-selection t)
|
(put 'autopair-insert-opening 'delete-selection t)
|
||||||
(put 'autopair-skip-close-maybe 'delete-selection t)
|
(put 'autopair-skip-close-maybe 'delete-selection t)
|
||||||
|
|
Loading…
Reference in a new issue