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

unix.superglobalmegacorp.com

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