(provide (quote terminal)) (require (quote ehelp)) (defvar terminal-escape-char 30 "\ *All characters except for this are passed verbatim through the terminal-emulator. This character acts as a prefix for commands to the emulator program itself. Type this character twice to send it through the emulator. Type ? after typing it for a list of possible commands. This variable is local to each terminal-emulator buffer.") (defvar terminal-scrolling t "\ *If non-nil, the terminal-emulator will `scroll' when output occurs past the bottom of the screen. If nil, output will `wrap' to the top of the screen. This variable is local to each terminal-emulator buffer.") (defvar terminal-more-processing t "\ *If non-nil, do more-processing. This variable is local to each terminal-emulator buffer.") (defvar terminal-redisplay-interval 5000 "\ *Maximum number of characters which will be processed by the terminal-emulator before a screen redisplay is forced. Set this to a large value for greater throughput, set it smaller for more frequent updates but overall slower performance.") (defvar terminal-more-break-insertion "*** More break -- Press space to continue ***") (defvar terminal-escape-map nil) (defvar terminal-map nil) (defvar terminal-more-break-map nil) (if terminal-map nil (let ((map (make-keymap))) (fillarray map (quote te-pass-through)) (setq terminal-map map))) (if terminal-escape-map nil (let ((map (make-keymap))) (fillarray map (quote undefined)) (let ((s "0")) (while (<= (aref s 0) 57) (define-key map s (quote digit-argument)) (aset s 0 (1+ (aref s 0))))) (define-key map "b" (quote switch-to-buffer)) (define-key map "o" (quote other-window)) (define-key map "e" (quote te-set-escape-char)) (define-key map " " (quote redraw-display)) (define-key map "" (quote te-flush-pending-output)) (define-key map "m" (quote te-toggle-more-processing)) (define-key map "x" (quote te-escape-extended-command)) (define-key map "?" (quote te-escape-help)) (define-key map (char-to-string help-char) (quote te-escape-help)) (setq terminal-escape-map map))) (defvar te-escape-command-alist nil) (if te-escape-command-alist nil (setq te-escape-command-alist (quote (("Set Escape Character" . te-set-escape-char) ("Refresh" . redraw-display) ("Record Output" . te-set-output-log) ("Photo" . te-set-output-log) ("Tofu" . te-tofu) ("Stuff Input" . te-stuff-string) ("Flush Pending Output" . te-flush-pending-output) ("Enable More Processing" . te-enable-more-processing) ("Disable More Processing" . te-disable-more-processing) ("Scroll at end of page" . te-do-scrolling) ("Wrap at end of page" . te-do-wrapping) ("Switch To Buffer" . switch-to-buffer) ("Other Window" . other-window) ("Kill Buffer" . kill-buffer) ("Help" . te-escape-help) ("Set Redisplay Interval" . te-set-redisplay-interval))))) (if terminal-more-break-map nil (let ((map (make-keymap))) (fillarray map (quote te-more-break-unread)) (define-key map (char-to-string help-char) (quote te-more-break-help)) (define-key map " " (quote te-more-break-resume)) (define-key map " " (quote redraw-display)) (define-key map "" (quote te-more-break-flush-pending-output)) (define-key map " (defun te-escape nil (interactive) (byte-code "?CE E ?E !^I !^I f\" (defun te-escape-help nil "\ Provide help on commands available after terminal-escape-char is typed." (interactive) (byte-code "^AA!^A !AC!)+" [char terminal-escape-char nil message "Terminal emulator escape help..." single-key-description with-electric-help (lambda nil (byte-code "CEE%!^CEE!!^CEIII A#I#!^ID!f+ Type \"%s\" twice to send a single \"%s\" through. Other chars following \"%s\" are interpreted as follows: " substitute-command-keys "\\{terminal-escape-map} " " Subcommands of \"%s\" (%s) " where-is-internal te-escape-extended-command fboundp sortcar copy-sequence string< sort (lambda (a b) (byte-code "A@ @\"+" [a b string<] 3)) documentation "Not documented" string-match " " 0 match-beginning " \"" "\": " write-char 10] 23))] 4)) (defun te-escape-extended-command nil (interactive) (byte-code "?AAA AA$).  .* (defun te-escape-extended-command-unread nil (interactive) (byte-code "^ %^A +" [unread-command-char last-input-char nil te-escape-extended-command] 2)) (defun te-set-escape-char (c) "\ Change the terminal-emulator escape character." (interactive "cSet escape character to: ") (byte-code "E A Uf !C!#^ %)+" [o terminal-escape-char c nil message "\"%s\" is escape char" "\"%s\" is now escape; \"%s\" passes though" single-key-description] 6)) (defun te-stuff-string (string) "\ Read a string to send to through the terminal emulator as though that string had been typed on the keyboard. Very poor man's file transfer protocol." (interactive "sStuff string: ") (byte-code "^A \"+" [te-process string nil process-send-string] 3)) (defun te-set-output-log (name) "\ Record output from the terminal emulator in a buffer." (interactive (byte-code "f ?+ A\"f !f\" !q^E ^Ep!^E )^C !%^AII!\"+" [te-log-buffer nil name equal "" message "Output logging off." get-buffer get-buffer-create fundamental-mode buffer-flush-undo erase-buffer "Recording terminal emulator output into buffer \"%s\"" buffer-name] 12)) (defun te-tofu nil "\ Discontinue output log." (interactive) (byte-code "?AA!+" [nil te-set-output-log] 2)) (defun te-toggle (sym arg) (byte-code "A !?f (defun te-toggle-more-processing (arg) (interactive "p") (byte-code "EAAA\"f (defun te-toggle-scrolling (arg) (interactive "p") (byte-code "?AAA\"f (defun te-enable-more-processing nil "\ Enable ** MORE ** processing" (interactive) (byte-code "?AA!+" [t nil te-toggle-more-processing] 2)) (defun te-disable-more-processing nil "\ Disable ** MORE ** processing" (interactive) (byte-code "?AA!+" [nil te-toggle-more-processing] 2)) (defun te-do-scrolling nil "\ Scroll at end of page (yuck)" (interactive) (byte-code "?AA!+" [t nil te-toggle-scrolling] 2)) (defun te-do-wrapping nil "\ Wrap to top of window at end of page" (interactive) (byte-code "?AA!+" [nil te-toggle-scrolling] 2)) (defun te-set-redisplay-interval (arg) "\ Set the maximum interval (in output characters) between screen updates. Set this number to large value for greater throughput, set it smaller for more frequent updates (but overall slower performance." (interactive "NMax number of output chars between redisplay updates: ") (byte-code "EA]%^?+" [arg terminal-redisplay-interval te-redisplay-count nil 1 0] 2)) (put (quote te-more-break-unread) (quote suppress-keymap) t) (defun te-more-break-unread nil (interactive) (byte-code "? Uf (defun te-more-break-resume nil "\ Proceed past the **MORE** break, allowing the next page of output to appear" (interactive) (byte-code "?AA!^A +" [nil message "Continuing from more break" te-more-break-unwind] 3)) (defun te-more-break-help nil "\ Provide help on commands available in a terminal-emulator **MORE** break" (interactive) (byte-code "?AA!^AA!^AA!+" [nil message "Terminal-emulator more break help..." sit-for 0 with-electric-help (lambda nil (byte-code "AA!^AAACEA#EE!#!^AEE!!^AI!^+" [terminal-more-break-map t nil princ "Terminal-emulator more break. " format "Type \"%s\" (te-more-break-resume) %s " where-is-internal te-more-break-resume documentation substitute-command-keys "\\{terminal-more-break-map} " "Any other key is passed through to the program running under the terminal emulator and disables more processing until all pending output has been dealt with."] 9))] 4)) (defun te-more-break-advance-one-line nil "\ Allow one more line of text to be output before doing another more break." (interactive) (byte-code "?%^A +" [te-more-count nil 1 te-more-break-unwind] 2)) (defun te-more-break-flush-pending-output nil "\ Discard any output which has been received by the terminal emulator but not yet proceesed and then proceed from the more break." (interactive) (byte-code "?A ^A +" [nil te-more-break-unwind te-flush-pending-output] 3)) (defun te-flush-pending-output nil "\ Discard any as-yet-unprocessed output which has been received by the terminal emulator." (interactive) (byte-code "^A?f *** %d chars of pending output flushed *** " te-update-pending-output-display te-process-output sit-for] 8)) (defun te-pass-through nil "\ Send the last character typed through the terminal-emulator without any interpretation" (interactive) (byte-code "? =f . (defun te-set-window-start nil (byte-code "Ap!. T\"Yf$ T\"Yf? T\"E#\",@ (defun te-pending-output-length nil (byte-code " @ A . @G\\ A%^, (defun te-more-break nil (byte-code "EA!^IA!^`%^IA!^I %^I !^IA!^I !%^IA!^DNE%^O \\\"^ c)^UY!^TB!^aaA\"+" [t te-more-old-point te-more-old-local-map terminal-more-break-map te-more-old-filter te-process te-more-old-mode-line-format mode-line-format mode-line-buffer-identification terminal-more-break-insertion te-width te-set-more-count make-local-variable current-local-map use-local-map process-filter "-- **MORE** " "%-" set-process-filter (lambda (process string) (byte-code "SA!q^A C\"%)^A +" [process te-pending-output string process-buffer nconc te-update-pending-output-display] 4)) te-update-pending-output-display window-buffer selected-window message "More break " forward-char 1 delete-region run-hooks terminal-more-break-hook sit-for 0 throw te-process-output] 20)) (defun te-more-break-unwind nil (byte-code "I!^I \"^ b^ O ))^*E!+" [te-more-old-local-map te-process te-more-old-filter te-more-old-point mode-line-format te-more-old-mode-line-format buffer-read-only nil terminal-more-break-insertion te-width te-more-count t use-local-map set-process-filter set-buffer-modified-p buffer-modified-p forward-char 1 delete-region insert-char 32 259259 te-newline te-process-output] 10)) (defun te-set-more-count (newline) (byte-code "A`eZ T\" . (defun te-newline nil "\ Move down a line, optionally do more processing, perhaps wrap/scroll, move to start of new line, clear to end of line." (byte-code "A ^?+ (defun te-down-vertically-or-scroll nil "\ Move down a line vertically, or scroll at bottom." (byte-code "iA ^mf' (defun te-move-to-position nil (byte-code "A CZA CZ V+ T\"#b*^?+" [y x te-width te-height nil te-more-count te-get-char 32 + * -1] 8)) (defun te-clear-rest-of-line nil (byte-code "S`A ^`ZA``\\\"^AA[\"))+" [n end-of-line delete-region insert-char 32] 5)) (defun te-clear-rest-of-screen nil (byte-code "SA ^A ^m?.\" (defun te-clear-screen nil (byte-code "A ^A W. \"^Ec^, (defun te-insert-lines nil (byte-code "n?f E`eZ T\"E#E EZ ^IIdI T\"Zd\"^`d=.2 (defun te-delete-lines nil (byte-code "n?f E`eZ T\"E#E EZ ^II``I T\"\\d^\"^Sdb^ (defun te-beginning-of-line nil (byte-code "A +" [beginning-of-line] 2)) (defun te-backward-char nil (byte-code "n?. (defun te-forward-char nil (byte-code "l?. (defun te-delete nil (byte-code "nf (defun te-beep nil (byte-code "A +" [beep] 2)) (defun te-insert-spaces nil (byte-code "`A AZA ^`Z^ AXf (defun te-delete-char nil (byte-code "`A AZA ^`Z^ AXf (defun te-losing-unix nil (byte-code "?" [nil] 1)) (defun te-output-tab nil (byte-code "`A ^`ZAA A\"ZC ^`Z^ \\b++" [p x l beginning-of-line 8 logand 7 end-of-line] 6)) (defun te-filter (process string) (byte-code "p ?E !q^ b^E (defun te-process-output (preemptable) (byte-code "?^A?^A   C !%=?.( @A@ H%^ T% G=fD ?fZ =.- #%+| G ON!^ c^`%^* ^ ` Z\\^% ^ G=fi ,o  Oc^ G=f EAAB%,I \"^O ZT!),=U U=f/UU Y\"A+,?8U .La .LaaE\"^, (defun te-get-char nil (byte-code "Af, H T% G=f# (defun te-redisplay-if-necessary (length) (byte-code " Z%AX.\" %+" [te-redisplay-count length terminal-redisplay-interval 0 window-buffer selected-window waiting-for-user-input-p te-update-pending-output-display sit-for] 7)) (defun te-update-pending-output-display nil (byte-code "A?f AWf E\\E\"\"%)^EI !+" [te-pending-output te-pending-output-info length "" te-pending-output-length 1500 format "(%dK chars output pending) " / 512 1024 set-buffer-modified-p buffer-modified-p] 6)) (defun te-sentinel (process message) (byte-code "A!C=+D E!=.: ******* " "******* " waiting-for-user-input-p recenter -1] 12)) (defvar te-stty-string "stty -nl new dec echo" "\ Command string (to be interpreted by \"sh\") which sets the modes of the virtual terminal to be appropriate for interactive use.") (defvar explicit-shell-file-name nil "\ *If non-nil, is file name to use for explicitly requested inferior shell.") (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 (byte-code "SAA!q^ACA!?+ +7 U )^E Up!% .n f Type %s %s for help" single-key-description mapconcat where-is-internal te-escape-help " " use-local-map run-hooks terminal-mode-hook] 28)) (defun te-parse-program-and-args (s) (byte-code "AC\"fQ (put (quote terminal-mode) (quote mode-class) (quote special)) (defun terminal-mode nil "\ Set up variables for use f the terminal-emualtor. One should not call this -- it is an internal function of the terminal-emulator" (byte-code "O ^Op!^?^?^?^?^?^*A!^OA!%^*C!^OC!%^*E!^OE!%^*E!^OE!% ^*U!^*U!^*U!^*E!^UC% ^*E!^e% ^*I!^? ^*T!^*I!^? (defun te-quote-arg-for-sh (fuckme) (byte-code "AC\"f  AOP%^?Z  OI TOR T%^, IQ++" [fuckme t harder cretin stupid nil string-match "\\`[a-zA-Z0-9-+=_.@/:]+\\'" "[$]" prin1-to-string "" 0 "[\"\\$]" "\\" "\""] 11)) .