Emacs 在todo state change hook之后,对带有指定标记的条目在组织上执行代码

Emacs 在todo state change hook之后,对带有指定标记的条目在组织上执行代码,emacs,elisp,org-mode,Emacs,Elisp,Org Mode,我有一些组织文件,内容如下: * HOLD Some todo heading :project: #+BEGIN_SRC shell grunt watch #+END_SRC * TODO Some other heading :test: #+BEGIN_SRC emacs-lisp (message "TEST") #+END_SRC 我想在时钟输入时从HOLD切换到INPROGRESS状态。这很简单,我明白了 然

我有一些组织文件,内容如下:

* HOLD Some todo heading             :project:
  #+BEGIN_SRC shell
  grunt watch
  #+END_SRC
* TODO Some other heading             :test:
  #+BEGIN_SRC emacs-lisp
  (message "TEST")
  #+END_SRC
我想在时钟输入时从
HOLD
切换到
INPROGRESS
状态。这很简单,我明白了

然后在todo state change hook之后的
org上,我想执行条目中包含的代码,但只执行特定标记上的代码

因此,我得到:

(defun tester/after-change-hook()
  "Test function on hook."
  (when (string= org-state "INPROGRESS") 

    ;; DO SOMETHING on entry with 'project' tag

    ;; DO SOMETHING on entry with 'test' tag

    ;; MAYBE TRY TO EXECUTE CODE ON entry with 'project' tag

    ;; MAYBE TRY TO EXECUTE CODE ON entry with 'test' tag

  )
)
(add-hook 'org-after-todo-state-change-hook 'tester/after-change-hook)
不幸的是,我不知道如何编写函数来在特定标记上执行代码或在特定标记上执行内联代码

我一直在尝试使用
组织扫描标记
函数或
组织元素映射

我看得出来

但不幸的是,所有这些口齿不清的东西对我来说就像一个黑魔法。 我不知道如何编写函数来测试当前计时任务上的标记。 有人能帮我学习一下lisp语法吗? 理论上,我知道做我想做的事情需要哪些函数。
在现实生活中,我不知道如何用lisp编写它。

匹配标记列表中成员的一种方法是使用类似
(成员“test”标记)
——请参见下面的示例,其中名为
test
的标记的出现将产生祝贺消息,或者,如果名为
test
的标签不存在,则显示一条钓鱼信息。您还可以使用regexp来匹配整个单词或部分单词,但这超出了本示例的范围


下面是一个4步方法来测试下面的示例。[该示例由@lawlist使用Org版本8.2.5c进行测试。]

  • (1)将我的整个代码复制并粘贴到您的
    .emacs
    文件中;保存文件;然后,重新启动Emacs

  • (2)打开一个新缓冲区并键入:

    * This is a task. :test:lawlist:
    
  • (3)
    M-x组织模式

  • (4)将光标放在刚键入的行上的任意位置,然后:
    M-x示例

一旦您启动并运行了这个示例(不做任何修改),您就可以慢慢地进行自己的修改——在过程中的各个阶段继续测试您的新代码,这样您的代码中的任何错误都不会失控(这将使调试变得更加困难)



不幸的是,我不能用你的例子。我无法发送任何标签。问题是,我只是不知道如何获得当前任务…'对象'?我无法获取'element',因为我收到消息:“保存偏移:符号的函数定义为void:element”。如果您有较旧版本的
组织模式
,您可能需要将其添加到
.emacs
文件:
(需要'org element)
。我将把它添加到我的示例中。我在答案中添加了步骤1到步骤4,让您开始——我删除了我之前的简短评论,基本上说了同样的话。我使用的
let
绑定术语
元素
取决于上面定义它在点
处等于
org元素。你是对的。非常感谢你。我的测试代码中有个bug。我必须更好地理解“let”的功能,现在我得到了它的功能。正如我所看到的,我可以硬编码一些标记并测试它是否是标记列表的成员,而不是放一些其他代码或lambda来代替消息。还有一个问题是:如果在源代码块中定义了,如何解析条目内容和运行shell代码?我建议组合一个尝试函数示例,并针对shell代码和源代码块问题打开一个新问题。一旦我能更准确地理解被搜索的东西是什么样子,我可能也会尝试回答这个问题……:)我看到我把这个条件缩进得有点太多了,也许这是你困惑的一部分——我会把它缩进一级——这可能会帮助以后阅读这篇文章的其他人。
(require 'org)

(require 'org-element)

(defun example ()
(interactive)
  (save-excursion
    (org-back-to-heading t)
    (let* (
        (element (org-element-at-point))
        (title (org-element-property :title element))
        (tags (org-element-property :tags element)))
      (cond
        ((and
            (equal title "")
            (not (equal tags nil)))
          (error "The `title` cannot be blank."))
        ((and
            (equal tags nil)
            (not (equal title "")))
          (error "The `tags` cannot be blank."))
        ((and
            (equal title "")
            (equal tags nil))
          (error "The `title` and `tags` cannot be blank."))
        ((and
            (not (equal tags nil))
            (not (equal title "")))
          (message "TITLE:  %s  |  TAG(S):  %s" title tags)
          (if (member "test" tags)
            (message "Congratulations:  You found a match.")
            (message "Uh-oh -- no match -- go fish!")))  ))))