新手想转向 purcell 配置

原本在 doom 中用的很好的函数,到 purcell 配置中报错。(可能是小白问题,但是实在是不知道从哪里搜起)

;; Copy Done To-Dos to Today
(defun my/org-roam-copy-todo-to-today ()
  (interactive)
  (let ((org-refile-keep t) ;; Set this to nil to delete the original!
        (org-roam-dailies-capture-templates
          '(("t" "tasks" entry "%?"
             :if-new (file+head+olp "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n#+ARCHIVE: journal.org::\n" ("%<%Y-%m-%d>" "Tasks")))))
        (org-after-refile-insert-hook #'save-buffer)
        today-file
        pos)
    (save-window-excursion
      (org-roam-dailies--capture (current-time) t)
      (setq today-file (buffer-file-name))
      (setq pos (point)))

    ;; Only refile if the target file is different than the current file
    (unless (equal (file-truename today-file)
                   (file-truename (buffer-file-name)))
      (org-refile nil nil (list "Tasks" today-file nil pos)))))

(add-to-list 'org-after-todo-state-change-hook
             (lambda ()
               ;; DONE 和 CANCELLED 的 To-Dos 自动复制到今日
               ;; 同时过滤掉 habit 的 To-Dos
               (when (and (or (equal org-state "DONE") (equal org-state "CANCELLED")) (not (org-find-property "STYLE")))
                 (my/org-roam-copy-todo-to-today))))

报错信息如下:

symbol’s value as variable is void org-after-todo-state-change-hook

可能是加载顺序的问题,运行这段代码的时候还没加载org-after-todo-state-change-hook

我用了很久的 Purcell 配置,挺好用的。

你的问题应该是因为没加载 org-mode。把你的代码放在 with-eval-after-load 里面应该就可以了。 比如:

(with-eval-after-load 'org
;; 你的代码
  )

加进入了,不报错了,但是在 To-Dos 状态变更时没有触发。 :innocent:

别转了,doom挺好的。我兜兜转转还是回到了doom。

:joy:,doom 是挺好的,就是混着 vim 和 emacs 的快捷键不太爽。比如 C-p 和 C-n 就变成了 company 的快捷键了,本来是移动光标的。

我这边测试了下,可以触发函数啊。

你 C-h v org-after-todo-state-change-hook 看看这个变量的值是什么?看看是不是你的函数。

结局就是自己攒一套配置,及早开始吧

1 个赞

从你的截图看,org-after-todo-state-change-hook 已经生效了,已经加入了你的匿名函数。

你只能自己去诊断 my/org-roam-copy-todo-to-today 函数是否正常运行了,你可以在你函数里面加一些显示消息来帮助诊断。

好的,麻烦您了,我自己再看看。

好奇怪,debug 了一下发现 my/org-roam-copy-todo-to-today 也是被调用了的,走完了的。。。

可以用单步调试再分析下

感觉有几个原因

  1. TODO 变为 DONE 状态的时候 modeline 输出的是 Note Stored,就没有调用 hook。
  2. 变为 HOLD 的时候成功调用了 hook,但是报错 defining as dynamic an already lexical var: org-roam-dailies-capture-templates

你说的和你代码写的正好反了,代码是:如果不是habit的TODO项,只有切换到DONECANCELLED,才会调用my/org-roam-copy-todo-to-today,其他都不会调用。代码是没问题的,建议提供个能复现的最小配置。

这些应该够了

(when *is-a-mac*
  (maybe-require-package 'grab-mac-link))

(require 'org)
(require 'org-agenda)
;; Files
(setq org-agenda-files (file-expand-wildcards "~/Dropbox/org/agenda/*.org"))

(setq org-todo-keywords
      '((sequence "TODO(t)" "NEXT(n!)" "HOLD(h@/!)" "|" "DONE(d!)")
        (sequence "WAITING(w@/!)" "|" "CANCELLED(c@/!)")))

(with-eval-after-load 'org
  ;; Copy Done To-Dos to Today
(defun my/org-roam-copy-todo-to-today ()
  (interactive)
  (let ((org-refile-keep t) ;; Set this to nil to delete the original!
        (org-after-refile-insert-hook #'save-buffer)
        today-file
        pos)
    (save-window-excursion
      (org-roam-dailies--capture (current-time) t)
      (setq today-file (buffer-file-name))
      (setq pos (point)))

    ;; Only refile if the target file is different than the current file
    (unless (equal (file-truename today-file)
                   (file-truename (buffer-file-name)))
      (org-refile nil nil (list "Tasks" today-file nil pos)))))

(add-to-list 'org-after-todo-state-change-hook
             (lambda ()
               ;; DONE 和 CANCELLED 的 To-Dos 自动复制到今日
               ;; 同时过滤掉 habit 的 To-Dos
               (when (and (or (equal org-state "HOLD") (equal org-state "CANCELLED")) (not (org-find-property "STYLE")))
                 (my/org-roam-copy-todo-to-today))))
)

(provide 'init-org)

这里的 org-roam-dailies--capture 函数在 Doom 里面是可以成功调用的,org-roam 中的。但是在 vanilla emacs 里面就不行,找不到这个函数。

另外我把 org-roam-dailies--capture 函数改成 org-roam-dailies-capture-today 之后,是报defining as dynamic an already lexical var: org-roam-dailies-capture-templates 这个应该是这里不能用 let,但水平有限,不知道咋改😂可能要学习一下 elisp,主要是 today-filepos 不知道什么意思,前面的都是赋值。

这是还没加载,require 一下就可以了,根据你上面的代码在emacs -Q下无法复现,能正常工作。

这两个就是你前面定义的变量,前者是今天的org-roam-dailies文件,后者是文件里的光标位置。

(org-refile nil nil (list "Tasks" today-file nil pos))

这句的意思是把当前的TODO项复制到今天的org-roam-dailies文件中的Task项下面。具体可以看org-refile的doc

好的,太感谢了,我今晚再看看。

我始终不行,我换了个 capture- today 的函数,相比较之前那个函数多了一个选择模版的步骤,不过也能用,非常感谢耐心的解答。