请问下emacs有没有类似vim的拷贝文本高亮的插件

如题,vim有个插件叫vim-highlightedyank,拷贝的字符高亮,请问下emacs有相似的插件么,或者用elisp好实现么??

多谢 我先看看去

可以试试这个:

https://github.com/k-talo/volatile-highlights.el

懒猫的thing-edit值得拥有 https://manateelazycat.github.io/emacs/2018/12/22/thing-edit.html

多谢 我去试下

这个我安装上去,用的evil的配置,复制一行yy,那一行没有高亮,是我的配置不对么? 我的配置:

(use-package volatile-highlights
  :ensure t
  :config
  (volatile-highlights-mode t)
  ;;-----------------------------------------------------------------------------
  ;; Supporting evil-mode.
  ;;-----------------------------------------------------------------------------
  (vhl/define-extension 'evil 'evil-paste-after 'evil-paste-before
                        'evil-paste-pop 'evil-move)
  (vhl/install-extension 'evil)
  ;;-----------------------------------------------------------------------------
  ;; Supporting undo-tree.
  ;;-----------------------------------------------------------------------------
  (vhl/define-extension 'undo-tree 'undo-tree-yank 'undo-tree-move)
  (vhl/install-extension 'undo-tree)
  )

兄弟,这个的功能好像不是我需要的吧?还是我没理解对?

这个功能是我之前用Spacemacs的Evil键位用到的,后来改回原生的就没有用过了,你可以参考一下Spacemacs的配置:

我自己用advice实现了这个功能,对evil-yank和lispyeville-yank添加after的advice,高亮yank region 0.5秒。高亮方法参考的highlight-regexp的最终的方法,用overlay。

(defface fwar34-hi-yellow
  '((((min-colors 88) (background dark))
     (:background "yellow1" :foreground "black"))
    (((background dark)) (:background "yellow" :foreground "black"))
    (((min-colors 88)) (:background "yellow1"))
    (t (:background "yellow")))
  "Default face for hi-lock mode.")

(defun fwar34/highlight-yank (beg end &rest _)
  (let ((overlay (make-overlay beg end)))
    (overlay-put overlay 'face 'fwar34-hi-yellow)
    (make-thread (lambda ()
                   (sleep-for 0 500)
                   (remove-overlays beg end 'face 'fwar34-hi-yellow))))
  )
(advice-add #'evil-yank :after #'fwar34/highlight-yank)
(advice-add #'lispyville-yank :after #'fwar34/highlight-yank)

这样实现现在还有个问题,删除的时候同样会调用evil-yank,所以也会开线程,还没找见evil-yank有什么标志能控制这个线程启动的

1 个赞

删除创建线程的也修复了,对单独的evil-yank-XXX添加advice

;; (advice-add #'evil-yank :after #'fwar34/highlight-yank) ;; delete also use evil-yank
(advice-add #'evil-yank-rectangle :after #'fwar34/highlight-yank)
(advice-add #'evil-yank-lines :after #'fwar34/highlight-yank)
(advice-add #'evil-yank-characters :after #'fwar34/highlight-yank)

(advice-add #'lispyville-yank :after #'fwar34/highlight-yank)

晕 只注意高亮了,发现复制粘贴比较快的时候有问题,吧overlay好像也给粘贴了,还要再调整下。

知道原因了,应该是复制后立即在复制的region中粘贴(例如原地粘贴)后,overlay的region好像变大了,但是我的线程删除的overlay还是老的region。可以再粘贴前判断下是否有overlay,有的话,清除就行。我再调整下。

后来试了下不用再粘贴前移除自己添加的overlay,只要把线程中移除overlay的接口换成delete-overlay就可以,这个接口会删除整个overlay,而不是region的overlay

;;-------------------------------------------------------------
;; highlight yank region
;;-------------------------------------------------------------
(defface fwar34-hi-yellow
  '((((min-colors 88) (background dark))
     (:background "yellow1" :foreground "black"))
    (((background dark)) (:background "yellow" :foreground "black"))
    (((min-colors 88)) (:background "yellow1"))
    (t (:background "yellow")))
  "Default face for hi-lock mode.")

(defun fwar34/highlight-yank (beg end &rest _)
  (let ((overlay (make-overlay beg end)))
    (overlay-put overlay 'face 'fwar34-hi-yellow)
    (overlay-put overlay 'fwar34-flag t) ;; set my overlay flag
    (make-thread (lambda ()
                   (sleep-for 0 500)
                   ;; (remove-overlays beg end 'face 'fwar34-hi-yellow)))
                   (delete-overlay overlay)))
    ))
;; (advice-add #'evil-yank :after #'fwar34/highlight-yank) ;; evil-delete also use evil-yank
(advice-add #'evil-yank-rectangle :after #'fwar34/highlight-yank)
(advice-add #'evil-yank-lines :after #'fwar34/highlight-yank)
(advice-add #'evil-yank-characters :after #'fwar34/highlight-yank)

(advice-add #'lispyville-yank :after #'fwar34/highlight-yank)

当然也可以在粘贴前移除自己的overlay

(defun fwar34/remove-fwar34-overlay-before-paste (&rest _)
  (interactive)
  (let ((overlays (overlays-at (point))))
    (while overlays
      (let ((overlay (car overlays)))
        (when (overlay-get overlay 'fwar34-flag)
          (delete-overlay overlay)))
      (setq overlays (cdr overlays)))))
(advice-add #'evil-paste-before :after #'fwar34/remove-fwar34-overlay-before-paste)
(advice-add #'evil-paste-after :after #'fwar34/remove-fwar34-overlay-before-paste)