unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-22 13:54 Is there a "selective setq locator/highlighter" anywhere? Alan Mackenzie
@ 2009-01-22 13:44 ` Lennart Borgman
  2009-01-22 16:23   ` Stefan Monnier
  2009-01-23 15:41   ` Alan Mackenzie
  2009-01-22 14:49 ` Stefan Monnier
  2009-01-22 18:06 ` Davis Herring
  2 siblings, 2 replies; 9+ messages in thread
From: Lennart Borgman @ 2009-01-22 13:44 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

On Thu, Jan 22, 2009 at 2:54 PM, Alan Mackenzie <acm@muc.de> wrote:
> Hi, Emacs!
>
> I sometimes have problems with long rambling elisp defuns, in that some
> critical variable, say `c-state-cache' is updated in several (or even
> many) places in the defun, and it's difficult to see the places it gets
> changed.
>
> Hi-lock-mode is helpful here, in that I can highlight occurances of
> "c-state-cache" and occurances of "setq".  But the longer and ramblinger
> a defun becomes, the less helpful is this.
>
> I would like a tool which would highlight these:
>
>    (setq foo bar
>          c-state-cache (cdr c-state-cache))
>    (setcar c-state-cache (caar c-state-cache))

Can't you catch this with a regexp? (And I never understood what the
multi setq is good for.)

> , but not this:
>
>    (setq old-cache c-state-cache)
>
> .  Does anybody know of anything like this in existance?
>
> Thanks!
>
> --
> Alan Mackenzie (Nuremberg, Germany).
>
>
>




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Is there a "selective setq locator/highlighter" anywhere?
@ 2009-01-22 13:54 Alan Mackenzie
  2009-01-22 13:44 ` Lennart Borgman
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Alan Mackenzie @ 2009-01-22 13:54 UTC (permalink / raw)
  To: emacs-devel

Hi, Emacs!

I sometimes have problems with long rambling elisp defuns, in that some
critical variable, say `c-state-cache' is updated in several (or even
many) places in the defun, and it's difficult to see the places it gets
changed.

Hi-lock-mode is helpful here, in that I can highlight occurances of
"c-state-cache" and occurances of "setq".  But the longer and ramblinger
a defun becomes, the less helpful is this.

I would like a tool which would highlight these:

    (setq foo bar
          c-state-cache (cdr c-state-cache))
    (setcar c-state-cache (caar c-state-cache))

, but not this:

    (setq old-cache c-state-cache)

.  Does anybody know of anything like this in existance?

Thanks!

-- 
Alan Mackenzie (Nuremberg, Germany).




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-22 13:54 Is there a "selective setq locator/highlighter" anywhere? Alan Mackenzie
  2009-01-22 13:44 ` Lennart Borgman
@ 2009-01-22 14:49 ` Stefan Monnier
  2009-01-22 18:06 ` Davis Herring
  2 siblings, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2009-01-22 14:49 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

> I sometimes have problems with long rambling elisp defuns, in that some
> critical variable, say `c-state-cache' is updated in several (or even
> many) places in the defun, and it's difficult to see the places it gets
> changed.

> Hi-lock-mode is helpful here, in that I can highlight occurances of
> "c-state-cache" and occurances of "setq".  But the longer and ramblinger
> a defun becomes, the less helpful is this.

> I would like a tool which would highlight these:

>     (setq foo bar
>           c-state-cache (cdr c-state-cache))
>     (setcar c-state-cache (caar c-state-cache))

> , but not this:

>     (setq old-cache c-state-cache)

> .  Does anybody know of anything like this in existance?

