org-agenda-redo受Evil状态钩子影响导致global-hl-line-mode异常问题求助
问题描述
我用以下代码通过Evil状态钩子控制global-hl-line-mode,以此区分插入状态与普通状态:
(add-hook 'evil-insert-state-entry-hook (lambda () (global-hl-line-mode 0))) (add-hook 'evil-insert-state-exit-hook (lambda () (global-hl-line-mode 1)))
同时编写了自定义Org捕获函数:
(defun my/org-capture-idea () "Capture an idea..." (interactive) (org-capture nil "i") (org-save-all-org-buffers) (with-current-buffer "*Org Agenda*" ; 在议程缓冲区时刷新 (let ((hl-line global-hl-line-mode)) ; 尝试保存当前状态 (org-agenda-redo) ; 该函数会触发Evil钩子关闭global-hl-line-mode (when hl-line (global-hl-line-mode 1))))) ; 尝试恢复状态,但无效
单独测试保存/恢复状态的代码是有效的:
(let ((hl-line global-hl-line-mode)) (global-hl-line-mode 0) (when hl-line (global-hl-line-mode 1)))
但将这段逻辑放到my/org-capture-idea中后,执行org-agenda-redo无法保留global-hl-line-mode的原有状态,无论之前是开启还是关闭,最终都会被关掉。
解决方案
问题根源在于org-agenda-redo执行过程中,内部触发了Evil状态切换(比如临时进入插入状态再退出),导致你的钩子函数被调用,修改了global-hl-line-mode的状态——你用let保存的是执行前的初始状态,但中间钩子已经改变了实际状态,最后恢复的初始状态无法覆盖钩子的修改,因此逻辑失效。
以下是几种可行的解决方式:
方式一:临时禁用Evil钩子
在执行org-agenda-redo期间,临时移除控制global-hl-line-mode的钩子,执行完成后再恢复,避免钩子干扰状态:
(defun my/org-capture-idea () "Capture an idea..." (interactive) (org-capture nil "i") (org-save-all-org-buffers) (with-current-buffer "*Org Agenda*" (let ((hl-line global-hl-line-mode)) ;; 临时移除钩子 (remove-hook 'evil-insert-state-entry-hook #'(lambda () (global-hl-line-mode 0))) (remove-hook 'evil-insert-state-exit-hook #'(lambda () (global-hl-line-mode 1))) ;; 确保无论是否出错,钩子都会被恢复 (unwind-protect (org-agenda-redo) (add-hook 'evil-insert-state-entry-hook #'(lambda () (global-hl-line-mode 0))) (add-hook 'evil-insert-state-exit-hook #'(lambda () (global-hl-line-mode 1)))) ;; 恢复原始模式状态 (setq global-hl-line-mode hl-line) (global-hl-line-mode (if hl-line 1 0)))))
方式二:让钩子跳过Org Agenda缓冲区
修改钩子函数,只在非Org Agenda缓冲区生效,避免干扰特殊缓冲区的状态:
(add-hook 'evil-insert-state-entry-hook (lambda () (unless (string-match-p "\\*Org Agenda\\*" (buffer-name)) (global-hl-line-mode 0)))) (add-hook 'evil-insert-state-exit-hook (lambda () (unless (string-match-p "\\*Org Agenda\\*" (buffer-name)) (global-hl-line-mode 1))))
修改后,你的原始my/org-capture-idea函数无需改动,就能正常保留global-hl-line-mode的状态。
内容的提问来源于stack exchange,提问作者maxfriis
相关产品推荐
相关产品推荐

