flow-ctrl.el 4.92 KB
Newer Older
Eric S. Raymond's avatar
Eric S. Raymond committed
1 2
;;; flow-ctrl.el --- help for lusers on cu(1) or ttys with wired-in ^S/^Q flow control

Paul Eggert's avatar
Paul Eggert committed
3
;; Copyright (C) 1990-1991, 1994, 2001-2020 Free Software Foundation,
4
;; Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

Glenn Morris's avatar
Glenn Morris committed
6
;; Author: Kevin Gallagher
7
;; Maintainer: emacs-devel@gnu.org
Eric S. Raymond's avatar
Eric S. Raymond committed
8
;; Adapted-By: ESR
Eric S. Raymond's avatar
Eric S. Raymond committed
9
;; Keywords: hardware
Eric S. Raymond's avatar
Eric S. Raymond committed
10

11 12
;; This file is part of GNU Emacs.

13
;; GNU Emacs is free software: you can redistribute it and/or modify
14
;; it under the terms of the GNU General Public License as published by
15 16
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
17 18 19 20 21 22 23

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
24
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
Eric S. Raymond's avatar
Eric S. Raymond committed
25 26

;;; Commentary:
Jim Blandy's avatar
Jim Blandy committed
27

Erik Naggum's avatar
Erik Naggum committed
28 29 30
;; Terminals that use XON/XOFF flow control can cause problems with
;; GNU Emacs users.  This file contains Emacs Lisp code that makes it
;; easy for a user to deal with this problem, when using such a
31 32
;; terminal.
;;
Erik Naggum's avatar
Erik Naggum committed
33 34
;; To invoke these adjustments, a user need only invoke the function
;; enable-flow-control-on with a list of terminal types in his/her own
35
;; init file.  As arguments, give it the names of one or more terminal
Erik Naggum's avatar
Erik Naggum committed
36
;; types in use by that user which require flow control adjustments.
37 38
;; Here's an example:
;;
Erik Naggum's avatar
Erik Naggum committed
39 40 41 42
;;	(enable-flow-control-on "vt200" "vt300" "vt101" "vt131")

;; Portability note: This uses (getenv "TERM"), and therefore probably
;; won't work outside of UNIX-like environments.
Jim Blandy's avatar
Jim Blandy committed
43

Eric S. Raymond's avatar
Eric S. Raymond committed
44 45
;;; Code:

46 47 48 49
(defvar flow-control-c-s-replacement ?\034
  "Character that replaces C-s, when flow control handling is enabled.")
(defvar flow-control-c-q-replacement ?\036
  "Character that replaces C-q, when flow control handling is enabled.")
Jim Blandy's avatar
Jim Blandy committed
50

51 52
(put 'keyboard-translate-table 'char-table-extra-slots 0)

53 54 55 56 57 58 59 60 61 62 63 64 65 66
;;;###autoload
(defun enable-flow-control (&optional argument)
  "Toggle flow control handling.
When handling is enabled, user can type C-s as C-\\, and C-q as C-^.
With arg, enable flow control mode if arg is positive, otherwise disable."
  (interactive "P")
  (if (if argument
	  ;; Argument means enable if arg is positive.
	  (<= (prefix-numeric-value argument) 0)
	;; No arg means toggle.
	(nth 1 (current-input-mode)))
      (progn
	;; Turn flow control off, and stop exchanging chars.
	(set-input-mode t nil (nth 2 (current-input-mode)))
67 68
	(if keyboard-translate-table
	    (progn
69 70 71 72
	      (aset keyboard-translate-table flow-control-c-s-replacement nil)
	      (aset keyboard-translate-table ?\^s nil)
	      (aset keyboard-translate-table flow-control-c-q-replacement nil)
	      (aset keyboard-translate-table ?\^q nil))))
73 74 75 76
    ;; Turn flow control on.
    ;; Tell emacs to pass C-s and C-q to OS.
    (set-input-mode nil t (nth 2 (current-input-mode)))
    ;; Initialize translate table, saving previous mappings, if any.
77 78 79 80 81 82 83 84 85 86 87 88 89 90
    (cond ((null keyboard-translate-table)
	   (setq keyboard-translate-table
		 (make-char-table 'keyboard-translate-table nil)))
	  ((char-table-p keyboard-translate-table)
	   (setq keyboard-translate-table
		 (copy-sequence keyboard-translate-table)))
	  (t
	   (let ((the-table (make-char-table 'keyboard-translate-table nil)))
	     (let ((i 0)
		   (j (length keyboard-translate-table)))
	       (while (< i j)
		 (aset the-table i (elt keyboard-translate-table i))
		 (setq i (1+ i))))
	     (setq keyboard-translate-table the-table))))
91 92 93 94 95 96
    ;; Swap C-s and C-\
    (aset keyboard-translate-table flow-control-c-s-replacement ?\^s)
    (aset keyboard-translate-table ?\^s flow-control-c-s-replacement)
    ;; Swap C-q and C-^
    (aset keyboard-translate-table flow-control-c-q-replacement ?\^q)
    (aset keyboard-translate-table ?\^q flow-control-c-q-replacement)
97
    (message "XON/XOFF adjustment for %s: use %s for C-s, and use %s for C-q"
98
	     (getenv "TERM")
99 100
	     (single-key-description flow-control-c-s-replacement)
	     (single-key-description flow-control-c-q-replacement))
101
    (sleep-for 2)))			; Give user a chance to see message.
Jim Blandy's avatar
Jim Blandy committed
102 103

;;;###autoload
104
(defun enable-flow-control-on (&rest losing-terminal-types)
105
  "Enable flow control if using one of a specified set of terminal types.
106
Use `(enable-flow-control-on \"vt100\" \"h19\")' to enable flow control
107
on VT-100 and H19 terminals.  When flow control is enabled,
108
you must type C-\\ to get the effect of a C-s, and type C-^
109
to get the effect of a C-q."
Jim Blandy's avatar
Jim Blandy committed
110 111
  (let ((term (getenv "TERM"))
	hyphend)
112 113 114 115 116 117 118 119
    ;; Look for TERM in LOSING-TERMINAL-TYPES.
    ;; If we don't find it literally, try stripping off words
    ;; from the end, one by one.
    (while (and term (not (member term losing-terminal-types)))
      ;; Strip off last hyphen and what follows, then try again.
      (if (setq hyphend (string-match "[-_][^-_]+$" term))
	  (setq term (substring term 0 hyphend))
	(setq term nil)))
120
    (if term
121
	(enable-flow-control))))
Jim Blandy's avatar
Jim Blandy committed
122

Jim Blandy's avatar
Jim Blandy committed
123 124
(provide 'flow-ctrl)

Eric S. Raymond's avatar
Eric S. Raymond committed
125
;;; flow-ctrl.el ends here