I don't.  But you could start by changing all your (setq var1 val1 var2
val2 ...) forms so as to only use (setq var val).  That should make it
a lot easier.


        Stefan




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-22 13:44 ` Lennart Borgman
@ 2009-01-22 16:23   ` Stefan Monnier
  2009-01-23 15:41   ` Alan Mackenzie
  1 sibling, 0 replies; 9+ messages in thread
From: Stefan Monnier @ 2009-01-22 16:23 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: Alan Mackenzie, emacs-devel

> (And I never understood what the multi setq is good for.)

Nothing,


        Stefan




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-22 13:54 Is there a "selective setq locator/highlighter" anywhere? Alan Mackenzie
  2009-01-22 13:44 ` Lennart Borgman
  2009-01-22 14:49 ` Stefan Monnier
@ 2009-01-22 18:06 ` Davis Herring
  2009-01-23 15:58   ` Is there a "selective setq locator/highlighter" anywhere? There is now! Alan Mackenzie
  2 siblings, 1 reply; 9+ messages in thread
From: Davis Herring @ 2009-01-22 18:06 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

> I would like a tool which would highlight these:
>
>     (setq foo bar
>           c-state-cache (cdr c-state-cache))
>     (setcar c-state-cache (caar c-state-cache))
>
> , but not this:
>
>     (setq old-cache c-state-cache)

Not a polished tool, by any means, but can't you just do

;; Handles set, setq, setcar, setcdr
(save-excursion
  (save-restriction
    (widen)
    (goto-char (point-min))
    (while (re-search-forward "(set\\(q?\\|c[ad]r\\)\\>" nil t)
      (skip-syntax-forward "^ >")
      (while
          (progn
            (skip-syntax-forward " >'p")
            (when (looking-at "c-state-cache")
              (let ((o (make-overlay (point) (match-end 0) nil t)))
                (overlay-put o 'face 'highlight)
                (overlay-put o 'c-state-cache t)
                (overlay-put o 'evaporate t)))
            (ignore-errors (forward-sexp 2) t))))))

;; Putting the (meaningless) "c-state-cache" property
;; on the overlay means we can remove them easily:
(remove-overlays nil nil 'c-state-cache t)

Wrap in defuns/commands as desired.

Davis

-- 
This product is sold by volume, not by mass.  If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-23 15:41   ` Alan Mackenzie
@ 2009-01-23 15:36     ` Lennart Borgman
  2009-01-23 16:12       ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2009-01-23 15:36 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

On Fri, Jan 23, 2009 at 4:41 PM, Alan Mackenzie <acm@muc.de> wrote:
> On Thu, Jan 22, 2009 at 02:44:11PM +0100, Lennart Borgman wrote:
>> On Thu, Jan 22, 2009 at 2:54 PM, Alan Mackenzie <acm@muc.de> wrote:
>> > Hi, Emacs!
>
> [ .... ]
>
>> > I would like a tool which would highlight these:
>
>> >    (setq foo bar
>> >          c-state-cache (cdr c-state-cache))
>> >    (setcar c-state-cache (caar c-state-cache))
>
>> Can't you catch this with a regexp? (And I never understood what the
>> multi setq is good for.)
>
> A regexp will only work in practice, sort of, not in theory.  In
> particular, regexps (which are mathematically equivalent to finite state
> machines) can't parse arbitrarily nested structures (for which one needs
> a push-down automaton or suchlike.

I believe saving state is not needed here. Can't you use something like

   (setq \(\w+ \w+\)*[ \t\n\r]+?c-state-cache




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-22 13:44 ` Lennart Borgman
  2009-01-22 16:23   ` Stefan Monnier
@ 2009-01-23 15:41   ` Alan Mackenzie
  2009-01-23 15:36     ` Lennart Borgman
  1 sibling, 1 reply; 9+ messages in thread
From: Alan Mackenzie @ 2009-01-23 15:41 UTC (permalink / raw)
  To: Lennart Borgman; +Cc: emacs-devel

On Thu, Jan 22, 2009 at 02:44:11PM +0100, Lennart Borgman wrote:
> On Thu, Jan 22, 2009 at 2:54 PM, Alan Mackenzie <acm@muc.de> wrote:
> > Hi, Emacs!

[ .... ]

> > I would like a tool which would highlight these:

> >    (setq foo bar
> >          c-state-cache (cdr c-state-cache))
> >    (setcar c-state-cache (caar c-state-cache))

> Can't you catch this with a regexp? (And I never understood what the
> multi setq is good for.)

A regexp will only work in practice, sort of, not in theory.  In
particular, regexps (which are mathematically equivalent to finite state
machines) can't parse arbitrarily nested structures (for which one needs
a push-down automaton or suchlike.

> > .  Does anybody know of anything like this in existance?

Anyhow, I've thrown together a requisite piece of software.  See another
post.

-- 
Alan Mackenzie (Nuremberg, Germany).




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere? There is now!
  2009-01-22 18:06 ` Davis Herring
