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

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

Re: replacing a function with another one


From: lee
Subject: Re: replacing a function with another one
Date: Tue, 11 Mar 2014 05:11:18 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

Michael Heerdegen <michael_heerdegen@web.de> writes:

> lee <lee@yun.yagibdah.de> writes:
>
>> > Instead, use an auxiliary variable, e.g.
>>
>> Hm, I have experimented with variables and found that things don´t work
>> when the variables are local.  But then, I can´t get add-advice to work,
>> not even with global variables.  It´s too complicated, and the
>> documentation is not understandable at all.
>>
>> It also seems that it is not possible at all to make a mode on top of
>> hi-lock-mode which does what I want.  Variables have to be local per
>> buffer, and with that, it´s not possible to read patterns from different
>> buffers because the variables change because buffers must be switched to
>> read the patterns.
>
> Please don't get confused.  Use global auxiliary variables for things
> that reflect buffer independent states.

But these things are not global.  There is a combination of buffer A and
buffer B, buffer C, ..., buffer N.  The buffers B..N can all contain
patterns that need to be read and used to for highlighting with buffer
A.

To keep it simple, I have assumed that there is only buffer A and buffer
B.  Support for multiple buffers might be added later.

Now for buffer A, it must be remembered that its patters are in buffer
B.  That goes for multiple combinations of buffers A and B.

When the variables used to remember this are global, there can only be a
single combination of buffers.

I have experimented with defvar-local:


(defvar-local test nil)

(defun foo
(setq test (current-buffer))
(message "test-1 %s" (buffer-name test))
(find-file "some.file")
(message "test-2 %s" (buffer-name test)))


When you call foo, the value of test will change according to the
current buffer.  So you cannot use a local variable.  Use a global one
and it doesn´t change, but then you don´t know anymore from which buffer
patterns were used for which buffer when you do it with multiple files.

> And you can always get the buffer local binding of a variable foo in
> any buffer b with
>
>   (with-current-buffer b foo)
>
> There is no limitation from the Emacs' side.

But then I don´t have the variables from the buffer I´m doing this from.

> Mmh, ok, let's start from the beginning and simple.  Let's add some
> mechanism that allows to specify additional, directory local hi-lock
> patterns.  That should be simple as this:
>
>     (defvar hi-lock-dir-patterns nil)  ;; use as dir local variable
>     
>     (advice-add
>      'hi-lock-find-patterns :after
>      (lambda (&rest _)
>        (hi-lock-set-file-patterns
>         (append hi-lock-file-patterns
>                 hi-lock-dir-patterns))))
>

I can´t get advice-add to work.  The documentation doesn´t explain it,
and google doesn´t find any examples.  It either doesn´t work, or I´m
getting weird error messages that don´t tell me anything.  Code that
works fine when used in a function suddenly gives an error message that
says that setq is an invalid function.  Remove the (setq something
tosomething) and suddenly all the rest of the function is invalid for no
reason.

> The advice just merges in the additional patterns.

Well, it can only be used :before or :after.  Using it :before didn´t
work because I had to switch buffers in the prepended part, and
apparently after that part was completed, the buffer was switched back.

> Note that using directory local variables has the advantage that me
> must not explicitly look up the patterns, because the directory local
> variable is automatically bound when the file is opened.

?

> This should be all to do as long as you don't want to automatically save
> additional patterns

That is one of the next steps.  With add-advice, It´s not working at all
atm.

> - you have to add them yourself in the .dir-locals
> file.
>
> If you want such automatic saving, we would just have to substitute the
> dir local variable with a mechanism that loads and saves explicitly.  Is
> this what you want?

I simply want to store the patterns in one (and at some time multiple)
different buffers rather than in the buffer they are applied to.  I want
that to work transparently, for saving, loading and keeping the patterns
up to date (i. e. when something that used to be highlighted is
completely removed, the pattern for it needs to be removed, too),
without duplicates.  To assign a file A with patterns to another file B, I
just want to put a line into file B so that the patterns in file A are
used to highlight file B.  File A can than be used with many files B.

