Emacs - 创建自定义高亮括号功能

时间:2014-06-01 23:42:20

标签: emacs elisp

我正在寻求一些帮助,请进一步修改highlight-parentheses库中的以下已修改摘录:https://github.com/nschum/highlight-parentheses.el [Fn 1。]

目标目标是使用mapcardolist之类的内容自动将INSERT-FACE-HERE替换为每次 my-parens-faces 执行循环时,变量while 面对不同的面。视觉效果将是基于嵌套水平的括号的彩虹色。

我正在使用post-command-hook和类似remove-overlays的函数删除叠加层,然后在下面添加带有parens函数的新叠加层。我不会移动任何叠加层 - 只是创建和删除。最终版本将使用面的变量和目标特定叠加层进行删除,但下面是一个示例:(add-hook 'post-command-hook (lambda () (remove-overlays) (parens)))

每次while执行循环时,我都希望从变量my-parens-faces插入不同的面 - 按顺序排列,如dolist。例如:

  • while执行循环#1:(:foreground "black" :background "cyan")

  • while执行循环#2:(:foreground "blue" :background "purple")

  • while执行循环#3:(:foreground "green" :background "blue")

  • while执行循环#4:(:foreground "yellow" :background "purple")

  • while执行循环#5:(:foreground "orange" :background "yellow")

  • while执行循环#6:(:foreground "red" :background "green")

  • while执行循环#7:(:foreground "pink" :background "brown")

  • while执行循环#8:(:foreground "blue" :background "beige")

  
(defun parens ()
  (let* (pos1 pos2)
    (save-excursion
      (condition-case err
        (while (setq pos1 (cadr (syntax-ppss pos1)))
          (overlay-put (make-overlay pos1 (1+ pos1)) 'face 'INSERT-FACE-HERE)
          (when (setq pos2 (scan-sexps pos1 1))
            (overlay-put (make-overlay (1- pos2) pos2) 'face 'INSERT-FACE-HERE)))
        (error nil)) )))

(defvar my-parens-faces '(
  (:foreground "black" :background "cyan")
  (:foreground "blue" :background "purple")
  (:foreground "green" :background "blue")
  (:foreground "yellow" :background "purple")
  (:foreground "orange" :background "yellow")
  (:foreground "red" :background "green")
  (:foreground "pink" :background "brown")
  (:foreground "blue" :background "beige")))

[脚注编号1 :对 highlight-parentheses 库的引用需要回答此问题,但该引用包含在内这样就可以为作者(即Nikolaj Schumacher)提供适当的属性,他在这个问题中启发了parens函数。]

1 个答案:

答案 0 :(得分:2)

(defvar parens-mode-command-exclusions '(mwheel-scroll scroll-up scroll-down)
  "List of functions that are excluded from triggering the function `parens'.")

(defvar parens-mode-syntax-table
  (let ((st (make-syntax-table)))
    st)
  "Syntax table used while executing the function `parens'.")

(defgroup parens nil
  "Faces for highlighting parentheses in `parens-mode'."
  :group 'parens)

(defface parens-one-face
  '((t (:foreground "magenta")))
  "Face for `parens-one-face'."
  :group 'parens)

(defface parens-two-face
  '((t (:foreground "red")))
  "Face for `parens-two-face'."
  :group 'parens)

(defface parens-three-face
  '((t (:foreground "yellow")))
  "Face for `parens-three-face'."
  :group 'parens)

(defface parens-four-face
  '((t (:foreground "green")))
  "Face for `parens-four-face'."
  :group 'parens)

(defface parens-five-face
  '((t (:foreground "cyan")))
  "Face for `parens-five-face'."
  :group 'parens)

(defface parens-six-face
  '((t (:foreground "orange")))
  "Face for `parens-six-face'."
  :group 'parens)

(defface parens-seven-face
  '((t (:foreground "purple")))
  "Face for `parens-seven-face'."
  :group 'parens)

(defface parens-eight-face
  '((t (:foreground "blue")))
  "Face for `parens-eight-face'."
  :group 'parens)

(defface parens-nine-face
  '((t (:foreground "brown")))
  "Face for `parens-nine-face'."
  :group 'parens)

(defface parens-ten-face
  '((t (:foreground "white")))
  "Face for `parens-ten-face'."
  :group 'parens)

(defvar parens-overlays-exist-p nil
"Simple test to see whether the parens overlays have been placed.")
(make-variable-buffer-local 'parens-overlays-exist-p)

(defun parens ()
"Portions of this function were borrowed from the library
`highlight-parentheses` written by Nikolaj Schumacher.
https://github.com/nschum/highlight-parentheses.el"
  (unless (memq this-command parens-mode-command-exclusions)
    (with-syntax-table parens-mode-syntax-table
      (let* (
          (pt (point))
          (pos1 (if
                  (or
                    (= pt (point-min))
                    (eq (preceding-char) 40) ;; open-parentheses
                    (eq (preceding-char) 91) ;; open-squre-bracket
                    (eq (preceding-char) 123)) ;; open-wavy-bracket
              pt
              (1- pt)))
          pos2
          selected-face
          (i 0) )
        (remove-parens-overlays)
        (save-excursion
          (condition-case nil
            (while (setq pos1 (cadr (syntax-ppss pos1)))
              (if (= i 10)
                (setq i 1)
                (setq i (1+ i)))
              (cond
                ((= i 1)
                  (setq selected-face 'parens-one-face))
                ((= i 2)
                  (setq selected-face 'parens-two-face))
                ((= i 3)
                  (setq selected-face 'parens-three-face))
                ((= i 4)
                  (setq selected-face 'parens-four-face))
                ((= i 5)
                  (setq selected-face 'parens-five-face))
                ((= i 6)
                  (setq selected-face 'parens-six-face))
                ((= i 7)
                  (setq selected-face 'parens-seven-face))
                ((= i 8)
                  (setq selected-face 'parens-eight-face))
                ((= i 9)
                  (setq selected-face 'parens-nine-face))
                ((= i 10)
                  (setq selected-face 'parens-ten-face)) )
              (overlay-put (make-overlay pos1 (1+ pos1)) 'face selected-face)
              (when (setq pos2 (scan-sexps pos1 1))
                (overlay-put (make-overlay (1- pos2) pos2) 'face selected-face)))
            (error nil) ))
        (setq parens-overlays-exist-p t)))))

(defun remove-parens-overlays ()
  (when parens-overlays-exist-p
    (dolist (face '(
        parens-one-face
        parens-two-face
        parens-three-face
        parens-four-face
        parens-five-face
        parens-six-face
        parens-seven-face
        parens-eight-face
        parens-nine-face
        parens-ten-face))
      (remove-overlays nil nil 'face face)) 
    (setq parens-overlays-exist-p nil)))

(defun turn-off-parens-mode ()
  (parens-mode -1))

(define-minor-mode parens-mode
"A minor-mode for highlighting parentheses."
  :init-value nil
  :lighter " ‹›"
  :keymap nil
  :global nil
  :group 'parens
  (cond
    (parens-mode
      (add-hook 'post-command-hook 'parens t t)
      (add-hook 'change-major-mode-hook 'turn-off-parens-mode nil t)
      (when (called-interactively-p 'any)
        (message "Turned ON `parens-mode`.")))
    (t
      (remove-hook 'post-command-hook 'parens t)
      (remove-hook 'change-major-mode-hook 'turn-off-parens-mode t)
      (remove-parens-overlays)
      (when (called-interactively-p 'any)
        (message "Turned OFF `parens-mode`.")))))