@ 2009-01-23 15:58   ` Alan Mackenzie
  0 siblings, 0 replies; 9+ messages in thread
From: Alan Mackenzie @ 2009-01-23 15:58 UTC (permalink / raw)
  To: Davis Herring; +Cc: emacs-devel

Hi, Davis!

On Thu, Jan 22, 2009 at 10:06:28AM -0800, Davis Herring wrote:
> > I would like a tool which would highlight these:

> >     (setq foo bar
> >           c-state-cache (cdr c-state-cache))
> >     (setcar c-state-cache (caar c-state-cache))

> > , but not this:

> >     (setq old-cache c-state-cache)

> Not a polished tool, by any means, but can't you just do

[ .... ]

> Wrap in defuns/commands as desired.

Thanks!  In the end, I just threw it together, and it rapidly converged
to something functional.  It handles setq, setc[ad]r and let\*?,
arbitrarily nested.  For some reason, I was thinking of a solution which
would first read (as in read/eval/print loop) a defun and then step
through the structure.  This was silly.  ;-)  Anyhow, here it is for
anybody interested.  It uses hi-lock-mode a little bit:

#########################################################################
;; Selective setq highlighting:
;;
;; Given a symbol, locate and/or highlight all places where the symbol's value
;; is changed; currently this means "(setq foo" (including multiple versions
;; of it), "(setcar foo" or "(setcdr foo", or "(let (...(foo ..)" or
;; "(let*...".

(defun sshi-forward-WS ()
  (save-match-data
    (forward-comment 1048575)
    (search-forward-regexp "[[:space:]]*")))

(defun sshi-sym-value ()
  "Parse the symbol followed by a sexp at point.
Return the positions of the symbol/sexp as a dotted pair of
dotted pairs like this
    ((SYM-START . SYM-END) . (SEXP-START . SEXP-END)).
Point is left after any WS/comments at sexp-end.
On error, throw an error."
  (let (sym-pos sexp-start)
    (if (looking-at "\\(\\(\\w\\|\\s_\\)+\\_>\\)") ; a symbol.
	;;             1  2            2       1
	(progn
	  (setq sym-pos (cons (match-beginning 1) (match-end 1)))
	  (goto-char (match-end 0))
	  (sshi-forward-WS)
	  (setq sexp-start (point))
	  (condition-case nil
	      (forward-sexp)
	    (error
	     (error "sshi-sym-value: invalid sexp at %s" (point)))))
      (error "sshi-sym-value: missing symbol at %s" (point)))
    (prog1 (cons sym-pos (cons sexp-start (point)))
      (sshi-forward-WS))))

(defun sshi-push-sym-sexps (sym places)
  "  Push the locations of SYM settings onto PLACES, returning PLACES.
This includes any setq's etc. recursively contained in the sexp.
Point should be at a symbol in a \"setq\" type construct.  Point
is left after WS/comments after the sexp."
  (let ((sym-val (sshi-sym-value)))
    (if (string=
	 (buffer-substring-no-properties (caar sym-val) (cdar sym-val))
	 sym)
	(push (car sym-val) places))
    (when (eq (char-after (cadr sym-val)) ?\()
      (goto-char (cadr sym-val))
      (setq places
	    (append (save-restriction
		      (narrow-to-region (cadr sym-val) (cddr sym-val))
		      (sshi-list sym))
		    places))
      (sshi-forward-WS))
    places))

(defun sshi-list (sym)
  "Return a list of places within the current restriction where SYM is set.
This is a list of dotted pairs of the form (BEGIN-SYM . END-SYM).

The current restriction should exactly contain a list, and point
should be at (point-min) on entry.  Point is left at (point-max)
at exit."
  (let (places sym-start)
    (forward-char)			; over ?\(
    (sshi-forward-WS)
    (while (/= (char-after) ?\))
      (cond
       ((looking-at "(\\(setc[ad]r\\_>\\)")
	(goto-char (match-end 0)) (sshi-forward-WS)
	(setq places (sshi-push-sym-sexps sym places))
	(sshi-forward-WS)
	(forward-char)			; over ?\)
	(sshi-forward-WS))

       ((looking-at "(\\(setq\\_>\\)")
	(goto-char (match-end 0)) (sshi-forward-WS)
	(while (/= (char-after) ?\))
	  (setq places (sshi-push-sym-sexps sym places))
	  (sshi-forward-WS))
	(forward-char) (sshi-forward-WS)) ; over ?\)

       ((looking-at "(\\(let\\*?\\_>\\)")
	(goto-char (match-end 0)) (sshi-forward-WS)
	(or (eq (char-after) ?\()
	    (error "sshi: missing bindings list at %s" (point)))
	(forward-char) (sshi-forward-WS) ; over ?\(
	(while (/= (char-after) ?\))
	  (if (eq (char-after) ?\()	; binding with initialisation
	      (progn
		(forward-char) (sshi-forward-WS) ; over ?\( of a single binding.
		(setq places (sshi-push-sym-sexps sym places))
		(forward-char))		; over terminating ?\) of the binding
	    (setq sym-start (point))  ; symbol (initialised implicitly to nil)
	    (forward-sexp)
	    (if (string= (buffer-substring sym-start (point)) sym)
		(push (cons sym-start (point)) places))
	    (sshi-forward-WS)))
	(forward-char) (sshi-forward-WS)) ; over ?\) enclosing all bindings
	
       ((eq (char-after) ?\()
	(mark-sexp)
	(save-restriction
	  (narrow-to-region (point) (mark))
	  (setq places (append (sshi-list sym) places)))
	(sshi-forward-WS))

       (t (forward-sexp) (sshi-forward-WS))))
    (forward-char)			; over ?\)
    places))

(defvar sshi-symbol-hist nil
  "The symbol history list used by selective-setq")
(defun sshi-defun (arg sym face)
  "Highlight SYM each place within the current defun where it is setq'd or setc[ad]r'd.
With a prefix arg, remove the highlighting for SYM."
  (interactive
   (list
    current-prefix-arg
    (let* ((sym (symbol-at-point))
	   (s (and sym (symbol-name sym))))
      (read-string
       "Symbol: "				; prompt
       s					; initial-input
       'sshi-symbol-hist			; history
       s))
    (unless current-prefix-arg (hi-lock-read-face-name))))

  (save-excursion
    (save-restriction
      (narrow-to-defun)
      ;(beginning-of-defun)
      (goto-char (point-min))	       ; beginning-of-defun drops a mark.  :-(
      (let ((places (sshi-list sym)))
	(mapc
	 (lambda (elt)
	   (let* (ov ovs)
	     (setq ovs (overlays-at (car elt)))
	     (while (and ovs
			 (setq ov (car ovs))
			 (not (overlay-get ov 'sshi)))
	       (setq ovs (cdr ovs)))
	     (when ovs
	       (delete-overlay ov))
	     (unless arg
	       (setq ov (make-overlay (car elt) (cdr elt) nil nil nil))
	       (overlay-put ov 'sshi t)
	       (overlay-put ov 'face face))))
	 places)))))

(define-key emacs-lisp-mode-map "\C-xwz" 'sshi-defun)
#########################################################################
> Davis

-- 
Alan Mackenzie (Nuremberg, Germany).




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is there a "selective setq locator/highlighter" anywhere?
  2009-01-23 15:36     ` Lennart Borgman