Once that works, the files A could have multiple lines in them to use
patterns from multiple files B.

Files B do not need to have patterns in themselves, though it would be
nice if they could.


Sigh ... Any idea why the following does not work:


(defvar ext-hi-lock-original-buffer nil
  "Remember the buffer for which hi-lock highlighting-patterns
  that are being read from another buffer are to be applied to
  --- that is the original buffer.")


(defvar ext-hi-lock-patterns-buffer nil)


(defvar ext-hi-lock-disable-all nil)


(defun my-test-unless ()
  (interactive)
  (unless ext-hi-lock-disable-all
    (message "enabled")))


;;
;; functions modifying functions in hi-lock.el
;;

(defun ext-hi-lock-find-other-patterns ()
  "See if there is a line in the current buffer specifying that
hi-lock highlighting-patterns should be read from another
file. When the line is found, visit the other file and read the
patterns from its buffer, then apply them to the current buffer."
  (unless ext-hi-lock-disable-all
    ;; (when (not ext-hi-lock-original-buffer)
    (setq ext-hi-lock-original-buffer (current-buffer))
    (save-excursion
      (save-restriction
        (widen)
        (goto-char (point-min))
        (when (re-search-forward "^// ext-fontify-defs: " nil t)
          (let ((filename (thing-at-point 'filename)))
            (when filename
              (when (file-exists-p filename)
                (message "start: original-buffer: %s, current-b: %s"
                         (buffer-name ext-hi-lock-original-buffer)
                         (buffer-name (current-buffer)))
                (setq ext-hi-lock-patterns-buffer (find-file-noselect filename))
                (message "found file: original-buffer: %s, current-b: %s"
                         (buffer-name ext-hi-lock-original-buffer)
                         (buffer-name (current-buffer)))
                (when ext-hi-lock-patterns-buffer
                  (message "get patterns from %s"
                           (buffer-name ext-hi-lock-patterns-buffer))
                  (set-buffer ext-hi-lock-patterns-buffer)
                  (setq ext-hi-lock-disable-all t)
                  (set-auto-mode-0 'hi-lock-mode t)
                  (setq ext-hi-lock-disable-all nil)
                  (message "buffer set: original-buffer: %s, current-b: %s"
                           (buffer-name ext-hi-lock-original-buffer)
                           (buffer-name (current-buffer)))
                  ;; search the whole buffer for patterns
                  (setq hi-lock-file-patterns-range (point-max)))))))))))


(advice-add
 'hi-lock-find-patterns :before
 'ext-hi-lock-find-other-patterns)

(advice-add
 'hi-lock-set-file-patterns :before
 (lambda (patterns)
   (my-test-unless)
   (unless ext-hi-lock-disable-all
     (message "set on buffer: %s"
              (buffer-name (current-buffer)))
     (set-buffer ext-hi-lock-original-buffer)
     (message "set now buffer: %s --- should be buffer %s"
              (buffer-name (current-buffer))
              (buffer-name ext-hi-lock-original-buffer))
     (setq ext-hi-lock-disable-all t)
     (hi-lock-set-file-patterns patterns)
     (setq ext-hi-lock-disable-all nil)
     ))
 '((name . ext-hi-lock-switch-to-original-buffer)))


(defun ext-hi-lock-message (unused)
  (message "patterns probably from %s for %s"
           ext-hi-lock-patterns-buffer
           ext-hi-lock-original-buffer))

(setq hi-lock-file-patterns-policy 'ext-hi-lock-message)


It just doesn´t apply the patterns.  For unknown reasons,
hi-lock-set-file-patterns is not called when the original buffer has a
line in it to pull in patterns from another buffer.


-- 
Knowledge is volatile and fluid.  Software is power.



reply via email to

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