Attached are two code snippets that I came up with since I started
using slime a few weeks ago. Probably there exist better ways to do
these things, but I couldn't find them so I wrote my own. If there
really isn't an existing way to do these things, perhaps they could be
added to Slime.
The first is intended to facilitate debugging. Often I find myself in
an sldb buffer looking at a stack trace and it's not clear what went
wrong. I'd like to evaluate some expressions in the stack frame to
see intermediate results, but I don't want to type them in again.
After all, I already typed them in and they're sitting there in the
source file. So I type "v" in the debug buffer, put the point in an
interesting place and execute gsn/slime-eval-last-expression-in-frame.
It finds the sexp at point, switches to the sldb buffer, evaluates the
expression, and then switches back. One sub-optimal thing is that the
frame in which the expression is evaluated depends on hte position of
the point in the sldb buffer even though you use the command in your
source buffer. But using sldb-show-source, this seems to work fairly
well.
The second set of functions is alters
slime-next-note/slime-previous-note to scan through certain types of
compiler notes, rather than hitting them all. I found that I was
getting zillions of notes and the errors were getting lost in the
mix. So gsn/slime-next-not and gsn/slime-previous-note by default
scan through all notes. However, with a prefix arg, they prompt for a
type of error and henceforth stop only at that type of note.
Comments/suggestions on style/implementation are welcome.
Greg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun gsn/slime-eval-last-expression-in-frame (sexp)
"Eval the expression at POINT in a frame in the slime debugger.
The frame used is determined by the location of POINT in the
slime debugger buffer. The idea is to be able to be able to
debug by using sldb-show-source in the slime debug buffer and
then easily evaluate expression in your source file near the
problem."
(interactive (list (slime-last-expression)))
(if (not (sldb-get-default-buffer))
(error "No debugger buffer")
(save-excursion
(set-buffer (sldb-get-default-buffer))
(sldb-eval-in-frame sexp))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar gsn/slime-scan-note-by-type-history nil
"List storing history of entries to minibuffer prompt in
gsn/slime-read-type")
(defvar gsn/slime-scan-note-by-type-current
'(:error :read-error :warning :style-warning :note)
"Current type of note for which to search. This is stored so
that the behavior is 'sticky' between invocations of the
commands.")
(defun gsn/slime-next-note (reset-type)
"Interactively search for the next compiler note of the type
given by gsn/slime-scan-note-by-type-current. With prefix arg,
prompt for the value of gsn/slime-scan-note-by-type-current."
(interactive "P")
(when reset-type
(gsn/slime-read-type))
(gsn/slime-next-note-by-type gsn/slime-scan-note-by-type-current))
(defun gsn/slime-previous-note (reset-type)
"Interactively search for the previous compiler note of the
type given by gsn/slime-scan-note-by-type-current. With prefix
arg, prompt for the value of
gsn/slime-scan-note-by-type-current."
(interactive "P")
(when reset-type
(gsn/slime-read-type))
(gsn/slime-previous-note-by-type gsn/slime-scan-note-by-type-current))
(defun gsn/slime-read-type ()
"Prompt for the value of gsn/slime-scan-note-by-type-current.
Store history (as strings) in
gsn/slime-scan-note-by-type-history. Convert the string to a
symbol and set gsn/slime-scan-note-by-type-current."
(let ((type-string (completing-read "Type (default error): "
'("all"
"error"
"read-error"
"warning"
"style-warning"
"note")
nil t nil
'gsn/slime-scan-note-by-type-history
"error")))
(push type-string gsn/slime-scan-note-by-type-history)
(setq gsn/slime-scan-note-by-type-current
(cdr (assoc type-string
'(("all" . (:error :read-error :warning
:style-warning :note))
("error" . (:error))
("read-error" . (:read-error))
("warning" . (:warning))
("style-warning" . (:style-warning))
("note" . (:note))))))))
(defun gsn/slime-scan-note-by-type (type scan-func)
"Move point to the next/previous compiler note of type TYPE.
SCAN-FUNC specifies how to advance through the notes so that this
function doens't have to be duplicated for -next- and -previous-"
(let ((original-pos (point))
(last-pos (point))
(sought-note-p
(lambda (type)
(and (slime-note-at-point)
(memq (overlay-get (slime-note-at-point) 'severity)
type)))))
(funcall scan-func)
(while (and (/= last-pos (point))
(not (funcall sought-note-p type)))
(setq last-pos (point))
(funcall scan-func))
;; let the user know if there are no more notes
(if (funcall sought-note-p type)
(slime-show-note (slime-note-at-point))
;; If no next note, go back to where you started
(goto-char original-pos)
(message "No more notes."))))
(defun gsn/slime-next-note-by-type (type)
"Move point to the next compiler note of type TYPE."
(gsn/slime-scan-note-by-type type 'slime-find-next-note))
(defun gsn/slime-previous-note-by-type (type)
"Move point to the next/previous compiler note of type TYPE."
(gsn/slime-scan-note-by-type type 'slime-find-previous-note))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;