@ 2009-01-23 16:12       ` Lennart Borgman
  0 siblings, 0 replies; 9+ messages in thread
From: Lennart Borgman @ 2009-01-23 16:12 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: emacs-devel

On Fri, Jan 23, 2009 at 4:36 PM, Lennart Borgman
<lennart.borgman@gmail.com> wrote:
> On Fri, Jan 23, 2009 at 4:41 PM, Alan Mackenzie <acm@muc.de> wrote:
>> On Thu, Jan 22, 2009 at 02:44:11PM +0100, Lennart Borgman wrote:
>>> On Thu, Jan 22, 2009 at 2:54 PM, Alan Mackenzie <acm@muc.de> wrote:
>>> > Hi, Emacs!
>>
>> [ .... ]
>>
>>> > I would like a tool which would highlight these:
>>
>>> >    (setq foo bar
>>> >          c-state-cache (cdr c-state-cache))
>>> >    (setcar c-state-cache (caar c-state-cache))
>>
>>> Can't you catch this with a regexp? (And I never understood what the
>>> multi setq is good for.)
>>
>> A regexp will only work in practice, sort of, not in theory.  In
>> particular, regexps (which are mathematically equivalent to finite state
>> machines) can't parse arbitrarily nested structures (for which one needs
>> a push-down automaton or suchlike.
>
> I believe saving state is not needed here. Can't you use something like
>
>   (setq \(\w+ \w+\)*[ \t\n\r]+?c-state-cache

Eh, though that does not work of course if the value part is more
complicated. You are right, state must be saved here.




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-01-23 16:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-22 13:54 Is there a "selective setq locator/highlighter" anywhere? Alan Mackenzie
2009-01-22 13:44 ` Lennart Borgman
2009-01-22 16:23   ` Stefan Monnier
2009-01-23 15:41   ` Alan Mackenzie
2009-01-23 15:36     ` Lennart Borgman
2009-01-23 16:12       ` Lennart Borgman
2009-01-22 14:49 ` Stefan Monnier
2009-01-22 18:06 ` Davis Herring
2009-01-23 15:58   ` Is there a "selective setq locator/highlighter" anywhere? There is now! Alan Mackenzie

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.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).