on master help sign in
Graphics.Vty.Input: haddock pass
commitde3a20391ff7ba7e5d8b87cc388407bc317237c2 authorJonathan Daugherty <cygnus@foobox.com> dateSun 22 Jan 2017, 15:03 (10 years ago) parent7342cff
1 file changed+64−97
src/Graphics/Vty/Input.hs+64−97
src/Graphics/Vty/Input.hs+64−97
@@ -1,103 +1,97 @@
11{-# LANGUAGE RecordWildCards #-}
22
3−-- | The input layer for VTY. This provides methods for initializing an
4−-- 'Input' structure which can then be used to read 'Event's from the
3+-- | This module provides the input layer for Vty, including methods
4+-- for initializing an 'Input' structure and reading 'Event's from the
55-- terminal.
66--
7−-- The history of terminals has resulted in a broken input process. Some
8−-- keys and combinations will not reliably map to the expected events
9−-- by any terminal program. Even those not using vty. There is no 1:1
10−-- mapping from key events to bytes read from the terminal input device.
11−-- In very limited cases the terminal and vty's input process can be
12−-- customized to resolve these issues.
13−--
14−-- See "Graphics.Vty.Config" for how to configure vty's input
15−-- processing. Customizing terminfo and the terminal is beyond the scope
16−-- of this documentation.
7+-- Note that due to the evolution of terminal emulators, some keys
8+-- and combinations will not reliably map to the expected events by
9+-- any terminal program. There is no 1:1 mapping from key events to
10+-- bytes read from the terminal input device. In very limited cases the
11+-- terminal and vty's input process can be customized to resolve these
12+-- issues; see "Graphics.Vty.Config" for how to configure vty's input
13+-- processing.
1714--
1815-- = VTY's Implementation
1916--
2017-- There are two input modes:
2118--
22−-- 1. 7 bit
19+-- 1. 7-bit
2320--
24−-- 2. 8 bit
21+-- 2. 8-bit
2522--
26−-- 7 bit input is the default and the expected in most use cases. This
27−-- is what vty uses.
23+-- The 7-bit input mode is the default and the expected mode in most use
24+-- cases. This is what Vty uses.
2825--
29−-- == 7 bit input encoding
26+-- == 7-bit input encoding
3027--
3128-- Control key combinations are represented by masking the two high bits
32−-- of the 7bit input. Back in the day the control key actually grounded
33−-- the two high bit wires: 6 and 7. This is why control key combos map
34−-- to single character events: The input bytes are identical. The input
35−-- byte is the bit encoding of the character with bits 6 and 7 masked.
36−-- Bit 6 is set by shift. Bit 6 and 7 are masked by control. EG:
29+-- of the 7-bit input. Historically the control key actually grounded
30+-- the two high bit wires: 6 and 7. This is why control key combos
31+-- map to single character events: the input bytes are identical. The
32+-- input byte is the bit encoding of the character with bits 6 and 7
33+-- masked. Bit 6 is set by shift. Bit 6 and 7 are masked by control. For
34+-- example,
3735--
38−-- * Control-I is 'i', `01101001`, has bit 6 and 7 masked to become
39−-- `00001001`. Which is the ASCII and UTF-8 encoding of the tab key.
36+-- * Control-I is 'i', `01101001`, and has bit 6 and 7 masked to become
37+-- `00001001`, which is the ASCII and UTF-8 encoding of the Tab key.
4038--
4139-- * Control+Shift-C is 'C', `01000011`, with bit 6 and 7 set to zero
42−-- which makes `0000011` and is the "End of Text" code.
40+-- which is `0000011` and is the "End of Text" code.
4341--
44−-- * Hypothesis: This is why capital-A, 'A', has value 65 in ASCII: This
42+-- * Hypothesis: This is why capital-A, 'A', has value 65 in ASCII: this
4543-- is the value 1 with bit 7 set and 6 unset.
4644--
4745-- * Hypothesis: Bit 6 is unset by upper case letters because,
4846-- initially, there were only upper case letters used and a 5 bit
4947-- encoding.
5048--
51−-- == 8 bit encoding
49+-- == 8-bit encoding
5250--
53−-- The 8th bit was originally used for parity checking. Useless for
54−-- emulators. Some terminal emulators support a 8 bit input encoding.
55−-- While this provides some advantages the actual usage is low. Most
56−-- systems use 7bit mode but recognize 8bit control characters when
57−-- escaped. This is what vty does.
51+-- The 8th bit was originally used for parity checking which is useless
52+-- for terminal emulators. Some terminal emulators support an 8-bit
53+-- input encoding. While this provides some advantages, the actual usage
54+-- is low. Most systems use 7-bit mode but recognize 8-bit control
55+-- characters when escaped. This is what Vty does.
5856--
5957-- == Escaped Control Keys
6058--
61−-- Using 7 bit input encoding the @ESC@ byte can signal the start of
62−-- an encoded control key. To differentiate a single @ESC@ eventfrom a
63−-- control key the timing of the input is used.
59+-- Using 7-bit input encoding, the @ESC@ byte can signal the start of
60+-- an encoded control key. To differentiate a single @ESC@ event from a
61+-- control key, the timing of the input is used.
6462--
65−-- 1. @ESC@ individually: @ESC@ byte; no bytes for 'singleEscPeriod'.
63+-- 1. @ESC@ individually: @ESC@ byte; no bytes following for a period of
64+-- 'VMIN' milliseconds.
6665--
67−-- 2. control keys that contain @ESC@ in their encoding: The @ESC byte;
68−-- followed by more bytes read within 'singleEscPeriod'. All bytes up
69−-- until the next valid input block are passed to the classifier.
66+-- 2. Control keys that contain @ESC@ in their encoding: The @ESC byte
67+-- is followed by more bytes read within 'VMIN' milliseconds. All bytes
68+-- up until the next valid input block are passed to the classifier.
7069--
7170-- If the current runtime is the threaded runtime then the terminal's
7271-- @VMIN@ and @VTIME@ behavior reliably implement the above rules. If
73−-- the current runtime does not support forkOS then there is currently
72+-- the current runtime does not support 'forkOS' then there is currently
7473-- no implementation.
7574--
76−-- Vty used to emulate @VMIN@ and @VTIME@. This was a input loop
77−-- which did tricky things with non-blocking reads and timers. The
78−-- implementation was not reliable. A reliable implementation is
79−-- possible, but there are no plans to implement this.
80−--
8175-- == Unicode Input and Escaped Control Key Sequences
8276--
8377-- The input encoding determines how UTF-8 encoded characters are
84−-- recognize.
78+-- recognized.
8579--
86−-- * 7 bit mode: UTF-8 can be input unambiguiously. UTF-8 input is
80+-- * 7-bit mode: UTF-8 can be input unambiguiously. UTF-8 input is
8781-- a superset of ASCII. UTF-8 does not overlap escaped control key
8882-- sequences. However, the escape key must be differentiated from
8983-- escaped control key sequences by the timing of the input bytes.
9084--
91−-- * 8 bit mode: UTF-8 cannot be input unambiguously. This does not
85+-- * 8-bit mode: UTF-8 cannot be input unambiguously. This does not
9286-- require using the timing of input bytes to differentiate the escape
93−-- key. Many terminals do not support 8 bit mode.
87+-- key. Many terminals do not support 8-bit mode.
9488--
9589-- == Terminfo
9690--
9791-- The terminfo system is used to determine how some keys are encoded.
98−-- Terminfo is incomplete. In some cases terminfo is incorrect. Vty
92+-- Terminfo is incomplete and in some cases terminfo is incorrect. Vty
9993-- assumes terminfo is correct but provides a mechanism to override
100−-- terminfo. See "Graphics.Vty.Config" specifically 'inputOverrides'.
94+-- terminfo; see "Graphics.Vty.Config", specifically 'inputOverrides'.
10195--
10296-- == Terminal Input is Broken
10397--
@@ -105,38 +99,18 @@
10599-- to reliably resolve these issues.
106100--
107101-- One resolution would be to ditch standard terminal interfaces
108−-- entirely and just go directly to scancodes. A reasonable option for
109−-- vty if everybody used the linux kernel console. I hear GUIs are
110−-- popular these days. Sadly, GUI terminal emulators don't provide
111−-- access to scancodes AFAIK.
112−--
113−-- All is lost? Not really. "Graphics.Vty.Config" supports customizing
114−-- the input byte to event mapping and xterm supports customizing the
115−-- scancode to input byte mapping. With a lot of work a user's system
116−-- can be set up to encode all the key combos in an almost-sane manner.
117−--
118−-- There are other tricky work arounds that can be done. I have no
119−-- interest in implementing most of these. They are not really worth the
120−-- time.
121−--
122−-- == Terminal Output is Also Broken
102+-- entirely and just go directly to scancodes. This would be a
103+-- reasonable option for Vty if everybody used the linux kernel console
104+-- but for obvious reasons this is not possible.
123105--
124−-- This isn't the only odd aspect of terminals due to historical
125−-- aspects that no longer apply. EG: Some terminfo capabilities specify
126−-- millisecond delays. (Capabilities are how terminfo describes the
127−-- control sequence to output red, for instance) This is to account for
128−-- the slow speed of hardcopy teletype interfaces. Cause, uh, we totally
129−-- still use those.
130−--
131−-- The output encoding of colors and attributes are also rife with
132−-- issues.
106+-- The "Graphics.Vty.Config" module supports customizing the
107+-- input-byte-to-event mapping and xterm supports customizing the
108+-- scancode-to-input-byte mapping. With a lot of work a user's system
109+-- can be set up to encode all the key combos in an almost-sane manner.
133110--
134111-- == See also
135112--
136113-- * http://www.leonerd.org.uk/hacks/fixterms/
137−--
138−-- In my experience this cannot resolve the issues without changes to
139−-- the terminal emulator and device.
140114module Graphics.Vty.Input
141115 ( Key(..)
142116 , Modifier(..)
@@ -161,35 +135,28 @@ import System.Posix.Signals.Exts
161135import Data.Monoid ((<>))
162136
163137-- | Set up the terminal with file descriptor `inputFd` for input.
164−-- Returns a 'Input'.
138+-- Returns an 'Input'.
165139--
166140-- The table used to determine the 'Events' to produce for the input
167−-- bytes comes from 'classifyMapForTerm'. Which is then overridden by
168−-- the the applicable entries from 'inputMap'.
141+-- bytes comes from 'classifyMapForTerm' which is then overridden by
142+-- the the applicable entries from the configuration's 'inputMap'.
169143--
170144-- The terminal device is configured with the attributes:
171145--
172−-- * IXON disabled
173−-- - disables software flow control on outgoing data. This stops
174−-- the process from being suspended if the output terminal cannot
175−-- keep up. I presume this has little effect these days. I hope
176−-- this means that output will be buffered if the terminal cannot
177−-- keep up. In the old days the output might of been dropped?
178−--
179−-- "raw" mode is used for input.
146+-- * IXON disabled: disables software flow control on outgoing data.
147+-- This stops the process from being suspended if the output terminal
148+-- cannot keep up.
180149--
181−-- * ISIG disabled
182−-- - enables keyboard combinations that result in signals.
150+-- * Raw mode is used for input.
183151--
184−-- * ECHO disabled
185−-- - input is not echoed to the output.
152+-- * ISIG disabled (enables keyboard combinations that result in
153+-- signals)
186154--
187−-- * ICANON disabled
188−-- - canonical mode (line mode) input is not used.
155+-- * ECHO disabled (input is not echoed to the output)
189156--
190−-- * IEXTEN disabled
191−-- - extended functions are disabled.
157+-- * ICANON disabled (canonical mode (line mode) input is not used)
192158--
159+-- * IEXTEN disabled (extended functions are disabled)
193160inputForConfig :: Config -> IO Input
194161inputForConfig config@Config{ termName = Just termName
195162 , inputFd = Just termFd