首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用cons单元格定义并在以后删除与“`dolist`”的覆盖

如何使用cons单元格定义并在以后删除与“`dolist`”的覆盖
EN

Stack Overflow用户
提问于 2014-08-24 01:35:20
回答 2查看 126关注 0票数 1

我正在寻找一些指导,请,以减少执行我的自定义覆盖删除功能所需的时间。导致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

代码语言:javascript
复制
(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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-24 18:09:12

第一稿(2014年8月24日):第一稿将变量定义为cons单元-- car是预定的覆盖字符串,cdrnil。当光标访问字符123时,将在这些字符的顶部放置一个覆盖,并使用setcdr将适用的cons单元格的cdr设置为t。覆盖删除函数包含一个变量名列表和相应的cons单元--当cons单元格的cdr为非nil(即t)时,覆盖被删除,适用的cons单元的cdr被使用setcdr设置回nil。这种设置的优点是,覆盖删除函数将快速查看并跳过cons单元cdrnil的变量--因此在处理具有预定覆盖字符串的大量变量时节省了大量时间。

编辑(2014年8月26日):重新编码修改代码,允许在不同缓冲区中使用相同的变量名,并设置缓冲区-本地值。相关线程是: with buffer-local variables cycle and change its value

代码语言:javascript
复制
(defvar variable-one
  (cons
    (concat
      (propertize (char-to-string ?\u007C)
        'face 'font-lock-warning-face
        'cursor t)
      (propertize "1" 'face 'highlight 'cursor t) )
    nil))

(make-variable-buffer-local 'variable-one)

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

(make-variable-buffer-local 'variable-two)

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

(make-variable-buffer-local 'variable-three)

(defun sub-char ()
  (cond
    ((eq (char-after (point)) 49)
      (let ((newlist (copy-list variable-one)))
        (setcdr newlist t)
        (setq-local variable-one newlist)
        (overlay-put (make-overlay (point) (1+ (point))) 'display (car variable-one))))
    ((eq (char-after (point)) 50)
      (let ((newlist (copy-list variable-two)))
        (setcdr newlist t)
        (setq-local variable-two newlist)
        (overlay-put (make-overlay (point) (1+ (point))) 'display (car variable-two))))
    ((eq (char-after (point)) 51)
      (let ((newlist (copy-list variable-three)))
        (setcdr newlist t)
        (setq-local variable-three newlist)
        (overlay-put (make-overlay (point) (1+ (point))) 'display (car variable-three))))))

(defun remove-sub-char ()
  (dolist (character `(
      (variable-one ,variable-one)
      (variable-two ,variable-two)
      (variable-three ,variable-three)))
    (when (cdr (car (cdr character)))
      (let* (
          (var (car character))
          (newlist (copy-list (car (cdr character)))) )
        (remove-overlays (point-min) (point-max) 'display (car (car (cdr character))))
        (setcdr newlist nil)
        (set (car character) newlist)
        (message "var1: %s | var2: %s | var3: %s" variable-one variable-two variable-three) ))))

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

(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`."))))
票数 0
EN

Stack Overflow用户

发布于 2014-08-27 02:45:05

我建议您首先摆脱您的variable-FOO-p vars:不仅它们的名称是错误的( "-p“后缀指的是谓词,这些谓词必须是函数,而不是变量),而且它们是不必要的。与其告诉remove-overlays删除带有特定display属性的所有覆盖,不如添加自己的属性(例如,(overlay-put <youroverlay> 'vline t)),这样您就可以执行单个(remove-overlays (point-min) (point-max) 'vline t)了。当然,另一种至少也能工作的方法是保留一个单独的缓冲区局部变量(更好的是,窗口局部变量),它包含当前放置的所有覆盖的列表。通过这种方式,您可以使用单个(mapc #'delete-overlay vline--overlays)删除这些覆盖,这样效率更高。通过移动/重用这些覆盖,而不是删除它们,然后创建新的覆盖,可以使其更加高效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25467815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档