* 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).