reddit / emacs

Using pcase-let to get elements from nested structure

pragmat1c1 路 2022-05-13 11:08
I am looking at the text properties of an `org-ql-search` results buffer by running this: `(setq text-props (text-properties-at (point)))` Now looking at `text-props` (pasted below), I see a deeply nested list that has all sorts of information. Now I am trying to get one specific info [1] out of it using `pcase-let`, but without success. This is how I try it: ``` (pcase-let ((`(:CREATED ,date) text-props)) (message "Contains %S" date)) ``` [1] This is what I want to get: `"[2022-05-03 Tue 19:06]"` from this `:CREATED "[2022-05-03 Tue 19:06]"` ## Text properties with deelpy nested structure (wrap-prefix # (" " 0 2 (org-habit-p nil todo-state # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) org-agenda-type search org-hd-marker #<marker at 795 in prm.org> org-marker #<marker at 795 in prm.org> title (# ("Stefan fragen, ob was unternehmen" 0 33 (:parent (headline (:raw-value # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) :begin 795 :end 842 :pre-blank 0 :contents-begin 843 :contents-end 843 :level 3 :priority 69 :tags nil :todo-keyword # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) :todo-type done :post-blank 1 :footnote-section-p nil :archivedp nil :commentedp nil :post-affiliated 795 :closed (timestamp (:type inactive :raw-value "[2022-05-13 Fri 12:04]" :year-start 2022 :month-start 5 :day-start 13 :hour-start 12 :minute-start 4 :year-end 2022 :month-end 5 :day-end 13 :hour-end 12 :minute-end 4 :begin 851 :end 874 :post-blank 1)) :scheduled (timestamp (:type active :raw-value "<2022-05-13 Fri>" :year-start 2022 :month-start 5 :day-start 13 :hour-start nil :minute-start nil :year-end 2022 :month-end 5 :day-end 13 :hour-end nil :minute-end nil :begin 885 :end 901 :post-blank 0)) :CREATED "[2022-05-03 Tue 19:06]" :title # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) :org-marker #<marker at 795 in prm.org> :org-hd-marker #<marker at 795 in prm.org> :relative-due-date # ("today" 0 5 (help-echo "<2022-05-13 Fri>" face org-ql-view-due-date))))))) CREATED "[2022-05-03 Tue 19:06]" scheduled (timestamp (:type active :raw-value "<2022-05-13 Fri>" :year-start 2022 :month-start 5 :day-start 13 :hour-start nil :minute-start nil :year-end 2022 :month-end 5 :day-end 13 :hour-end nil :minute-end nil :begin 885 :end 901 :post-blank 0)) closed (timestamp (:type inactive :raw-value "[2022-05-13 Fri 12:04]" :year-start 2022 :month-start 5 :day-start 13 :hour-start 12 :minute-start 4 :year-end 2022 :month-end 5 :day-end 13 :hour-end 12 :minute-end 4 :begin 851 :end 874 :post-blank 1)) post-affiliated 795 commentedp nil archivedp nil footnote-section-p nil post-blank 1 todo-type done todo-keyword # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) tags nil priority 69 level 3 contents-end 843 contents-begin 843 pre-blank 0 end 842 begin 795 raw-value # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) fontified t)) fontified t raw-value # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) begin 795 end 842 pre-blank 0 contents-begin 843 contents-end 843 level 3 priority 69 tags nil todo-keyword # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) todo-type done post-blank 1 footnote-section-p nil archivedp nil commentedp nil post-affiliated 795 closed (timestamp (:type inactive :raw-value "[2022-05-13 Fri 12:04]" :year-start 2022 :month-start 5 :day-start 13 :hour-start 12 :minute-start 4 :year-end 2022 :month-end 5 :day-end 13 :hour-end 12 :minute-end 4 :begin 851 :end 874 :post-blank 1)) scheduled (timestamp (:type active :raw-value "<2022-05-13 Fri>" :year-start 2022 :month-start 5 :day-start 13 :hour-start nil :minute-start nil :year-end 2022 :month-end 5 :day-end 13 :hour-end nil :minute-end nil :begin 885 :end 901 :post-blank 0)) CREATED "[2022-05-03 Tue 19:06]" title (# ("Stefan fragen, ob was unternehmen" 0 33 (:parent (headline (:raw-value # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) :begin 795 :end 842 :pre-blank 0 :contents-begin 843 :contents-end 843 :level 3 :priority 69 :tags nil :todo-keyword # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) :todo-type done :post-blank 1 :footnote-section-p nil :archivedp nil :commentedp nil :post-affiliated 795 :closed (timestamp (:type inactive :raw-value "[2022-05-13 Fri 12:04]" :year-start 2022 :month-start 5 :day-start 13 :hour-start 12 :minute-start 4 :year-end 2022 :month-end 5 :day-end 13 :hour-end 12 :minute-end 4 :begin 851 :end 874 :post-blank 1)) :scheduled (timestamp (:type active :raw-value "<2022-05-13 Fri>" :year-start 2022 :month-start 5 :day-start 13 :hour-start nil :minute-start nil :year-end 2022 :month-end 5 :day-end 13 :hour-end nil :minute-end nil :begin 885 :end 901 :post-blank 0)) :CREATED "[2022-05-03 Tue 19:06]" :title # ("Stefan fragen, ob was unternehmen" 0 33 (face org-scheduled-today)) :org-marker #<marker at 795 in prm.org> :org-hd-marker #<marker at 795 in prm.org> :relative-due-date # ("today" 0 5 (help-echo "<2022-05-13 Fri>" face org-ql-view-due-date))))))) org-marker #<marker at 795 in prm.org> org-hd-marker #<marker at 795 in prm.org> org-agenda-type search todo-state # ("DONE" 0 4 (fontified t org-todo-head # ("TODO" 0 4 (face org-todo)) org-category "馃搰 PRM" wrap-prefix " " line-prefix # ("**" 0 2 (face org-indent)) face org-done)) org-habit-p nil)
_viz_ 路 2022-05-13 11:21
Please indent the lines by four spaces instead of using triple backquotes to enclose them in a codeblock. This way, everyone can see it.
pragmat1c1 路 2022-05-13 11:23
Done
akirakom 路 2022-05-13 11:27
You could use this instead: (org-with-point-at (get-text-property (point) 'org-hd-marker) (org-entry-get nil "CREATED"))
[deleted] 路 2022-05-13 11:31
[deleted]
pragmat1c1 路 2022-05-13 11:31
>(org-with-point-at (get-text-property (point) 'org-hd-marker) (org-entry-get nil "CREATED")) Thank you. That works. But I was trying to understand `pcase-let`. Nontheless: Trying to understand your code, I run this first: `(get-text-property (point) 'org-hd-marker)` results in `nil` (with cursor on a headline in an org file). Wondering why.
usaoc 路 2022-05-13 15:12
[Quasipatterns](https://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote-Patterns.html) match exactly as you specify, no more and no less. In your case, the quasipattern is `(:CREATED ,date)`, which matches a list of two elements whose `car` is `:CREATED` and binds its `cadr` to `date`.
7890yuiop 路 2022-05-14 11:34
I have to say that this surprised me: (pcase-let ((`(:CREATED ,date) '(foo bar baz))) (message "Contains %S" date)) "Contains bar" I see that it's documented -- with `pcase-let` you are *required* to pass a data structure which is an exact match for your patterns, as it will not attempt to validate it, and the outcome in the presence of mis-matches is undefined. It's just not what I expected it to be. As one can bind variables with plain `pcase` as well, doing that may be safer.
usaoc 路 2022-05-14 11:48
Huh, interesting. It seems that `pcase-let*` and friends currently `ignore` all tests. Thanks for reminding me.
yantar92 路 2022-05-14 11:51
> Trying to understand your code, I run this first: (get-text-property (point) 'org-hd-marker) results in nil (with cursor on a headline in an org file). Wondering why. Because 'org-hd-marker property is the way agenda (and org-ql, copying agenda behaviour) stores reference to original headline from the text in agenda buffer. There is not such property outside agenda/org-ql buffer.