You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 09:14:52