【问题标题】:Emacs -- creating a custom highlight parentheses functionEmacs——创建自定义高亮括号函数
【发布时间】:2014-06-01 23:42:20
【问题描述】:

我正在寻求一些帮助,请进一步修改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")))

[脚注 1highlight-parentheses 库的引用是不需要来回答这个问题的,但引用被包括在内以便为在此问题中启发 parens 函数的作者(即 Nikolaj Schumacher)赋予适当的属性。]

【问题讨论】:

  • 你有什么理由不只使用rainbow-delimiters-mode
  • @Justin Wood -- 我正在编写一个不相关的自定义次要模式,由于使用函数 move-overlay 而不是删除叠加层而导致杂乱的叠加层对象放置在周围而受到干扰。上面名为parens 的函数可以工作,它只需要添加一个dolist - 但是,在处理whiledolist 时我会感到困惑并且不知道如何处理它。我通过只在其中构建我需要的基本功能来消除我的次要模式中的冲突——在这种情况下,一旦我了解如何一起使用dolistwhileparens 将满足我的需求。跨度>
  • @lawlist 您的次要模式被任意叠加搞糊涂了?!为什么这特别是由move-overlay 引起的?难道你不能改变你的次要模式只在它自己创建的叠加层上工作吗?
  • @lunaryorn -- 有两个可能的嫌疑人。使用库highlight-parentheses,在point-min 创建了多个覆盖对象,并且它们随着post-command-hook 的每次连续运行而累积——这逐渐减慢了我将覆盖从window-start 放置到window-end 的无关函数。第二个可能的嫌疑人是当make-overlaypoint 而非overlay-put 上执行时,完全删除该覆盖是有问题的。移除,而不是移动,效果很好;与overlay-put 一起执行make-overlay 也是如此。
  • @lawlist 我看不出有什么明显的理由说明为什么其中任何一个都应该与来自另一个库(如彩虹分隔符)的覆盖冲突。

标签: emacs elisp


【解决方案1】:
(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`.")))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多