* Re: org-open-link-from-string in a program
2013-08-03 8:46 org-open-link-from-string in a program Eric Abrahamsen
@ 2013-08-03 9:18 ` Thorsten Jolitz
2013-08-03 10:26 ` Eric Abrahamsen
2013-08-04 4:21 ` Eric Abrahamsen
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: Thorsten Jolitz @ 2013-08-03 9:18 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I'm trying to write a small function that programmatically follows a
> link to a gnus message, then calls
> `gnus-summary-wide-reply-with-original' to start a reply to that
> message. It seemed like `org-open-link-from-string' (after extracting
> the address part from the link) would be the right choice, but I'm
> seeing odd behavior.
>
> When gnus sets up the reply buffer it also adds several hooks and
> actions for restoring windows and marking messages as responded-to, etc,
> and these hooks and actions depend on the value of (current-buffer) when
> the reply was initiated. That's supposed to be the gnus summary buffer.
>
> When I call all this from a function, however, (current-buffer)
> continues to return the org buffer I started in, even after the link was
> opened, which confuses gnus, and me. What I mean is this:
>
> (let ((addr the-address-part-of-the-link))
> (org-open-link-from-string addr)
> (message "%s" (current-buffer)) ; returns the org buffer I started in
> (call-interactively
> 'gnus-summary-wide-reply-with-original))
>
> There must be something I'm misunderstanding about how buffers work when
> you're doing something non-interactive. If I manually eval the
> org-open-link-from-string statement, I end up in the summary buffer,
> obviously, and all works fine.
#+begin_src emacs-lisp
(defun org-open-link-from-string (s &optional arg reference-buffer)
"Open a link in the string S, as if it was in Org-mode."
[...snip...]
(org-open-at-point arg reference-buffer)))))
#+end_src
,----------------------------------------------------------------------
| org-open-at-point is an interactive Lisp function in `org.el'.
|
| (org-open-at-point &optional ARG REFERENCE-BUFFER)
|
| Open link at or after point.
| If there is no link at point, this function will search forward up to
| the end of the current line.
| Normally, files will be opened by an appropriate application. If the
| optional prefix argument ARG is non-nil, Emacs will visit the file.
| With a double prefix argument, try to open outside of Emacs, in the
| application the system uses for this file type.
`----------------------------------------------------------------------
Maybe because you call
,---------------------------------
| (org-open-link-from-string addr)
`---------------------------------
without ARG, Emacs is not visiting the file and thus its buffer does not
become current?
Anyway, when you're done - please share, this is quite interesting.
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 9:18 ` Thorsten Jolitz
@ 2013-08-03 10:26 ` Eric Abrahamsen
2013-08-03 10:56 ` Thorsten Jolitz
0 siblings, 1 reply; 9+ messages in thread
From: Eric Abrahamsen @ 2013-08-03 10:26 UTC (permalink / raw)
To: emacs-orgmode
Thorsten Jolitz <tjolitz@gmail.com> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> I'm trying to write a small function that programmatically follows a
>> link to a gnus message, then calls
>> `gnus-summary-wide-reply-with-original' to start a reply to that
>> message. It seemed like `org-open-link-from-string' (after extracting
>> the address part from the link) would be the right choice, but I'm
>> seeing odd behavior.
>>
>> When gnus sets up the reply buffer it also adds several hooks and
>> actions for restoring windows and marking messages as responded-to, etc,
>> and these hooks and actions depend on the value of (current-buffer) when
>> the reply was initiated. That's supposed to be the gnus summary buffer.
>>
>> When I call all this from a function, however, (current-buffer)
>> continues to return the org buffer I started in, even after the link was
>> opened, which confuses gnus, and me. What I mean is this:
>>
>> (let ((addr the-address-part-of-the-link))
>> (org-open-link-from-string addr)
>> (message "%s" (current-buffer)) ; returns the org buffer I started in
>> (call-interactively
>> 'gnus-summary-wide-reply-with-original))
>>
>> There must be something I'm misunderstanding about how buffers work when
>> you're doing something non-interactive. If I manually eval the
>> org-open-link-from-string statement, I end up in the summary buffer,
>> obviously, and all works fine.
>
> #+begin_src emacs-lisp
> (defun org-open-link-from-string (s &optional arg reference-buffer)
> "Open a link in the string S, as if it was in Org-mode."
> [...snip...]
> (org-open-at-point arg reference-buffer)))))
> #+end_src
>
> ,----------------------------------------------------------------------
> | org-open-at-point is an interactive Lisp function in `org.el'.
> |
> | (org-open-at-point &optional ARG REFERENCE-BUFFER)
> |
> | Open link at or after point.
> | If there is no link at point, this function will search forward up to
> | the end of the current line.
> | Normally, files will be opened by an appropriate application. If the
> | optional prefix argument ARG is non-nil, Emacs will visit the file.
> | With a double prefix argument, try to open outside of Emacs, in the
> | application the system uses for this file type.
> `----------------------------------------------------------------------
>
> Maybe because you call
>
> ,---------------------------------
> | (org-open-link-from-string addr)
> `---------------------------------
>
> without ARG, Emacs is not visiting the file and thus its buffer does not
> become current?
Huh, interesting -- I had looked at that function, and assumed that the
what the arg did was to force a file that might otherwise be opened by
an external process to be opened in emacs. I still think that's what it
means (and adding a '(4) doesn't solve the problem), but there's other
stuff in there that might lead to a solution.
> Anyway, when you're done - please share, this is quite interesting.
I will! It's pretty much done, except for this one little bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 10:26 ` Eric Abrahamsen
@ 2013-08-03 10:56 ` Thorsten Jolitz
2013-08-03 11:04 ` Eric Abrahamsen
0 siblings, 1 reply; 9+ messages in thread
From: Thorsten Jolitz @ 2013-08-03 10:56 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>
>>> I'm trying to write a small function that programmatically follows a
>>> link to a gnus message, then calls
>>> `gnus-summary-wide-reply-with-original' to start a reply to that
>>> message. It seemed like `org-open-link-from-string' (after extracting
>>> the address part from the link) would be the right choice, but I'm
>>> seeing odd behavior.
[...]
>> #+begin_src emacs-lisp
>> (defun org-open-link-from-string (s &optional arg reference-buffer)
>> "Open a link in the string S, as if it was in Org-mode."
>> [...snip...]
>> (org-open-at-point arg reference-buffer)))))
>> #+end_src
>>
>> ,----------------------------------------------------------------------
>> | org-open-at-point is an interactive Lisp function in `org.el'.
>> |
>> | (org-open-at-point &optional ARG REFERENCE-BUFFER)
>> |
>> | Open link at or after point.
>> | If there is no link at point, this function will search forward up to
>> | the end of the current line.
>> | Normally, files will be opened by an appropriate application. If the
>> | optional prefix argument ARG is non-nil, Emacs will visit the file.
>> | With a double prefix argument, try to open outside of Emacs, in the
>> | application the system uses for this file type.
>> `----------------------------------------------------------------------
>>
>> Maybe because you call
>>
>> ,---------------------------------
>> | (org-open-link-from-string addr)
>> `---------------------------------
>>
>> without ARG, Emacs is not visiting the file and thus its buffer does not
>> become current?
>
> Huh, interesting -- I had looked at that function, and assumed that the
> what the arg did was to force a file that might otherwise be opened by
> an external process to be opened in emacs. I still think that's what it
> means (and adding a '(4) doesn't solve the problem), but there's other
> stuff in there that might lead to a solution.
Yes, you are right about the meaning of ARG, I should have looked twice.
>> Anyway, when you're done - please share, this is quite interesting.
>
> I will! It's pretty much done, except for this one little bug.
I can imagine that this is very useful for managing phonecalls to be
made in the future...
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 10:56 ` Thorsten Jolitz
@ 2013-08-03 11:04 ` Eric Abrahamsen
2013-08-03 11:18 ` Thorsten Jolitz
0 siblings, 1 reply; 9+ messages in thread
From: Eric Abrahamsen @ 2013-08-03 11:04 UTC (permalink / raw)
To: emacs-orgmode
Thorsten Jolitz <tjolitz@gmail.com> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> Thorsten Jolitz <tjolitz@gmail.com> writes:
>>
>>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>>
>>>> I'm trying to write a small function that programmatically follows a
>>>> link to a gnus message, then calls
>>>> `gnus-summary-wide-reply-with-original' to start a reply to that
>>>> message. It seemed like `org-open-link-from-string' (after extracting
>>>> the address part from the link) would be the right choice, but I'm
>>>> seeing odd behavior.
>
> [...]
>
>>> #+begin_src emacs-lisp
>>> (defun org-open-link-from-string (s &optional arg reference-buffer)
>>> "Open a link in the string S, as if it was in Org-mode."
>>> [...snip...]
>>> (org-open-at-point arg reference-buffer)))))
>>> #+end_src
>>>
>>> ,----------------------------------------------------------------------
>>> | org-open-at-point is an interactive Lisp function in `org.el'.
>>> |
>>> | (org-open-at-point &optional ARG REFERENCE-BUFFER)
>>> |
>>> | Open link at or after point.
>>> | If there is no link at point, this function will search forward up to
>>> | the end of the current line.
>>> | Normally, files will be opened by an appropriate application. If the
>>> | optional prefix argument ARG is non-nil, Emacs will visit the file.
>>> | With a double prefix argument, try to open outside of Emacs, in the
>>> | application the system uses for this file type.
>>> `----------------------------------------------------------------------
>>>
>>> Maybe because you call
>>>
>>> ,---------------------------------
>>> | (org-open-link-from-string addr)
>>> `---------------------------------
>>>
>>> without ARG, Emacs is not visiting the file and thus its buffer does not
>>> become current?
>>
>> Huh, interesting -- I had looked at that function, and assumed that the
>> what the arg did was to force a file that might otherwise be opened by
>> an external process to be opened in emacs. I still think that's what it
>> means (and adding a '(4) doesn't solve the problem), but there's other
>> stuff in there that might lead to a solution.
>
> Yes, you are right about the meaning of ARG, I should have looked twice.
>
>>> Anyway, when you're done - please share, this is quite interesting.
>>
>> I will! It's pretty much done, except for this one little bug.
>
> I can imagine that this is very useful for managing phonecalls to be
> made in the future...
Well this will only cover composing and replying to emails, but if you
have a function that automatically makes a phone call, I suppose it
would serve as a template...
Mostly I'm doing it because a full half of my work seems to be replying
to interminable emails, and I wanted something that would keep me in the
agenda as much as possible: hit a key on a TODO, type the email, send
it, and there you are back in the agenda again. It's turning out to be
a little more complicated than I thought!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 11:04 ` Eric Abrahamsen
@ 2013-08-03 11:18 ` Thorsten Jolitz
0 siblings, 0 replies; 9+ messages in thread
From: Thorsten Jolitz @ 2013-08-03 11:18 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>
>>> Thorsten Jolitz <tjolitz@gmail.com> writes:
>>>
>>>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>> I can imagine that this is very useful for managing phonecalls to be
>> made in the future...
>
> Well this will only cover composing and replying to emails, but if you
> have a function that automatically makes a phone call, I suppose it
> would serve as a template...
did I write phonecalls? I meant emails, obviously, and I stop posting
for today and go out for walk ... ;)
> Mostly I'm doing it because a full half of my work seems to be replying
> to interminable emails, and I wanted something that would keep me in the
> agenda as much as possible: hit a key on a TODO, type the email, send
> it, and there you are back in the agenda again. It's turning out to be
> a little more complicated than I thought!
thats more of less what I imagined, and it definitely sounds useful.
--
cheers,
Thorsten
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 8:46 org-open-link-from-string in a program Eric Abrahamsen
2013-08-03 9:18 ` Thorsten Jolitz
@ 2013-08-04 4:21 ` Eric Abrahamsen
2013-08-04 8:22 ` Eric Abrahamsen
2013-08-08 5:58 ` [CODE] " Eric Abrahamsen
3 siblings, 0 replies; 9+ messages in thread
From: Eric Abrahamsen @ 2013-08-04 4:21 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I'm trying to write a small function that programmatically follows a
> link to a gnus message, then calls
> `gnus-summary-wide-reply-with-original' to start a reply to that
> message. It seemed like `org-open-link-from-string' (after extracting
> the address part from the link) would be the right choice, but I'm
> seeing odd behavior.
>
> When gnus sets up the reply buffer it also adds several hooks and
> actions for restoring windows and marking messages as responded-to, etc,
> and these hooks and actions depend on the value of (current-buffer) when
> the reply was initiated. That's supposed to be the gnus summary buffer.
>
> When I call all this from a function, however, (current-buffer)
> continues to return the org buffer I started in, even after the link was
> opened, which confuses gnus, and me. What I mean is this:
>
> (let ((addr the-address-part-of-the-link))
> (org-open-link-from-string addr)
> (message "%s" (current-buffer)) ; returns the org buffer I started in
> (call-interactively
> 'gnus-summary-wide-reply-with-original))
>
> There must be something I'm misunderstanding about how buffers work when
> you're doing something non-interactive. If I manually eval the
> org-open-link-from-string statement, I end up in the summary buffer,
> obviously, and all works fine.
Hmm, I tried sticking a (redisplay) after opening the link, thinking
that might "reset" what is considered the current buffer, and it still
doesn't do it!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: org-open-link-from-string in a program
2013-08-03 8:46 org-open-link-from-string in a program Eric Abrahamsen
2013-08-03 9:18 ` Thorsten Jolitz
2013-08-04 4:21 ` Eric Abrahamsen
@ 2013-08-04 8:22 ` Eric Abrahamsen
2013-08-08 5:58 ` [CODE] " Eric Abrahamsen
3 siblings, 0 replies; 9+ messages in thread
From: Eric Abrahamsen @ 2013-08-04 8:22 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I'm trying to write a small function that programmatically follows a
> link to a gnus message, then calls
> `gnus-summary-wide-reply-with-original' to start a reply to that
> message. It seemed like `org-open-link-from-string' (after extracting
> the address part from the link) would be the right choice, but I'm
> seeing odd behavior.
>
> When gnus sets up the reply buffer it also adds several hooks and
> actions for restoring windows and marking messages as responded-to, etc,
> and these hooks and actions depend on the value of (current-buffer) when
> the reply was initiated. That's supposed to be the gnus summary buffer.
>
> When I call all this from a function, however, (current-buffer)
> continues to return the org buffer I started in, even after the link was
> opened, which confuses gnus, and me. What I mean is this:
>
> (let ((addr the-address-part-of-the-link))
> (org-open-link-from-string addr)
> (message "%s" (current-buffer)) ; returns the org buffer I started in
> (call-interactively
> 'gnus-summary-wide-reply-with-original))
>
> There must be something I'm misunderstanding about how buffers work when
> you're doing something non-interactive. If I manually eval the
> org-open-link-from-string statement, I end up in the summary buffer,
> obviously, and all works fine.
>
> What am I not getting?
>
> Thanks!
> Eric
I think I've got it: when `org-open-link-from-string' calls
`org-open-at-point', it passes the current buffer as an argument.
`org-open-at-point' then wraps the call to `org-link-protocols'
(specifically `org-gnus-open' in this case) in a `with-current-buffer'
that uses that original buffer.
To be honest I'm not really sure if that's the problem -- once
`org-open-link-from-string' returns, I would think that interior
`with-current-buffer' had passed out of scope. Gnus sets up the reply
buffer after open-link-from-string has returned, by which point I would
think it could get new values of `current-buffer'.
Anyway, it works to replace `org-open-link-from-string' with:
(org-gnus-open (org-link-unescape link-address))
So that's what I'll do! Once I've made sure I haven't broken these
functions while messing with them, I'll post code here.
Eric
^ permalink raw reply [flat|nested] 9+ messages in thread
* [CODE] org-open-link-from-string in a program
2013-08-03 8:46 org-open-link-from-string in a program Eric Abrahamsen
` (2 preceding siblings ...)
2013-08-04 8:22 ` Eric Abrahamsen
@ 2013-08-08 5:58 ` Eric Abrahamsen
3 siblings, 0 replies; 9+ messages in thread
From: Eric Abrahamsen @ 2013-08-08 5:58 UTC (permalink / raw)
To: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I'm trying to write a small function that programmatically follows a
> link to a gnus message, then calls
> `gnus-summary-wide-reply-with-original' to start a reply to that
> message.
Okay, this seems like a fair amount of code for something that doesn't
actually do all that much, but here it is. I have one capture template
that incorporates a link to a gnus message in the headline (for REPLY
todos), and a different one that prompts for one or more mailto: or
bbdb: links, and puts them in the headline (with an EMAIL todo).
Sometimes I have mailto links and message links in the same header, so I
can reply to a message and copy other people on the reply.
The two main functions here (org-mail-handle-mail and
org-mail-handle-mail-agenda) look at the headline under point and
hopefully DTRT with the links they find there.
Like I said, the whole point of this is single-key-in, single-key-out
capturing and handling of email todos.
Things that are weird:
1. I've used an "org-mail" prefix, which doesn't otherwise exist.
2. It assumes you're using gnus
3. It assumes you want to reply to messages using `gnus-wide-reply-with-original'
4. It still seems a wee bit fragile. Gnus doesn't take kindly to be
operated non-interactively; I've used call-interactively where I can,
just in case, but sometimes odd things happen.
Anyway, there it is. I'd be happy to stick it on worg, put it in
contrib, or just leave it here. If anyone wants it tweaked or expanded
or generalized (it doesn't do org-contact contacts, for example), just
let me know.
(defvar org-mail-window-conf nil
"Save org-buffer window configuration here, for later
restoration.")
(defun org-mail-restore-after-send ()
(gnus-summary-exit nil t)
(when (window-configuration-p org-mail-window-conf)
(set-window-configuration org-mail-window-conf))
(call-interactively 'org-agenda-todo))
(defun org-mail-handle-mail (&optional interactive-p)
"Handle mail-related links for current headline."
tC (interactive "p")
(unless (org-back-to-heading t)
(error "Not in an org item"))
(when interactive-p
(setq org-mail-window-conf (current-window-configuration)))
(let ((todo-kwd
(org-element-property :todo-keyword (org-element-at-point)))
message mailto)
(while (re-search-forward org-any-link-re (line-end-position) t)
(let ((addr (or (match-string-no-properties 2)
(match-string-no-properties 0))))
(cond
((string-match "^<?gnus:" addr)
(push (substring addr (match-end 0)) message))
((string-match "^<?mailto:" addr)
(push (substring addr (match-end 0)) mailto))
((and (featurep 'bbdb)
(string-match-p "^<?bbdb:" addr))
(with-current-buffer bbdb-buffer-name
(let ((recs bbdb-records))
(org-open-link-from-string addr)
(let ((mail (bbdb-mail-address (bbdb-current-record))))
(bbdb-display-records recs)
(push mail mailto))))))))
(cond
(message
(org-gnus-open (org-link-unescape (car message)))
(call-interactively
'gnus-summary-wide-reply-with-original)
(when mailto
(message-goto-to)
(insert ", ")
(insert (mapconcat 'identity mailto ", "))
(message-goto-body))
(add-to-list 'message-exit-actions
'org-mail-restore-after-send t))
(mailto
(compose-mail (mapconcat 'identity mailto ", ")
nil nil nil nil nil nil
'org-mail-restore-after-send))
(t
(error "No mail-related links in headline")))))
(defun org-mail-handle-mail-agenda ()
"Examine item at point for mail-related links, and handle them."
(interactive)
(org-agenda-check-type t 'agenda 'timeline 'todo 'tags)
(org-agenda-check-no-diary)
(let* ((marker (or (org-get-at-bol 'org-hd-marker)
(org-agenda-error)))
(buffer (marker-buffer marker))
(pos (marker-position marker)))
(setq org-mail-window-conf (current-window-configuration))
(with-current-buffer buffer
(widen)
(goto-char pos)
(org-mail-handle-mail))))
^ permalink raw reply [flat|nested] 9+ messages in thread