Saturday, 1 August 2020

Emacs / Viper / Unicode Parenthises

Agda ではUnicodeな括弧を良く使うわけなんだけど、show match して欲しいよね?

  ( [ { ⁅ ⁽ ₍ 〈 ⎴ ⟅ ⟦ ⟨ ⟪ ⦃ 〈 《 「 『 【 〔 〖 〚 ︵ ︷ ︹ ︻ ︽ ︿ ﹁ ﹃ ﹙ ﹛ ﹝ ( [ { 「
  ) ] } ⁆ ⁾ ₎ 〉 ⎵ ⟆ ⟧ ⟩ ⟫ ⦄ 〉 》 」 』 】 〕 〗 〛 ︶ ︸ ︺ ︼ ︾ ﹀ ﹂ ﹄ ﹚ ﹜ ﹞ ) ] } 」

このあたり。evil.el は dot (command の repeat ) が馬鹿過ぎて諦めました。たぶん、agda-mode との干渉もあるんでしょう。

結論的には以下のコードを ~/.emacs.d/init.el に入れればよい。まぁ、少し動作はおかしいが、良しとする。
(space は全角間隔にしてるのでコピペでは動きません)

;; extend parenthises match
;; "\u0028 " "\u005b " "\u007b " "\u2045 " "\u207d " "\u208d " "\u2329 " "\u23b4 " "\u27c5 " "\u27e6 " "\u27e8 " "\u27ea " "\u2983 "
;; "\u0029 " "\u005d " "\u007d " "\u2046 " "\u207e " "\u208e " "\u232a " "\u23b5 " "\u27c6 " "\u27e7 " "\u27e9 " "\u27eb " "\u2984 "
;;
(eval-after-load "viper"
 '(defun viper-paren-match (arg)
 "Go to the matching parenthesis."
 (interactive "P")
 (viper-leave-region-active)
 (let ((com (viper-getcom arg))
    (parse-sexp-ignore-comments viper-parse-sexp-ignore-comments)
    anchor-point)
  (if (integerp arg)
    (if (or (> arg 99) (< arg 1))
      (error "Prefix must be between 1 and 99")
     (goto-char
      (if (> (point-max) 80000)
        (* (/ (point-max) 100) arg)
       (/ (* (point-max) arg) 100)))
     (back-to-indentation))
   (let (beg-lim end-lim)
    (if (and (eolp) (not (bolp))) (forward-char -1))
    (if ( not( looking-at "[][(){}\u2045\u207d\u208d\u2329\u23b4\u27c5\u27e6\u27e8\u27ea\u2983\u2046\u207e\u209e\u232a\u23b5\u27c6\u27e7\u27e9\u27eb\u2984]"))
      (setq anchor-point (point)))
    (save-excursion
     (beginning-of-line)
     (setq beg-lim (point))
     (end-of-line)
     (setq end-lim (point)))
    (cond ((re-search-forward "[][(){}\u2045\u207d\u208d\u2329\u23b4\u27c5\u27e6\u27e8\u27ea\u2983\u2046\u207e\u209e\u232a\u23b5\u27c6\u27e7\u27e9\u27eb\u2984]" end-lim t)
        (backward-char) )
       ((re-search-backward "[][(){}\u2045\u207d\u208d\u2329\u23b4\u27c5\u27e6\u27e8\u27ea\u2983\u2046\u207e\u209e\u232a\u23b5\u27c6\u27e7\u27e9\u27eb\u2984]" beg-lim t))
       (t
        (error "No matching character on line"))))
   (cond ((looking-at "[\(\[{\u2045\u207d\u208d\u2329\u23b4\u27c5\u27e6\u27e8\u27ea\u2983]")
       (if com (viper-move-marker-locally 'viper-com-point (point)))
       (forward-sexp 1)
       (if com
         (viper-execute-com 'viper-paren-match nil com)
        (backward-char)))
      (anchor-point
       (if com
         (progn
          (viper-move-marker-locally 'viper-com-point anchor-point)
          (forward-char 1)
          (viper-execute-com 'viper-paren-match nil com)
          )))
      ((looking-at "[])}\u2046\u207e\u209e\u232a\u23b5\u27c6\u27e7\u27e9\u27eb\u2984]")
       (forward-char)
       (if com (viper-move-marker-locally 'viper-com-point (point)))
       (backward-sexp 1)
       (if com (viper-execute-com 'viper-paren-match nil com)))
      (t (error "")))))))

https://stackoverflow.com/questions/15717103/preferred-method-of-overriding-an-emacs-lisp-function

No comments: