Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!LCS.MIT.EDU!mly From: mly@LCS.MIT.EDU Newsgroups: gnu.emacs.bug Subject: Minor timing bug in the terminal emulator library (18.55) Message-ID: <8911290015.aa25254@mintaka.lcs.mit.edu> Date: 29 Nov 89 05:15:20 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 152 If the subprocess exits almost-immediately, its buffer may end up in fundamental mode but with the evil terminal-emulator local-map. To fix, replace the following definition in emacs/lisp/terminal.el. (defun terminal-emulator (buffer program args &optional width height) "Under a display-terminal emulator in BUFFER, run PROGRAM on arguments ARGS. ARGS is a list of argument-strings. Remaining arguments are WIDTH and HEIGHT. BUFFER's contents are made an image of the display generated by that program, and any input typed when BUFFER is the current Emacs buffer is sent to that program an keyboard input. Interactively, BUFFER defaults to \"*terminal*\" and PROGRAM and ARGS are parsed from an input-string using your usual shell. WIDTH and HEIGHT are determined from the size of the current window -- WIDTH will be one less than the window's width, HEIGHT will be its height. To switch buffers and leave the emulator, or to give commands to the emulator itself (as opposed to the program running under it), type Control-^. The following character is an emulator command. Type Control-^ twice to send it to the subprogram. This escape character may be changed using the variable `terminal-escape-char'. `Meta' characters may not currently be sent through the terminal emulator. Here is a list of some of the variables which control the behaviour of the emulator -- see their documentation for more information: terminal-escape-char, terminal-scrolling, terminal-more-processing, terminal-redisplay-interval. This function calls the value of terminal-mode-hook if that exists and is non-nil after the terminal buffer has been set up and the subprocess started. Presently with `termcap' only; if somebody sends us code to make this work with `terminfo' we will try to use it." (interactive (cons (save-excursion (set-buffer (get-buffer-create "*terminal*")) (buffer-name (if (or (not (boundp 'te-process)) (null te-process) (not (eq (process-status te-process) 'run))) (current-buffer) (generate-new-buffer "*terminal*")))) (append (let* ((default-s ;; Default shell is same thing M-x shell uses. (or explicit-shell-file-name (getenv "ESHELL") (getenv "SHELL") "/bin/sh")) (s (read-string (format "Run program in emulator: (default %s) " default-s)))) (if (equal s "") (list default-s '()) (te-parse-program-and-args s)))))) (switch-to-buffer buffer) (if (null width) (setq width (- (window-width (selected-window)) 1))) (if (null height) (setq height (- (window-height (selected-window)) 1))) (terminal-mode) (setq te-width width te-height height) (setq mode-line-buffer-identification (list (format "Emacs terminal %dx%d: %%b " te-width te-height) 'te-pending-output-info)) (let ((buffer-read-only nil)) (te-clear-screen)) (let (process) (while (setq process (get-buffer-process (current-buffer))) (if (y-or-n-p (format "Kill process %s? " (process-name process))) (delete-process process) (error "Process %s not killed" (process-name process)))) (condition-case err (let ((termcap ;; Because of Unix Brain Death(tm), we can't change ;; the terminal type of a running process, and so ;; terminal size and scrollability are wired-down ;; at this point. ("Detach? What's that?") (concat (format "emacs-virtual:co#%d:li#%d:%s" ;; Sigh. These can't be dynamically changed. te-width te-height (if terminal-scrolling "" "ns:")) ;;-- Basic things ;; cursor-motion, bol, forward/backward char "cm=^p=%+ %+ :cr=^p^a:le=^p^b:nd=^p^f:" ;; newline, clear eof/eof, audible bell "nw=^j:ce=^pc:cd=^pC:cl=^p^l:bl=^p^g:" ;; insert/delete char/line "IC=^p_%+ :DC=^pd%+ :AL=^p^o%+ :DL=^p^k%+ :" ;;-- Not-widely-known (ie nonstandard) flags, which mean ;; o writing in the last column of the last line ;; doesn't cause idiotic scrolling, and ;; o don't use idiotische c-s/c-q sogenannte ;; ``flow control'' auf keinen Fall. "LP:NF:" ;;-- For stupid or obsolete programs "ic=^p_!:dc=^pd!:al=^p^o!:dl=^p^k!:ho=^p= :" ;;-- For disgusting programs. ;; (VI? What losers need these, I wonder?) "im=:ei=:dm=:ed=:mi:do=^p^j:nl=^p^j:bs:"))) (if (fboundp 'start-subprocess) ;; this winning function would do everything, except that ;; rms doesn't want it. (setq process (start-subprocess "terminal-emulator" program args 'channel-type 'terminal 'filter 'te-filter 'buffer (current-buffer) 'sentinel 'te-sentinel 'modify-environment (list (cons "TERM" "emacs-virtual") (cons "TERMCAP" termcap)))) ;; so instead we resort to this... (setq process (start-process "terminal-emulator" (current-buffer) "/bin/sh" "-c" ;; Yuck!!! Start a shell to set some terminal ;; control characteristics. Then start the ;; "env" program to setup the terminal type ;; Then finally start the program we wanted. (format "%s; exec %s TERM=emacs-virtual %s %s" te-stty-string (te-quote-arg-for-sh (concat exec-directory "env")) (te-quote-arg-for-sh (concat "TERMCAP=" termcap)) (mapconcat 'te-quote-arg-for-sh (cons program args) " ")))) (set-process-filter process 'te-filter) (set-process-sentinel process 'te-sentinel)) (setq te-process process)) (error (fundamental-mode) (signal (car err) (cdr err)))) ;; sigh (if (default-value 'meta-flag) (progn (message "Note: Meta key disabled due to maybe-eventually-reparable braindamage") (sit-for 1))) (message "Entering emacs terminal-emulator... Type %s %s for help" (single-key-description terminal-escape-char) (mapconcat 'single-key-description (where-is-internal 'te-escape-help terminal-escape-map t) " ")) (if (eq (process-status process) 'run) (progn (setq inhibit-quit t) ;sport death (use-local-map terminal-map) (run-hooks 'terminal-mode-hook))) (if (not (eq (process-status process) 'run)) (fundamental-mode)))) Brought to you by Super Global Mega Corp .com