home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / terms / flow-ctrl.el < prev    next >
Encoding:
Text File  |  1993-03-27  |  11.3 KB  |  280 lines

  1. ; From: "Jeff Morgenthaler" <jpmorgen@wisp4.physics.wisc.edu>
  2. ; Subject: flow-ctrl.el
  3. ; Date: Fri, 26 Mar 93 23:52:34 -0600
  4. ;;; File:  flow-ctrl.el, v 3.0 (emacs 18[.58] version)
  5. ;;;
  6. ;;;               -------   -------------   ---------------------
  7. ;;;               F l o w   C o n t r o l   A d j u s t m e n t s
  8. ;;;               -------   -------------   ---------------------
  9. ;;;
  10. ;;;
  11. ;;; Copyright (C) 1990 Free Software Foundation, Inc.
  12. ;;; Copyright (C) 1993 Jeff Morgenthaler
  13. ;;; Thanks to Kevin Gallagher for TERM-in-list and Joe Wells for
  14. ;;; encouragement to code everything right.  
  15. ;;;
  16.  
  17. ;; LCD Archive Entry:
  18. ;; flow-ctrl|Jeff Morgenthaler|jpmorgen@wisp4.physics.wisc.edu|
  19. ;; Flow control adjustments to remap C-s and C-q.|
  20. ;; 23-Mar-1993|1.0|~/terms/flow-ctrl.el.Z|
  21.  
  22. ;; Archived at archive.cis.ohio-state.edu
  23.  
  24.  
  25. ;;; GNU Emacs is distributed in the hope that it will be useful, but
  26. ;;; WITHOUT ANY WARRANTY.  No author or distributor accepts
  27. ;;; RESPONSIBILITY TO anyone for the consequences of using it or for
  28. ;;; whether it serves any particular purpose or works at all, unless 
  29. ;;; he says so in writing.  Refer to the GNU Emacs General Public
  30. ;;; License for full details.
  31. ;;;
  32. ;;;  Send bug reports and suggestions for improvement to Jeff Morgenthaler
  33. ;;;  (jpmorgen@wisp4.physics.wisc.edu).
  34. ;;;
  35. ;;; Everyone is granted permission to copy, modify and redistribute
  36. ;;; GNU Emacs, but only under the conditions described in the GNU
  37. ;;; Emacs General Public License.  A copy of this license is supposed
  38. ;;; to have been given to you along with GNU Emacs so you can know
  39. ;;; your rights and responsibilities.  It should be in a file named
  40. ;;; COPYING.  Among other things, the Copyright notice and this notice
  41. ;;; must be preserved on all copies.
  42. ;;;
  43.  
  44. ;;;; WARNING: this code uses set-input-mode, which is due to change
  45. ;;;; (slightly?) in emacs 19.
  46.  
  47. ;;;; XON/XOFF flow control is a primitive user interface scheme 
  48. ;;;; employed by most terminals, terminal servers, modems, and
  49. ;;;; operating systems.  XON/XOFF flow control allows the user,
  50. ;;;; terminal, modem, etc. to pause the data stream at any time for
  51. ;;;; whatever reason.  The standard flow control commands are C-s for
  52. ;;;; stop and C-q for "quontinue" (at least that's how I remember it).
  53.  
  54. ;;;; Users of GNU emacs will recognize C-s and C-q as the commands
  55. ;;;; isearch-forward and quote-insert, and part of the commands
  56. ;;;; save-buffer and toggle-read-only.  It does not take very long to
  57. ;;;; recognize the usefulness of these bindings in emacs (and the
  58. ;;;; emacs model in general--mnemonic key bindings) over any
  59. ;;;; usefulness that XON/XOFF flow control had or will ever had.
  60.  
  61. ;;;; Emacs does the best it can to turn XON/XOFF flow control off.
  62. ;;;; Unfortunately, due to poor planing on the part of the inventors
  63. ;;;; of XON/XOFF flow control, it is only possible to disable flow
  64. ;;;; control on the machine that is running emacs: there is no
  65. ;;;; standard sequence of characters that a remote terminal, modem,
  66. ;;;; operating system, etc. will interpret to mean "disable flow
  67. ;;;; control."
  68.  
  69. ;;;; Thus, it is up to each user to make sure that XON/XOFF flow
  70. ;;;; control is disabled at all hardware between the user and the
  71. ;;;; machine running emacs.  Terminals usually have an item in their
  72. ;;;; setup menu for flow control or "hsk."  Modems using the Hayes
  73. ;;;; standard "at" commands should respond to at&k0.  Terminal or
  74. ;;;; modem servers will often have a command such as "set port flow
  75. ;;;; control disable" to be issued an the "local" prompt.  In VMS, you
  76. ;;;; can issue the command SET TERM/PASSALL.  In UNIX, you can try
  77. ;;;; "stty start u stop u," rlogin -8, or use telnet....
  78.  
  79. ;;;; Unfortunately (and you probably wouldn't be reading this if this
  80. ;;;; wasn't the case for you) it is sometimes impossible or
  81. ;;;; inconvenient at the moment to disable flow control.  Emacs has
  82. ;;;; always had a solution for this: the C-\ and C-^ keys are not
  83. ;;;; bound to anything (unlike all the other control characters in
  84. ;;;; emacs).  Following the emacs model, these keys are fairly
  85. ;;;; mnemonic: C-\ (that is back-Slash) resembles / which is search in
  86. ;;;; more/vi/ed) and C-^ can clearly be associated with the ^ produced
  87. ;;;; by C-q C-w.  Also, emacs has a function (set-input-mode) which
  88. ;;;; allows the C-s and C-q characters to be passed to the machine on
  89. ;;;; which emacs is running in case the terminal, modem, server, etc.,
  90. ;;;; really can't handle the rate of data flow and has no other means
  91. ;;;; of flow control.
  92.  
  93. ;;;; What has been missing up to now has been a decent wrapper for
  94. ;;;; these already existing features so that users can function in
  95. ;;;; emacs even when they are stuck on broken hardware without
  96. ;;;; becoming expert emacs code writers.  By "decent wrapper" I mean a
  97. ;;;; function that can be called interactively (with M-x) that is
  98. ;;;; sensibly named.  The function should not interfere with other
  99. ;;;; functions which remap the keys and it should toggle, cleaning up
  100. ;;;; completely after itself.  Variables for customizing the key
  101. ;;;; remappings and an auto-start feature should also be included.
  102.  
  103. ;;;; flow-control-fix is such a function.
  104.  
  105. ;;;; The variables C-s-replacement, C-q-replacement and
  106. ;;;; terminal-uses-flow-control-chars are available for customization
  107. ;;;; of flow-control-fix.  Here are some examples of how to set them
  108. ;;;; (you would put these in your .emacs file):
  109.  
  110. ;;;; (setq C-s-replacement ?\C-t)
  111. ;;;; (setq terminal-uses-flow-control-chars 
  112. ;;;;   '("vt52" "vt100" "vt200"))
  113.  
  114. ;;;; TERM-in-list and init-keyboard-translate-table, which are useful
  115. ;;;; functions for further user customizations are also also defined.
  116.  
  117. ;;;; To make this facility available for use to all users, place this file
  118. ;;;; (flow-ctrl.el) into your site's public emacs/lisp directory and
  119. ;;;; add the following lines to your site's default.el file:
  120.  
  121. ;;;; (require 'flow-ctrl)
  122. ;;;; (auto-flow-control-fix)
  123.  
  124. ;;;; You may also want to preload flow-ctrl into emacs by putting the
  125. ;;;; code:
  126.  
  127. ;;;; (load "flow-ctrl")
  128.  
  129. ;;;; in your site-init.el file.  This will allow the functions
  130. ;;;; TERM-in-list and init-keyboard-translate-table to be called in
  131. ;;;; the user's .emacs file outside of their term-setup-hook.
  132.  
  133. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  134.  
  135. (provide 'flow-ctrl)
  136.  
  137. ;; default C-s, C-q replacements
  138. (defvar C-s-replacement ?\C-\\
  139.   "*Ascii version of character to substitute for Control-S.  Example of 
  140. setting this variable: (setq C-s-replacement ?\\C-t).")
  141.  
  142. (defvar C-q-replacement ?\C-^
  143.   "*Ascii version of character to substitute for Control-Q.  Example of 
  144. setting this variable: (setq C-q-replacement ?\\C-]).")
  145.  
  146. (defvar terminal-uses-flow-control-chars nil
  147.   "*List of general terminal types used by the user which are often 
  148. flow-control hobbled.  Used by auto-flow-control-fix.  Example of setting 
  149. this variable:
  150. (setq terminal-uses-flow-control-chars 
  151.    '(""vt52"" ""vt100"" ""vt200""))")
  152.  
  153. (defvar flow-control-fix-flag nil
  154.   "*Flag to indicate if flow control avoidance is in effect.")
  155.  
  156. (defun init-keyboard-translate-table ()
  157.   "Initialize translate table, saving previous mappings, if any."
  158.   (let ((the-table (make-string 256 0)))
  159.     ;; Some users of PC and DEMACS need a large keyboard-translate-table
  160.     (let ((i 0)
  161.       (j (length keyboard-translate-table)))
  162.       (while (< i j)
  163.     (aset the-table i (elt keyboard-translate-table i))
  164.     (setq i (1+ i)))
  165.       (while (< i 256)
  166.     (aset the-table i i)
  167.     (setq i (1+ i))))
  168.     (setq keyboard-translate-table the-table)))
  169.  
  170. (defun TERM-in-list (term-list)
  171.   "Returns t if the current terminal \(TERM\) is in term-list.  Drops 
  172. everything in TERM past the first hyphen. Example of term-list:
  173.   '\(""vt52"" ""vt100"" ""vt200""\)"
  174.   (let ((term (getenv "TERM"))
  175.     hyphend
  176.     TERM-in-list)
  177.     ;; Make sure TERM is set. Some people start emacs from their 
  178.     ;; .xinitrc or .xsession file, in which case TERM is not set
  179.     (if term
  180.     (progn
  181.       ;; Strip off hyphen and what follows
  182.       (while (setq hyphend (string-match "[-_][^-_]+$" term))
  183.         (setq term (substring term 0 hyphend)))
  184.       (let ((len (length term-list))
  185.         (idx 0)
  186.         (temp-term nil))
  187.         (while (and (< idx len)
  188.             (not temp-term))
  189.           (if (string-equal term 
  190.                 (nth idx term-list))
  191.           (progn
  192.             (setq TERM-in-list t)
  193.             (setq temp-term term))
  194.         (setq idx (1+ idx)))))))
  195.     TERM-in-list))
  196.  
  197. (defun flow-control-fix (arg)
  198.   "Replaces C-s with C-s-replacement, C-q with C-q-replacement \(C-\\
  199. and C-^ by default\) and tells emacs to pass C-s and C-q on to the
  200. operating system.  Gets around XON/XOFF flow control.  This is a last
  201. resort fix!  First try turning off flow control at your terminal \(with
  202. the setup menu\), modem \(at&k0\), terminal server \(set port flow
  203. control disable\), machine you are logging in through \(SET TERM/PASSALL
  204. or rlogin -8\), etc.  Turns on with an argument of t or a positive
  205. argument, off with an argument of nil or negative argument, and toggles 
  206. with no argument."
  207.  
  208.   (interactive
  209.    (list
  210.     (if current-prefix-arg
  211.     ;; If an argument is specified, then turn on if non-negative else
  212.     ;; turn off if negative.
  213.     (>= (prefix-numeric-value current-prefix-arg) 0)
  214.       ;; If no argument is specified, then toggle.
  215.       'toggle)))
  216.  
  217.   (setq flow-control-fix-flag
  218.     (if (eq arg 'toggle)
  219.         (not flow-control-fix-flag)
  220.      arg))
  221.   ;; Thanks to the elisp prowess of jbw for the above sequence!
  222.  
  223.  
  224.   (if flow-control-fix-flag
  225.     ;; Tell emacs to pass C-s and C-q to OS and swap out C-s and C-q.
  226.     (progn
  227.       (set-input-mode nil t)
  228.       ;; !!!!!!!!!!!!emacs 19 users will have to change this!!!!!!!!!!!!!!!!
  229.       (init-keyboard-translate-table)
  230.       ;; Swap C-s and C-s-replacement
  231.       (aset keyboard-translate-table C-s-replacement ?\^s)
  232.       (aset keyboard-translate-table ?\^s C-s-replacement)
  233.       ;; Swap C-q and C-q-replacement
  234.       (aset keyboard-translate-table C-q-replacement ?\^q)
  235.       (aset keyboard-translate-table ?\^q C-q-replacement)
  236.       (message (concat "XON/XOFF adjustment for " 
  237.                  (getenv "TERM") 
  238.                ":  use "(single-key-description C-s-replacement)
  239.                " for C-s  and  use  "
  240.                (single-key-description C-q-replacement)
  241.                " for C-q."))
  242.       (sleep-for 1) ; Give user a chance to see message.
  243.       )
  244.     ;; Tell emacs to not pass C-s and C-q to OS and reset keys.
  245.     (progn
  246.       (set-input-mode nil nil)
  247.       ;; !!!!!!!!!!!!emacs 19 users will have to change this!!!!!!!!!!!!!!!!
  248.       ;; Restore C-s and C-s-replacement
  249.       (init-keyboard-translate-table)
  250.       (aset keyboard-translate-table ?\^s ?\^s)
  251.       (aset keyboard-translate-table C-s-replacement C-s-replacement)
  252.       ;; Restore C-q and C-q-replacement
  253.       (aset keyboard-translate-table ?\^q ?\^q)
  254.       (aset keyboard-translate-table C-q-replacement C-q-replacement)
  255.       (message "C-s and C-q restored.")
  256.       )
  257.     )
  258.   )
  259.  
  260. (defun auto-flow-control-fix ()
  261.   "Enables flow control avoidance using flow-control-fix if the user is
  262. not using X windows and the current terminal (TERM) is in the
  263. terminal-uses-flow-control-chars list.  Drops everything in TERM past
  264. the first hyphen."
  265.  
  266.   (if (or 
  267.        ;; invoked from a shell directly under an xterm:
  268.        (and (getenv "DISPLAY")
  269.         (getenv "WINDOWID")
  270.         (equal (getenv "TERM") "xterm"))
  271.        ;; this is a direct X client:
  272.        (eq 'x window-system))
  273.       ;; Never enable flow control avoidance if you are running X, no
  274.       ;; matter what the TERM variable is set to. (Thanks Joe).
  275.       nil
  276.     (if (TERM-in-list terminal-uses-flow-control-chars)
  277.     (flow-control-fix t)))
  278. )
  279.