@@ -1,15 +1,178 @@
1module Graphics.Vty.Input.Terminfo where
1module Graphics.Vty.Input.Terminfo where
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
6import System.Console.Terminfo
7import System.Console.Terminfo
9+-- | queries the terminal for all capability based input sequences then adds on a terminal dependent
10+-- input sequence mapping.
14+-- * http://vimdoc.sourceforge.net/htmldoc/term.html
18+-- * http://invisible-island.net/vttest/
20+-- * http://aperiodic.net/phil/archives/Geekery/term-function-keys.html
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
26+-- 1. build terminfo table for all caps. Missing caps are not added.
28+-- 2. add tables for visible chars, esc, del plus ctrl and meta.
30+-- 3. add internally defined table for given terminal type.
32+-- The override is currently done in 'compile'. Which is a bit odd.
34+-- \todo terminfo meta is not supported.
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
43+ : special_support_keys
44+ : internal_tables term_name
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)
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 = []
55+-- | Visible characters in the ISO-8859-1 and UTF-8 common set.
57+-- we limit to < 0xC1. The UTF8 sequence detector will catch all values 0xC2 and above before this
58+-- classify table is reached.
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]
67+-- | Non visible cahracters in the ISO-8859-1 and UTF-8 common set translated to ctrl + char.
69+-- \todo resolve CTRL-i is the same as tab
70+ctrl_chars :: ClassifyTable
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.
78+ctrl_meta_chars :: ClassifyTable
79+ctrl_meta_chars = map (\(s,EvKey c m) -> ('\ESC':s, EvKey c (MMeta:m)))
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 [])
92+-- | classify table directly generated from terminfo cap strings
96+-- * ka1 - keypad up-left
98+-- * ka3 - keypad up-right
100+-- * kb2 - keypad center
102+-- * kbs - keypad backspace
108+-- * kc1 - keypad left-down
110+-- * kc3 - keypad right-down
120+-- * kf0 - kf63 - function keys
128+-- * knp - next page (page down)
130+-- * kpp - previous page (page up)
134+-- * kDC - shift delete
136+-- * kEND - shift end
138+-- * kHOM - shift home
140+-- * kIC - shift insert
142+-- * kLFT - shift left
144+-- * kRIT - shift right
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
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) [])