Quick
index
main
eev
maths
blogme
dednat4
littlelangs
PURO
(GAC2,
λ, etc)
(Chapa 1)

emacs
lua
(la)tex
fvwm
tcl
forth
icon
debian
irc
contact

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.

;; (find-enode "Interactive Shell")
;; (find-enode "Shell Mode")
;; (find-enode "Shell Prompts")

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...