on master help sign in
split input table generation based on terminal type
0bbc339Corey O'Connor
CHANGELOG+7−5
@@ -1,6 +1,13 @@
15.0.0
15.0.0
2 * removed the typeclass based terminal and display context interface in favor of a data
2 * removed the typeclass based terminal and display context interface in favor of a data
3 structure of properties interface.
3 structure of properties interface.
4+ * input handling changes
5+ * KASCII is not KChar
6+ * KPN5 is now KCenter
7+ * tests exist.
8+ * the default amount of time between ESC and a subsequent character that causes VTY to
9+ interpret the input as "ESC" then the character, versus some special key, has been
10+ increased to 4000 microseconds; 4 milliseconds.
4 * renamed the Terminal interface to Output
11 * renamed the Terminal interface to Output
5 * The default picture for an image now uses the "clear" background. This background fills
12 * The default picture for an image now uses the "clear" background. This background fills
6 background spans with spaces or just ends the line.
13 background spans with spaces or just ends the line.
@@ -24,11 +31,6 @@
24 * alternate (setf/setb) color maps supported. Though colors beyond the first 8 are just a
31 * alternate (setf/setb) color maps supported. Though colors beyond the first 8 are just a
25 guess.
32 guess.
26 * added "rgb_color" for easy support of RGB specified colors.
33 * added "rgb_color" for easy support of RGB specified colors.
27− * input handling changes
28− * tests exist.
29− * the default amount of time between ESC and a subsequent character that causes VTY to
30− interpret the input as "ESC" then the character, versus some special key, has been
31− increased to 4000 microseconds; 4 milliseconds.
32 * examples moved to vty-examples package. See test directory for cabal file.
34 * examples moved to vty-examples package. See test directory for cabal file.
33 * vty-interactive-terminal-test
35 * vty-interactive-terminal-test
34 * interactive test. Useful for building a bug report for vty's author.
36 * interactive test. Useful for building a bug report for vty's author.
README.md+6−5
@@ -31,15 +31,16 @@ git clone git://github.com/coreyoconnor/vty.git
31* Supports all ANSI SGR-modes (defined in console_codes(4)) with
31* Supports all ANSI SGR-modes (defined in console_codes(4)) with
32 a type-safe interface.
32 a type-safe interface.
33
33
34−* Properly handles cleanup.
34+* Properly handles cleanup, but not due to signals.
35
35
36# Known Issues
36# Known Issues
37
37
38−* The character encoding of the output terminal is assumed to be UTF-8.
38+* Signal handling of STOP, TERM and INT are non existent.
39
39
40−* Minimal support for special keys on terminals other than the
40+* The character encoding of the terminal is assumed to be UTF-8.
41− linux-console. (F1-5 and arrow keys should work, but anything
41+
42− shifted isn't likely to.)
42+* Terminfo is assumed to be correct unless the terminal (as declared by TERM) starts with xterm or
43+ ansi. This means that some terminals will not have correct special key support (shifted F10 etc)
43
44
44* Uses the TIOCGWINSZ ioctl to find the current window size, which
45* Uses the TIOCGWINSZ ioctl to find the current window size, which
45 appears to be limited to Linux and *BSD.
46 appears to be limited to Linux and *BSD.
cbits/set_term_timing.c+3−3
@@ -3,11 +3,11 @@
3#include <unistd.h>
3#include <unistd.h>
4#include <stdlib.h>
4#include <stdlib.h>
5
5
6−void vty_set_term_timing(void)
6+void vty_set_term_timing(int fd)
7{
7{
8 struct termios trm;
8 struct termios trm;
9− tcgetattr(STDIN_FILENO, &trm);
9+ tcgetattr(fd, &trm);
10 trm.c_cc[VMIN] = 0;
10 trm.c_cc[VMIN] = 0;
11 trm.c_cc[VTIME] = 0;
11 trm.c_cc[VTIME] = 0;
12− tcsetattr(STDIN_FILENO, TCSANOW, &trm);
12+ tcsetattr(fd, TCSANOW, &trm);
13}
13}
src/Graphics/Vty.hs+7−6
@@ -66,18 +66,19 @@ import qualified System.Console.Terminfo as Terminfo
66--
66--
67-- \todo Remove explicit `shutdown` requirement.
67-- \todo Remove explicit `shutdown` requirement.
68data Vty = Vty
68data Vty = Vty
69− { -- | Outputs the given Picture. Equivalent to output_picture applied to a display context
69+ { -- | Outputs the given Picture. Equivalent to 'output_picture' applied to a display context
70− -- implicitly managed by Vty.
70+ -- implicitly managed by Vty. The managed display context is reset on resize.
71 update :: Picture -> IO ()
71 update :: Picture -> IO ()
72− -- | Get one Event object, blocking if necessary.
72+ -- | Get one Event object, blocking if necessary. This will refresh the terminal if the event
73+ -- is a 'EvResize'.
73 , next_event :: IO Event
74 , next_event :: IO Event
74 -- | The input interface. See 'Input'
75 -- | The input interface. See 'Input'
75 , input_iface :: Input
76 , input_iface :: Input
76 -- | The output interface. See 'Output'
77 -- | The output interface. See 'Output'
77 , output_iface :: Output
78 , output_iface :: Output
78 -- | Refresh the display. Normally the library takes care of refreshing. Nonetheless, some
79 -- | Refresh the display. Normally the library takes care of refreshing. Nonetheless, some
79− -- other program might output to the terminal and mess the display. In that case the user
80+ -- other program might output to the terminal and mess up the display. In that case the
80− -- might want to force a refresh.
81+ -- application might want to force a refresh.
81 , refresh :: IO ()
82 , refresh :: IO ()
82 -- | Clean up after vty.
83 -- | Clean up after vty.
83 -- The above methods will throw an exception if executed after this is executed.
84 -- The above methods will throw an exception if executed after this is executed.
@@ -97,11 +98,11 @@ mkVtyEscDelay :: Int -> IO Vty
97mkVtyEscDelay escDelay = do
98mkVtyEscDelay escDelay = do
98 input <- input_for_current_terminal escDelay
99 input <- input_for_current_terminal escDelay
99 out <- output_for_current_terminal
100 out <- output_for_current_terminal
100− reserve_display out
101 intMkVty input out
101 intMkVty input out
102
102
103intMkVty :: Input -> Output -> IO Vty
103intMkVty :: Input -> Output -> IO Vty
104intMkVty input out = do
104intMkVty input out = do
105+ reserve_display out
105 let shutdown_io = do
106 let shutdown_io = do
106 shutdown_input input
107 shutdown_input input
107 release_display out
108 release_display out
src/Graphics/Vty/Input.hs+3−5
@@ -11,7 +11,7 @@ module Graphics.Vty.Input ( Key(..)
11 )
11 )
12 where
12 where
13
13
14−import Graphics.Vty.Input.Data
14+import Graphics.Vty.Input.Events
15import Graphics.Vty.Input.Internal
15import Graphics.Vty.Input.Internal
16import Graphics.Vty.Input.Terminfo
16import Graphics.Vty.Input.Terminfo
17
17
@@ -55,8 +55,7 @@ input_for_current_terminal escDelay = do
55 term_name <- getEnv "TERM"
55 term_name <- getEnv "TERM"
56 input_for_name_and_io escDelay term_name stdInput
56 input_for_name_and_io escDelay term_name stdInput
57
57
58−-- | Set up the terminal for input. Returns a function which reads key
58+-- | Set up the terminal attached to the given Fd for input. Returns a 'Input'.
59−-- events, and a function for shutting down the terminal access.
60--
59--
61-- The terminal is modified as follows:
60-- The terminal is modified as follows:
62--
61--
@@ -89,8 +88,7 @@ input_for_name_and_io escDelay term_name term_in = do
89 , EnableEcho, ProcessInput, ExtendedFunctions
88 , EnableEcho, ProcessInput, ExtendedFunctions
90 ]
89 ]
91 setTerminalAttributes term_in attr' Immediately
90 setTerminalAttributes term_in attr' Immediately
92− -- TODO: pass Fd to set_term_timing
91+ set_term_timing term_in
93− set_term_timing
94 let classify_table = classify_table_for_term terminal
92 let classify_table = classify_table_for_term terminal
95 (eventChannel, shutdown_event_processing) <- initInputForFd escDelay classify_table term_in
93 (eventChannel, shutdown_event_processing) <- initInputForFd escDelay classify_table term_in
96 let pokeIO = Catch $ do
94 let pokeIO = Catch $ do
src/Graphics/Vty/Input/Data.hsdeleted−33
@@ -1,33 +0,0 @@
1−-- Copyright Corey O'Connor
2−module Graphics.Vty.Input.Data ( module Graphics.Vty.Input.Data
3− , module Graphics.Vty.Input.Data.ANSI
4− , module Graphics.Vty.Input.Events
5− )
6−where
7−
8−import Graphics.Vty.Input.Data.ANSI
9−import Graphics.Vty.Input.Events
10−
11−map_to_legacy_table :: ClassifyTable -> ClassifyTableV1
12−map_to_legacy_table = map f
13− where f (s, EvKey k mods) = (s, (k, mods))
14− f _ = error "no mapping for mouse or resize events"
15−
16−-- | classify table directly generated from terminfo cap strings
17−keys_from_caps_table :: ClassifyTable
18−keys_from_caps_table =
19− [ ("khome", EvKey KHome [])
20− , ("kend", EvKey KEnd [])
21− , ("cbt", EvKey KBackTab [])
22− , ("kcud1", EvKey KDown [])
23− , ("kcuu1", EvKey KUp [])
24− , ("kcuf1", EvKey KRight [])
25− , ("kcub1", EvKey KLeft [])
26− , ("kLFT", EvKey KLeft [MShift])
27− , ("kRIT", EvKey KRight [MShift])
28− ] ++ function_key_caps_table
29−
30−-- | cap names for function keys
31−function_key_caps_table :: ClassifyTable
32−function_key_caps_table = flip map [0..63] $ \n -> ("kf" ++ show n, EvKey (KFun n) [])
33−
src/Graphics/Vty/Input/Events.hs+27−8
@@ -2,10 +2,17 @@ module Graphics.Vty.Input.Events where
2
2
3-- | Representations of non-modifier keys.
3-- | Representations of non-modifier keys.
4--
4--
5−-- KFun is indexed from 0 to 63. Range of supported FKeys varies by terminal and keyboard.
5+-- * KFun is indexed from 0 to 63. Range of supported FKeys varies by terminal and keyboard.
6+--
7+-- * KUpLeft, KUpRight, KDownLeft, KDownRight, KCenter support varies by terminal and keyboard.
8+--
9+-- * Actually, support for most of these but KEsc, KChar, KBS, and KEnter vary by terminal and
10+-- keyboard.
11+data Key = KEsc | KChar Char | KBS | KEnter
12+ | KLeft | KRight | KUp | KDown
13+ | KUpLeft | KUpRight | KDownLeft | KDownRight | KCenter
6−data Key = KEsc | KFun Int | KBackTab | KPrtScr | KPause | KASCII Char | KBS | KIns
14+ | KFun Int | KBackTab | KPrtScr | KPause | KIns
7− | KHome | KPageUp | KDel | KEnd | KPageDown | KBegin | KNP5 | KUp | KMenu
15+ | KHome | KPageUp | KDel | KEnd | KPageDown | KBegin | KMenu
8− | KLeft | KDown | KRight | KEnter
9 deriving (Eq,Show,Ord)
16 deriving (Eq,Show,Ord)
10
17
11-- | Modifier keys. Key codes are interpreted such that users are more likely to
18-- | Modifier keys. Key codes are interpreted such that users are more likely to
@@ -14,20 +21,32 @@ data Key = KEsc | KFun Int | KBackTab | KPrtScr | KPause | KASCII Char | KBS | K
14data Modifier = MShift | MCtrl | MMeta | MAlt
21data Modifier = MShift | MCtrl | MMeta | MAlt
15 deriving (Eq,Show,Ord)
22 deriving (Eq,Show,Ord)
16
23
17−-- | Mouse buttons. Not yet used.
24+-- | Mouse buttons.
25+--
26+-- \todo not supported.
18data Button = BLeft | BMiddle | BRight
27data Button = BLeft | BMiddle | BRight
19 deriving (Eq,Show,Ord)
28 deriving (Eq,Show,Ord)
20
29
21-- | Events.
30-- | Events.
31+data Event
32+ = EvKey Key [Modifier]
33+ -- | \todo mouse events are not supported
22−data Event = EvKey Key [Modifier] | EvMouse Int Int Button [Modifier]
34+ | EvMouse Int Int Button [Modifier]
35+ -- | if read from 'event_channel' this is the size at the time of the signal. If read from
36+ -- 'next_event' this is the size at the time the event was processed by Vty. Typically these are
37+ -- the same, but if somebody is resizing the terminal quickly they can be different.
23− | EvResize Int Int
38+ | EvResize Int Int
24 deriving (Eq,Show,Ord)
39 deriving (Eq,Show,Ord)
25
40
26-- | representation of mapping from input bytes to key and modifier.
41-- | representation of mapping from input bytes to key and modifier.
27--
42--
28−-- deprecated
43+-- Deprecated. Only used internally
29type ClassifyTableV1 = [(String, (Key, [Modifier]))]
44type ClassifyTableV1 = [(String, (Key, [Modifier]))]
30
45
31-- | representation of mapping from input bytes to event
46-- | representation of mapping from input bytes to event
32type ClassifyTable = [(String, Event)]
47type ClassifyTable = [(String, Event)]
33
48
49+map_to_legacy_table :: ClassifyTable -> ClassifyTableV1
50+map_to_legacy_table = map f
51+ where f (s, EvKey k mods) = (s, (k, mods))
52+ f _ = error "no mapping for mouse or resize events"
src/Graphics/Vty/Input/Internal.hs+13−4
@@ -1,6 +1,6 @@
1module Graphics.Vty.Input.Internal where
1module Graphics.Vty.Input.Internal where
2
2
3−import Graphics.Vty.Input.Data
3+import Graphics.Vty.Input.Events
4
4
5import Codec.Binary.UTF8.Generic (decode)
5import Codec.Binary.UTF8.Generic (decode)
6import Control.Concurrent
6import Control.Concurrent
@@ -23,7 +23,11 @@ import System.Posix.IO ( fdReadBuf
23import System.Posix.Types (Fd(..))
23import System.Posix.Types (Fd(..))
24
24
25data Input = Input
25data Input = Input
26+ { -- | Channel of events direct from input processing. Unlike 'next_event' this will not refresh
27+ -- the display if the next event is an 'EvResize'.
26− { event_channel :: Chan Event
28+ event_channel :: Chan Event
29+ -- | Shuts down the input processing. This should return the terminal input state to before
30+ -- the input initialized.
27 , shutdown_input :: IO ()
31 , shutdown_input :: IO ()
28 }
32 }
29
33
@@ -35,6 +39,11 @@ data KClass
35 | MisPfx Key [Modifier] [Char]
39 | MisPfx Key [Modifier] [Char]
36 deriving(Show)
40 deriving(Show)
37
41
42+-- The input uses two magic character:
43+--
44+-- * '\xFFFD' for "stop processing"
45+-- * '\xFFFE' for "previous input chunk is complete" Which is used to differentiate a single ESC
46+-- from using ESC as meta or to indicate a control sequence.
38inputToEventThread :: (String -> KClass) -> Chan Char -> Chan Event -> IO ()
47inputToEventThread :: (String -> KClass) -> Chan Char -> Chan Event -> IO ()
39inputToEventThread classifier inputChannel eventChannel = loop []
48inputToEventThread classifier inputChannel eventChannel = loop []
40 where loop kb = case classifier kb of
49 where loop kb = case classifier kb of
@@ -129,7 +138,7 @@ initInputForFd escDelay classify_table input_fd = do
129 readAll
138 readAll
130 loop
139 loop
131 return ()
140 return ()
132− -- | If there is no input for some time, this thread puts '\xFFFE' in the
141+ -- If there is no input for some time, this thread puts '\xFFFE' in the
133 -- inputChannel.
142 -- inputChannel.
134 noInputThread :: IO ()
143 noInputThread :: IO ()
135 noInputThread = when (escDelay > 0) loop
144 noInputThread = when (escDelay > 0) loop
@@ -153,4 +162,4 @@ initInputForFd escDelay classify_table input_fd = do
153 killThread inputThreadId
162 killThread inputThreadId
154 return (eventChannel, shutdown_event_processing)
163 return (eventChannel, shutdown_event_processing)
155
164
156−foreign import ccall "vty_set_term_timing" set_term_timing :: IO ()
165+foreign import ccall "vty_set_term_timing" set_term_timing :: Fd -> IO ()
src/Graphics/Vty/Input/Terminfo.hs+169−6
@@ -1,15 +1,178 @@
1module Graphics.Vty.Input.Terminfo where
1module Graphics.Vty.Input.Terminfo where
2
2
3−import Graphics.Vty.Input.Data
3+import Graphics.Vty.Input.Events
4+import qualified Graphics.Vty.Input.Terminfo.VT100 as VT100
4−import Graphics.Vty.Input.Internal
5+import qualified Graphics.Vty.Input.Terminfo.XTerm7Bit as XTerm7Bit
5
6
6import System.Console.Terminfo
7import System.Console.Terminfo
7
8
9+-- | queries the terminal for all capability based input sequences then adds on a terminal dependent
10+-- input sequence mapping.
11+--
12+-- For reference see:
13+--
14+-- * http://vimdoc.sourceforge.net/htmldoc/term.html
15+--
16+-- * vim74/src/term.c
17+--
18+-- * http://invisible-island.net/vttest/
19+--
20+-- * http://aperiodic.net/phil/archives/Geekery/term-function-keys.html
21+--
22+-- This is painful. Terminfo is incomplete. The vim source implies that terminfo is also incorrect.
23+-- Vty assumes that the an internal terminfo table added to the system provided terminfo table is
24+-- correct.
25+--
26+-- 1. build terminfo table for all caps. Missing caps are not added.
27+--
28+-- 2. add tables for visible chars, esc, del plus ctrl and meta.
29+--
30+-- 3. add internally defined table for given terminal type.
31+--
32+-- The override is currently done in 'compile'. Which is a bit odd.
33+--
34+-- \todo terminfo meta is not supported.
35+-- \todo no 8bit
36+classify_table_for_term :: String -> Terminal -> ClassifyTableV1
37+classify_table_for_term term_name term =
38+ concatMap map_to_legacy_table
39+ $ caps_classify_table term keys_from_caps_table
40+ : visible_chars
41+ : ctrl_chars
42+ : ctrl_meta_chars
43+ : special_support_keys
44+ : internal_tables term_name
45+
8caps_classify_table :: Terminal -> [(String,Event)] -> [(String,Event)]
46caps_classify_table :: Terminal -> [(String,Event)] -> [(String,Event)]
9caps_classify_table terminal table = [(x,y) | (Just x,y) <- map extract_cap table]
47caps_classify_table terminal table = [(x,y) | (Just x,y) <- map extract_cap table]
10 where extract_cap = first (getCapability terminal . tiGetStr)
48 where extract_cap = first (getCapability terminal . tiGetStr)
11
49
12−classify_table_for_term :: Terminal -> ClassifyTableV1
50+internal_tables term_name
13−classify_table_for_term term =
51+ | ANSI.supports term_name = ANSI.tables
14− let caps_legacy_table = map_to_legacy_table $ caps_classify_table term keys_from_caps_table
52+ | XTerm7Bit.supports term_name = XTerm7Bit.tables
15− in concat $ caps_legacy_table : ansi_classify_table
53+ | otherwise = []
54+
55+-- | Visible characters in the ISO-8859-1 and UTF-8 common set.
56+--
57+-- we limit to < 0xC1. The UTF8 sequence detector will catch all values 0xC2 and above before this
58+-- classify table is reached.
59+--
60+-- TODO: resolve
61+-- 1. start at ' '. The earlier characters are all ctrl_char_keys
62+visible_chars :: ClassifyTable
63+visible_chars = [ ([x], EvKey (KChar x) [])
64+ | x <- [' ' .. toEnum 0xC1]
65+ ]
66+
67+-- | Non visible cahracters in the ISO-8859-1 and UTF-8 common set translated to ctrl + char.
68+--
69+-- \todo resolve CTRL-i is the same as tab
70+ctrl_chars :: ClassifyTable
71+ctrl_chars =
72+ [ ([toEnum x],EvKey (KChar y) [MCtrl])
73+ | (x,y) <- zip ([0..31]) ('@':['a'..'z']++['['..'_']),
74+ y /= 'i' -- Resolve issue #3 where CTRL-i hides TAB.
75+ ]
76+
77+-- | Ctrl+Meta+Char
78+ctrl_meta_chars :: ClassifyTable
79+ctrl_meta_chars = map (\(s,EvKey c m) -> ('\ESC':s, EvKey c (MMeta:m)))
80+
81+-- | esc, meta esc, delete, meta delete, enter, meta enter
82+special_support_keys :: ClassifyTable
83+special_support_keys =
84+ [ -- special support for ESC
85+ ("\ESC",EvKey KEsc []), ("\ESC\ESC",EvKey KEsc [MMeta])
86+ -- Special support for backspace
87+ , ("\DEL",EvKey KBS []), ("\ESC\DEL",EvKey KBS [MMeta])
88+ -- Special support for Enter
89+ , ("\ESC\^J",EvKey KEnter [MMeta]), ("\^J",EvKey KEnter [])
90+ ]
91+
92+-- | classify table directly generated from terminfo cap strings
93+--
94+-- these are:
95+--
96+-- * ka1 - keypad up-left
97+--
98+-- * ka3 - keypad up-right
99+--
100+-- * kb2 - keypad center
101+--
102+-- * kbs - keypad backspace
103+--
104+-- * kbeg - begin
105+--
106+-- * kcbt - back tab
107+--
108+-- * kc1 - keypad left-down
109+--
110+-- * kc3 - keypad right-down
111+--
112+-- * kdch1 - delete
113+--
114+-- * kcud1 - down
115+--
116+-- * kend - end
117+--
118+-- * kent - enter
119+--
120+-- * kf0 - kf63 - function keys
121+--
122+-- * khome - KHome
123+--
124+-- * kich1 - insert
125+--
126+-- * kcub1 - left
127+--
128+-- * knp - next page (page down)
129+--
130+-- * kpp - previous page (page up)
131+--
132+-- * kcuf1 - right
133+--
134+-- * kDC - shift delete
135+--
136+-- * kEND - shift end
137+--
138+-- * kHOM - shift home
139+--
140+-- * kIC - shift insert
141+--
142+-- * kLFT - shift left
143+--
144+-- * kRIT - shift right
145+--
146+-- * kcuu1 - up
147+keys_from_caps_table :: ClassifyTable
148+keys_from_caps_table =
149+ [ ("ka1", EvKey KUpLeft [])
150+ , ("ka3", EvKey KUpRight [])
151+ , ("kb2", EvKey KCenter [])
152+ , ("kbs", EvKey KBS [])
153+ , ("kbeg", EvKey KBegin [])
154+ , ("kcbt", EvKey KBackTab [])
155+ , ("kc1", EvKey KDownLeft [])
156+ , ("kc3", EvKey KDownRight [])
157+ , ("kdch1", EvKey KDel [])
158+ , ("kcud1", EvKey KDown [])
159+ , ("kend", EvKey KEnd [])
160+ , ("kent", EvKey KEnter [])
161+ , ("khome", EvKey KHome [])
162+ , ("kich1", EvKey KIns [])
163+ , ("kcub1", EvKey KLeft [])
164+ , ("knp", EvKey KPageDown [])
165+ , ("kpp", EvKey KPageUp [])
166+ , ("kcuf1", EvKey KRight [])
167+ , ("kDC", EvKey KDel [MShift])
168+ , ("kEND", EvKey KEnd [MShift])
169+ , ("kHOM", EvKey KHome [MShift])
170+ , ("kIC", EvKey KIns [MShift])
171+ , ("kLFT", EvKey KLeft [MShift])
172+ , ("kRIT", EvKey KRight [MShift])
173+ , ("kcuu1", EvKey KUp [])
174+ ] ++ function_key_caps_table
175+
176+-- | cap names for function keys
177+function_key_caps_table :: ClassifyTable
178+function_key_caps_table = flip map [0..63] $ \n -> ("kf" ++ show n, EvKey (KFun n) [])
src/Graphics/Vty/Input/Terminfo/ANSI.hsnew file+85
@@ -0,0 +1,85 @@
1+module Graphics.Vty.Input.Terminfo.ANSI where
2+
3+import Graphics.Vty.Input.Events
4+
5+-- | Terminals augmented by the built in ANSI input mapping.
6+supports "ansi" = True
7+supports _ = False
8+
9+-- | Encoding for navigation keys.
10+nav_keys_0 :: ClassifyTable
11+nav_keys_0 =
12+ [ k "G" KCenter
13+ , k "P" KPause
14+ , k "A" KUp
15+ , k "B" KDown
16+ , k "C" KRight
17+ , k "D" KLeft
18+ , k "H" KHome
19+ , k "F" KEnd
20+ , k "E" KBegin
21+ ]
22+ where k c s = ("\ESC["++c, EvKey s [])
23+
24+-- | VT 100 (?) encoding for shift, meta and ctrl plus arrows/home/end
25+nav_keys_1 :: ClassifyTable
26+nav_keys_1 =
27+ [("\ESC[" ++ charCnt ++ show mc++c,(s,m))
28+ | charCnt <- ["1;", ""], -- we can have a count or not
29+ (m,mc) <- [([MShift],2::Int), ([MCtrl],5), ([MMeta],3),
30+ ([MShift, MCtrl],6), ([MShift, MMeta],4)], -- modifiers and their codes
31+ -- directions and their codes
32+ (c,s) <- [("A", KUp), ("B", KDown), ("C", KRight), ("D", KLeft), ("H", KHome), ("F", KEnd)]
33+ ]
34+
35+-- | VT 100 (?) encoding for ins, del, pageup, pagedown, home, end
36+nav_keys_2 :: ClassifyTableV1
37+nav_keys_2 =
38+ let k n s = ("\ESC["++show n++"~",(s,[]))
39+ in zipWith k [2::Int,3,5,6,1,4]
40+ [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
41+
42+-- | VT 100 (?) encoding for ctrl + ins, del, pageup, pagedown, home, end
43+nav_keys_3 :: ClassifyTableV1
44+nav_keys_3 =
45+ let k n s = ("\ESC["++show n++";5~",(s,[MCtrl]))
46+ in zipWith k [2::Int,3,5,6,1,4]
47+ [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
48+
49+-- | VT 100 (?) encoding for shift plus function keys
50+--
51+-- TODO: I suspect this should be generated by interpretting the terminals use of meta mode:
52+-- "If the terminal has a ``meta key'' which acts as a shift key, setting the 8th bit of any
53+-- character transmitted, this fact can be indicated with km. Other- wise, software will
54+-- assume that the 8th bit is parity and it will usually be cleared. If strings exist to turn this
55+-- ``meta mode'' on and off, they can be given as smm and rmm."
56+--
57+-- That is more complex than below. I cannot fault the original author for just hard coding a table.
58+function_keys_1 :: ClassifyTableV1
59+function_keys_1 =
60+ let f ff nrs m = [ ("\ESC["++show n++"~",(KFun (n-(nrs!!0)+ff), m)) | n <- nrs ] in
61+ concat [f 1 [25,26] [MShift], f 3 [28,29] [MShift], f 5 [31..34] [MShift] ]
62+
63+-- | VT 100 (?) encoding for meta plus char
64+--
65+-- TODO: resolve -
66+--
67+-- 1. removed 'ESC' from second list due to duplication with "special_support_keys".
68+-- 2. removed '[' from second list due to conflict with 7-bit encoding for ESC. Whether meta+[ is
69+-- the same as ESC should examine km and current encoding.
70+-- 3. stopped enumeration at '~' instead of '\DEL'. The latter is mapped to KBS by
71+-- special_support_keys.
72+function_keys_2 :: ClassifyTableV1
73+function_keys_2 = [ ('\ESC':[x],(KASCII x,[MMeta])) | x <- '\t':[' ' .. '~'],
74+ x /= '[']
75+
76+tables :: [ClassifyTableV1]
77+tables =
78+ [ nav_keys_0
79+ , nav_keys_1
80+ , nav_keys_2
81+ , nav_keys_3
82+ , function_keys_1
83+ , function_keys_2
84+ ]
85+
src/Graphics/Vty/Input/Data/ANSI.hs → src/Graphics/Vty/Input/Terminfo/XTerm7Bit.hsrenamed+7−45
@@ -1,7 +1,11 @@
1−module Graphics.Vty.Input.Data.ANSI where
1+module Graphics.Vty.Input.Terminfo.XTerm where
2
2
3import Graphics.Vty.Input.Events
3import Graphics.Vty.Input.Events
4
4
5+-- | The built in input augmentation for XTerm supports any TERM starting with xterm except those
6+-- containing 8bit.
7+supports term_name = "xterm" `isPrefixOf` term_name && !("8bit" `isInfixOf` term_name)
8+
5-- | Encoding for navigation keys.
9-- | Encoding for navigation keys.
6--
10--
7-- TODO: This is not the same as the input bytes pulled from teh caps table.
11-- TODO: This is not the same as the input bytes pulled from teh caps table.
@@ -43,16 +47,6 @@ nav_keys_3 =
43 in zipWith k [2::Int,3,5,6,1,4]
47 in zipWith k [2::Int,3,5,6,1,4]
44 [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
48 [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
45
49
46−-- | Support for simple characters.
47−--
48−-- we limit to < 0xC1. The UTF8 sequence detector will catch all values 0xC2 and above before this
49−-- classify table is reached.
50−--
51−-- TODO: resolve
52−-- 1. start at ' '. The earlier characters are all ctrl_char_keys
53−simple_chars :: ClassifyTableV1
54−simple_chars = [(x:[],(KASCII x,[])) | x <- [' ' .. toEnum 0xC1]]
55−
56-- | VT 100 (?) encoding for shift plus function keys
50-- | VT 100 (?) encoding for shift plus function keys
57--
51--
58-- TODO: I suspect this should be generated by interpretting the terminals use of meta mode:
52-- TODO: I suspect this should be generated by interpretting the terminals use of meta mode:
@@ -80,46 +74,14 @@ function_keys_2 :: ClassifyTableV1
80function_keys_2 = [ ('\ESC':[x],(KASCII x,[MMeta])) | x <- '\t':[' ' .. '~'],
74function_keys_2 = [ ('\ESC':[x],(KASCII x,[MMeta])) | x <- '\t':[' ' .. '~'],
81 x /= '[']
75 x /= '[']
82
76
83−-- | Ctrl+Char
84−ctrl_char_keys :: ClassifyTableV1
85−ctrl_char_keys =
86− [ ([toEnum x],(KASCII y,[MCtrl]))
87− | (x,y) <- zip ([0..31]) ('@':['a'..'z']++['['..'_']),
88− y /= 'i' -- Resolve issue #3 where CTRL-i hides TAB.
89− ]
90−
91−-- | Ctrl+Meta+Char
92−--
93−-- TODO: CTRL-i is the same as tab thing
94−ctrl_meta_keys :: ClassifyTableV1
95−ctrl_meta_keys =
96− [ ('\ESC':[toEnum x],(KASCII y,[MMeta,MCtrl])) | (x,y) <- zip [0..31] ('@':['a'..'z']++['['..'_']),
97− y /= 'i'
98− ]
99−
100−-- | Special support
101−special_support_keys :: ClassifyTableV1
102−special_support_keys =
103− [ -- special support for ESC
104− ("\ESC",(KEsc,[])) , ("\ESC\ESC",(KEsc,[MMeta]))
105− -- Special support for backspace
106− , ("\DEL",(KBS,[])), ("\ESC\DEL",(KBS,[MMeta]))
107− -- Special support for Enter
108− , ("\ESC\^J",(KEnter,[MMeta])), ("\^J",(KEnter,[]))
109− ]
110−
111-- | classify table for ANSI terminals
77-- | classify table for ANSI terminals
112−ansi_classify_table :: [ClassifyTableV1]
78+tables :: [ClassifyTableV1]
113−ansi_classify_table =
79+tables =
114 [ nav_keys_0
80 [ nav_keys_0
115 , nav_keys_1
81 , nav_keys_1
116 , nav_keys_2
82 , nav_keys_2
117 , nav_keys_3
83 , nav_keys_3
118− , simple_chars
119 , function_keys_1
84 , function_keys_1
120 , function_keys_2
85 , function_keys_2
121− , ctrl_char_keys
122− , ctrl_meta_keys
123− , special_support_keys
124 ]
86 ]
125
87
vty.cabal+7−7
@@ -18,7 +18,7 @@ description:
18 executable should be sent to the Vty maintainter to aid in debugging the issue.
18 executable should be sent to the Vty maintainter to aid in debugging the issue.
19 .
19 .
20 Notable infelicities: Sometimes poor efficiency; Assumes UTF-8 character encoding support by the
20 Notable infelicities: Sometimes poor efficiency; Assumes UTF-8 character encoding support by the
21− terminal;
21+ terminal; Poor signal handling; Requires terminfo.
22 .
22 .
23 Project is hosted on github.com: https:\/\/github.com\/coreyoconnor\/vty
23 Project is hosted on github.com: https:\/\/github.com\/coreyoconnor\/vty
24 .
24 .
@@ -34,7 +34,7 @@ data-files: README.md,
34 AUTHORS,
34 AUTHORS,
35 CHANGELOG,
35 CHANGELOG,
36 LICENSE
36 LICENSE
37−tested-with: ghc >= 7.6.2
37+tested-with: GHC >= 7.6.2
38
38
39library
39library
40 default-language: Haskell2010
40 default-language: Haskell2010
@@ -62,9 +62,7 @@ library
62 Graphics.Vty.Inline
62 Graphics.Vty.Inline
63 Graphics.Vty.Inline.Unsafe
63 Graphics.Vty.Inline.Unsafe
64 Graphics.Vty.Input
64 Graphics.Vty.Input
65− Graphics.Vty.Input.Data
65+ Graphics.Vty.Input.Events
66− Graphics.Vty.Input.Internal
67− Graphics.Vty.Input.Terminfo
68 Graphics.Vty.Picture
66 Graphics.Vty.Picture
69 Graphics.Vty.Prelude
67 Graphics.Vty.Prelude
70 Graphics.Vty.Output
68 Graphics.Vty.Output
@@ -77,6 +75,8 @@ library
77 Graphics.Vty.Debug
75 Graphics.Vty.Debug
78 Graphics.Vty.DisplayAttributes
76 Graphics.Vty.DisplayAttributes
79 Graphics.Vty.Image.Internal
77 Graphics.Vty.Image.Internal
78+ Graphics.Vty.Input.Internal
79+ Graphics.Vty.Input.Terminfo
80 Graphics.Vty.PictureToSpans
80 Graphics.Vty.PictureToSpans
81 Graphics.Vty.Span
81 Graphics.Vty.Span
82 Graphics.Vty.Output.Mock
82 Graphics.Vty.Output.Mock
@@ -87,8 +87,8 @@ library
87
87
88 other-modules: Graphics.Vty.Attributes.Color
88 other-modules: Graphics.Vty.Attributes.Color
89 Graphics.Vty.Attributes.Color240
89 Graphics.Vty.Attributes.Color240
90− Graphics.Vty.Input.Data.ANSI
90+ Graphics.Vty.Input.Terminfo.ANSI
91− Graphics.Vty.Input.Events
91+ Graphics.Vty.Input.Terminfo.XTerm7Bit
92
92
93 c-sources: cbits/gwinsz.c
93 c-sources: cbits/gwinsz.c
94 cbits/set_term_timing.c
94 cbits/set_term_timing.c