Annotation of 43BSDReno/contrib/emacs-18.55/lisp/terminal.el, revision 1.1

1.1     ! root        1: ;; Terminal emulator for GNU Emacs.
        !             2: ;; Copyright (C) 1986, 1987 Free Software Foundation, Inc.
        !             3: ;; Written by Richard Mlynarik, November 1986.
        !             4: 
        !             5: ;; This file is part of GNU Emacs.
        !             6: 
        !             7: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             8: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             9: ;; accepts responsibility to anyone for the consequences of using it
        !            10: ;; or for whether it serves any particular purpose or works at all,
        !            11: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            12: ;; License for full details.
        !            13: 
        !            14: ;; Everyone is granted permission to copy, modify and redistribute
        !            15: ;; GNU Emacs, but only under the conditions described in the
        !            16: ;; GNU Emacs General Public License.   A copy of this license is
        !            17: ;; supposed to have been given to you along with GNU Emacs so you
        !            18: ;; can know your rights and responsibilities.  It should be in a
        !            19: ;; file named COPYING.  Among other things, the copyright notice
        !            20: ;; and this notice must be preserved on all copies.
        !            21: 
        !            22: ;;>>TODO
        !            23: ;;>> terminfo?
        !            24: ;;>> ** Nothing can be done about emacs' meta-lossage **
        !            25: ;;>>  (without redoing keymaps `sanely' -- ask Mly for details)
        !            26: 
        !            27: ;;>> One probably wants to do setenv MORE -c when running with
        !            28: ;;>>   more-processing enabled.
        !            29: 
        !            30: (provide 'terminal)
        !            31: (require 'ehelp)
        !            32: 
        !            33: (defvar terminal-escape-char ?\C-^
        !            34:   "*All characters except for this are passed verbatim through the
        !            35: terminal-emulator.  This character acts as a prefix for commands
        !            36: to the emulator program itself.  Type this character twice to send
        !            37: it through the emulator.  Type ? after typing it for a list of
        !            38: possible commands.
        !            39: This variable is local to each terminal-emulator buffer.")
        !            40: 
        !            41: (defvar terminal-scrolling t
        !            42:   "*If non-nil, the terminal-emulator will `scroll' when output occurs
        !            43: past the bottom of the screen.  If nil, output will `wrap' to the top
        !            44: of the screen.
        !            45: This variable is local to each terminal-emulator buffer.")
        !            46: 
        !            47: (defvar terminal-more-processing t
        !            48:   "*If non-nil, do more-processing.
        !            49: This variable is local to each terminal-emulator buffer.")
        !            50: 
        !            51: ;; If you are the sort of loser who uses scrolling without more breaks
        !            52: ;; and expects to actually see anything, you should probably set this to
        !            53: ;; around 400
        !            54: (defvar terminal-redisplay-interval 5000
        !            55:   "*Maximum number of characters which will be processed by the
        !            56: terminal-emulator before a screen redisplay is forced.
        !            57: Set this to a large value for greater throughput,
        !            58: set it smaller for more frequent updates but overall slower
        !            59: performance.")
        !            60: 
        !            61: (defvar terminal-more-break-insertion
        !            62:   "*** More break -- Press space to continue ***")
        !            63: 
        !            64: (defvar terminal-escape-map nil)
        !            65: (defvar terminal-map nil)
        !            66: (defvar terminal-more-break-map nil)
        !            67: (if terminal-map
        !            68:     nil
        !            69:   (let ((map (make-keymap)))
        !            70:     (fillarray map 'te-pass-through)
        !            71:     ;(define-key map "\C-l"
        !            72:     ;  '(lambda () (interactive) (te-pass-through) (redraw-display)))
        !            73:     (setq terminal-map map)))
        !            74: 
        !            75: ;(setq terminal-escape-map nil)
        !            76: (if terminal-escape-map
        !            77:     nil
        !            78:   (let ((map (make-keymap)))
        !            79:     ;(fillarray map 'te-escape-extended-command-unread)
        !            80:     (fillarray map 'undefined)
        !            81:     (let ((s "0"))
        !            82:       (while (<= (aref s 0) ?9)
        !            83:        (define-key map s 'digit-argument)
        !            84:        (aset s 0 (1+ (aref s 0)))))
        !            85:     (define-key map "b" 'switch-to-buffer)
        !            86:     (define-key map "o" 'other-window)
        !            87:     (define-key map "e" 'te-set-escape-char)
        !            88:     (define-key map "\C-l" 'redraw-display)
        !            89:     (define-key map "\C-o" 'te-flush-pending-output)
        !            90:     (define-key map "m" 'te-toggle-more-processing)
        !            91:     (define-key map "x" 'te-escape-extended-command)
        !            92:     (define-key map "?" 'te-escape-help)
        !            93:     (define-key map (char-to-string help-char) 'te-escape-help)
        !            94:     (setq terminal-escape-map map)))
        !            95: 
        !            96: (defvar te-escape-command-alist ())
        !            97: ;(setq te-escape-command-alist ())
        !            98: (if te-escape-command-alist
        !            99:     nil
        !           100:   (setq te-escape-command-alist
        !           101:        '(("Set Escape Character" . te-set-escape-char)
        !           102:          ("Refresh" . redraw-display)
        !           103:          ("Record Output" . te-set-output-log)
        !           104:          ("Photo" . te-set-output-log)
        !           105:          ("Tofu" . te-tofu) ;; confuse the uninitiated
        !           106:          ("Stuff Input" . te-stuff-string)
        !           107:          ("Flush Pending Output" . te-flush-pending-output)
        !           108:          ("Enable More Processing" . te-enable-more-processing)
        !           109:          ("Disable More Processing" . te-disable-more-processing)
        !           110:          ("Scroll at end of page" . te-do-scrolling)
        !           111:          ("Wrap at end of page" . te-do-wrapping)
        !           112:          ("Switch To Buffer" . switch-to-buffer)
        !           113:          ("Other Window" . other-window)
        !           114:          ("Kill Buffer" . kill-buffer)
        !           115:          ("Help" . te-escape-help)
        !           116:          ("Set Redisplay Interval" . te-set-redisplay-interval)
        !           117:          )))
        !           118: 
        !           119: ;(setq terminal-more-break-map nil)
        !           120: (if terminal-more-break-map
        !           121:     nil
        !           122:   (let ((map (make-keymap)))
        !           123:     (fillarray map 'te-more-break-unread)
        !           124:     (define-key map (char-to-string help-char) 'te-more-break-help)
        !           125:     (define-key map " " 'te-more-break-resume)
        !           126:     (define-key map "\C-l" 'redraw-display)
        !           127:     (define-key map "\C-o" 'te-more-break-flush-pending-output)
        !           128:     ;;>>> this isn't right
        !           129:     ;(define-key map "\^?" 'te-more-break-flush-pending-output) ;DEL
        !           130:     (define-key map "\r" 'te-more-break-advance-one-line)
        !           131: 
        !           132:     (setq terminal-more-break-map map)))
        !           133:   
        !           134: 
        !           135: ;;;;  escape map
        !           136: 
        !           137: (defun te-escape ()
        !           138:   (interactive)
        !           139:   (let (s 
        !           140:        (local (current-local-map))
        !           141:        (global (current-global-map)))
        !           142:     (unwind-protect
        !           143:        (progn
        !           144:          (use-global-map terminal-escape-map)
        !           145:          (use-local-map terminal-escape-map)
        !           146:          (setq s (read-key-sequence
        !           147:                    (if prefix-arg
        !           148:                        (format "Emacs Terminal escape> %d "
        !           149:                                (prefix-numeric-value prefix-arg))
        !           150:                        "Emacs Terminal escape> "))))
        !           151:       (use-global-map global)
        !           152:       (use-local-map local))
        !           153:     (message "")
        !           154:     (cond ((string= s (make-string 1 terminal-escape-char))
        !           155:           (setq last-command-char terminal-escape-char)
        !           156:           (let ((terminal-escape-char -259))
        !           157:             (te-pass-through)))
        !           158:          ((setq s (lookup-key terminal-escape-map s))
        !           159:           (call-interactively s)))))
        !           160: 
        !           161: (defun te-escape-help ()
        !           162:   "Provide help on commands available after terminal-escape-char is typed."
        !           163:   (interactive)
        !           164:   (message "Terminal emulator escape help...")
        !           165:   (let ((char (single-key-description terminal-escape-char)))
        !           166:     (with-electric-help
        !           167:       (function (lambda ()
        !           168:         (princ (format "Terminal-emulator escape, invoked by \"%s\"
        !           169: Type \"%s\" twice to send a single \"%s\" through.
        !           170: 
        !           171: Other chars following \"%s\" are interpreted as follows:\n"
        !           172:                        char char char char))
        !           173: 
        !           174:         (princ (substitute-command-keys "\\{terminal-escape-map}\n"))
        !           175:         (princ (format "\nSubcommands of \"%s\" (%s)\n"
        !           176:                        (where-is-internal 'te-escape-extended-command
        !           177:                                           terminal-escape-map t)
        !           178:                        'te-escape-extended-command))
        !           179:         (let ((l (if (fboundp 'sortcar)
        !           180:                      (sortcar (copy-sequence te-escape-command-alist)
        !           181:                               'string<)
        !           182:                      (sort (copy-sequence te-escape-command-alist)
        !           183:                            (function (lambda (a b)
        !           184:                               (string< (car a) (car b))))))))
        !           185:           (while l
        !           186:             (let ((doc (or (documentation (cdr (car l)))
        !           187:                            "Not documented")))
        !           188:               (if (string-match "\n" doc)
        !           189:                   ;; just use first line of documentation
        !           190:                   (setq doc (substring doc 0 (match-beginning 0))))
        !           191:               (princ "  \"")
        !           192:               (princ (car (car l)))
        !           193:               (princ "\":\n     ")
        !           194:               (princ doc)
        !           195:               (write-char ?\n))
        !           196:             (setq l (cdr l))))
        !           197:         nil)))))
        !           198: 
        !           199:                        
        !           200: 
        !           201: (defun te-escape-extended-command ()
        !           202:   (interactive)
        !           203:   (let ((c (let ((completion-ignore-case t))
        !           204:             (completing-read "terminal command: "
        !           205:                              te-escape-command-alist
        !           206:                              nil t))))
        !           207:     (if c
        !           208:        (catch 'foo
        !           209:          (setq c (downcase c))
        !           210:          (let ((l te-escape-command-alist))
        !           211:            (while l
        !           212:              (if (string= c (downcase (car (car l))))
        !           213:                  (throw 'foo (call-interactively (cdr (car l))))
        !           214:                (setq l (cdr l)))))))))
        !           215: 
        !           216: ;; not used.
        !           217: (defun te-escape-extended-command-unread ()
        !           218:   (interactive)
        !           219:   (setq unread-command-char last-input-char)
        !           220:   (te-escape-extended-command))
        !           221: 
        !           222: (defun te-set-escape-char (c)
        !           223:   "Change the terminal-emulator escape character."
        !           224:   (interactive "cSet escape character to: ")
        !           225:   (let ((o terminal-escape-char))
        !           226:     (message (if (= o c)
        !           227:                 "\"%s\" is escape char"
        !           228:                 "\"%s\" is now escape; \"%s\" passes though")
        !           229:             (single-key-description c)
        !           230:             (single-key-description o))
        !           231:     (setq terminal-escape-char c)))
        !           232: 
        !           233: 
        !           234: (defun te-stuff-string (string)
        !           235:   "Read a string to send to through the terminal emulator
        !           236: as though that string had been typed on the keyboard.
        !           237: 
        !           238: Very poor man's file transfer protocol."
        !           239:   (interactive "sStuff string: ")
        !           240:   (process-send-string te-process string))
        !           241: 
        !           242: (defun te-set-output-log (name)
        !           243:   "Record output from the terminal emulator in a buffer."
        !           244:   (interactive (list (if te-log-buffer
        !           245:                         nil
        !           246:                       (read-buffer "Record output in buffer: "
        !           247:                                    (format "%s output-log"
        !           248:                                            (buffer-name (current-buffer)))
        !           249:                                    nil))))
        !           250:   (if (or (null name) (equal name ""))
        !           251:       (progn (setq te-log-buffer nil)
        !           252:             (message "Output logging off."))
        !           253:     (if (get-buffer name)
        !           254:        nil
        !           255:       (save-excursion
        !           256:        (set-buffer (get-buffer-create name))
        !           257:        (fundamental-mode)
        !           258:        (buffer-flush-undo (current-buffer))
        !           259:        (erase-buffer)))
        !           260:     (setq te-log-buffer (get-buffer name))
        !           261:     (message "Recording terminal emulator output into buffer \"%s\""
        !           262:             (buffer-name te-log-buffer))))
        !           263: 
        !           264: (defun te-tofu ()
        !           265:   "Discontinue output log."
        !           266:   (interactive)
        !           267:   (te-set-output-log nil))
        !           268:   
        !           269: 
        !           270: (defun te-toggle (sym arg)
        !           271:   (set sym (cond ((not (numberp arg)) arg)
        !           272:                 ((= arg 1) (not (symbol-value sym)))
        !           273:                 ((< arg 0) nil)
        !           274:                 (t t))))
        !           275: 
        !           276: (defun te-toggle-more-processing (arg)
        !           277:   (interactive "p")
        !           278:   (message (if (te-toggle 'terminal-more-processing arg)
        !           279:               "More processing on" "More processing off"))
        !           280:   (if terminal-more-processing (setq te-more-count -1)))
        !           281: 
        !           282: (defun te-toggle-scrolling (arg)
        !           283:   (interactive "p")
        !           284:   (message (if (te-toggle 'terminal-scrolling arg)
        !           285:               "Scroll at end of page" "Wrap at end of page")))
        !           286: 
        !           287: (defun te-enable-more-processing ()
        !           288:   "Enable ** MORE ** processing"
        !           289:   (interactive)
        !           290:   (te-toggle-more-processing t))
        !           291: 
        !           292: (defun te-disable-more-processing ()
        !           293:   "Disable ** MORE ** processing"
        !           294:   (interactive)
        !           295:   (te-toggle-more-processing nil))
        !           296: 
        !           297: (defun te-do-scrolling ()
        !           298:   "Scroll at end of page (yuck)"
        !           299:   (interactive)
        !           300:   (te-toggle-scrolling t))
        !           301: 
        !           302: (defun te-do-wrapping ()
        !           303:   "Wrap to top of window at end of page"
        !           304:   (interactive)
        !           305:   (te-toggle-scrolling nil))
        !           306: 
        !           307: 
        !           308: (defun te-set-redisplay-interval (arg)
        !           309:   "Set the maximum interval (in output characters) between screen updates.
        !           310: Set this number to large value for greater throughput,
        !           311: set it smaller for more frequent updates (but overall slower performance."
        !           312:   (interactive "NMax number of output chars between redisplay updates: ")
        !           313:   (setq arg (max arg 1))
        !           314:   (setq terminal-redisplay-interval arg
        !           315:        te-redisplay-count 0))
        !           316: 
        !           317: ;;;; more map
        !           318: 
        !           319: ;; every command -must- call te-more-break-unwind
        !           320: ;; or grave lossage will result
        !           321: 
        !           322: (put 'te-more-break-unread 'suppress-keymap t)
        !           323: (defun te-more-break-unread ()
        !           324:   (interactive)
        !           325:   (if (= last-input-char terminal-escape-char)
        !           326:       (call-interactively 'te-escape)
        !           327:     (message "Continuing from more break (\"%s\" typed, %d chars output pending...)"
        !           328:             (single-key-description last-input-char)
        !           329:             (te-pending-output-length))
        !           330:     (setq te-more-count 259259)
        !           331:     (te-more-break-unwind)
        !           332:     (let ((terminal-more-processing nil))
        !           333:       (te-pass-through))))
        !           334: 
        !           335: (defun te-more-break-resume ()
        !           336:   "Proceed past the **MORE** break,
        !           337: allowing the next page of output to appear"
        !           338:   (interactive)
        !           339:   (message "Continuing from more break")
        !           340:   (te-more-break-unwind))
        !           341: 
        !           342: (defun te-more-break-help ()
        !           343:   "Provide help on commands available in a terminal-emulator **MORE** break"
        !           344:   (interactive)
        !           345:   (message "Terminal-emulator more break help...")
        !           346:   (sit-for 0)
        !           347:   (with-electric-help
        !           348:     (function (lambda ()
        !           349:       (princ "Terminal-emulator more break.\n\n")
        !           350:       (princ (format "Type \"%s\" (te-more-break-resume)\n%s\n"
        !           351:                     (where-is-internal 'te-more-break-resume
        !           352:                                        terminal-more-break-map t)
        !           353:                     (documentation 'te-more-break-resume)))
        !           354:       (princ (substitute-command-keys "\\{terminal-more-break-map}\n"))
        !           355:       (princ "Any other key is passed through to the program
        !           356: running under the terminal emulator and disables more processing until
        !           357: all pending output has been dealt with.")
        !           358:       nil))))
        !           359: 
        !           360: 
        !           361: (defun te-more-break-advance-one-line ()
        !           362:   "Allow one more line of text to be output before doing another more break."
        !           363:   (interactive)
        !           364:   (setq te-more-count 1)
        !           365:   (te-more-break-unwind))
        !           366: 
        !           367: (defun te-more-break-flush-pending-output ()
        !           368:   "Discard any output which has been received by the terminal emulator but
        !           369: not yet proceesed and then proceed from the more break."
        !           370:   (interactive)
        !           371:   (te-more-break-unwind)
        !           372:   (te-flush-pending-output))
        !           373: 
        !           374: (defun te-flush-pending-output ()
        !           375:   "Discard any as-yet-unprocessed output which has been received by
        !           376: the terminal emulator."
        !           377:   (interactive)
        !           378:   ;; this could conceivably be confusing in the presence of
        !           379:   ;; escape-sequences spanning process-output chunks
        !           380:   (if (null (cdr te-pending-output))
        !           381:       (message "(There is no output pending)")
        !           382:     (let ((length (te-pending-output-length)))
        !           383:       (message "Flushing %d chars of pending output" length)
        !           384:       (setq te-pending-output
        !           385:            (list 0 (format "\n*** %d chars of pending output flushed ***\n"
        !           386:                            length)))
        !           387:       (te-update-pending-output-display)
        !           388:       (te-process-output nil)
        !           389:       (sit-for 0))))
        !           390: 
        !           391: 
        !           392: (defun te-pass-through ()
        !           393:   "Send the last character typed through the terminal-emulator
        !           394: without any interpretation"
        !           395:   (interactive)
        !           396:   (if (eql last-input-char terminal-escape-char)
        !           397:       (call-interactively 'te-escape)
        !           398:     (and terminal-more-processing
        !           399:         (null (cdr te-pending-output))
        !           400:         (te-set-more-count nil))
        !           401:     (send-string te-process (make-string 1 last-input-char))
        !           402:     (te-process-output t))) 
        !           403: 
        !           404: (defun te-set-window-start ()
        !           405:   (let* ((w (get-buffer-window (current-buffer)))
        !           406:         (h (if w (window-height w))))
        !           407:     (cond ((not w)) ; buffer not displayed
        !           408:          ((>= h (/ (- (point) (point-min)) (1+ te-width)))
        !           409:           ;; this is the normal case
        !           410:           (set-window-start w (point-min)))
        !           411:          ;; this happens if some vandal shrinks our window.
        !           412:          ((>= h (/ (- (point-max) (point)) (1+ te-width)))
        !           413:           (set-window-start w (- (point-max) (* h (1+ te-width)) -1)))
        !           414:          ;; I give up.
        !           415:          (t nil))))
        !           416: 
        !           417: (defun te-pending-output-length ()
        !           418:   (let ((length (car te-pending-output))
        !           419:        (tem (cdr te-pending-output)))
        !           420:     (while tem
        !           421:       (setq length (+ length (length (car tem))) tem (cdr tem)))
        !           422:     length))
        !           423: 
        !           424: ;;;; more break hair
        !           425: 
        !           426: (defun te-more-break ()
        !           427:   (te-set-more-count t)
        !           428:   (make-local-variable 'te-more-old-point)
        !           429:   (setq te-more-old-point (point))
        !           430:   (make-local-variable 'te-more-old-local-map)
        !           431:   (setq te-more-old-local-map (current-local-map))
        !           432:   (use-local-map terminal-more-break-map)
        !           433:   (make-local-variable 'te-more-old-filter)
        !           434:   (setq te-more-old-filter (process-filter te-process))
        !           435:   (make-local-variable 'te-more-old-mode-line-format)
        !           436:   (setq te-more-old-mode-line-format mode-line-format
        !           437:        mode-line-format (list "--   **MORE**  "
        !           438:                               mode-line-buffer-identification
        !           439:                               "%-"))
        !           440:   (set-process-filter te-process
        !           441:     (function (lambda (process string)
        !           442:                (save-excursion
        !           443:                  (set-buffer (process-buffer process))
        !           444:                  (setq te-pending-output (nconc te-pending-output
        !           445:                                                 (list string))))
        !           446:                  (te-update-pending-output-display))))
        !           447:   (te-update-pending-output-display)
        !           448:   (if (eq (window-buffer (selected-window)) (current-buffer))
        !           449:       (message "More break "))
        !           450:   (or (eobp)
        !           451:       (null terminal-more-break-insertion)
        !           452:       (save-excursion
        !           453:        (forward-char 1)
        !           454:        (delete-region (point) (+ (point) te-width))
        !           455:        (insert terminal-more-break-insertion)))
        !           456:   (run-hooks 'terminal-more-break-hook)
        !           457:   (sit-for 0) ;get display to update
        !           458:   (throw 'te-process-output t))
        !           459: 
        !           460: (defun te-more-break-unwind ()
        !           461:   (use-local-map te-more-old-local-map)
        !           462:   (set-process-filter te-process te-more-old-filter)
        !           463:   (goto-char te-more-old-point)
        !           464:   (setq mode-line-format te-more-old-mode-line-format)
        !           465:   (set-buffer-modified-p (buffer-modified-p))
        !           466:   (let ((buffer-read-only nil))
        !           467:     (cond ((eobp))
        !           468:          (terminal-more-break-insertion
        !           469:           (forward-char 1)
        !           470:           (delete-region (point)
        !           471:                          (+ (point) (length terminal-more-break-insertion)))
        !           472:           (insert-char ?\  te-width)
        !           473:           (goto-char te-more-old-point)))
        !           474:     (setq te-more-old-point nil)
        !           475:     (let ((te-more-count 259259))
        !           476:       (te-newline)))
        !           477:   ;(sit-for 0)
        !           478:   (te-process-output t))
        !           479: 
        !           480: (defun te-set-more-count (newline)
        !           481:   (let ((line (/ (- (point) (point-min)) (1+ te-width))))
        !           482:     (if newline (setq line (1+ line)))
        !           483:     (cond ((= line te-height)
        !           484:           (setq te-more-count te-height))
        !           485:          ;>>>> something is strange.  Investigate this!
        !           486:          ((= line (1- te-height))
        !           487:           (setq te-more-count te-height))
        !           488:          ((or (< line (/ te-height 2))
        !           489:               (> (- te-height line) 10))
        !           490:           ;; break at end of this page
        !           491:           (setq te-more-count (- te-height line)))
        !           492:          (t
        !           493:           ;; migrate back towards top (ie bottom) of screen.
        !           494:           (setq te-more-count (- te-height
        !           495:                                  (if (> te-height 10) 2 1)))))))
        !           496: 
        !           497: 
        !           498: ;;;; More or less straight-forward terminal escapes
        !           499: 
        !           500: ;; ^j, meaning `newline' to non-display programs.
        !           501: ;; (Who would think of ever writing a system which doesn't understand
        !           502: ;;  display terminals natively?  Un*x:  The Operating System of the Future.)
        !           503: (defun te-newline ()
        !           504:   "Move down a line, optionally do more processing, perhaps wrap/scroll,
        !           505: move to start of new line, clear to end of line."
        !           506:   (end-of-line)
        !           507:   (cond ((not terminal-more-processing))
        !           508:        ((< (setq te-more-count (1- te-more-count)) 0)
        !           509:         (te-set-more-count t))
        !           510:        ((eql te-more-count 0)
        !           511:         ;; this doesn't return
        !           512:         (te-more-break)))
        !           513:   (if (eobp)
        !           514:       (progn
        !           515:        (delete-region (point-min) (+ (point-min) te-width))
        !           516:        (goto-char (point-min))
        !           517:        (if terminal-scrolling
        !           518:            (progn (delete-char 1)
        !           519:                   (goto-char (point-max))
        !           520:                   (insert ?\n))))
        !           521:     (forward-char 1)
        !           522:     (delete-region (point) (+ (point) te-width)))
        !           523:   (insert-char ?\  te-width)
        !           524:   (beginning-of-line)
        !           525:   (te-set-window-start))
        !           526: 
        !           527: ;; ^p ^j
        !           528: ;; Handle the `do' or `nl' termcap capability.
        !           529: ;;>> I am not sure why this broken, obsolete, capability is here.
        !           530: ;;>> Perhaps it is for VIle.  No comment was made about why it
        !           531: ;;>> was added (in "Sun Dec  6 01:22:27 1987  Richard Stallman")
        !           532: (defun te-down-vertically-or-scroll ()
        !           533:   "Move down a line vertically, or scroll at bottom."
        !           534:   (let ((column (current-column)))
        !           535:     (end-of-line)
        !           536:     (if (eobp)
        !           537:        (progn
        !           538:          (delete-region (point-min) (+ (point-min) te-width))
        !           539:          (goto-char (point-min))
        !           540:          (delete-char 1)
        !           541:          (goto-char (point-max))
        !           542:          (insert ?\n)
        !           543:          (insert-char ?\  te-width)
        !           544:          (beginning-of-line))
        !           545:       (forward-line 1))
        !           546:     (move-to-column column))
        !           547:   (te-set-window-start))
        !           548: 
        !           549: ; ^p = x+32 y+32
        !           550: (defun te-move-to-position ()
        !           551:   ;; must offset by #o40 since cretinous unix won't send a 004 char through
        !           552:   (let ((y (- (te-get-char) 32))
        !           553:        (x (- (te-get-char) 32)))
        !           554:     (if (or (> x te-width)
        !           555:            (> y te-height))
        !           556:        () ;(error "fucked %d %d" x y)
        !           557:       (goto-char (+ (point-min) x (* y (1+ te-width))))
        !           558:       ;(te-set-window-start?)
        !           559:       ))
        !           560:   (setq te-more-count -1))
        !           561: 
        !           562: 
        !           563: 
        !           564: ;; ^p c
        !           565: (defun te-clear-rest-of-line ()
        !           566:   (save-excursion
        !           567:     (let ((n (- (point) (progn (end-of-line) (point)))))
        !           568:       (delete-region (point) (+ (point) n))
        !           569:       (insert-char ?\  (- n)))))
        !           570: 
        !           571: 
        !           572: ;; ^p C
        !           573: (defun te-clear-rest-of-screen ()
        !           574:   (save-excursion
        !           575:     (te-clear-rest-of-line)
        !           576:     (while (progn (end-of-line) (not (eobp)))
        !           577:       (forward-char 1) (end-of-line)
        !           578:       (delete-region (- (point) te-width) (point))
        !           579:       (insert-char ?\  te-width))))
        !           580:       
        !           581: 
        !           582: ;; ^p ^l
        !           583: (defun te-clear-screen ()
        !           584:   ;; regenerate buffer to compensate for (nonexistent!!) bugs.
        !           585:   (erase-buffer)
        !           586:   (let ((i 0))
        !           587:     (while (< i te-height)
        !           588:       (setq i (1+ i))
        !           589:       (insert-char ?\  te-width)
        !           590:       (insert ?\n)))
        !           591:   (delete-region (1- (point-max)) (point-max))
        !           592:   (goto-char (point-min))
        !           593:   (setq te-more-count -1))
        !           594: 
        !           595: 
        !           596: ;; ^p ^o count+32
        !           597: (defun te-insert-lines ()
        !           598:   (if (not (bolp))
        !           599:       ();(error "fooI")
        !           600:     (save-excursion
        !           601:       (let* ((line (- te-height (/ (- (point) (point-min)) (1+ te-width)) -1))
        !           602:             (n (min (- (te-get-char) ?\ ) line))
        !           603:             (i 0))
        !           604:        (delete-region (- (point-max) (* n (1+ te-width))) (point-max))
        !           605:        (if (eql (point) (point-max)) (insert ?\n))
        !           606:        (while (< i n)
        !           607:          (setq i (1+ i))
        !           608:          (insert-char ?\  te-width)
        !           609:          (or (eql i line) (insert ?\n))))))
        !           610:   (setq te-more-count -1))
        !           611: 
        !           612: 
        !           613: ;; ^p ^k count+32
        !           614: (defun te-delete-lines ()
        !           615:   (if (not (bolp))
        !           616:       ();(error "fooD")
        !           617:     (let* ((line (- te-height (/ (- (point) (point-min)) (1+ te-width)) -1))
        !           618:           (n (min (- (te-get-char) ?\ ) line))
        !           619:           (i 0))
        !           620:       (delete-region (point)
        !           621:                     (min (+ (point) (* n (1+ te-width))) (point-max)))
        !           622:       (save-excursion
        !           623:        (goto-char (point-max))
        !           624:        (while (< i n)
        !           625:          (setq i (1+ i))
        !           626:          (insert-char ?\  te-width)
        !           627:          (or (eql i line) (insert ?\n))))))
        !           628:   (setq te-more-count -1))
        !           629: 
        !           630: ;; ^p ^a
        !           631: (defun te-beginning-of-line ()
        !           632:   (beginning-of-line))
        !           633: 
        !           634: ;; ^p ^b
        !           635: (defun te-backward-char ()
        !           636:   (if (not (bolp))
        !           637:       (backward-char 1)))
        !           638: 
        !           639: ;; ^p ^f
        !           640: (defun te-forward-char ()
        !           641:   (if (not (eolp))
        !           642:       (forward-char 1)))
        !           643: 
        !           644: 
        !           645: ;; 0177
        !           646: (defun te-delete ()
        !           647:   (if (bolp)
        !           648:       ()
        !           649:     (delete-region (1- (point)) (point))
        !           650:     (insert ?\ )
        !           651:     (forward-char -1)))
        !           652: 
        !           653: ;; ^p ^g
        !           654: (defun te-beep ()
        !           655:   (beep))
        !           656: 
        !           657: 
        !           658: ;; ^p _ count+32
        !           659: (defun te-insert-spaces ()
        !           660:   (let* ((p (point))
        !           661:         (n (min (- (te-get-char) 32)
        !           662:                 (- (progn (end-of-line) (point)) p))))
        !           663:     (if (<= n 0)
        !           664:        nil
        !           665:       (delete-char (- n))
        !           666:       (goto-char p)
        !           667:       (insert-char ?\  n))
        !           668:     (goto-char p)))
        !           669: 
        !           670: ;; ^p d count+32  (should be ^p ^d but cretinous un*x won't send ^d chars!!!)
        !           671: (defun te-delete-char ()
        !           672:   (let* ((p (point))
        !           673:         (n (min (- (te-get-char) 32)
        !           674:                 (- (progn (end-of-line) (point)) p))))
        !           675:     (if (<= n 0)
        !           676:        nil
        !           677:       (insert-char ?\  n)
        !           678:       (goto-char p)
        !           679:       (delete-char n))
        !           680:     (goto-char p)))
        !           681: 
        !           682: 
        !           683: 
        !           684: ;; disgusting unix-required shit
        !           685: ;;  Are we living twenty years in the past yet?
        !           686: 
        !           687: (defun te-losing-unix ()
        !           688:   ;(what lossage)
        !           689:   ;(message "fucking-unix: %d" char)
        !           690:   )
        !           691: 
        !           692: ;; ^i
        !           693: (defun te-output-tab ()
        !           694:   (let* ((p (point))
        !           695:         (x (- p (progn (beginning-of-line) (point))))
        !           696:         (l (min (- 8 (logand x 7))
        !           697:                 (progn (end-of-line) (- (point) p)))))
        !           698:     (goto-char (+ p l))))
        !           699: 
        !           700: ;; Also:
        !           701: ;;  ^m => beginning-of-line (for which it -should- be using ^p ^a, right?!!)
        !           702: ;;  ^g => te-beep (for which it should use ^p ^g)
        !           703: ;;  ^h => te-backward-char (for which it should use ^p ^b)
        !           704: 
        !           705: 
        !           706: 
        !           707: (defun te-filter (process string)
        !           708:   (let* ((obuf (current-buffer))
        !           709:         (m meta-flag))
        !           710:     ;; can't use save-excursion, as that preserves point, which we don't want
        !           711:     (unwind-protect
        !           712:        (progn
        !           713:          (set-buffer (process-buffer process))
        !           714:          (goto-char te-saved-point)
        !           715:          (and (bufferp te-log-buffer)
        !           716:               (if (null (buffer-name te-log-buffer))
        !           717:                   ;; killed
        !           718:                   (setq te-log-buffer nil)
        !           719:                 (set-buffer te-log-buffer)
        !           720:                 (goto-char (point-max))
        !           721:                 (insert string)
        !           722:                 (set-buffer (process-buffer process))))
        !           723:          (setq te-pending-output (nconc te-pending-output (list string)))
        !           724:          (te-update-pending-output-display)
        !           725:          ;; this binding is needed because emacs looks at meta-flag when
        !           726:          ;;  the keystroke is read from the keyboard, not when it is about
        !           727:          ;;  to be fed into a keymap (or returned by read-char)
        !           728:          ;; There still could be some screws, though.
        !           729:          (let ((meta-flag m))
        !           730:            (te-process-output (eq (current-buffer)
        !           731:                                   (window-buffer (selected-window)))))
        !           732:          (set-buffer (process-buffer process))
        !           733:          (setq te-saved-point (point)))
        !           734:       (set-buffer obuf))))
        !           735: 
        !           736: ;; fucking unix has -such- braindamaged lack of tty control...
        !           737: (defun te-process-output (preemptable)
        !           738:   ;;>> There seems no good reason to ever disallow preemption
        !           739:   (setq preemptable t)
        !           740:   (catch 'te-process-output
        !           741:     (let ((buffer-read-only nil)
        !           742:          (string nil) ostring start char (matchpos nil))
        !           743:       (while (cdr te-pending-output)
        !           744:        (setq ostring string
        !           745:              start (car te-pending-output)
        !           746:              string (car (cdr te-pending-output))
        !           747:              char (aref string start))
        !           748:        (if (eql (setq start (1+ start)) (length string))
        !           749:            (progn (setq te-pending-output
        !           750:                           (cons 0 (cdr (cdr te-pending-output)))
        !           751:                         start 0
        !           752:                         string (car (cdr te-pending-output)))
        !           753:                   (te-update-pending-output-display))
        !           754:            (setcar te-pending-output start))
        !           755:        (if (and (> char ?\037) (< char ?\377))
        !           756:            (cond ((eolp)
        !           757:                   ;; unread char
        !           758:                   (if (eql start 0)
        !           759:                       (setq te-pending-output
        !           760:                             (cons 0 (cons (make-string 1 char)
        !           761:                                           (cdr te-pending-output))))
        !           762:                       (setcar te-pending-output (1- start)))
        !           763:                   (te-newline))
        !           764:                  ((null string)
        !           765:                   (delete-char 1) (insert char)
        !           766:                   (te-redisplay-if-necessary 1))
        !           767:                  (t
        !           768:                   (let ((end (or (and (eq ostring string) matchpos)
        !           769:                                  (setq matchpos (string-match
        !           770:                                                   "[\000-\037\177-\377]"
        !           771:                                                   string start))
        !           772:                                  (length string))))
        !           773:                     (delete-char 1) (insert char)
        !           774:                     (setq char (point)) (end-of-line)
        !           775:                     (setq end (min end (+ start (- (point) char))))
        !           776:                     (goto-char char)
        !           777:                     (if (eql end matchpos) (setq matchpos nil))
        !           778:                     (delete-region (point) (+ (point) (- end start)))
        !           779:                     (insert (if (and (eql start 0)
        !           780:                                      (eql end (length string)))
        !           781:                                 string
        !           782:                                 (substring string start end)))
        !           783:                     (if (eql end (length string))
        !           784:                         (setq te-pending-output
        !           785:                               (cons 0 (cdr (cdr te-pending-output))))
        !           786:                         (setcar te-pending-output end))
        !           787:                     (te-redisplay-if-necessary (1+ (- end start))))))
        !           788:          ;; I suppose if I split the guts of this out into a separate
        !           789:          ;;  function we could trivially emulate different terminals
        !           790:          ;; Who cares in any case?  (Apart from stupid losers using rlogin)
        !           791:          (funcall
        !           792:            (if (eql char ?\^p)
        !           793:                (or (cdr (assq (te-get-char)
        !           794:                               '((?= . te-move-to-position)
        !           795:                                 (?c . te-clear-rest-of-line)
        !           796:                                 (?C . te-clear-rest-of-screen)
        !           797:                                 (?\C-o . te-insert-lines)
        !           798:                                 (?\C-k . te-delete-lines)
        !           799:                                 ;; not necessary, but help sometimes.
        !           800:                                 (?\C-a . te-beginning-of-line)
        !           801:                                 (?\C-b . te-backward-char)
        !           802:                                 ;; should be C-d, but un*x
        !           803:                                 ;;  pty's won't send \004 through!
        !           804:                                  ;; Can you believe this?
        !           805:                                 (?d . te-delete-char)
        !           806:                                 (?_ . te-insert-spaces)
        !           807:                                 ;; random
        !           808:                                 (?\C-f . te-forward-char)
        !           809:                                 (?\C-g . te-beep)
        !           810:                                 (?\C-j . te-down-vertically-or-scroll)
        !           811:                                 (?\C-l . te-clear-screen)
        !           812:                                 )))
        !           813:                    'te-losing-unix)
        !           814:                (or (cdr (assq char
        !           815:                               '((?\C-j . te-newline)
        !           816:                                 (?\177 . te-delete)
        !           817:                                 ;; Did I ask to be sent these characters?
        !           818:                                 ;; I don't remember doing so, either.
        !           819:                                 ;; (Perhaps some operating system or
        !           820:                                 ;; other is completely incompetent...)
        !           821:                                 (?\C-m . te-beginning-of-line) ;fuck me harder
        !           822:                                 (?\C-g . te-beep)             ;again and again!
        !           823:                                 (?\C-h . te-backward-char)     ;wa12id!!
        !           824:                                 (?\C-i . te-output-tab))))     ;(spiked)
        !           825:                    'te-losing-unix)))                ;That feels better
        !           826:          (te-redisplay-if-necessary 1))
        !           827:        (and preemptable
        !           828:             (input-pending-p)
        !           829:             ;; preemptable output!  Oh my!!
        !           830:             (throw 'te-process-output t)))))
        !           831:   ;; We must update window-point in every window displaying our buffer
        !           832:   (let* ((s (selected-window))
        !           833:         (w s))
        !           834:     (while (not (eq s (setq w (next-window w))))
        !           835:       (if (eq (window-buffer w) (current-buffer))
        !           836:          (set-window-point w (point))))))
        !           837: 
        !           838: (defun te-get-char ()
        !           839:   (if (cdr te-pending-output)
        !           840:       (let ((start (car te-pending-output))
        !           841:            (string (car (cdr te-pending-output))))
        !           842:        (prog1 (aref string start)
        !           843:          (if (eql (setq start (1+ start)) (length string))
        !           844:              (setq te-pending-output (cons 0 (cdr (cdr te-pending-output))))
        !           845:              (setcar te-pending-output start))))
        !           846:     (catch 'char
        !           847:       (let ((filter (process-filter te-process)))
        !           848:        (unwind-protect
        !           849:            (progn
        !           850:              (set-process-filter te-process
        !           851:                                  (function (lambda (p s)
        !           852:                                     (or (eql (length s) 1)
        !           853:                                         (setq te-pending-output (list 1 s)))
        !           854:                                     (throw 'char (aref s 0)))))
        !           855:              (accept-process-output te-process))
        !           856:          (set-process-filter te-process filter))))))
        !           857: 
        !           858: 
        !           859: (defun te-redisplay-if-necessary (length)
        !           860:   (and (<= (setq te-redisplay-count (- te-redisplay-count length)) 0)
        !           861:        (eq (current-buffer) (window-buffer (selected-window)))
        !           862:        (waiting-for-user-input-p)
        !           863:        (progn (te-update-pending-output-display)
        !           864:              (sit-for 0)
        !           865:              (setq te-redisplay-count terminal-redisplay-interval))))
        !           866: 
        !           867: (defun te-update-pending-output-display ()
        !           868:   (if (null (cdr te-pending-output))
        !           869:       (setq te-pending-output-info "")      
        !           870:     (let ((length (te-pending-output-length)))
        !           871:       (if (< length 1500)
        !           872:          (setq te-pending-output-info "")
        !           873:        (setq te-pending-output-info (format "(%dK chars output pending) "
        !           874:                                             (/ (+ length 512) 1024))))))
        !           875:   ;; update mode line
        !           876:   (set-buffer-modified-p (buffer-modified-p)))
        !           877: 
        !           878: 
        !           879: (defun te-sentinel (process message)
        !           880:   (cond ((eq (process-status process) 'run))
        !           881:        ((null (buffer-name (process-buffer process)))) ;deleted
        !           882:        (t (let ((b (current-buffer)))
        !           883:             (save-excursion
        !           884:               (set-buffer (process-buffer process))
        !           885:               (setq buffer-read-only nil)
        !           886:               (fundamental-mode)
        !           887:               (goto-char (point-max))
        !           888:               (delete-blank-lines)
        !           889:               (delete-horizontal-space)
        !           890:               (insert "\n*******\n" message "*******\n"))
        !           891:             (if (and (eq b (process-buffer process))
        !           892:                      (waiting-for-user-input-p))
        !           893:                 (progn (goto-char (point-max))
        !           894:                        (recenter -1)))))))
        !           895: 
        !           896: (defvar te-stty-string "stty -nl new dec echo"
        !           897:   "Command string (to be interpreted by \"sh\") which sets the modes
        !           898: of the virtual terminal to be appropriate for interactive use.")
        !           899: 
        !           900: (defvar explicit-shell-file-name nil
        !           901:   "*If non-nil, is file name to use for explicitly requested inferior shell.")
        !           902: 
        !           903: (defun terminal-emulator (buffer program args &optional width height)
        !           904:   "Under a display-terminal emulator in BUFFER, run PROGRAM on arguments ARGS.
        !           905: ARGS is a list of argument-strings.  Remaining arguments are WIDTH and HEIGHT.
        !           906: BUFFER's contents are made an image of the display generated by that program,
        !           907: and any input typed when BUFFER is the current Emacs buffer is sent to that
        !           908: program an keyboard input.
        !           909: 
        !           910: Interactively, BUFFER defaults to \"*terminal*\" and PROGRAM and ARGS
        !           911: are parsed from an input-string using your usual shell.
        !           912: WIDTH and HEIGHT are determined from the size of the current window
        !           913: -- WIDTH will be one less than the window's width, HEIGHT will be its height.
        !           914: 
        !           915: To switch buffers and leave the emulator, or to give commands
        !           916: to the emulator itself (as opposed to the program running under it),
        !           917: type Control-^.  The following character is an emulator command.
        !           918: Type Control-^ twice to send it to the subprogram.
        !           919: This escape character may be changed using the variable `terminal-escape-char'.
        !           920: 
        !           921: `Meta' characters may not currently be sent through the terminal emulator.
        !           922: 
        !           923: Here is a list of some of the variables which control the behaviour
        !           924: of the emulator -- see their documentation for more information:
        !           925: terminal-escape-char, terminal-scrolling, terminal-more-processing,
        !           926: terminal-redisplay-interval.
        !           927: 
        !           928: This function calls the value of terminal-mode-hook if that exists
        !           929: and is non-nil after the terminal buffer has been set up and the
        !           930: subprocess started.
        !           931: 
        !           932: Presently with `termcap' only; if somebody sends us code to make this
        !           933: work with `terminfo' we will try to use it."
        !           934:   (interactive
        !           935:     (cons (save-excursion
        !           936:            (set-buffer (get-buffer-create "*terminal*"))
        !           937:            (buffer-name (if (or (not (boundp 'te-process))
        !           938:                                 (null te-process)
        !           939:                                 (not (eq (process-status te-process)
        !           940:                                          'run)))
        !           941:                             (current-buffer)
        !           942:                           (generate-new-buffer "*terminal*"))))
        !           943:          (append
        !           944:            (let* ((default-s
        !           945:                     ;; Default shell is same thing M-x shell uses.
        !           946:                     (or explicit-shell-file-name
        !           947:                         (getenv "ESHELL")
        !           948:                         (getenv "SHELL")
        !           949:                         "/bin/sh"))
        !           950:                   (s (read-string
        !           951:                       (format "Run program in emulator: (default %s) "
        !           952:                               default-s))))
        !           953:              (if (equal s "")
        !           954:                  (list default-s '())
        !           955:                (te-parse-program-and-args s))))))
        !           956:   (switch-to-buffer buffer)
        !           957:   (if (null width) (setq width (- (window-width (selected-window)) 1)))
        !           958:   (if (null height) (setq height (- (window-height (selected-window)) 1)))
        !           959:   (terminal-mode)
        !           960:   (setq te-width width te-height height)
        !           961:   (setq mode-line-buffer-identification
        !           962:        (list (format "Emacs terminal %dx%d: %%b  " te-width te-height)
        !           963:              'te-pending-output-info))
        !           964:   (let ((buffer-read-only nil))
        !           965:     (te-clear-screen))
        !           966:   (let (process)
        !           967:     (while (setq process (get-buffer-process (current-buffer)))
        !           968:       (if (y-or-n-p (format "Kill process %s? " (process-name process)))
        !           969:          (delete-process process)
        !           970:        (error "Process %s not killed" (process-name process)))))
        !           971:   (condition-case err
        !           972:       (let ((termcap
        !           973:              ;; Because of Unix Brain Death(tm), we can't change
        !           974:              ;;  the terminal type of a running process, and so
        !           975:              ;;  terminal size and scrollability are wired-down
        !           976:              ;;  at this point.  ("Detach?  What's that?")
        !           977:              (concat (format "emacs-virtual:co#%d:li#%d:%s"
        !           978:                              ;; Sigh.  These can't be dynamically changed.
        !           979:                              te-width te-height (if terminal-scrolling
        !           980:                                                     "" "ns:"))
        !           981:                      ;;-- Basic things
        !           982:                      ;; cursor-motion, bol, forward/backward char
        !           983:                      "cm=^p=%+ %+ :cr=^p^a:le=^p^b:nd=^p^f:"
        !           984:                      ;; newline, clear eof/eof, audible bell
        !           985:                      "nw=^j:ce=^pc:cd=^pC:cl=^p^l:bl=^p^g:"
        !           986:                      ;; insert/delete char/line
        !           987:                      "IC=^p_%+ :DC=^pd%+ :AL=^p^o%+ :DL=^p^k%+ :"
        !           988:                      ;;-- Not-widely-known (ie nonstandard) flags, which mean
        !           989:                      ;; o writing in the last column of the last line
        !           990:                      ;;   doesn't cause idiotic scrolling, and
        !           991:                      ;; o don't use idiotische c-s/c-q sogenannte
        !           992:                      ;;   ``flow control'' auf keinen Fall.
        !           993:                      "LP:NF:"
        !           994:                      ;;-- For stupid or obsolete programs
        !           995:                      "ic=^p_!:dc=^pd!:al=^p^o!:dl=^p^k!:ho=^p=  :"
        !           996:                      ;;-- For disgusting programs.
        !           997:                      ;; (VI? What losers need these, I wonder?)
        !           998:                      "im=:ei=:dm=:ed=:mi:do=^p^j:nl=^p^j:bs:")))
        !           999:        (if (fboundp 'start-subprocess)
        !          1000:            ;; this winning function would do everything, except that
        !          1001:            ;;  rms doesn't want it.
        !          1002:            (setq te-process (start-subprocess "terminal-emulator"
        !          1003:                               program args
        !          1004:                               'channel-type 'terminal
        !          1005:                               'filter 'te-filter
        !          1006:                               'buffer (current-buffer)
        !          1007:                               'sentinel 'te-sentinel
        !          1008:                               'modify-environment
        !          1009:                                 (list (cons "TERM" "emacs-virtual")
        !          1010:                                       (cons "TERMCAP" termcap))))
        !          1011:          ;; so instead we resort to this...
        !          1012:          (setq te-process (start-process "terminal-emulator" (current-buffer)
        !          1013:                             "/bin/sh" "-c"
        !          1014:                             ;; Yuck!!! Start a shell to set some terminal
        !          1015:                             ;; control characteristics.  Then start the
        !          1016:                             ;; "env" program to setup the terminal type
        !          1017:                             ;; Then finally start the program we wanted.
        !          1018:                             (format "%s; exec %s TERM=emacs-virtual %s %s"
        !          1019:                                      te-stty-string
        !          1020:                                     (te-quote-arg-for-sh
        !          1021:                                       (concat exec-directory "env"))
        !          1022:                                     (te-quote-arg-for-sh
        !          1023:                                       (concat "TERMCAP=" termcap))
        !          1024:                                     (mapconcat 'te-quote-arg-for-sh
        !          1025:                                                (cons program args) " "))))
        !          1026:          (set-process-filter te-process 'te-filter)
        !          1027:          (set-process-sentinel te-process 'te-sentinel)))
        !          1028:     (error (fundamental-mode)
        !          1029:           (signal (car err) (cdr err))))
        !          1030:   ;; sigh
        !          1031:   (if (default-value 'meta-flag)
        !          1032:       (progn (message
        !          1033:  "Note:  Meta key disabled due to maybe-eventually-reparable braindamage")
        !          1034:             (sit-for 1)))
        !          1035:   (message "Entering emacs terminal-emulator...  Type %s %s for help"
        !          1036:           (single-key-description terminal-escape-char)
        !          1037:           (mapconcat 'single-key-description
        !          1038:                      (where-is-internal 'te-escape-help
        !          1039:                                         terminal-escape-map
        !          1040:                                         t)
        !          1041:                      " "))
        !          1042:   (setq inhibit-quit t)                        ;sport death
        !          1043:   (use-local-map terminal-map)
        !          1044:   (run-hooks 'terminal-mode-hook))
        !          1045: 
        !          1046: (defun te-parse-program-and-args (s)
        !          1047:   (cond ((string-match "\\`\\([a-zA-Z0-9-+=_.@/:]+[ \t]*\\)+\\'" s)
        !          1048:         (let ((l ()) (p 0))
        !          1049:           (while p
        !          1050:             (setq l (cons (if (string-match
        !          1051:                                "\\([a-zA-Z0-9-+=_.@/:]+\\)\\([ \t]+\\)*"
        !          1052:                                s p)
        !          1053:                               (prog1 (substring s p (match-end 1))
        !          1054:                                 (setq p (match-end 0))
        !          1055:                                 (if (eql p (length s)) (setq p nil)))
        !          1056:                               (prog1 (substring s p)
        !          1057:                                 (setq p nil)))
        !          1058:                           l)))
        !          1059:           (setq l (nreverse l))
        !          1060:           (list (car l) (cdr l))))
        !          1061:        ((and (string-match "[ \t]" s) (not (file-exists-p s)))
        !          1062:         (list shell-file-name (list "-c" (concat "exec " s))))
        !          1063:        (t (list s ()))))
        !          1064: 
        !          1065: (put 'terminal-mode 'mode-class 'special)
        !          1066: ;; This is only separated out from function terminal-emulator
        !          1067: ;; to keep the latter a little more managable.
        !          1068: (defun terminal-mode ()
        !          1069:   "Set up variables for use f the terminal-emualtor.
        !          1070: One should not call this -- it is an internal function
        !          1071: of the terminal-emulator"
        !          1072:   (kill-all-local-variables)
        !          1073:   (buffer-flush-undo (current-buffer))
        !          1074:   (setq major-mode 'terminal-mode)
        !          1075:   (setq mode-name "terminal")
        !          1076: ; (make-local-variable 'Helper-return-blurb)
        !          1077: ; (setq Helper-return-blurb "return to terminal simulator")
        !          1078:   (setq mode-line-process '(": %s"))
        !          1079:   (setq buffer-read-only t)
        !          1080:   (setq truncate-lines t)
        !          1081:   (make-local-variable 'terminal-escape-char)
        !          1082:   (setq terminal-escape-char (default-value 'terminal-escape-char))
        !          1083:   (make-local-variable 'terminal-scrolling)
        !          1084:   (setq terminal-scrolling (default-value 'terminal-scrolling))
        !          1085:   (make-local-variable 'terminal-more-processing)
        !          1086:   (setq terminal-more-processing (default-value 'terminal-more-processing))
        !          1087:   (make-local-variable 'terminal-redisplay-interval)
        !          1088:   (setq terminal-redisplay-interval (default-value 'terminal-redisplay-interval))
        !          1089:   (make-local-variable 'te-width)
        !          1090:   (make-local-variable 'te-height)
        !          1091:   (make-local-variable 'te-process)
        !          1092:   (make-local-variable 'te-pending-output)
        !          1093:   (setq te-pending-output (list 0))
        !          1094:   (make-local-variable 'te-saved-point)
        !          1095:   (setq te-saved-point (point-min))
        !          1096:   (make-local-variable 'te-pending-output-info) ;for the mode line
        !          1097:   (setq te-pending-output-info "")
        !          1098:   (make-local-variable 'inhibit-quit)
        !          1099:   ;(setq inhibit-quit t)
        !          1100:   (make-local-variable 'te-log-buffer)
        !          1101:   (setq te-log-buffer nil)
        !          1102:   (make-local-variable 'te-more-count)
        !          1103:   (setq te-more-count -1)
        !          1104:   (make-local-variable 'te-redisplay-count)
        !          1105:   (setq te-redisplay-count terminal-redisplay-interval)
        !          1106:   ;;>> Nothing can be done about this without decruftifying
        !          1107:   ;;>>  emacs keymaps.
        !          1108:   (make-local-variable 'meta-flag) ;sigh
        !          1109:   (setq meta-flag nil)
        !          1110:   ;(use-local-map terminal-mode-map)
        !          1111:   ;; terminal-mode-hook is called above in function terminal-emulator
        !          1112:   )
        !          1113: 
        !          1114: ;;;; what a complete loss
        !          1115: 
        !          1116: (defun te-quote-arg-for-sh (fuckme)
        !          1117:   (cond ((string-match "\\`[a-zA-Z0-9-+=_.@/:]+\\'"
        !          1118:                       fuckme)
        !          1119:         fuckme)
        !          1120:        ((not (string-match "[$]" fuckme))
        !          1121:         ;; "[\"\\]" are special to sh and the lisp reader in the same way
        !          1122:         (prin1-to-string fuckme))
        !          1123:        (t
        !          1124:         (let ((harder "")
        !          1125:               (cretin 0)
        !          1126:               (stupid 0))
        !          1127:           (while (cond ((>= cretin (length fuckme))
        !          1128:                         nil)
        !          1129:                        ;; this is the set of chars magic with "..." in `sh'
        !          1130:                        ((setq stupid (string-match "[\"\\$]"
        !          1131:                                                    fuckme cretin))
        !          1132:                         t)
        !          1133:                        (t (setq harder (concat harder
        !          1134:                                                (substring fuckme cretin)))
        !          1135:                           nil))
        !          1136:             (setq harder (concat harder (substring fuckme cretin stupid)
        !          1137:                                   ;; Can't use ?\\ since `concat'
        !          1138:                                   ;; unfortunately does prin1-to-string
        !          1139:                                   ;; on fixna.  Amazing.
        !          1140:                                  "\\"
        !          1141:                                  (substring fuckme
        !          1142:                                             stupid
        !          1143:                                             (1+ stupid)))
        !          1144:                   cretin (1+ stupid)))
        !          1145:           (concat "\"" harder "\"")))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.