@@ -0,0 +1,46 @@
1+-- | This module provides bracketed paste support as described at
2+--
3+-- http://cirw.in/blog/bracketed-paste
4+module Graphics.Vty.Input.Paste
5+ ( parseBracketedPaste
6+ , bracketedPasteStarted
7+ , bracketedPasteFinished
8+ ) where
9+
10+import Graphics.Vty.Input.Events
11+import Graphics.Vty.Input.Classify.Types
12+
13+import Data.List (isPrefixOf, isInfixOf)
14+
15+bracketedPasteStart :: String
16+bracketedPasteStart = "\ESC[200~"
17+
18+bracketedPasteEnd :: String
19+bracketedPasteEnd = "\ESC[201~"
20+
21+-- | Does the input start a bracketed paste?
22+bracketedPasteStarted :: String -> Bool
23+bracketedPasteStarted = isPrefixOf bracketedPasteStart
24+
25+-- | Does the input contain a complete bracketed paste?
26+bracketedPasteFinished :: String -> Bool
27+bracketedPasteFinished = isInfixOf bracketedPasteEnd
28+
29+-- | Parse a bracketed paste. This should only be called on a string if
30+-- both 'bracketedPasteStarted' and 'bracketedPasteFinished' return
31+-- 'True'.
32+parseBracketedPaste :: String -> KClass
33+parseBracketedPaste s =
34+ let (p, rest) = takeUntil (drop (length bracketedPasteStart) s) bracketedPasteEnd
35+ rest' = if bracketedPasteEnd `isPrefixOf` rest
36+ then drop (length bracketedPasteEnd) rest
37+ else rest
38+ in Valid (EvPaste p) rest'
39+
40+takeUntil :: (Eq a) => [a] -> [a] -> ([a],[a])
41+takeUntil [] _ = ([], [])
42+takeUntil cs sub
43+ | length cs < length sub = (cs, [])
44+ | take (length sub) cs == sub = ([], drop (length sub) cs)
45+ | otherwise = let (pre, suf) = takeUntil (tail cs) sub
46+ in (head cs:pre, suf)