The attached patch improves the interaction between SLIME-HIGHLIGHT-EDITS-MODE and SLIME-MACROEXPANSION-MINOR-MODE such that macroexpanding in-place will highlight the affected region only. Same happens when going-back to the previous macroexpansion by `undo'.
It depends on my last patch which introduces the global variable SLIME-USE-HIGHLIGH-EDITS-MODE.
One issue remains: As of now, it's possible to get to an empty Macroexpansion Buffer by `undo'. I have a local hack that all it basically does, is
(remap 'undo (lambda (arg) ... (undo arg) (when (zerop (buffer-size)) (redo))))
Though, as you see, that makes use of redo.el which is not part of standard Emacs, unfortunately.
2006-05-18 Tobias C. Rittweiler <PUT-MY-ADDRESS-HERE>
* slime.el (slime-get-temp-buffer-create): New keyword REUSEP which indicates whether an already-existing buffer named like the buffer to be created should be reused, i.e. not killed, then freshly created. Update docstring accordingly. (slime-with-output-to-temp-buffer): Make &optional arg MODE an &key keyword arg. Add REUSEP keyword.
* slime.el (slime-macroexpansion-minor-mode-map): Make remapped `undo' update highlighted edits in the macroexpansion buffer. (slime-eval-macroexpand-in-place): Update highlighted edits when macroexpanding in-place. (slime-eval-macroexpand): Reuse macroexpansion buffer if it exists already to preserve `undo' functionality.
--- /home/tcr/src/from-upstream/slime/slime.el 2006-05-18 16:25:50.000000000 +0200 +++ slime.el 2006-05-18 16:34:01.000000000 +0200 @@ -1186,16 +1190,19 @@ "The window config "fingerprint" after displaying the buffer."))
;; Interface -(defun* slime-get-temp-buffer-create (name &key mode noselectp) +(defun* slime-get-temp-buffer-create (name &key mode noselectp reusep) "Return a fresh temporary buffer called NAME in MODE. The buffer also uses the minor-mode `slime-temp-buffer-mode'. Pressing `q' in the buffer will restore the window configuration to the way it is when the buffer was created, i.e. when this function was called.
-If NOSELECTP is true then the buffer is shown by `display-buffer', -otherwise it is shown and selected by `pop-to-buffer'." +If NOSELECTP is true, then the buffer is shown by `display-buffer', +otherwise it is shown and selected by `pop-to-buffer'. + +If REUSEP is true and a buffer does already exist with name NAME, +then the buffer will be reused instead of being killed." (let ((window-config (current-window-configuration))) - (when (get-buffer name) (kill-buffer name)) + (when (and (get-buffer name) (not reusep)) (kill-buffer name)) (with-current-buffer (get-buffer-create name) (when mode (funcall mode)) (slime-temp-buffer-mode 1) @@ -1208,14 +1215,17 @@ (current-buffer))))
;; Interface -(defmacro* slime-with-output-to-temp-buffer ((name &optional mode) +(defmacro* slime-with-output-to-temp-buffer ((name &key mode reusep) package &rest body) "Similar to `with-output-to-temp-buffer'. Also saves the window configuration, and inherits the current `slime-connection' in a buffer-local variable." `(let ((connection (slime-connection)) - (standard-output (slime-get-temp-buffer-create ,name :mode ',mode))) - (prog1 (with-current-buffer standard-output ,@body) + (standard-output (slime-get-temp-buffer-create ,name :mode ',mode + :reusep ,reusep))) + (prog1 (with-current-buffer standard-output + ;; set explicitely to NIL in case the buffer got reused. (REUSEP) + (let ((buffer-read-only nil)) ,@body)) (with-current-buffer standard-output (setq slime-buffer-connection connection) (setq slime-buffer-package ,package) @@ -7018,7 +7028,7 @@ (defun slime-show-apropos (plists string package summary) (if (null plists) (message "No apropos matches for %S" string) - (slime-with-output-to-temp-buffer ("*SLIME Apropos*" apropos-mode) package + (slime-with-output-to-temp-buffer ("*SLIME Apropos*" :mode apropos-mode) package (set-syntax-table lisp-mode-syntax-table) (slime-mode t) (if (boundp 'header-line-format) @@ -7338,6 +7348,8 @@ (remap 'undo '(lambda (&optional arg) (interactive) (let ((buffer-read-only nil)) + (when slime-use-highlight-edits-mode + (slime-remove-edits (point-min) (point-max))) (undo arg)))))
(defvar slime-eval-macroexpand-expression nil @@ -7353,8 +7365,10 @@ slime-eval-macroexpand-expression (lambda (expansion) (slime-with-output-to-temp-buffer - ("*SLIME macroexpansion*" lisp-mode) package + ;; reusep for preserving `undo' functionality. + ("*SLIME macroexpansion*" :mode lisp-mode :reusep t) package (slime-macroexpansion-minor-mode) + (erase-buffer) (insert expansion) (font-lock-fontify-buffer))))))
@@ -7373,6 +7387,8 @@ (lambda (expansion) (with-current-buffer buffer (let ((buffer-read-only nil)) + (when slime-use-highlight-edits-mode + (slime-remove-edits (point-min) (point-max))) (goto-char start) (delete-region start end) (insert expansion)