如何使用cons单元定义并随后删除带有“dolist”的叠加层

时间:2014-08-24 01:35:20

标签: emacs elisp

我正在寻找一些指导,以减少执行自定义叠加删除功能所需的时间。延迟最多0.1秒是因为过多的变量都有值,但并非每个变量都必须使用。

我的目标是在每次使用第一个变量时附加一个可以设置为非nil的第二个变量,但我不确定如何设置它以及如何将其合并到重叠删除功能中。

或许看起来像这样的东西会很有用:

  • 如果(variable-one . t),则(remove-overlays (point-min) (point-max) 'display character)

在以下示例中,只要光标访问任何这些字符,M-x sub-char-mode就会在字符1,2或3上放置一个叠加层:

  • 1将成为|1

  • 2将成为|2

  • 3将成为|3

  
(defvar variable-one (concat
  (propertize (char-to-string ?\u007C)
    'face 'font-lock-warning-face
    'cursor t)
  (propertize "1" 'face 'highlight 'cursor t) ))

(defvar variable-one-p (cons variable-one nil))

(defvar variable-two (concat
  (propertize (char-to-string ?\u007C)
    'face 'font-lock-warning-face
    'cursor t)
  (propertize "2" 'face 'highlight 'cursor t) ))

(defvar variable-two-p (cons variable-two nil))

(defvar variable-three (concat
  (propertize (char-to-string ?\u007C)
    'face 'font-lock-warning-face
    'cursor t)
  (propertize "3" 'face 'highlight 'cursor t) ))

(defvar variable-three-p (cons variable-three nil))

(defun substitute-character ()
  (cond
    ((eq (char-after (point)) 49)
      (setq variable-one-p (cons variable-one t))
      (overlay-put (make-overlay (point) (1+ (point))) 'display variable-one))
    ((eq (char-after (point)) 50)
      (setq variable-two-p (cons variable-two t))
      (overlay-put (make-overlay (point) (1+ (point))) 'display variable-two))
    ((eq (char-after (point)) 51)
      (setq variable-three-p (cons variable-three t))
      (overlay-put (make-overlay (point) (1+ (point))) 'display variable-three))))

(defun remove-sub-char ()
  (dolist (character `(
      ,variable-one
      ,variable-two
      ,variable-three))
    (remove-overlays (point-min) (point-max) 'display character))
 (dolist (my-variable `(
      ,variable-one-p
      ,variable-two-p
      ,variable-three-p))
    (setq my-variable nil)) )

(defun sub-char-post-command-hook ()
  (remove-sub-char)
  (substitute-character))

(define-minor-mode sub-char-mode
"A minor-mode for testing overlay-removal with cons cells."
  :init-value nil
  :lighter " OV-REMOVE"
  :keymap nil
  :global nil
  :group 'lawlist
  (cond
    (sub-char-mode
      (add-hook 'post-command-hook 'sub-char-post-command-hook nil t)
      (message "Turned ON `sub-char-mode`."))
    (t
      (remove-hook 'post-command-hook 'sub-char-post-command-hook t)
      (remove-sub-char)
      (message "Turned OFF `sub-char-mode`."))))

在此粘贴此图片的道歉 - 随意删除它。但我无法将其粘贴到评论中,以回复您的评论要求外观。这是vline-style = composecol-highlight-vline-face-flag = nil

enter image description here

2 个答案:

答案 0 :(得分:0)

初稿(2014年8月24日):第一个答案草案将变量定义为cons单元格 - car是预定的叠加字符串,并且cdrnil。当光标访问字符123时,会在这些字符的顶部放置一个叠加层,并且适用的cdr单元格的cons位于使用t设置为setcdr。覆盖删除功能包含变量名称列表和相应的cons单元格 - 当cdr单元格的cons为非nil时(即{{1} }}),移除叠加层,并使用t将适用的cdr单元格的cons设置回nil。此类设置的优点是叠加删除功能将快速查看,然后跳过setcdr单元格conscdr的变量 - 从而节省大量时间用预定的覆盖字符串处理大量变量。

编辑(2014年8月26日):修改了允许在不同缓冲区中使用相同变量名并设置缓冲区本地值的代码。相关主题是:How to use `setcdr` with buffer-local variables Incorporate variable name into `dolist` cycle and change its value

  
nil

答案 1 :(得分:0)

我建议你先摆脱你的variable-FOO-p vars:不仅名字错了(&#34; -p&#34;后缀用于谓词它们必然是功能,而不是变量)但它们是不必要的。不要告诉remove-overlays删除具有特定display属性的所有叠加层,只需添加您自己的属性(例如(overlay-put <youroverlay> 'vline t)),这样您就可以执行单个(remove-overlays (point-min) (point-max) 'vline t)。当然,另一种至少也能起作用的方法是保留一个缓冲区局部变量(更好的是,窗口局部变量),它保存了当前放置的所有叠加层的列表。这样,您可以使用单个(mapc #'delete-overlay vline--overlays)删除这些叠加层,这样更有效。通过移动 / 重用这些叠加层而不是删除它们然后再创建新的叠加层,可以提高效率。