1{-# OPTIONS_HADDOCK hide #-}
2-- This makes a kind of tri. Has space efficiency issues with large
3-- input blocks. Likely building a parser and just applying that would
5module Graphics.Vty.Input.Classify
11import Graphics.Vty.Input.Events
12import Graphics.Vty.Input.Mouse
13import Graphics.Vty.Input.Focus
14import Graphics.Vty.Input.Paste
15import Graphics.Vty.Input.Classify.Types
17import Codec.Binary.UTF8.Generic (decode)
19import Data.List (inits)
20import qualified Data.Map as M( fromList, lookup )
21import Data.Maybe ( mapMaybe )
22import qualified Data.Set as S( fromList, member )
27compile :: ClassifyMap -> [Char] -> KClass
28compile table = cl' where
29 -- take all prefixes and create a set of these
30 prefixSet = S.fromList $ concatMap (init . inits . fst) $ table
31 maxValidInputLength = maximum (map (length . fst) table)
32 eventForInput = M.fromList table
34 cl' inputBlock = case M.lookup inputBlock eventForInput of
35 -- if the inputBlock is exactly what is expected for an
36 -- event then consume the whole block and return the event
38 Nothing -> case S.member inputBlock prefixSet of
40 -- look up progressively smaller tails of the input
41 -- block until an event is found The assumption is that
42 -- the event that consumes the most input bytes should
44 -- The test verifyFullSynInputToEvent2x verifies this.
45 -- H: There will always be one match. The prefixSet
46 -- contains, by definition, all prefixes of an event.
48 let inputPrefixes = reverse $ take maxValidInputLength $ tail $ inits inputBlock
49 in case mapMaybe (\s -> (,) s `fmap` M.lookup s eventForInput) inputPrefixes of
50 (s,e) : _ -> Valid e (drop (length s) inputBlock)
51 -- neither a prefix or a full event.
54classify :: ClassifyMap -> [Char] -> KClass
56 let standardClassifier = compile table
58 _ | bracketedPasteStarted s ->
59 if bracketedPasteFinished s
60 then parseBracketedPaste s
62 _ | isMouseEvent s -> classifyMouseEvent s
63 _ | isFocusEvent s -> classifyFocusEvent s
64 c:cs | ord c >= 0xC2 -> classifyUtf8 c cs
65 _ -> standardClassifier s
67classifyUtf8 :: Char -> [Char] -> KClass
69 let n = utf8Length (ord c)
70 (codepoint,rest) = splitAt n (c:cs)
73 codepoint8 = map (fromIntegral . ord) codepoint
75 in case decode codepoint8 of
76 _ | n < length codepoint -> Prefix
77 Just (unicodeChar, _) -> Valid (EvKey (KChar unicodeChar) []) rest
78 -- something bad happened; just ignore and continue.
81utf8Length :: (Num t, Ord a, Num a) => a -> t
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list