|
Comint bugs
The problems that I've been having (over the last years!) with
comint-based modes are of two different kinds: 1) sometimes Emacs gets
stuck waiting for a prompt, and 2) sometimes some output is lost.
The following definitions can be evaluated in any vanilla Emacs,
and they will create a minor mode
(defun eep-line ()
"The contents of the current line."
(buffer-substring (point-at-bol) (point-at-eol)))
(defun eep-eval (str)
"Wrap STR in a progn then read it and eval it."
(eval (read (concat "(progn\n" str "\n)"))))
(defun eep-there (code)
"Eval CODE at the otther window."
(save-selected-window (other-window 1) (eval code)))
(defun eep-send (line) ()
"Insert LINE at point in the other window, then \"type\" a RET."
(eep-there `(insert ,line))
(eep-there '(call-interactively (key-binding "\r"))))
(defun eep-eval-or-send ()
"Send this line to the other window, or eval it as lisp if it starts with `!'."
(interactive)
(let ((line (eep-line)))
(if (string-match "^!\\(.*\\)" line) ; lines with a '!'
(eep-eval (match-string 1 line)) ; are eval'ed,
(eep-send line))) ; other lines are sent
(next-line 1))
(defun eep-kill (b)
"Like `kill-buffer', but don't ask questions."
(if (get-buffer b)
(let ((kill-buffer-query-functions nil)) (kill-buffer b))))
(setq eep-mode-map (make-sparse-keymap))
(define-key eep-mode-map [f8] 'eep-eval-or-send)
(define-minor-mode eep-mode "Makes the keymap `eep-mode-map' active."
:lighter " eep" :init-value t :global t)
;; Now we have a minor mode called eep-mode.
;; It should be active (due to the ":init-value t" above),
;; the string "eep" should be visible in the list of minor
;; modes in the mode line, and now <F8> invokes eep-eval-or-send.
;; This is a miniature varsion of eepitch:
;; ...
|
;; Part 2: if you've evaluated all of the sexps above, then you should
;; have created and activated a minor mode called "epp" (look for the
;; string "eep" in the mode line), and <F8> should work...
! (delete-other-windows)
! (split-window-vertically)
! (eep-kill "*shell*")
! (eep-there '(shell))
lua
protorepl = function (n)
io.write("0> "); local str = io.read()
for i=1,n-1 do io.write(i.."> "); str = str.."\n"..io.read() end
print(str)
end
protorepl(1) -- here the "print(str)" prints "foo"
foo
protorepl(2)
foo
bar
|
! (delete-other-windows)
! (split-window-vertically)
! (eep-kill "*lua*")
! (make-comint "lua" "lua")
! (eep-there '(switch-to-buffer "*lua*"))
protorepl = function (n)
io.write("0> "); local str = io.read()
for i=1,n-1 do io.write(i.."> "); str = str.."\n"..io.read() end
print(str)
end
protorepl(1) -- here the output of "print(str)" disappears
foo
protorepl(2)
foo
bar
|
;; Part 3: discussion of the output
Here is the output of the first test, in which the Lua
interpreter was invoked from a "*shell*" buffer:
/home/edrx(edrx:re)# lua51
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> protorepl = function (n)
>> io.write("0> "); local str = io.read()
>> for i=1,n-1 do io.write(i.."> "); str = str.."\n"..io.read() end
>> print(str)
>> end
> protorepl(1) -- here the "print(str)" prints "foo"
0> foo
foo
> protorepl(2)
0> foo
1> bar
foo
bar
>
And here is the output of the second test, in which the Lua
interpreter runs in a buffer created with
(make-comint "lua" "lua"):
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> protorepl = function (n)
>> io.write("0> "); local str = io.read()
>> for i=1,n-1 do io.write(i.."> "); str = str.."\n"..io.read() end
>> print(str)
>> end
> protorepl(1) -- here the output of "print(str)" disappears
0> foo
> protorepl(2)
0> foo
1> bar
foo
bar
>
|
A problem: the misbehaviour described above does not
happen when I start Emacs with -Q... so there's something in my
(huuuge) .emacs that triggers it, and I did not have the time to track
that down. That's why I did not send that bug report to the emacs
mailing lists...
|