* access a let* value whe ndefining a function?
@ 2018-10-23 17:40 Matt Price
2018-10-23 18:31 ` John Kitchin
0 siblings, 1 reply; 6+ messages in thread
From: Matt Price @ 2018-10-23 17:40 UTC (permalink / raw)
To: Org Mode
[-- Attachment #1: Type: text/plain, Size: 596 bytes --]
Hey, I guess this is OT.
I'm trying to advice org-mime-org-buffer-htmlize so that it returns to the
org buffer when its done. I want to do something like this:
(let ((thisbuffer (current-buffer))
(advice-add
'mu4e-sent-handler
:after (lambda (docid props)
(switch-to-buffer thisbuffer)
(advice-remove 'mu4e-sent-handler 'om-sent-advice)
) '((name . 'om-sent-advice)))
but by the time the hook is run, the (let) has long since lapsed, and
thisbuffer is no longer defined. Can I force evaluation of the variable
during definition?
Thanks,
m
[-- Attachment #2: Type: text/html, Size: 868 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: access a let* value whe ndefining a function?
2018-10-23 17:40 access a let* value whe ndefining a function? Matt Price
@ 2018-10-23 18:31 ` John Kitchin
2018-10-23 19:38 ` Matt Price
0 siblings, 1 reply; 6+ messages in thread
From: John Kitchin @ 2018-10-23 18:31 UTC (permalink / raw)
To: Matt Price; +Cc: org-mode-email
[-- Attachment #1: Type: text/plain, Size: 1936 bytes --]
I think that what you really want to do here is modify org-mime-compose so
that you can use the send-actions argument to message-mail. In
scimax-email.el I use that to be able to turn an org-heading into an email,
send it, and then jump back to the heading to insert some information about
the email into the heading properties after it is sent. A lot of the
information gets passed via global variables. Maybe there is a better way
to do that, I wrote that code a long time ago.
Otherwise, you need to figure out how to use something like a macro that
captures the current-buffer and creates a lambda function with that
information in it, and attaches it to the message-buffer hook somehow. For
example this will display a message-box for me after the message is sent.
(let ((f `(lambda ()
(message-box "Came from %s" ,(current-buffer)))))
(message-mail)
(add-hook 'kill-buffer-hook f nil t))
Some important notes is this hook is added in local mode, so it only
affects that email buffer.
John
-----------------------------------
Professor John Kitchin
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu
On Tue, Oct 23, 2018 at 1:40 PM Matt Price <moptop99@gmail.com> wrote:
> Hey, I guess this is OT.
>
> I'm trying to advice org-mime-org-buffer-htmlize so that it returns to the
> org buffer when its done. I want to do something like this:
>
> (let ((thisbuffer (current-buffer))
> (advice-add
> 'mu4e-sent-handler
> :after (lambda (docid props)
> (switch-to-buffer thisbuffer)
> (advice-remove 'mu4e-sent-handler 'om-sent-advice)
> ) '((name . 'om-sent-advice)))
>
> but by the time the hook is run, the (let) has long since lapsed, and
> thisbuffer is no longer defined. Can I force evaluation of the variable
> during definition?
>
> Thanks,
> m
>
[-- Attachment #2: Type: text/html, Size: 2859 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: access a let* value whe ndefining a function?
2018-10-23 18:31 ` John Kitchin
@ 2018-10-23 19:38 ` Matt Price
2018-10-23 20:05 ` Matt Price
2018-10-23 20:34 ` John Kitchin
0 siblings, 2 replies; 6+ messages in thread
From: Matt Price @ 2018-10-23 19:38 UTC (permalink / raw)
To: John Kitchin; +Cc: Org Mode
[-- Attachment #1: Type: text/plain, Size: 3283 bytes --]
On Tue, Oct 23, 2018 at 2:32 PM John Kitchin <jkitchin@andrew.cmu.edu>
wrote:
> I think that what you really want to do here is modify org-mime-compose so
> that you can use the send-actions argument to message-mail. In
> scimax-email.el I use that to be able to turn an org-heading into an email,
> send it, and then jump back to the heading to insert some information about
> the email into the heading properties after it is sent. A lot of the
> information gets passed via global variables. Maybe there is a better way
> to do that, I wrote that code a long time ago.
>
>
I'm trying to use mu4e~compose-mail instead of message-compose, I guess
mostly because I want to be able to use the mu4e email address completion
features in the `To:` header. And it wouldalso be nice to save the email
to the appropriate mu folder. But I didn't seem to be able to make mu4e
bounce back to my buffer no matter what I do, and though mu4e~compose-mail
accepts a return-action argument it doesn't actually use it :-(.
> Otherwise, you need to figure out how to use something like a macro that
> captures the current-buffer and creates a lambda function with that
> information in it, and attaches it to the message-buffer hook somehow. For
> example this will display a message-box for me after the message is sent.
>
> (let ((f `(lambda ()
> (message-box "Came from %s" ,(current-buffer)))))
> (message-mail)
> (add-hook 'kill-buffer-hook f nil t))
>
> Some important notes is this hook is added in local mode, so it only
> affects that email buffer.
>
>
Can you explain to me what yo umean by "added in local mode" -- how is that
achieved?
Meanwhile, htis is what I've done and it seems to work:
(eval (car (read-from-string
(concat
"(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
(lambda ()
(switch-to-buffer
(get-buffer \""
(buffer-name)
"\" ))
(advice-remove
'mu4e~switch-back-to-mu4e-buffer \"om-temp-advice\"))
'((name . \"om-temp-advice\")))"))))
seems a little baroque. Maybe what you have there is way better. I don't
really undertand backquotes and leading ocmmas even now.
> John
>
> -----------------------------------
> Professor John Kitchin
> Doherty Hall A207F
> Department of Chemical Engineering
> Carnegie Mellon University
> Pittsburgh, PA 15213
> 412-268-7803
> @johnkitchin
> http://kitchingroup.cheme.cmu.edu
>
>
>
> On Tue, Oct 23, 2018 at 1:40 PM Matt Price <moptop99@gmail.com> wrote:
>
>> Hey, I guess this is OT.
>>
>> I'm trying to advice org-mime-org-buffer-htmlize so that it returns to
>> the org buffer when its done. I want to do something like this:
>>
>> (let ((thisbuffer (current-buffer))
>> (advice-add
>> 'mu4e-sent-handler
>> :after (lambda (docid props)
>> (switch-to-buffer thisbuffer)
>> (advice-remove 'mu4e-sent-handler 'om-sent-advice)
>> ) '((name . 'om-sent-advice)))
>>
>> but by the time the hook is run, the (let) has long since lapsed, and
>> thisbuffer is no longer defined. Can I force evaluation of the variable
>> during definition?
>>
>> Thanks,
>> m
>>
>
[-- Attachment #2: Type: text/html, Size: 5363 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: access a let* value whe ndefining a function?
2018-10-23 19:38 ` Matt Price
@ 2018-10-23 20:05 ` Matt Price
2018-10-23 20:34 ` John Kitchin
1 sibling, 0 replies; 6+ messages in thread
From: Matt Price @ 2018-10-23 20:05 UTC (permalink / raw)
To: John Kitchin; +Cc: Org Mode
[-- Attachment #1: Type: text/plain, Size: 3994 bytes --]
On Tue, Oct 23, 2018 at 3:38 PM Matt Price <moptop99@gmail.com> wrote:
>
>
> On Tue, Oct 23, 2018 at 2:32 PM John Kitchin <jkitchin@andrew.cmu.edu>
> wrote:
>
>> I think that what you really want to do here is modify org-mime-compose
>> so that you can use the send-actions argument to message-mail. In
>> scimax-email.el I use that to be able to turn an org-heading into an email,
>> send it, and then jump back to the heading to insert some information about
>> the email into the heading properties after it is sent. A lot of the
>> information gets passed via global variables. Maybe there is a better way
>> to do that, I wrote that code a long time ago.
>>
>>
> I'm trying to use mu4e~compose-mail instead of message-compose, I guess
> mostly because I want to be able to use the mu4e email address completion
> features in the `To:` header. And it wouldalso be nice to save the email
> to the appropriate mu folder. But I didn't seem to be able to make mu4e
> bounce back to my buffer no matter what I do, and though mu4e~compose-mail
> accepts a return-action argument it doesn't actually use it :-(.
>
>
>> Otherwise, you need to figure out how to use something like a macro that
>> captures the current-buffer and creates a lambda function with that
>> information in it, and attaches it to the message-buffer hook somehow. For
>> example this will display a message-box for me after the message is sent.
>>
>> (let ((f `(lambda ()
>> (message-box "Came from %s" ,(current-buffer)))))
>> (message-mail)
>> (add-hook 'kill-buffer-hook f nil t))
>>
>> Some important notes is this hook is added in local mode, so it only
>> affects that email buffer.
>>
>>
> Can you explain to me what yo umean by "added in local mode" -- how is
> that achieved?
>
> Meanwhile, htis is what I've done and it seems to work:
>
> (eval (car (read-from-string
> (concat
> "(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
> (lambda ()
> (switch-to-buffer
> (get-buffer \""
> (buffer-name)
> "\" ))
> (advice-remove
> 'mu4e~switch-back-to-mu4e-buffer \"om-temp-advice\"))
> '((name . \"om-temp-advice\")))"))))
>
> seems a little baroque. Maybe what you have there is way better. I don't
> really undertand backquotes and leading ocmmas even now.
>
>
> I'd think this owuld be equivalent but the advice removal isn't working:
(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
(eval
`(lambda ()
(switch-to-buffer (get-buffer ,(buffer-name) ))
(advice-remove 'mu4e~switch-back-to-mu4e-buffer
"om-temp-advice")
'((name . "om-temp-advice") ))))
the naming isn't being carried out succesfully. I guess the regular
quoting works differnely inside a backquote or osmething?
>
>
>> John
>>
>> -----------------------------------
>> Professor John Kitchin
>> Doherty Hall A207F
>> Department of Chemical Engineering
>> Carnegie Mellon University
>> Pittsburgh, PA 15213
>> 412-268-7803
>> @johnkitchin
>> http://kitchingroup.cheme.cmu.edu
>>
>>
>>
>> On Tue, Oct 23, 2018 at 1:40 PM Matt Price <moptop99@gmail.com> wrote:
>>
>>> Hey, I guess this is OT.
>>>
>>> I'm trying to advice org-mime-org-buffer-htmlize so that it returns to
>>> the org buffer when its done. I want to do something like this:
>>>
>>> (let ((thisbuffer (current-buffer))
>>> (advice-add
>>> 'mu4e-sent-handler
>>> :after (lambda (docid props)
>>> (switch-to-buffer thisbuffer)
>>> (advice-remove 'mu4e-sent-handler 'om-sent-advice)
>>> ) '((name . 'om-sent-advice)))
>>>
>>> but by the time the hook is run, the (let) has long since lapsed, and
>>> thisbuffer is no longer defined. Can I force evaluation of the variable
>>> during definition?
>>>
>>> Thanks,
>>> m
>>>
>>
[-- Attachment #2: Type: text/html, Size: 6722 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: access a let* value whe ndefining a function?
2018-10-23 19:38 ` Matt Price
2018-10-23 20:05 ` Matt Price
@ 2018-10-23 20:34 ` John Kitchin
2018-10-24 11:58 ` Matt Price
1 sibling, 1 reply; 6+ messages in thread
From: John Kitchin @ 2018-10-23 20:34 UTC (permalink / raw)
To: Matt Price; +Cc: Org Mode
Matt Price <moptop99@gmail.com> writes:
> On Tue, Oct 23, 2018 at 2:32 PM John Kitchin <jkitchin@andrew.cmu.edu>
> wrote:
>
>> I think that what you really want to do here is modify org-mime-compose so
>> that you can use the send-actions argument to message-mail. In
>> scimax-email.el I use that to be able to turn an org-heading into an email,
>> send it, and then jump back to the heading to insert some information about
>> the email into the heading properties after it is sent. A lot of the
>> information gets passed via global variables. Maybe there is a better way
>> to do that, I wrote that code a long time ago.
>>
>>
> I'm trying to use mu4e~compose-mail instead of message-compose, I guess
> mostly because I want to be able to use the mu4e email address completion
> features in the `To:` header. And it wouldalso be nice to save the email
> to the appropriate mu folder. But I didn't seem to be able to make mu4e
> bounce back to my buffer no matter what I do, and though mu4e~compose-mail
> accepts a return-action argument it doesn't actually use it :-(.
This is kind of tricky. Here is an approach that seems to work:
(defun my-compose ()
(interactive)
(mu4e~compose-mail)
(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
`(lambda ()
(switch-to-buffer (get-buffer ,(buffer-name) ))
(advice-remove 'mu4e~switch-back-to-mu4e-buffer "om-temp-advice"))
'((name . "om-temp-advice"))))
You just call M-x my-compose to get this behavior. I guess you could
advise mu4e~compose too to add the advice.
It seems necessary to use a temporary advice here. I wasn't aware of the
name way of removing advice, that is pretty nice here, since we use a
changing anonymous function.
>
>
>> Otherwise, you need to figure out how to use something like a macro that
>> captures the current-buffer and creates a lambda function with that
>> information in it, and attaches it to the message-buffer hook somehow. For
>> example this will display a message-box for me after the message is sent.
>>
>> (let ((f `(lambda ()
>> (message-box "Came from %s" ,(current-buffer)))))
>> (message-mail)
>> (add-hook 'kill-buffer-hook f nil t))
>>
>> Some important notes is this hook is added in local mode, so it only
>> affects that email buffer.
>>
>>
> Can you explain to me what yo umean by "added in local mode" -- how is that
> achieved?
This is what the final t argument in the add-hood function does. I think
it makes the hook local to the buffer it runs in, as opposed to in every buffer.
>
> Meanwhile, htis is what I've done and it seems to work:
>
> (eval (car (read-from-string
> (concat
> "(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
> (lambda ()
> (switch-to-buffer
> (get-buffer \""
> (buffer-name)
> "\" ))
> (advice-remove
> 'mu4e~switch-back-to-mu4e-buffer \"om-temp-advice\"))
> '((name . \"om-temp-advice\")))"))))
This is practically the same as my `, solution above, you just use
strings to protect some parts of code from evaluation, regular function
calls in places, and then you concat it all together and read it. The `,
syntax is optional, but without it you have to use list and quotes to
build up the code in a similar way:
(let ((f (list
'lambda ()
(list 'message-box "Came from %s" (current-buffer)))))
(message-mail)
(add-hook 'kill-buffer-hook f nil t))
here the ' means treat something like a symbol, and don't evaluate it.
We build up the lambda expression using runtime information, e.g. what
is the current-buffer when the code is run.
>
> seems a little baroque. Maybe what you have there is way better. I don't
> really undertand backquotes and leading ocmmas even now.
It takes some practice. Suppose you have some variables defined, e.g.
a=3, then here are two ways to make a list where you put the value of a
into the first place, and a symbol b in the second place.
(list a 'b) => '(3 'b)
`(,a b) => '(3 'b)
This lets you build up expressions, including functions that are defined
at runtime. Lots of macros use this syntax to build up expressions that
are later evaluated.
>
>
>
>
>> John
>>
>> -----------------------------------
>> Professor John Kitchin
>> Doherty Hall A207F
>> Department of Chemical Engineering
>> Carnegie Mellon University
>> Pittsburgh, PA 15213
>> 412-268-7803
>> @johnkitchin
>> http://kitchingroup.cheme.cmu.edu
>>
>>
>>
>> On Tue, Oct 23, 2018 at 1:40 PM Matt Price <moptop99@gmail.com> wrote:
>>
>>> Hey, I guess this is OT.
>>>
>>> I'm trying to advice org-mime-org-buffer-htmlize so that it returns to
>>> the org buffer when its done. I want to do something like this:
>>>
>>> (let ((thisbuffer (current-buffer))
>>> (advice-add
>>> 'mu4e-sent-handler
>>> :after (lambda (docid props)
>>> (switch-to-buffer thisbuffer)
>>> (advice-remove 'mu4e-sent-handler 'om-sent-advice)
>>> ) '((name . 'om-sent-advice)))
>>>
>>> but by the time the hook is run, the (let) has long since lapsed, and
>>> thisbuffer is no longer defined. Can I force evaluation of the variable
>>> during definition?
>>>
>>> Thanks,
>>> m
>>>
>>
--
Professor John Kitchin
Doherty Hall A207F
Department of Chemical Engineering
Carnegie Mellon University
Pittsburgh, PA 15213
412-268-7803
@johnkitchin
http://kitchingroup.cheme.cmu.edu
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: access a let* value whe ndefining a function?
2018-10-23 20:34 ` John Kitchin
@ 2018-10-24 11:58 ` Matt Price
0 siblings, 0 replies; 6+ messages in thread
From: Matt Price @ 2018-10-24 11:58 UTC (permalink / raw)
To: John Kitchin; +Cc: Org Mode
[-- Attachment #1: Type: text/plain, Size: 6061 bytes --]
On Tue, Oct 23, 2018 at 4:34 PM John Kitchin <jkitchin@andrew.cmu.edu>
wrote:
>
> Matt Price <moptop99@gmail.com> writes:
>
> > On Tue, Oct 23, 2018 at 2:32 PM John Kitchin <jkitchin@andrew.cmu.edu>
> > wrote:
> >
> >> I think that what you really want to do here is modify org-mime-compose
> so
> >> that you can use the send-actions argument to message-mail. In
> >> scimax-email.el I use that to be able to turn an org-heading into an
> email,
> >> send it, and then jump back to the heading to insert some information
> about
> >> the email into the heading properties after it is sent. A lot of the
> >> information gets passed via global variables. Maybe there is a better
> way
> >> to do that, I wrote that code a long time ago.
> >>
> >>
> > I'm trying to use mu4e~compose-mail instead of message-compose, I guess
> > mostly because I want to be able to use the mu4e email address completion
> > features in the `To:` header. And it wouldalso be nice to save the email
> > to the appropriate mu folder. But I didn't seem to be able to make mu4e
> > bounce back to my buffer no matter what I do, and though
> mu4e~compose-mail
> > accepts a return-action argument it doesn't actually use it :-(.
>
> This is kind of tricky. Here is an approach that seems to work:
>
> (defun my-compose ()
> (interactive)
> (mu4e~compose-mail)
> (advice-add 'mu4e~switch-back-to-mu4e-buffer :after
> `(lambda ()
> (switch-to-buffer (get-buffer ,(buffer-name) ))
> (advice-remove 'mu4e~switch-back-to-mu4e-buffer
> "om-temp-advice"))
> '((name . "om-temp-advice"))))
>
> You just call M-x my-compose to get this behavior. I guess you could
> advise mu4e~compose too to add the advice.
>
> Right now I am adding my advice from inside of ~org-mime-org-*-htmlize~ in
the org-mime code (which I guess you no longer use, since you have written
your own email handler). It seems to be a good place for it & is minimally
invasive to other packages. Here's the code ` code I attempted but which
didn't work for me:
(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
(eval
`(lambda ()
(switch-to-buffer (get-buffer ,(buffer-name) ))
(advice-remove 'mu4e~switch-back-to-mu4e-buffer
"om-temp-advice")
'((name . "om-temp-advice") ))))
Seems like maybe the problem fore me is the extra "eval". What maybe I
don't understand is why the backquote works when the ordinary way to add an
advice is the unquoted
(advice-add 'sym (lambda () (message "I am an advice"))
while IIUC yours should evaluate to
(advice-add 'sym '(lambda () (message "I am an advice"))
There should be a difference, shouldn't there? But clearly I don't
understand.
> It seems necessary to use a temporary advice here. I wasn't aware of the
> name way of removing advice, that is pretty nice here, since we use a
> changing anonymous function.
>
> yes it's nice right?
> >> Otherwise, you need to figure out how to use something like a macro that
> >> captures the current-buffer and creates a lambda function with that
> >> information in it, and attaches it to the message-buffer hook somehow.
> For
> >> example this will display a message-box for me after the message is
> sent.
> >>
> >> (let ((f `(lambda ()
> >> (message-box "Came from %s" ,(current-buffer)))))
> >> (message-mail)
> >> (add-hook 'kill-buffer-hook f nil t))
> >>
> >> Some important notes is this hook is added in local mode, so it only
> >> affects that email buffer.
> >>
> >>
> > Can you explain to me what yo umean by "added in local mode" -- how is
> that
> > achieved?
>
> This is what the final t argument in the add-hood function does. I think
> it makes the hook local to the buffer it runs in, as opposed to in every
> buffer.
>
>
OK thanks that's very helpful. I guess my problem was that there was no
built-in hook that executed *after* mu4e~switch-back-to-buffer.
Which is why I have had to learn about advice.
> >
> > Meanwhile, htis is what I've done and it seems to work:
> >
> > (eval (car (read-from-string
> > (concat
> > "(advice-add 'mu4e~switch-back-to-mu4e-buffer :after
> > (lambda ()
> > (switch-to-buffer
> > (get-buffer \""
> > (buffer-name)
> > "\" ))
> > (advice-remove
> > 'mu4e~switch-back-to-mu4e-buffer \"om-temp-advice\"))
> > '((name . \"om-temp-advice\")))"))))
>
> This is practically the same as my `, solution above, you just use
> strings to protect some parts of code from evaluation, regular function
> calls in places, and then you concat it all together and read it. The `,
> syntax is optional, but without it you have to use list and quotes to
> build up the code in a similar way:
>
> (let ((f (list
> 'lambda ()
> (list 'message-box "Came from %s" (current-buffer)))))
> (message-mail)
> (add-hook 'kill-buffer-hook f nil t))
>
> here the ' means treat something like a symbol, and don't evaluate it.
> We build up the lambda expression using runtime information, e.g. what
> is the current-buffer when the code is run.
>
cool to see the unquoted code here. thank you.
>
> > seems a little baroque. Maybe what you have there is way better. I don't
> > really undertand backquotes and leading ocmmas even now.
>
> It takes some practice. Suppose you have some variables defined, e.g.
> a=3, then here are two ways to make a list where you put the value of a
> into the first place, and a symbol b in the second place.
>
> (list a 'b) => '(3 'b)
>
> `(,a b) => '(3 'b)
>
> This lets you build up expressions, including functions that are defined
> at runtime. Lots of macros use this syntax to build up expressions that
> are later evaluated.
>
>
THanks for the tutorial, John, htis is veyr helpful. Now also maybe I will
finally learn the difference between functions and macros. :-)
[-- Attachment #2: Type: text/html, Size: 8457 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-10-24 12:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-23 17:40 access a let* value whe ndefining a function? Matt Price
2018-10-23 18:31 ` John Kitchin
2018-10-23 19:38 ` Matt Price
2018-10-23 20:05 ` Matt Price
2018-10-23 20:34 ` John Kitchin
2018-10-24 11:58 ` Matt Price
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).