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

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

Re: ~`symbol-function' to get code as list even when byte-compiled?


From: Pascal J. Bourguignon
Subject: Re: ~`symbol-function' to get code as list even when byte-compiled?
Date: Mon, 25 May 2015 19:37:47 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Emanuel Berg <embe8573@student.uu.se> writes:

> Barry Margolin <barmar@alum.mit.edu> writes:
>
>> You can probably prevent it from being compiled,
>> maybe something like:
>>
>> (setf (symbol-function 'number-one-jump) '(lambda
>> (&optional not-used) ...))
>
> Yeah, but if I were to do special treatment, then
> I might as well put
>
>     (remove-hook 'w3m-display-hook 'number-one-jump)
>
> in "number-one-jump" and have it compiled like
> all others!
>
> The reason for this idea, which I should have said in
> the OP, is that I have many such jump functions, e.g.:
>
>     (defun emacs-wiki-jump (&optional not-used)
>       (if (search-forward "EmacsWiki" (point-max) t)
>           (beginning-of-line) ))
>
>     (defun urban-jump (&optional not-used)
>       (when (search-forward "Top Definition" (point-max) t)
>         (w3m-next-anchor)
>         (recenter-top-bottom 0) ))
>
> So instead of putting the corresponding remove-hook in
> every one, this is what "enable-jump" does. Only it
> doesn't work if the jump functions are compiled, which
> didn't occurred to me when I got the idea and wrote
> the code.
>
>> But can't you do something equivalent by using
>> advice instead of self-modifying code?
>
> Possibly - how would that work?

You could do something like this:

(defun split-body (body)
  (loop
    with docstring = nil
    with declarations = '()
    for forms on body
    while (and forms
               (cond
                 ((stringp (first forms)) (not docstring))
                 ((listp (first forms))
                  (member (first (first forms)) '(interactive declare)))
                 (t nil)))
    do (if (stringp (first forms))
           (setf docstring (first forms))
           (push (first forms) declarations))
    finally (return (list docstring (nreverse declarations) forms))))


(defmacro define-jump (name lamda-list &rest body)
  (destructuring-bind (docstring declarations body) (split-body body)
    `(progn
       (setf (get ',name 'jump-enabled) (list t nil))
       (defun ,name ,lambda-list
        ,@(when docstring (list docstring))
        ,@declarations
        (when (second (get ',name 'jump-enabled))
          (remove-hook 'w3m-display-hook (quote ,name))
          (setf (second (get ',name 'jump-enabled)) nil))
        ,@body))))

(defun enable-jump (name)
  (unless (first (get name 'jump-enabled))
    (error "%S is not a defined jump." name))
  (setf (second (get name 'jump-enabled)) t)
  (add-hook 'w3m-display-hook name))

(define-jump number-one-jump (&optional not-used) ; Google, Youtube
  (when (re-search-forward "^ 1." (point-max) t)
    (recenter-top-bottom 0)
    (w3m-next-anchor)))


(defun web-search ()
  (interactive)
  (let ((search (get-search-string "Google")))
    (unless (empty-string-p search)
      (w3m-new-tab (format "Google: %s" search))
      (w3m-search w3m-search-default-engine search) ))
  (enable-jump 'number-one-jump))




-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk




reply via email to

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