* Need help with macros
@ 2010-01-06 15:40 Cecil Westerhof
2010-01-06 17:18 ` Cecil Westerhof
2010-01-06 19:00 ` Pascal J. Bourguignon
0 siblings, 2 replies; 8+ messages in thread
From: Cecil Westerhof @ 2010-01-06 15:40 UTC (permalink / raw)
To: help-gnu-emacs
I am trying to make some useful functionality for Gnus. I think that I
should use a macro for that. I made the following macro (the two message
statements are just for debugging):
(defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
(message "#%s#%s#" key-binding (type-of key-binding))
(message "#%s#%s#" group-to-jump-to (type-of group-to-jump-to))
(define-key gnus-group-mode-map key-binding
(lambda ()
(interactive)
(gnus-group-jump-to-group group-to-jump-to))))
When calling this with:
(gnus-group-jump-bind "vjd" "nndraft:drafts")
In the message buffer it gives:
#vjd#string#
#nndraft:drafts#string#
And the return value is:
(lambda nil (interactive) (gnus-group-jump-to-group group-to-jump-to))
This is the first problem. Outside the macro group-to-jump-to is not
existing, I need the value of group-to-jump-to not the name itself. How
do I do this? I tried eval, but that did not work.
But of course I do not want to set the key bindings manually but data
driven. So I wrote the following function:
(defun gnus-group-do-jump-bind ()
(dolist (this-jump gnus-group-jump-list)
(let ((this-group (second this-jump))
(this-key (concat "vj" (first this-jump))))
(gnus-group-jump-bind this-key this-group))))
I defined the used value:
(setq gnus-group-jump-list
(list
'("d" "nndraft:drafts")
))
And call the function:
(gnus-group-do-jump-bind)
This gives in the message buffer:
#this-key#symbol#
#this-group#symbol#
Entering debugger...
And the debug output starts with:
Debugger entered--Lisp error: (wrong-type-argument arrayp this-key)
I tried to work with symbol-value, but that did not work.
What do I need to do to get this working?
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 15:40 Need help with macros Cecil Westerhof
@ 2010-01-06 17:18 ` Cecil Westerhof
2010-01-06 19:00 ` Pascal J. Bourguignon
1 sibling, 0 replies; 8+ messages in thread
From: Cecil Westerhof @ 2010-01-06 17:18 UTC (permalink / raw)
To: help-gnu-emacs
Cecil Westerhof <Cecil@decebal.nl> writes:
> I am trying to make some useful functionality for Gnus. I think that I
> should use a macro for that. I made the following macro (the two message
> statements are just for debugging):
> (defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
> (message "#%s#%s#" key-binding (type-of key-binding))
> (message "#%s#%s#" group-to-jump-to (type-of group-to-jump-to))
> (define-key gnus-group-mode-map key-binding
> (lambda ()
> (interactive)
> (gnus-group-jump-to-group group-to-jump-to))))
>
> When calling this with:
> (gnus-group-jump-bind "vjd" "nndraft:drafts")
>
> In the message buffer it gives:
> #vjd#string#
> #nndraft:drafts#string#
>
> And the return value is:
> (lambda nil (interactive) (gnus-group-jump-to-group group-to-jump-to))
>
> This is the first problem. Outside the macro group-to-jump-to is not
> existing, I need the value of group-to-jump-to not the name itself. How
> do I do this? I tried eval, but that did not work.
>
> But of course I do not want to set the key bindings manually but data
> driven. So I wrote the following function:
> (defun gnus-group-do-jump-bind ()
> (dolist (this-jump gnus-group-jump-list)
> (let ((this-group (second this-jump))
> (this-key (concat "vj" (first this-jump))))
> (gnus-group-jump-bind this-key this-group))))
>
> I defined the used value:
> (setq gnus-group-jump-list
> (list
> '("d" "nndraft:drafts")
> ))
>
> And call the function:
> (gnus-group-do-jump-bind)
>
> This gives in the message buffer:
> #this-key#symbol#
> #this-group#symbol#
> Entering debugger...
>
> And the debug output starts with:
> Debugger entered--Lisp error: (wrong-type-argument arrayp this-key)
>
> I tried to work with symbol-value, but that did not work.
>
> What do I need to do to get this working?
Found it:
(setq gnus-group-jump-list
(list
'("d" "nndraft:drafts")
))
(defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
`(define-key gnus-group-mode-map ,(symbol-value key-binding)
(lambda ()
(interactive)
(gnus-group-jump-to-group ,(symbol-value group-to-jump-to)))))
(defun gnus-group-do-jump-bind ()
(dolist (this-jump gnus-group-jump-list)
(let ((this-group (second this-jump))
(this-key (concat "vj" (first this-jump))))
(gnus-group-jump-bind this-key this-group))))
(gnus-group-do-jump-bind)
And this does what I want. A problem could be that:
(gnus-group-jump-bind "vjd" "nndraft:drafts")
does not work anymore, but just always use variables solves that
'problem'.
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 15:40 Need help with macros Cecil Westerhof
2010-01-06 17:18 ` Cecil Westerhof
@ 2010-01-06 19:00 ` Pascal J. Bourguignon
2010-01-06 19:25 ` Cecil Westerhof
1 sibling, 1 reply; 8+ messages in thread
From: Pascal J. Bourguignon @ 2010-01-06 19:00 UTC (permalink / raw)
To: help-gnu-emacs
Cecil Westerhof <Cecil@decebal.nl> writes:
> I am trying to make some useful functionality for Gnus. I think that I
> should use a macro for that. I made the following macro (the two message
> statements are just for debugging):
> (defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
> (message "#%s#%s#" key-binding (type-of key-binding))
I would avoid using the character # in lisp output, since it is
meaningful (readable).
(let ((print-circle t))
(let* ((a "hello")
(b (list a a)))
(print b)))
prints:
(#1="hello" #1#)
(read-from-string "(#1=\"hello\" #1#)")
--> ((#1="hello" #1#) . 16)
In a preceding message, I used "%S" instead. You should try it!
> (message "#%s#%s#" group-to-jump-to (type-of group-to-jump-to))
> (define-key gnus-group-mode-map key-binding
> (lambda ()
> (interactive)
> (gnus-group-jump-to-group group-to-jump-to))))
gnus-group-jump-bind has no need to be a macro. As a macro it is
wrong. Use defun!
> When calling this with:
> (gnus-group-jump-bind "vjd" "nndraft:drafts")
>
> In the message buffer it gives:
> #vjd#string#
> #nndraft:drafts#string#
>
> And the return value is:
> (lambda nil (interactive) (gnus-group-jump-to-group group-to-jump-to))
>
> This is the first problem. Outside the macro group-to-jump-to is not
> existing, I need the value of group-to-jump-to not the name itself. How
> do I do this? I tried eval, but that did not work.
By using a function instead of macro.
> But of course I do not want to set the key bindings manually but data
> driven. So I wrote the following function:
> (defun gnus-group-do-jump-bind ()
> (dolist (this-jump gnus-group-jump-list)
> (let ((this-group (second this-jump))
> (this-key (concat "vj" (first this-jump))))
> (gnus-group-jump-bind this-key this-group))))
>
> I defined the used value:
> (setq gnus-group-jump-list
> (list
> '("d" "nndraft:drafts")
> ))
>
> And call the function:
> (gnus-group-do-jump-bind)
>
> This gives in the message buffer:
> #this-key#symbol#
> #this-group#symbol#
> Entering debugger...
>
> And the debug output starts with:
> Debugger entered--Lisp error: (wrong-type-argument arrayp this-key)
>
> I tried to work with symbol-value, but that did not work.
>
> What do I need to do to get this working?
Make it a function.
--
__Pascal Bourguignon__ http://www.informatimago.com/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 19:00 ` Pascal J. Bourguignon
@ 2010-01-06 19:25 ` Cecil Westerhof
2010-01-06 19:48 ` Cecil Westerhof
2010-01-06 20:23 ` Pascal J. Bourguignon
0 siblings, 2 replies; 8+ messages in thread
From: Cecil Westerhof @ 2010-01-06 19:25 UTC (permalink / raw)
To: help-gnu-emacs
pjb@informatimago.com (Pascal J. Bourguignon) writes:
>> I am trying to make some useful functionality for Gnus. I think that I
>> should use a macro for that. I made the following macro (the two message
>> statements are just for debugging):
>> (defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
>> (message "#%s#%s#" key-binding (type-of key-binding))
>
> I would avoid using the character # in lisp output, since it is
> meaningful (readable).
>
> (let ((print-circle t))
> (let* ((a "hello")
> (b (list a a)))
> (print b)))
> prints:
> (#1="hello" #1#)
>
> (read-from-string "(#1=\"hello\" #1#)")
> --> ((#1="hello" #1#) . 16)
I do not really understand what happens here -but I am a newbie with
lisp, so that is not that strange-, but I will not use the '#' anymore.
> In a preceding message, I used "%S" instead. You should try it!
I find the '#' termination more clear, but I can get used to this.
Better safe as sorry.
>> (message "#%s#%s#" group-to-jump-to (type-of group-to-jump-to))
>> (define-key gnus-group-mode-map key-binding
>> (lambda ()
>> (interactive)
>> (gnus-group-jump-to-group group-to-jump-to))))
>
> gnus-group-jump-bind has no need to be a macro. As a macro it is
> wrong. Use defun!
I could not get the defun working, that is why I thought it had to be
done with a macro. The macro first also did not work. The macro works
now. I'll rewrite the macro to a defun.
I do have a lot of questions. I am glad that you and others are so
helpful. ;-)
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 19:25 ` Cecil Westerhof
@ 2010-01-06 19:48 ` Cecil Westerhof
2010-01-06 20:29 ` Pascal J. Bourguignon
2010-01-06 20:23 ` Pascal J. Bourguignon
1 sibling, 1 reply; 8+ messages in thread
From: Cecil Westerhof @ 2010-01-06 19:48 UTC (permalink / raw)
To: help-gnu-emacs
Cecil Westerhof <Cecil@decebal.nl> writes:
>> gnus-group-jump-bind has no need to be a macro. As a macro it is
>> wrong. Use defun!
>
> I could not get the defun working, that is why I thought it had to be
> done with a macro. The macro first also did not work. The macro works
> now. I'll rewrite the macro to a defun.
And this is without a macro:
(defun gnus-group-jump-bind ()
"Define the key bindings for jumping to groups;"
(dolist (this-jump gnus-group-jump-list)
(let ((this-description (second this-jump))
(this-group (third this-jump))
(this-key (concat "vj" (first this-jump))))
(define-key gnus-group-mode-map this-key
`(lambda ()
,this-description
(interactive)
(gnus-group-jump-to-group ,this-group))))))
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 19:48 ` Cecil Westerhof
@ 2010-01-06 20:29 ` Pascal J. Bourguignon
2010-01-07 10:35 ` Cecil Westerhof
0 siblings, 1 reply; 8+ messages in thread
From: Pascal J. Bourguignon @ 2010-01-06 20:29 UTC (permalink / raw)
To: help-gnu-emacs
Cecil Westerhof <Cecil@decebal.nl> writes:
> Cecil Westerhof <Cecil@decebal.nl> writes:
>
>>> gnus-group-jump-bind has no need to be a macro. As a macro it is
>>> wrong. Use defun!
>>
>> I could not get the defun working, that is why I thought it had to be
>> done with a macro. The macro first also did not work. The macro works
>> now. I'll rewrite the macro to a defun.
>
> And this is without a macro:
> (defun gnus-group-jump-bind ()
> "Define the key bindings for jumping to groups;"
> (dolist (this-jump gnus-group-jump-list)
> (let ((this-description (second this-jump))
> (this-group (third this-jump))
> (this-key (concat "vj" (first this-jump))))
> (define-key gnus-group-mode-map this-key
> `(lambda ()
> ,this-description
> (interactive)
> (gnus-group-jump-to-group ,this-group))))))
Good.
Two things.
1- I'd like it better if gnus-group-jump-list was a parameter of the
function rather than a global variable.
2- You could use destructuring-bind:
(defun gnus-group-jump-bind (jump-list)
"Define the key bindings for jumping to groups;"
(dolist (this-jump jump-list)
(destructuring-bind (this-key this-description this-group) this-jump
(let ((binding (concat "vj" this-key)))
(define-key gnus-group-mode-map binding
`(lambda ()
,this-description
(interactive)
(gnus-group-jump-to-group ,this-group)))))))
(gnus-group-jump-bind gnus-group-jump-list)
--
__Pascal Bourguignon__ http://www.informatimago.com/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 20:29 ` Pascal J. Bourguignon
@ 2010-01-07 10:35 ` Cecil Westerhof
0 siblings, 0 replies; 8+ messages in thread
From: Cecil Westerhof @ 2010-01-07 10:35 UTC (permalink / raw)
To: help-gnu-emacs
pjb@informatimago.com (Pascal J. Bourguignon) writes:
> 1- I'd like it better if gnus-group-jump-list was a parameter of the
> function rather than a global variable.
Point taken and implemented. I'll look into my toggle functionality
also. Would be nice to implement it there also without global variables.
> 2- You could use destructuring-bind:
>
> (defun gnus-group-jump-bind (jump-list)
> "Define the key bindings for jumping to groups;"
> (dolist (this-jump jump-list)
> (destructuring-bind (this-key this-description this-group) this-jump
> (let ((binding (concat "vj" this-key)))
> (define-key gnus-group-mode-map binding
> `(lambda ()
> ,this-description
> (interactive)
> (gnus-group-jump-to-group ,this-group)))))))
I did not know destructuring-bind. I made it:
(defun gnus-group-jump-bind (jump-list)
"Define the key bindings for jumping to groups;"
(dolist (this-jump jump-list)
(destructuring-bind (this-key this-description this-group) this-jump
(define-key gnus-group-mode-map (concat "vj" this-key)
`(lambda ()
,this-description
(interactive)
(gnus-group-jump-to-group ,this-group))))))
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Need help with macros
2010-01-06 19:25 ` Cecil Westerhof
2010-01-06 19:48 ` Cecil Westerhof
@ 2010-01-06 20:23 ` Pascal J. Bourguignon
1 sibling, 0 replies; 8+ messages in thread
From: Pascal J. Bourguignon @ 2010-01-06 20:23 UTC (permalink / raw)
To: help-gnu-emacs
Cecil Westerhof <Cecil@decebal.nl> writes:
> pjb@informatimago.com (Pascal J. Bourguignon) writes:
>
>>> I am trying to make some useful functionality for Gnus. I think that I
>>> should use a macro for that. I made the following macro (the two message
>>> statements are just for debugging):
>>> (defmacro gnus-group-jump-bind (key-binding group-to-jump-to)
>>> (message "#%s#%s#" key-binding (type-of key-binding))
>>
>> I would avoid using the character # in lisp output, since it is
>> meaningful (readable).
>>
>> (let ((print-circle t))
>> (let* ((a "hello")
>> (b (list a a)))
>> (print b)))
>> prints:
>> (#1="hello" #1#)
>>
>> (read-from-string "(#1=\"hello\" #1#)")
>> --> ((#1="hello" #1#) . 16)
>
> I do not really understand what happens here -but I am a newbie with
> lisp, so that is not that strange-, but I will not use the '#' anymore.
Most output written by print is readable by read.
The strings produced by prin1-to-string are redable by read-from-string.
This is gratis serialization/deserialization provided by lisp.
(prin1-to-string '(42 "abc" def [1 2 3]))
--> "(42 \"abc\" def [1 2 3])"
(car (read-from-string (prin1-to-string '(42 "abc" def [1 2 3]))))
--> (42 "abc" def [1 2 3])
(setf print-circle nil)
(let* ((s "abc")
(l (list s s)))
(prin1-to-string l))
--> "(\"abc\" \"abc\")"
(car (read-from-string (let* ((s "abc")
(l (list s s)))
(prin1-to-string l))))
--> ("abc" "abc")
Here, we get two different strings containing the same characters.
(let ((l2 (car (read-from-string (let* ((s "abc")
(l (list s s)))
(prin1-to-string l))))))
(eql (first l2) (second l2)))
--> nil
But the original list, l, had twice the same string in it. By setting
print-circle to t, prin1 and print will use the #= ## notation to make
reference to previously printed objects. (The number is used to
identify the object referenced, when there are several different
objects occuring in various places).
(setf print-circle t)
(let* ((s "abc")
(l (list s s)))
(prin1-to-string l))
--> "(#1=\"abc\" #1#)"
When reading these #= and ##, the object is not duplicated anymore.
(car (read-from-string (let* ((s "abc")
(l (list s s)))
(prin1-to-string l))))
--> (#1="abc" #1#)
(let ((l2 (car (read-from-string (let* ((s "abc")
(l (list s s)))
(prin1-to-string l))))))
(eql (first l2) (second l2)))
--> t
>> In a preceding message, I used "%S" instead. You should try it!
>
> I find the '#' termination more clear, but I can get used to this.
> Better safe as sorry.
Well, there's nothing wrong in your usage of #, but it is better in
general to print lisp data that is readable, so that you can easily
read it back if need be.
>>> (message "#%s#%s#" group-to-jump-to (type-of group-to-jump-to))
(let ((group-to-jump-to "example"))
(message "%S" (list group-to-jump-to (type-of group-to-jump-to))))
prints: ("example" string)
So you can copy-and-paste it and write:
(set group-to-jump-to (first '("example" string)))
or whatever later.
>>> (define-key gnus-group-mode-map key-binding
>>> (lambda ()
>>> (interactive)
>>> (gnus-group-jump-to-group group-to-jump-to))))
>>
>> gnus-group-jump-bind has no need to be a macro. As a macro it is
>> wrong. Use defun!
>
> I could not get the defun working, that is why I thought it had to be
> done with a macro. The macro first also did not work. The macro works
> now. I'll rewrite the macro to a defun.
>
> I do have a lot of questions. I am glad that you and others are so
> helpful. ;-)
define-key is itself a function so there should be no difficulty in
writing your gnus-group-jump-bind as a function.
--
__Pascal Bourguignon__ http://www.informatimago.com/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-01-07 10:35 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-06 15:40 Need help with macros Cecil Westerhof
2010-01-06 17:18 ` Cecil Westerhof
2010-01-06 19:00 ` Pascal J. Bourguignon
2010-01-06 19:25 ` Cecil Westerhof
2010-01-06 19:48 ` Cecil Westerhof
2010-01-06 20:29 ` Pascal J. Bourguignon
2010-01-07 10:35 ` Cecil Westerhof
2010-01-06 20:23 ` Pascal J. Bourguignon
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).