2

请问,测试特定待办事项状态和不等于今天的截止日期是否存在的最佳方法是什么?

org-state是一个“在 TODO 项的状态更改后运行的 [h]ook”。所以除非我真的改变了待办事项的状态,否则我认为我不能使用(string-equal org-state "Next Action"). string-equal下面列出的 每一行代码都被拒绝:Symbol's value as variable is void: org-todoorg-deadline. 截止日期是出现在待办事项状态下方的一条线,因此在测试这两个条件是否存在时也可能会造成问题。

(defun if-next-action-not-today-then-promote ()

(interactive)

    (goto-char (point-min))

    (while

    (re-search-forward "^\*\* Next Action" nil t)

        (when (and (string-equal org-todo "Next Action") (not (string-equal org-deadline "<%<%Y-%m-%d %a>>")) )

        (message "You have satisfied the two conditions . . . proceeding.")

        (org-todo "Active")  ;; change state to active

        (org-deadline nil "<%<%Y-%m-%d %a>>") ;; change deadline to today

         )

    )

)

示例 *.org 配置文件。

* TASKS

  ** Active [#A] First task due today. :lawlist:
     DEADLINE: <2013-07-11 Thu >

  ** Active [#A] Second task due today. :lawlist:
     DEADLINE: <2013-07-11 Thu >

  ** Next Action [#E] Test One -- make Active with deadline today. :lawlist:
     DEADLINE: <2013-07-31 Wed >

  ** Next Action [#E] Test Two -- make Active with deadline today. :lawlist:
     DEADLINE: <2013-07-31 Wed >

编辑:以下是 Jonathan Leech-Pepin 在下面的回答中提出的功能的修改。在答案的初稿中,由于存在问题,我无法从变量中获得任何东西-nil完全消除该引用似乎可以纠正问题。我沿途设置了消息,以便我可以更好地了解正在发生的事情。我使用而不是因为我想要一条消息让我知道条件不满足但该功能仍然正常工作。我已经运行了几个测试,包括将它包装到一个类型函数中,它工作得非常好——一个包装的函数可以通过多种方式完成,但这超出了这个线程的范围——例如,deadline(org-element-timestamp-interpreter . . . nil)ifunlesselsere-search-forward(&optional from-state to-state)然后(interactive)再往(setq . . .)下走;或(from-state to-state)(interactive (list (setq . . .)

(defun zin/org-test-deadline (from-state to-state)

"Change headline from FROM-STATE to TO-STATE if the deadline is not already set to today."

  (interactive "sChange from state: \nsChange to state: ")

    (unless (org-at-heading-p)
      (org-back-to-heading))

    (let* (

      (element (org-element-at-point))

      (todo-state (org-element-property :todo-keyword element))

      ;; "ignore-errors" avoids throwing an error message if there is no deadline.
      (deadline
        (ignore-errors
        (time-to-days
        (org-time-string-to-time
        (org-element-property :deadline element) ))))

      (today (time-to-days (current-time))) )

    (message "This is the element variable:  %s" element)

    (message "This is the today variable:  %s" today)

    (message "This is the deadline variable:  %s" deadline)

    (message "This is the todo-state variable:  %s" todo-state)

    (message "This is the from-state variable:  %s" from-state)

    (message "This is the to-state variable:  %s" to-state)

    (if (not (eq today deadline))
      (message "The deadline is not today.")
      (message "Today is the deadline."))

    (if (and
      (not (eq today deadline)) ;; condition -- deadline not equal to today
      (string= todo-state from-state) ) ;; condition -- todo-state equals from-state
        (progn ;; Process following list if conditions were met.
          (org-todo to-state)
          (org-deadline nil ".")
          (message "The conditions were met, so we did everything that was required.") )
      (message "The conditions were not met, so nothing has been done."))
  ))
4

1 回答 1

1

只要您使用Org 7.9.2或更大,以下应该可以工作。我通过调整截止日期和待办事项状态尽可能地对其进行了测试。

(defun zin/org-test-deadline (from-state to-state)
  "Change headline from FROM-STATE to TO-STATE if the deadline is
not already set to today."
  (interactive "sChange from state: \nsChange to state: ")
  (unless (org-at-heading-p)
    (org-back-to-heading))
  (let* ((element (org-element-at-point))
         (todo-state (org-element-property :todo-keyword
                                           element))
         ;; Do not give an error if there is no deadline
         (deadline (ignore-errors
                     (time-to-days
                      (org-time-string-to-time
                       (org-element-timestamp-interpreter
                        (org-element-property :deadline
                                              element) nil)))))
         (today (time-to-days (current-time))))
    (unless (or
             ;; Is there a deadline
             (not deadline)
             ;; Is the deadline today
             (eq today deadline)
             ;; Is the todo state the wrong one
             (not (string= todo-state from-state)))
      (org-todo to-state)
      (org-deadline nil "."))))

然后,您可以绑定 this 或将其包装在定义from-stateand的函数中to-state。如果以交互方式调用,它还将提示两种状态。

于 2013-07-12T12:42:39.283 回答