2011-11-07 1 views
3

LOGBOOKの時間エントリに基づいてTODOアイテムを見つけるカスタムアジェンダ検索を作成したいと思います。具体的には、待機状態のエントリをマークしたタイムスタンプに基づいて、WAITINGというタグが付けられた項目を検索したいと思います。これらのエントリは次のようになります。org-modeのLOGBOOKでタイムスタンプを使用したカスタム検索

:LOGBOOK: 
- State "WAITING"  from "TODO" [2011-11-02 Wed 15:10] \\ 
    Emailed so-and-so about such-and-such. 
:END: 

ログブックの情報でこれを行うことはできますか?私はバージョン7.5を使用していますが、必要に応じてアップグレードできます。

ありがとうございます!

編集:1つのユースケースは、1週間以上待っている待機中のtodoを見つけることです。 (これは通常、誰かに再度バグを起こさなければならないことを意味します)。

+0

ログブックに基づいて具体的な理由はありますか?アイテムが現在「待ち」している場合は、それに基づいてカスタム検索を行うことができます。私は、ここでのアーカイブ方法から何かを適応させることができると思われる:http://doc.norang.ca/org-mode.html#sec-12-2。一致するパラメータを "State \" WAITING \ ""と一致するように調整してください。私はそれをタイムスタンプだけに基づいて分類する方法と、含まれる他のものに分類する方法は特定できませんが。 –

+0

ユースケースの1つは、1週間以上前に待機状態に入ったアイテムを見つけることです。私のtodoセットアップは、開始する場所のように見えるログブックにWAITING状態に入った時刻を記録しているので、私は他のアプローチにもオープンしています。 –

+0

あなたが一致させたいと思っているLOGBOOKの時間入力は常に最新のものでしょうか?それは最新のログエントリでなければならないか、それ以降(更新に関係なく)その見出しのすべてのログブックエントリに一致する必要があります。最近のLOGBOOKエントリに一致させたいだけだと思っています。そうしないと、あなたのユースケースと一致しません。 –

答えて

3

以下は、必要なものです。ユースケースに合わせてカスタムアジェンダコマンドを調整するだけで済みます。 (私はTODOのキーワードを使用してそれをテストし、構成するとき)。このコードの一部は、組み込みのorg関数の作業を重複させる可能性があります。これは、ScheduledおよびDeadlineのアプローチ/延期の動作に似ていますが、再利用可能な特定の関数を見ることができませんでした。

カスタムコマンドで実際に使用する機能は次のとおりです。

(defun zin/since-state (since todo-state &optional done all) 
    "List Agenda items that are older than SINCE. 

TODO-STATE is a regexp for matching to TODO states. It is provided to 
`zin/find-state' to match inactive timestamps. 
SINCE is compared to the result of `zin/org-date-diff'. If 
`zin/org-date-diff' is greater than SINCE, the entry is shown in the 
Agenda. 
Optional argument DONE allows for done and not-done headlines to be 
evaluated. If DONE is non-nil, match completed tasks. 
Optional argument ALL is passed to `zin/find-state' to specify whether 
to search for any possible match of STATE, or only in the most recent 
log entry." 
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))) 
    ;; If DONE is non-nil, look for done keywords, if nil look for not-done 
    (if (member (org-get-todo-state) 
       (if done 
        org-done-keywords 
        org-not-done-keywords)) 
     (let* ((subtree-end (save-excursion (org-end-of-subtree t))) 
       (subtree-valid (save-excursion 
           (forward-line 1) 
           (if (and (< (point) subtree-end) 
             ;; Find the timestamp to test 
             (zin/find-state todo-state subtree-end all)) 
            (let ((startpoint (point))) 
            (forward-word 3) 
            ;; Convert timestamp into days difference from today 
            (zin/org-date-diff startpoint (point))))))) 
      (if (or (not subtree-valid) 
        (<= subtree-valid since)) 
       next-headline 
      nil)) 
     (or next-headline (point-max))))) 

次の関数は、再検索フォワードによってログブックエントリを検出します。

(defun zin/find-state (state &optional end all) 
    "Used to search through the logbook of subtrees. 

Tests to see if the first line of the logbook is a change of todo 
status to status STATE 
- Status \"STATE\" from ... 
The search brings the point to the start of YYYY-MM-DD in inactive timestamps. 

Optional argument END defines the point at which to stop searching. 
Optional argument ALL when non-nil specifies to look for any occurence 
of STATE in the subtree, not just in the most recent entry." 
    (let ((drawer (if all "" ":.*:\\W"))) 
    (re-search-forward (concat drawer ".*State \\\"" state "\\\"\\W+from.*\\[") end t))) 

最後の関数は、上記の関数によって検出された今日とタイムスタンプの日数の差を決定します。

(defun zin/org-date-diff (start end &optional compare) 
    "Calculate difference between selected timestamp to current date. 

The difference between the dates is calculated in days. 
START and END define the region within which the timestamp is found. 
Optional argument COMPARE allows for comparison to a specific date rather than to current date." 
    (let* ((start-date (if compare compare (calendar-current-date)))) 
    (- (calendar-absolute-from-gregorian start-date) (org-time-string-to-absolute (buffer-substring-no-properties start end))) 
    )) 

上記の機能を使用する2つのサンプルカスタムアジェンダコマンド。最初はあなたのユースケースにマッチしますが、正しいキーワードにマッチさせるには、単に「PEND」を「WAITING」に変更するだけです。 2番目のキーワードは、30日以上前に完了したDONEキーワードを検索します(最初のコメントでリンクした例で行ったように、この/前月に一致する月を持つタイムスタンプを探すのとは対照的です)。ジョナサン・リーチ・ピピンの答えに加えて

(setq org-agenda-custom-commands 
     (quote (("T" "Tasks that have been pending more than 7 days." tags "-REFILE/" 
       ((org-agenda-overriding-header "Pending tasks") 
       (org-agenda-skip-function '(zin/since-state 7 "PEND")))) 
       ("A" "Tasks that were completed more than 30 days ago." tags "-REFILE/" 
       ((org-agenda-overriding-header "Archivable tasks") 
       (org-agenda-skip-function '(zin/since-state 30 "\\\(DONE\\\|CANC\\\)" t)))) 
      ))) 
+0

ありがとう!これはまさに私が必要とするもののように見えます。残念ながら、組み込み関数の中には有用ではないものがありました。これは一般的な使用例のようです。また、zin/find-stateに渡される追加の引数 'all'があります。これを削除すると、コードが正しく機能しました。 –

+0

実際、 'zin/since-state'からの' zin/find-state'への呼び出しでは余分な 't'です。デフォルトではnilに設定されているので、議題コマンド自体から 't'を渡す必要があります(ALLが' t'の場合は、誤った陽性を生成するログブック内の最新のものだけでなく、私は答えの価値を修正します。 –

1

あなたは(setq org-log-done 'time)設定によって追加CLOSED:引き出しを見たい場合は、あなたがこのようなzin/find-state機能向上させることができます。

(defun zin/find-state (state &optional end all) 
    (let ((drawer (if all "" ":.*:\\W" "CLOSED:"))) 
    (or (re-search-forward (concat drawer ".*State \\\"" state "\\\"\\W+from.*\\[") end t) 
     (re-search-forward (concat drawer ".*\\[") end t)))) 

PSを:これはちょうどです答えの改善、正解はジョナサンの答えです。

関連する問題