help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Help needed with defadvice


From: Perry Smith
Subject: Re: Help needed with defadvice
Date: Fri, 22 Nov 2013 09:50:02 -0600

On Nov 22, 2013, at 1:09 AM, Alex Kost <address@hidden> wrote:

> Perry Smith (2013-11-22 06:45 +0400) wrote:
> 
>> I have this defadvice:
>> 
>> (defadvice get-buffer-create (around inherit activate)
>>  (let ((set-list (mapcar '(lambda ( v )
>>                           (cons v (symbol-value v)))
>>                        inherited-alist)))
>>    (with-current-buffer ad-do-it 
>>      (mapcar '(lambda ( c )
>>               (message "Setting %s to %s inside %s"
>>                        (car c) (cdr c) (buffer-name (current-buffer)))
>>               (set (car c) (cdr c)))
>>            set-list))))
>> 
>> inherited-alist is a list of symbols that I add to.  When a buffer is 
>> created, I run through the list of variables and get their values as seen 
>> from the current buffer.  I then call get-buffer-create (via ad-do-it) and 
>> do a set on each of the variables.  The "message" is there just for 
>> debugging.  I get the messages like I expect .... e.g. "Setting foo to dog 
>> inside cat.c" or whatever.  All the symbols in inherited-alist are 
>> buffer-local variables.

To Eric: changing let to let* had not effect.

> 
> 1. With `set' you set a global value, you probably want
> (set (make-local-variable (car c)) (cdr c)) instead of
> (set (car c) (cdr c)).

No change.  If this helps, when I do ^h-v cscope-out-buffer I get:

cscope-out-buffer is a variable defined in `cscope.el'.
Its value is "banana"

  Automatically becomes buffer-local when set.

Documentation:
Buffer associated with the cscope process

"banana" is the global I set with:
(set-default 'cscope-out-buffer "banana") in *scratch*

I'm coming to the conclusion that something after get-buffer-create
is blasting the local variables back to their defaults.  (By the
way, I have added another message after the set and it
shows that it is being set.  I've also explicitly set one of these
variables outside of the let and it is still not being set.

I changed it to be:

(defadvice get-buffer-create (around inherit activate)
  (let* ((set-list (mapcar '(lambda ( v )
                              (cons v (symbol-value v)))
                           inherited-alist)))
    (with-current-buffer ad-do-it 
      (mapcar (lambda ( c )
                (message "Setting %s to %s inside %s"
                         (car c) (cdr c) (buffer-name (current-buffer)))
                (set (make-local-variable (car c)) (cdr c)))
              set-list)))
  (setq cscope-out-buffer "juice"))

and describe-variable still has the same output.  It is still set to "banana" 
(not "juice")

(I tried setq as well as set with make-variable-buffer-local).

> 
> 2. Don't quote lambdas: <http://www.emacswiki.org/emacs/QuotedLambda>.

Ok.  (no change to my issue)

> 
> 3. "alist" means "association list", so you shouldn't call
> `inherited-alist' like this as it's a simple list.  For info about
> alists look at (info "(elisp) Association Lists").

Thanks... I should have known that.  In my defense, I wrote this
25 years ago and I haven't touched it since.

> 
> 4. I believe making an advice for `get-buffer-create' is not a good
> idea.  Don't you have a lot of messages about setting variables in
> *temp* buffers?  Thus you will set unintended variables for any new
> buffer.  Do you really need that?

I had it "up" a level or two doing advice for create-file-buffer but it had
the same problem.  The message will go away when I'm done.  I'm not
sure where I want to put it.

On perhaps a side note, the documentation for make-variable-buffer-local 
has this curious sentence:

Note that binding the variable with `let', or setting it while
a `let'-style binding made in this buffer is in effect,
does not make the variable buffer-local.

I think I'm doing the 2nd phrase -- right?  But then I get confused and
I don't understand why my other example works because it is inside
a let binding a well.  Even if I remove my let, I am likely going to be
inside a let but whoever is calling down to the function I am advising.

Thank you for your help,
Perry

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail


reply via email to

[Prev in Thread] Current Thread [Next in Thread]