[slime-devel] Re: some conveniences for slime-repl

Håkon Alstadheim haalst at online.no
Wed Dec 10 21:11:38 UTC 2003


Andreas Fuchs <asf at boinkor.net> wrote:
> Today, Luke Gorrie <luke at bluetail.com> wrote:
> > You mean like C-a but working from any line?
> > Maybe a job for C-M-u (backward-up-list)?
> 
> Something like that; anything that takes (point) to the true beginning
> of the input and not to the beginning of the line would be fine. I'd
> just like to have a way to navigate large expressions easily (-:

Comint mode has C-c C-p to go to previous prompt. This is taken in the
slime-repl by slime-pprint-eval-last-expression, which is not really
needed in the repl I think. Unbind that and bind to
comint-previous-prompt, and you're partway there. My problem is then:
if what comes between the prompts is only OUTPUT,
comint-previous-prompt will not work because it is looking for the
start of the previous input. This is not a problem in the normal
comint modes, because you always have some input before you get any
output. With lisp, which can be provoked to do output either from a
running thread or something coming in on the slime connection, this is
not good enough. I suggest removing :inferior t from the \C-p the
'slime-keys' variable, and adding something like (tested for 5
minutes):

(defun slime-repl-previous-prompt (n)
 "Move to end of Nth previous prompt in the buffer.
Unlike comint mode `comint-use-prompt-regexp-instead-of-fields' has no
effect, and we look for a read-only (i.e. prompt ) field rather than an
input field. "
;; cribbed and hacked from comint-previous-prompt
 (interactive "p")
 (slime-repl-next-prompt (- n)))

(defun slime-repl-next-prompt (n)
 "Move to end of Nth next prompt in the buffer.
Unlike comint mode `comint-use-prompt-regexp-instead-of-fields' has no
effect, and we look for a read-only (i.e. prompt ) field rather than an
input field. "
;; cribbed and hacked from comint-next-prompt
;; the 'read-only' thing is really not nice, but what else but a prompt
;;  would ever be read only? 
  (interactive "p")
  (let ((pos (point))
        (input-pos nil)
        prev-pos)
    (while (/= n 0)
      (setq prev-pos pos)
      (setq pos
            (if (> n 0)
                (next-single-char-property-change pos 'read-only)
              (previous-single-char-property-change pos 'read-only)))
      (cond ((or (null pos) (= pos prev-pos))
             ;; Ran off the end of the buffer.
             (when (> n 0)
               ;; There's always an input field at the end of the
               ;; buffer, but it has a `field' property of nil.
               (setq input-pos (point-max)))
             ;; stop iterating
             (setq n 0))
            ((eq (get-char-property pos 'read-only) nil)
             (setq n (if (< n 0) (1+ n) (1- n)))
             (setq input-pos pos))))
    (when input-pos
      (goto-char input-pos))))


(define-key slime-repl-mode-map "\C-c\C-n" 'slime-repl-next-prompt)
(define-key slime-repl-mode-map "\C-c\C-p" 'slime-repl-previous-prompt)


The reason this has only been tested for 5 minutes is that I had an
even grosser hack bound on C-a. This will move to column 0 if we're
already at the prompt, and then to the previous prompt if we're
already at col 0. This hack will henceforth be abandoned.

(defun slime-repl-bol ()
  "Go to the beginning of line or the prompt."
  (interactive)
  (let ((point (point)))
    (if (and (>= (point) slime-repl-input-start-mark)
             (slime-same-line-p (point) slime-repl-input-start-mark))
        (goto-char slime-repl-input-start-mark)
      (beginning-of-line 1))
    (if (eql point (point)) ; go to very beginning of line
        (forward-line 0))
    (if (eql point (point)) ; go to end of previous field
        (goto-char (previous-single-char-property-change (point)
  'read-only)))))




More information about the slime-devel mailing list