Changeset 12401

Jul 12, 2009, 3:54:07 AM (10 years ago)

Trac #155 fixed. Confim Listener Input now does this:


  1. Point is at the prompt: if a balanced expression is at the prompt, we send it to the Lisp. (The test for a balanced expression now skips over line-comments; this means that the comment gets added to the input history, for better or worse)
  1. Point is not at the prompt, but is somewhere in previous output. No selection is active. Copy the previous output to the input area and then do (1)
  1. Point is in previous output, with no selection. Search left and right for a well-formed s-expression. If at least one is found, copy the nearest found s-expression to the prompt, then do (1)
  1. Point is in previous input or output, and a selection is active. Copy the selected text to the prompt and do (1).

If more than one balanced expression is at the prompt, all get evaluated.

If at least one balanced expression is at the prompt, and at least unbalanced expression, none gets evaluated.

1 edited


  • trunk/source/cocoa-ide/hemlock/src/listener.lisp

    r12400 r12401  
    237237                 (top-listener-input-stream))
    238238                (balanced-expressions-in-region input-region))
    239         (let* ((string (region-to-string input-region)))
     239        (let* ((string (region-to-string input-region))
     240               (ring (value interactive-history)))
     241          (when (and (or (zerop (ring-length ring))
     242                         (string/= string (region-to-string (ring-ref ring 0))))
     243                     (> (length string) (value minimum-interactive-input-length)))
     244            (ring-push (copy-region input-region) ring))
    240245          (push (cons r nil) (value input-regions))
    241246          (move-mark (value buffer-input-mark) (current-point))
    250255      (send-input-region-to-lisp))))
     257(defun find-backward-form (mark)
     258  (let ((start (copy-mark mark))
     259        (end (copy-mark mark)))
     260    (block finding
     261      (or (form-offset start -1) (return-from finding nil))
     262      (or (form-offset end -1) (return-from finding nil))
     263      (or (form-offset end 1) (return-from finding nil))
     264      (region start end))))
     266(defun find-forward-form (mark)
     267  (let ((start (copy-mark mark))
     268        (end (copy-mark mark)))
     269    (block finding
     270      (or (form-offset start 1) (return-from finding nil))
     271      (or (form-offset end 1) (return-from finding nil))
     272      (or (form-offset start -1) (return-from finding nil))
     273      (region start end))))
     275(defun region= (r1 r2)
     276  (multiple-value-bind (r1-start r1-end)(region-bounds r1)
     277    (multiple-value-bind (r2-start r2-end)(region-bounds r2)
     278      (and (mark= r1-start r2-start)
     279           (mark= r1-end r2-end)))))
     281;;; find the start or end of the nearest lisp form. return a region if
     282;;; one is found, nil otherwise. try for a commonsense result.
     283(defun mark-nearest-form (mark)
     284  (let* ((backward-region (find-backward-form mark))
     285         (forward-region (find-forward-form mark)))
     286    (if backward-region
     287        (if forward-region
     288            ;; if we're in the middle of a token, then the backward
     289            ;; and forward regions will be the same
     290            (if (region= backward-region forward-region)
     291                backward-region
     292                ;; not equal, so figure out which is closer
     293                (let* ((mark-pos (mark-absolute-position mark))
     294                       (backward-dist (abs (- mark-pos (mark-absolute-position (region-end backward-region)))))
     295                       (forward-dist (abs (- (mark-absolute-position (region-start forward-region)) mark-pos))))
     296                  (if (< forward-dist backward-dist)
     297                      forward-region
     298                      backward-region)))
     299            backward-region)
     300        forward-region)))
    252302(defun send-expression-at-point-to-lisp ()
    253   ;; if it's not a well-formed expression, try to fix it up and send it
    254   ;; if we fail, don't send it
    255   )
     303  (let* ((nearest-form-region (mark-nearest-form (current-point))))
     304    (if nearest-form-region
     305        (send-region-to-lisp nearest-form-region)
     306        (beep))))
    257308(defcommand "Confirm Listener Input" (p)
Note: See TracChangeset for help on using the changeset viewer.