on master help sign in
add a debug log for input
commit522b740b8a33a9941cd6a576da9329e37e7c480d authorCorey O'Connor <coreyoconnor@gmail.com> dateSun 25 May 2014, 23:28 (12 years ago) parent857cb61
7 files changed+87−24
CHANGELOG+15−5 src/Graphics/Vty.hs+2−2 src/Graphics/Vty/Config.hs+46−12 src/Graphics/Vty/Input/Loop.hs+18 src/Graphics/Vty/Output.hs+2−2 test/VerifyConfig.hs+2−1 vty.cabal+2−2
CHANGELOG+15−5
@@ -1,17 +1,21 @@
115.0.0
22 * The naming convention now matches:
33 * http://www.haskell.org/haskellwiki/Programming_guidelines#Naming_Conventions
4− * all projects using vty for input must be compiled with -threaded. This could be resolved but
5− would like to avoid the complexity for now.
4+ * all projects using vty for input must be compiled with -threaded. Please notify vty author if
5+ this is not acceptable.
66 * mkVtyEscDelay has been removed. Use "mkVty def". Which initialized vty with the default
77 configuration.
88 * input handling changes
99 * KASCII is now KChar
1010 * KPN5 is now KCenter
1111 * tests exist.
12+ * Applications add to the input tables by setting inputOverrides of the Config.
13+ See Graphics.Vty.Config
14+ * Users can define input table extensions that will apply to all vty applications.
15+ See Graphics.Vty.Config
1216 * terminal timing is now handled by selecting an appropriate VTIME. Previously this was
13− implemented within Vty itself. This reduced complexity in vty but potentially provides
14− a different meta key behavior.
17+ implemented within Vty itself. This reduced complexity in vty but provides a different
18+ meta key behavior. There were no know users of the previous behavior.
1519 * The time vty will wait to verify an ESC byte means a single ESC key is the
1620 singleEscPeriod of the Input Config structure.
1721 * removed the typeclass based terminal and display context interface in favor of a data
@@ -25,7 +29,7 @@
2529 * Each layer is an image.
2630 * The layers for a picture are a list of images.
2731 * The first image is the top-most layer. The images are ordered from top to bottom.
28− * The transparent areas for a layer are the background_fill areas. These will be implicitly
32+ * The transparent areas for a layer are the backgroundFill areas. These will be implicitly
2933 added to to pad images when images of different sizes are joined.
3034 * If the background is clear there is no background layer.
3135 * If there is a background character then the bottom layer is the background layer.
@@ -37,6 +41,12 @@
3741 * alternate (setf/setb) color maps supported. Though colors beyond the first 8 are just a
3842 guess.
3943 * added "rgbColor" for easy support of RGB specified colors.
44+ * Both applications and users can add to the mapping used to translate from input bytes to
45+ events.
46+ * Additional information about input and output process can be appended to a debug log
47+ * Set environment variable VTY_DEBUG_LOG to path of debug log
48+ * Use "debugLog <path>" config directive
49+ * Set 'debugLog' property of Config
4050 * examples moved to vty-examples package. See test directory for cabal file.
4151 * vty-interactive-terminal-test
4252 * interactive test. Useful for building a bug report for vty's author.
src/Graphics/Vty.hs+2−2
@@ -109,8 +109,8 @@ data Vty = Vty
109109mkVty :: Config -> IO Vty
110110mkVty appConfig = do
111111 config <- mappend <$> pure appConfig <*> userConfig
112− input <- inputForCurrentTerminal config
113− out <- outputForCurrentTerminal
112+ input <- inputForCurrentTerminal config
113+ out <- outputForCurrentTerminal config
114114 intMkVty input out
115115
116116intMkVty :: Input -> Output -> IO Vty
src/Graphics/Vty/Config.hs+46−12
@@ -10,18 +10,37 @@
1010-- Each line of the input config is processed individually. Lines that fail to parse are ignored.
1111-- Later entries take precedence over earlier.
1212--
13−-- = Classify Table Overrides
13+-- For all directives:
14+--
15+-- @
16+-- string := \"\\\"\" chars+ \"\\\"\"
17+-- @
18+--
19+-- = Debug Directives
20+--
21+-- == @debugLog@
22+--
23+-- Format:
24+--
25+-- @
26+-- \"debugLog\" string
27+-- @
28+--
29+-- The value of the environment variable @VTY_DEBUG_LOG@ is equivalent to a debugLog entry at the
30+-- end of the last config file.
31+--
32+-- = Input Table Directives
1433--
1534-- == @map@
1635--
1736-- Directive format:
1837--
1938-- @
20−-- entry := \"map\" string key modifier_list
21−-- key := KEsc | KChar Char | KBS ... (same as 'Key')
22−-- modifier_list := \"[\" modifier+ \"]\"
23−-- modifier := MShift | MCtrl | MMeta | MAlt
24−-- string := \"\\\"\" chars+ \"\\\"\"
39+-- \"map\" string key modifier_list
40+-- where
41+-- key := KEsc | KChar Char | KBS ... (same as 'Key')
42+-- modifier_list := \"[\" modifier+ \"]\"
43+-- modifier := MShift | MCtrl | MMeta | MAlt
2544-- @
2645--
2746-- EG: If the contents are
@@ -34,6 +53,12 @@
3453-- Then the bytes @\"\\ESC[B\"@ will result in the KUp event. The bytes @\"\\ESC[1;3B\"@ will result
3554-- in the event KDown with the MAlt modifier.
3655--
56+-- If a debug log is requested then vty will output the current input table to the log in the above
57+-- format.
58+--
59+-- EG: Set VTY_DEBUG_LOG. Run vty. Check debug log for incorrect mappings. Add corrected mappings to
60+-- .vty/config
61+--
3762module Graphics.Vty.Config where
3863
3964-- ignore warning on GHC 7.6+. Required for GHC 7.4
@@ -62,9 +87,10 @@ import qualified Text.Parsec.Token as P
6287
6388data Config = Config
6489 { specifiedEscPeriod :: Maybe Int
65− -- | Debug information is appended to the file.
90+ -- | Debug information is appended to this file if not Nothing.
6691 , debugLog :: Maybe FilePath
67− -- | The (input byte, output event) pairs override VTY\'s built-in tables as well as terminfo.
92+ -- | The (input byte, output event) pairs extend the internal input table of VTY and the table
93+ -- from terminfo.
6894 --
6995 -- See "Graphics.Vty.Config" module documentation for documentation of the @map@ directive.
7096 , inputOverrides :: ClassifyTable
@@ -97,10 +123,12 @@ type ConfigParser s a = ParsecT s () (Writer Config) a
97123-- | Config from @'getAppUserDataDirectory'/config@ and @$VTY_CONFIG_FILE@
98124userConfig :: IO Config
99125userConfig = do
100− vtyConfig <- (mappend <$> getAppUserDataDirectory "vty" <*> pure "/config") >>= parseConfigFile
126+ userConfig <- (mappend <$> getAppUserDataDirectory "vty" <*> pure "/config") >>= parseConfigFile
101127 overridePath <- tryJust (guard . isDoesNotExistError) $ getEnv "VTY_CONFIG_FILE"
102128 overrideConfig <- either (const $ return def) parseConfigFile overridePath
103− return $ vtyConfig `mappend` overrideConfig
129+ debugLogPath <- tryJust (guard . isDoesNotExistError) $ getEnv "VTY_DEBUG_LOG"
130+ let debugLogConfig = either (const $ return def) (def { debugLog = Just debugLogPath })
131+ return $ mconcat [userConfig, overrideConfig, debugLogConfig]
104132
105133parseConfigFile :: FilePath -> IO Config
106134parseConfigFile path = do
@@ -130,7 +158,7 @@ configLanguage = LanguageDef
130158configLexer :: Stream s m Char => P.GenTokenParser s u m
131159configLexer = P.makeTokenParser configLanguage
132160
133−parseOverride = do
161+mapDecl = do
134162 void $ string "map"
135163 P.whiteSpace configLexer
136164 bytes <- P.stringLiteral configLexer
@@ -181,9 +209,15 @@ parseModifier = do
181209 "MAlt" -> return MAlt
182210 _ -> fail $ m ++ " is not a valid modifier identifier"
183211
212+debugLogDecl = do
213+ void $ string "debugLog"
214+ P.whiteSpace configLexer
215+ path <- P.stringLiteral configLexer
216+ lift $ tell $ def { debugLog = Just path }
217+
184218ignoreLine = void $ manyTill anyChar newline
185219
186220parseConfig = void $ many $ do
187221 P.whiteSpace configLexer
188− let directives = [parseOverride]
222+ let directives = [mapDecl, debugLogDecl]
189223 try (choice directives) <|> ignoreLine
src/Graphics/Vty/Input/Loop.hs+18
@@ -28,10 +28,13 @@ import Data.Word (Word8)
2828import Foreign ( allocaArray, peekArray, Ptr )
2929import Foreign.C.Types (CInt(..))
3030
31+import System.IO
3132import System.Posix.IO (fdReadBuf)
3233import System.Posix.Terminal
3334import System.Posix.Types (Fd(..))
3435
36+import Text.Printf (hPrintf)
37+
3538data Input = Input
3639 { -- | Channel of events direct from input processing. Unlike 'nextEvent' this will not refresh
3740 -- the display if the next event is an 'EvResize'.
@@ -43,6 +46,8 @@ data Input = Input
4346 , _configRef :: IORef Config
4447 -- | File descriptor used for input.
4548 , _inputFd :: Fd
49+ -- | input debug log
50+ , _inputDebug :: Maybe Handle
4651 }
4752
4853makeLenses ''Input
@@ -147,6 +152,16 @@ attributeControl fd = do
147152 unsetAttrs = setTerminalAttributes fd original Immediately
148153 return (setAttrs,unsetAttrs)
149154
155+logClassifyTable :: Input -> ClassifyTable -> IO()
156+logClassifyTable input classifyTable = case _inputDebug input of
157+ Nothing -> return ()
158+ Just h -> do
159+ forM_ classifyTable $ \i -> case i of
160+ (inBytes, EvKey k mods) -> hPrintf h "map %s %s %s\n" (show inBytes)
161+ (show k)
162+ (show mods)
163+ _ -> return ()
164+
150165initInputForFd :: Config -> ClassifyTable -> Fd -> IO Input
151166initInputForFd config classifyTable inFd = do
152167 applyTimingConfig inFd config
@@ -155,6 +170,9 @@ initInputForFd config classifyTable inFd = do
155170 <*> pure (writeIORef stopFlag True)
156171 <*> newIORef config
157172 <*> pure inFd
173+ <*> maybe Nothing (\f -> Just <$> openFile f AppendMode)
174+ (debugLog config)
175+ logClassifyTable classifyTable
158176 _ <- forkOS $ runInputProcessorLoop classifyTable input stopFlag
159177 return input
160178
src/Graphics/Vty/Output.hs+2−2
@@ -74,8 +74,8 @@ import System.IO
7474--
7575-- \todo add an implementation for windows that does not depend on terminfo. Should be installable
7676-- with only what is provided in the haskell platform. Use ansi-terminal
77−outputForCurrentTerminal :: ( Applicative m, MonadIO m ) => m Output
78−outputForCurrentTerminal = do
77+outputForCurrentTerminal :: ( Applicative m, MonadIO m ) => Config -> m Output
78+outputForCurrentTerminal _config = do
7979 termType <- liftIO $ getEnv "TERM"
8080 outHandle <- liftIO $ hDuplicate stdout
8181 outputForNameAndIO termType outHandle
test/VerifyConfig.hs+2−1
@@ -24,12 +24,13 @@ exampleConfig = [s|
2424map "\ESC[B" KUp []
2525askfjla dfasjdflk jasdlkfj asdfj -- lines failing parse should be ignored
2626map "\ESC[1;3B" KDown [MAlt]
27+debugLog "/tmp/vty-debug.txt"
2728|]
2829
2930exampleConfigConfig :: Config
3031exampleConfigConfig = Config
3132 { specifiedEscPeriod = def
32− , debugLog = def
33+ , debugLog = Just "/tmp/vty-debug.txt"
3334 , inputOverrides = [("\ESC[B", EvKey KUp []), ("\ESC[1;3B", EvKey KDown [MAlt])]
3435 }
3536
vty.cabal+2−2
@@ -21,8 +21,8 @@ description:
2121 If your terminal is not behaving as expected the results of the vty-interactive-terminal-test
2222 executable should be sent to the Vty maintainter to aid in debugging the issue.
2323 .
24− Notable infelicities: Sometimes poor efficiency; Assumes UTF-8 character encoding support by the
25− terminal; Poor signal handling; Requires terminfo.
24+ Notable infelicities: Assumes UTF-8 character encoding support by the terminal; Poor signal
25+ handling; Requires terminfo.
2626 .
2727 Project is hosted on github.com: https:\/\/github.com\/coreyoconnor\/vty
2828 .