jka@hpfcso.HP.COM (Jay Adams) (12/15/89)
As it turns out, I was working along similar lines not too long ago.
Here is what I came up with. multi-line-message and
multi-line-read-from-minibuffer could be replacements for the standard
emacs functions message and read-from-minibuffer.
multi-line-read-from-minibuffer, however, uses recursive-edit to read
the input string. The real read-from-minibuffer does some kind of
magic to read the input string.
This code is not copyrighted in any way so feel free to mass-produce
it, claim it as your own work, sell it for some exorbitant price, and
make a small fortune.
- Jay
(defun multi-line-message (string)
"Sort of like message 'cept STRING can be many lines."
(let ((index 0)
(lines (lines-in-string string)))
(if (= lines 1)
(message str)
(let (start
end
(old-window (selected-window)))
(unwind-protect
(progn
(select-window (minibuffer-window))
(enlarge-window (1- lines))
(setq start (point))
(insert string)
(setq end (point))
(select-window old-window)
(sit-for 33554431))
(select-window (minibuffer-window))
(enlarge-window (- 1 lines))
(delete-region start end)
(select-window old-window))))))
(defun lines-in-string (s width)
(let ((index 0)
(last 0)
(lines 1))
(while (string-match "\n" s index)
(if (>= (- (match-beginning 0) last) (1- width))
(setq lines (1+ lines)))
(setq lines (1+ lines)
last index
index (match-end 0)))
(if (>= (- (length s) index) (1- width))
(setq lines (1+ lines)))
lines))
(defun multi-line-read-from-minibuffer (prompt &optional initial keymap read)
"Read a string from the minibuffer, prompting with string PROMPT.
If optional second arg INITIAL-CONTENTS is non-nil, it is a string
to be inserted into the minibuffer before reading input.
Third arg KEYMAP is a keymap to use whilst reading; the default is
minibuffer-local-map.
If fourth arg READ is non-nil, then interpret the result as a lisp object
and return that object (ie (car (read-from-string <input-string>)))"
(or initial (setq initial ""))
(or keymap (setq keymap minibuffer-local-map))
(save-window-excursion
(select-window (minibuffer-window))
(let ((start (point))
input-begin
(scroll-step 1)
(lines (+ -1
(lines-in-string prompt (window-width))
(lines-in-string initial (window-width))))
result)
(unwind-protect
(progn
(enlarge-window (1- lines))
(insert "*")
(insert prompt)
(setq input-begin (point))
(insert initial)
(use-local-map keymap)
(recursive-edit)
(setq result (buffer-substring input-begin (point-max))))
(enlarge-window (- 1 lines))
(delete-region start (point-max)))
(if read
(car (read-from-string result))
result))))