@@ -1,15 +1,13 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE ForeignFunctionInterface #-}
31-- Copyright Corey O'Connor
42module Graphics.Vty.Input.Data where
53
6−-- |Representations of non-modifier keys.
4+-- | Representations of non-modifier keys.
75data Key = KEsc | KFun Int | KBackTab | KPrtScr | KPause | KASCII Char | KBS | KIns
86 | KHome | KPageUp | KDel | KEnd | KPageDown | KBegin | KNP5 | KUp | KMenu
97 | KLeft | KDown | KRight | KEnter
108 deriving (Eq,Show,Ord)
119
12−-- |Modifier keys. Key codes are interpreted such that users are more likely to
10+-- | Modifier keys. Key codes are interpreted such that users are more likely to
1311-- have Meta than Alt; for instance on the PC Linux console, 'MMeta' will
1412-- generally correspond to the physical Alt key.
1513data Modifier = MShift | MCtrl | MMeta | MAlt
@@ -24,17 +22,24 @@ data Event = EvKey Key [Modifier] | EvMouse Int Int Button [Modifier]
2422 | EvResize Int Int
2523 deriving (Eq,Show,Ord)
2624
27−data KClass = Valid Key [Modifier] | Invalid | Prefix | MisPfx Key [Modifier] [Char]
25+data KClass
26+ = Valid Key [Modifier]
27+ | Invalid
28+ | EndLoop
29+ | Prefix
30+ | MisPfx Key [Modifier] [Char]
2831 deriving(Show)
2932
30−map_to_legacy_table :: [(String, Event)] -> [(String, (Key, [Modifier]))]
33+type ClassifyTable = [(String, (Key, [Modifier]))]
34+
35+map_to_legacy_table :: [(String, Event)] -> ClassifyTable
3136map_to_legacy_table = map f
3237 where f (s, EvKey k mods) = (s, (k, mods))
3338 f _ = error "no mapping for mouse or resize events"
3439
3540-- | classify table directly generated from terminfo cap strings
36−caps_table :: [(String, Event)]
37−caps_table =
41+keys_from_caps_table :: [(String, Event)]
42+keys_from_caps_table =
3843 [ ("khome", EvKey KHome [])
3944 , ("kend", EvKey KEnd [])
4045 , ("cbt", EvKey KBackTab [])
@@ -46,62 +51,97 @@ caps_table =
4651 , ("kRIT", EvKey KRight [MShift])
4752 ]
4853
54+nav_keys_0 :: ClassifyTable
55+nav_keys_0 =
56+ [ k "G" KNP5
57+ , k "P" KPause
58+ , k "A" KUp
59+ , k "B" KDown
60+ , k "C" KRight
61+ , k "D" KLeft
62+ , k "H" KHome
63+ , k "F" KEnd
64+ , k "E" KBegin
65+ ]
66+ where k c s = ("\ESC["++c,(s,[]))
4967
50−-- | classify table for ANSI terminals
51−ansi_classify_table :: [[([Char], (Key, [Modifier]))]]
52−ansi_classify_table =
53− [ let k c s = ("\ESC["++c,(s,[])) in [ k "G" KNP5
54− , k "P" KPause
55− , k "A" KUp
56− , k "B" KDown
57− , k "C" KRight
58− , k "D" KLeft
59− , k "H" KHome
60− , k "F" KEnd
61− , k "E" KBegin
62− ],
63−
64− -- Support for arrows and KHome/KEnd
68+-- Support for arrows and KHome/KEnd
69+nav_keys_1 :: ClassifyTable
70+nav_keys_1 =
6571 [("\ESC[" ++ charCnt ++ show mc++c,(s,m))
6672 | charCnt <- ["1;", ""], -- we can have a count or not
6773 (m,mc) <- [([MShift],2::Int), ([MCtrl],5), ([MMeta],3),
6874 ([MShift, MCtrl],6), ([MShift, MMeta],4)], -- modifiers and their codes
6975 (c,s) <- [("A", KUp), ("B", KDown), ("C", KRight), ("D", KLeft), ("H", KHome), ("F", KEnd)] -- directions and their codes
70− ],
71−
72− let k n s = ("\ESC["++show n++"~",(s,[]))
73− in zipWith k [2::Int,3,5,6,1,4]
74− [KIns,KDel,KPageUp,KPageDown,KHome,KEnd],
75−
76− let k n s = ("\ESC["++show n++";5~",(s,[MCtrl]))
77− in zipWith k [2::Int,3,5,6,1,4]
78− [KIns,KDel,KPageUp,KPageDown,KHome,KEnd],
79−
80− -- Support for simple characters.
81− [ (x:[],(KASCII x,[])) | x <- map toEnum [0..255] ],
82−
83− -- Support for function keys (should use terminfo)
84− [ ("\ESC[["++[toEnum(64+i)],(KFun i,[])) | i <- [1..5] ],
85− let f ff nrs m = [ ("\ESC["++show n++"~",(KFun (n-(nrs!!0)+ff), m)) | n <- nrs ] in
86− concat [ f 6 [17..21] [], f 11 [23,24] [], f 1 [25,26] [MShift], f 3 [28,29] [MShift], f 5 [31..34] [MShift] ],
87− [ ('\ESC':[x],(KASCII x,[MMeta])) | x <- '\ESC':'\t':[' ' .. '\DEL'] ],
88−
89− -- Ctrl+Char
90− [ ([toEnum x],(KASCII y,[MCtrl]))
91− | (x,y) <- zip ([0..31]) ('@':['a'..'z']++['['..'_']),
92− y /= 'i' -- Resolve issue #3 where CTRL-i hides TAB.
93− ],
94−
95− -- Ctrl+Meta+Char
96− [ ('\ESC':[toEnum x],(KASCII y,[MMeta,MCtrl])) | (x,y) <- zip [0..31] ('@':['a'..'z']++['['..'_']) ],
76+ ]
77+
78+nav_keys_2 :: ClassifyTable
79+nav_keys_2 =
80+ let k n s = ("\ESC["++show n++"~",(s,[]))
81+ in zipWith k [2::Int,3,5,6,1,4]
82+ [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
83+
84+nav_keys_3 :: ClassifyTable
85+nav_keys_3 =
86+ let k n s = ("\ESC["++show n++";5~",(s,[MCtrl]))
87+ in zipWith k [2::Int,3,5,6,1,4]
88+ [KIns,KDel,KPageUp,KPageDown,KHome,KEnd]
89+
90+-- Support for simple characters.
91+-- we limit to < 0xC1. The UTF8 sequence detector will catch all values 0xC2 and above before this
92+-- classify table is reached.
93+simple_chars :: ClassifyTable
94+simple_chars = [ (x:[],(KASCII x,[])) | x <- map toEnum [0..0xC1] ]
95+
96+-- Support for function keys (should use terminfo)
97+function_keys_0 :: ClassifyTable
98+function_keys_0 = [ ("\ESC[["++[toEnum(64+i)],(KFun i,[])) | i <- [1..5] ]
99+
100+function_keys_1 :: ClassifyTable
101+function_keys_1 =
102+ let f ff nrs m = [ ("\ESC["++show n++"~",(KFun (n-(nrs!!0)+ff), m)) | n <- nrs ] in
103+ concat [ f 6 [17..21] [], f 11 [23,24] [], f 1 [25,26] [MShift], f 3 [28,29] [MShift], f 5 [31..34] [MShift] ]
104+
105+function_keys_2 :: ClassifyTable
106+function_keys_2 = [ ('\ESC':[x],(KASCII x,[MMeta])) | x <- '\ESC':'\t':[' ' .. '\DEL'] ]
107+
108+-- Ctrl+Char
109+ctrl_char_keys :: ClassifyTable
110+ctrl_char_keys =
111+ [ ([toEnum x],(KASCII y,[MCtrl]))
112+ | (x,y) <- zip ([0..31]) ('@':['a'..'z']++['['..'_']),
113+ y /= 'i' -- Resolve issue #3 where CTRL-i hides TAB.
114+ ]
97115
98− -- Special support
99− [ -- special support for ESC
100− ("\ESC",(KEsc,[])) , ("\ESC\ESC",(KEsc,[MMeta])),
116+-- Ctrl+Meta+Char
117+ctrl_meta_keys :: ClassifyTable
118+ctrl_meta_keys =
119+ [ ('\ESC':[toEnum x],(KASCII y,[MMeta,MCtrl])) | (x,y) <- zip [0..31] ('@':['a'..'z']++['['..'_']) ]
120+
121+-- Special support
122+special_support_keys :: ClassifyTable
123+special_support_keys =
124+ [ -- special support for ESC
125+ ("\ESC",(KEsc,[])) , ("\ESC\ESC",(KEsc,[MMeta]))
126+ -- Special support for backspace
127+ , ("\DEL",(KBS,[])), ("\ESC\DEL",(KBS,[MMeta]))
128+ -- Special support for Enter
129+ , ("\ESC\^J",(KEnter,[MMeta])), ("\^J",(KEnter,[]))
130+ ]
101131
102− -- Special support for backspace
103− ("\DEL",(KBS,[])), ("\ESC\DEL",(KBS,[MMeta])),
132+-- | classify table for ANSI terminals
133+ansi_classify_table :: [ClassifyTable]
134+ansi_classify_table =
135+ [ nav_keys_0
136+ , nav_keys_1
137+ , nav_keys_2
138+ , nav_keys_3
139+ , simple_chars
140+ , function_keys_0
141+ , function_keys_1
142+ , function_keys_2
143+ , ctrl_char_keys
144+ , ctrl_meta_keys
145+ , special_support_keys
146+ ]
104147
105− -- Special support for Enter
106− ("\ESC\^J",(KEnter,[MMeta])), ("\^J",(KEnter,[])) ]
107− ]