@@ -8,11 +8,11 @@
88#defined MIN_VERSION_base(x,y,z) 1
99#endif
1010
11−-- | Terminfo based terminal handling.
11+-- | Terminfo based terminal handling.
1212--
13−-- The color handling assumes tektronix like. No HP support provided. If the terminal is not one I
14−-- have easy access to then color support is entirely based of the docs. Probably with some
15−-- assumptions mixed in.
13+-- The color handling assumes tektronix like. No HP support provided. If
14+-- the terminal is not one I have easy access to then color support is
15+-- entirely based of the docs. Probably with some assumptions mixed in.
1616--
1717-- Copyright Corey O'Connor (coreyoconnor@gmail.com)
1818module Graphics.Vty.Output.TerminfoBased ( reserveTerminal )
@@ -78,8 +78,10 @@ data DisplayAttrCaps = DisplayAttrCaps
7878 , enterBoldMode :: Maybe CapExpression
7979 }
8080
81−-- kinda like: https://code.google.com/p/vim/source/browse/src/fileio.c#10422
82−-- fdWriteBuf will throw on error. Unless the error is EINTR. On EINTR the write will be retried.
81+-- kinda like:
82+-- https://code.google.com/p/vim/source/browse/src/fileio.c#10422
83+-- fdWriteBuf will throw on error. Unless the error is EINTR. On EINTR
84+-- the write will be retried.
8385fdWriteAll :: Fd -> Ptr Word8 -> Int -> Int -> IO Int
8486fdWriteAll outFd ptr len count
8587 | len < 0 = fail "fdWriteAll: len is less than 0"
@@ -95,22 +97,25 @@ sendCapToTerminal :: Output -> CapExpression -> [CapParam] -> IO ()
9597sendCapToTerminal t cap capParams = do
9698 outputByteBuffer t $ writeToByteString $ writeCapExpr cap capParams
9799
98−{- | Uses terminfo for all control codes. While this should provide the most compatible terminal
99− - terminfo does not support some features that would increase efficiency and improve compatibility:
100+{- | Uses terminfo for all control codes. While this should provide the
101+ - most compatible terminal terminfo does not support some features that
102+ - would increase efficiency and improve compatibility:
100103 -
101− - * determine the character encoding supported by the terminal. Should this be taken from the LANG
102− - environment variable?
104+ - * determine the character encoding supported by the terminal. Should
105+ - this be taken from the LANG environment variable?
103106 -
104107 - * Provide independent string capabilities for all display attributes.
105108 -
106− - todo: Some display attributes like underline and bold have independent string capabilities that
107− - should be used instead of the generic "sgr" string capability.
109+ - todo: Some display attributes like underline and bold have
110+ - independent string capabilities that should be used instead of the
111+ - generic "sgr" string capability.
108112 -}
109113reserveTerminal :: ( Applicative m, MonadIO m ) => String -> Fd -> m Output
110114reserveTerminal termName outFd = liftIO $ do
111115 ti <- Terminfo.setupTerm termName
112116 -- assumes set foreground always implies set background exists.
113− -- if set foreground is not set then all color changing style attributes are filtered.
117+ -- if set foreground is not set then all color changing style
118+ -- attributes are filtered.
114119 msetaf <- probeCap ti "setaf"
115120 msetf <- probeCap ti "setf"
116121 let (noColors, useAlt, setForeCap)
@@ -151,8 +156,9 @@ reserveTerminal termName outFd = liftIO $ do
151156 , supportsBell = return $ isJust $ ringBellAudio terminfoCaps
152157 , ringTerminalBell = liftIO $ maybeSendCap ringBellAudio []
153158 , reserveDisplay = liftIO $ do
154− -- If there is no support for smcup: Clear the screen and then move the mouse to the
155− -- home position to approximate the behavior.
159+ -- If there is no support for smcup: Clear the screen
160+ -- and then move the mouse to the home position to
161+ -- approximate the behavior.
156162 maybeSendCap smcup []
157163 sendCap clearScreen []
158164 , releaseDisplay = liftIO $ do
@@ -181,8 +187,8 @@ reserveTerminal termName outFd = liftIO $ do
181187 , setMode = const $ const $ return ()
182188 , getModeStatus = const $ return False
183189 , assumedStateRef = newAssumedStateRef
184− -- I think fix would help assure tActual is the only reference. I was having issues
185− -- tho.
190+ -- I think fix would help assure tActual is the only
191+ -- reference. I was having issues tho.
186192 , mkDisplayContext = \tActual -> liftIO . terminfoDisplayContext tActual terminfoCaps
187193 }
188194 sendCap s = sendCapToTerminal t (s terminfoCaps)
@@ -248,8 +254,9 @@ terminfoDisplayContext tActual terminfoCaps r = return dc
248254
249255-- | Portably setting the display attributes is a giant pain in the ass.
250256--
251−-- If the terminal supports the sgr capability (which sets the on/off state of each style
252−-- directly ; and, for no good reason, resets the colors to the default) this procedure is used:
257+-- If the terminal supports the sgr capability (which sets the on/off
258+-- state of each style directly ; and, for no good reason, resets the
259+-- colors to the default) this procedure is used:
253260--
254261-- 0. set the style attributes. This resets the fore and back color.
255262--
@@ -257,33 +264,37 @@ terminfoDisplayContext tActual terminfoCaps r = return dc
257264--
258265-- 2. likewise with the background color
259266--
260−-- If the terminal does not support the sgr cap then:
261−-- if there is a change from an applied color to the default (in either the fore or back color)
262−-- then:
267+-- If the terminal does not support the sgr cap then: if there is a
268+-- change from an applied color to the default (in either the fore or
269+-- back color) then:
263270--
264−-- 0. reset all display attributes (sgr0)
271+-- 0. reset all display attributes (sgr0)
265272--
266−-- 1. enter required style modes
273+-- 1. enter required style modes
267274--
268−-- 2. set the fore color if required
275+-- 2. set the fore color if required
269276--
270−-- 3. set the back color if required
277+-- 3. set the back color if required
271278--
272−-- Entering the required style modes could require a reset of the display attributes. If this is
273−-- the case then the back and fore colors always need to be set if not default.
279+-- Entering the required style modes could require a reset of the
280+-- display attributes. If this is the case then the back and fore colors
281+-- always need to be set if not default.
274282--
275283-- This equation implements the above logic.
276284--
277−-- \todo This assumes the removal of color changes in the display attributes is done as expected
278−-- with noColors == True. See `limitAttrForDisplay`
285+-- \todo This assumes the removal of color changes in the display
286+-- attributes is done as expected with noColors == True. See
287+-- `limitAttrForDisplay`
279288--
280−-- \todo This assumes that fewer state changes, followed by fewer bytes, is what to optimize. I
281−-- haven't measured this or even examined terminal implementations. *shrug*
289+-- \todo This assumes that fewer state changes, followed by fewer
290+-- bytes, is what to optimize. I haven't measured this or even examined
291+-- terminal implementations. *shrug*
282292terminfoWriteSetAttr :: DisplayContext -> TerminfoCaps -> FixedAttr -> Attr -> DisplayAttrDiff -> Write
283293terminfoWriteSetAttr dc terminfoCaps prevAttr reqAttr diffs = do
284294 case (foreColorDiff diffs == ColorToDefault) || (backColorDiff diffs == ColorToDefault) of
285− -- The only way to reset either color, portably, to the default is to use either the set
286− -- state capability or the set default capability.
295+ -- The only way to reset either color, portably, to the default
296+ -- is to use either the set state capability or the set default
297+ -- capability.
287298 True -> do
288299 case reqDisplayCapSeqFor (displayAttrCaps terminfoCaps)
289300 (fixedStyle attr )
@@ -302,18 +313,21 @@ terminfoWriteSetAttr dc terminfoCaps prevAttr reqAttr diffs = do
302313 (sgrArgsForState state)
303314 `mappend`
304315 setColors
305− -- Otherwise the display colors are not changing or changing between two non-default
306− -- points.
316+ -- Otherwise the display colors are not changing or changing
317+ -- between two non-default points.
307318 False -> do
308− -- Still, it could be the case that the change in display attributes requires the
309− -- colors to be reset because the required capability was not available.
319+ -- Still, it could be the case that the change in display
320+ -- attributes requires the colors to be reset because the
321+ -- required capability was not available.
310322 case reqDisplayCapSeqFor (displayAttrCaps terminfoCaps)
311323 (fixedStyle attr)
312324 (styleDiffs diffs) of
313− -- Really, if terminals were re-implemented with modern concepts instead of bowing
314− -- down to 40 yr old dumb terminal requirements this would be the only case ever
315− -- reached! Changes the style and color states according to the differences with
316− -- the currently applied states.
325+ -- Really, if terminals were re-implemented with modern
326+ -- concepts instead of bowing down to 40 yr old dumb
327+ -- terminal requirements this would be the only case
328+ -- ever reached! Changes the style and color states
329+ -- according to the differences with the currently
330+ -- applied states.
317331 EnterExitSeq caps -> foldMap (\cap -> writeCapExpr cap []) caps
318332 `mappend`
319333 writeColorDiff setForeColor (foreColorDiff diffs)
@@ -347,11 +361,11 @@ terminfoWriteSetAttr dc terminfoCaps prevAttr reqAttr diffs = do
347361 writeColorDiff f (SetColor c)
348362 = writeCapExpr (f terminfoCaps) [toEnum $ colorMap c]
349363
350−-- | The color table used by a terminal is a 16 color set followed by a 240 color set that might not
351−-- be supported by the terminal.
364+-- | The color table used by a terminal is a 16 color set followed by a
365+-- 240 color set that might not be supported by the terminal.
352366--
353−-- This takes a Color which clearly identifies which pallete to use and computes the index
354−-- into the full 256 color pallete.
367+-- This takes a Color which clearly identifies which pallete to use and
368+-- computes the index into the full 256 color pallete.
355369ansiColorIndex :: Color -> Int
356370ansiColorIndex (ISOColor v) = fromEnum v
357371ansiColorIndex (Color240 v) = 16 + fromEnum v
@@ -372,20 +386,23 @@ altColorIndex (ISOColor 7) = 7
372386altColorIndex (ISOColor v) = fromEnum v
373387altColorIndex (Color240 v) = 16 + fromEnum v
374388
375−{- | The sequence of terminfo caps to apply a given style are determined according to these rules.
389+{- | The sequence of terminfo caps to apply a given style are determined
390+ - according to these rules.
376391 -
377− - 1. The assumption is that it's preferable to use the simpler enter/exit mode capabilities than
378− - the full set display attribute state capability.
392+ - 1. The assumption is that it's preferable to use the simpler
393+ - enter/exit mode capabilities than the full set display attribute
394+ - state capability.
379395 -
380− - 2. If a mode is supposed to be removed but there is not an exit capability defined then the
381− - display attributes are reset to defaults then the display attribute state is set.
396+ - 2. If a mode is supposed to be removed but there is not an exit
397+ - capability defined then the display attributes are reset to defaults
398+ - then the display attribute state is set.
382399 -
383− - 3. If a mode is supposed to be applied but there is not an enter capability defined then then
384− - display attribute state is set if possible. Otherwise the mode is not applied.
385− -
386− - 4. If the display attribute state is being set then just update the arguments to that for any
387− - apply/remove.
400+ - 3. If a mode is supposed to be applied but there is not an enter
401+ - capability defined then then display attribute state is set if
402+ - possible. Otherwise the mode is not applied.
388403 -
404+ - 4. If the display attribute state is being set then just update the
405+ - arguments to that for any apply/remove.
389406 -}
390407data DisplayAttrSeq
391408 = EnterExitSeq [CapExpression]
@@ -415,17 +432,19 @@ sgrArgsForState attrState = map (\b -> if b then 1 else 0)
415432
416433reqDisplayCapSeqFor :: DisplayAttrCaps -> Style -> [StyleStateChange] -> DisplayAttrSeq
417434reqDisplayCapSeqFor caps s diffs
418− -- if the state transition implied by any diff cannot be supported with an enter/exit mode cap
419− -- then either the state needs to be set or the attribute change ignored.
435+ -- if the state transition implied by any diff cannot be supported
436+ -- with an enter/exit mode cap then either the state needs to be set
437+ -- or the attribute change ignored.
420438 = case (any noEnterExitCap diffs, isJust $ setAttrStates caps) of
421439 -- If all the diffs have an enter-exit cap then just use those
422440 ( False, _ ) -> EnterExitSeq $ map enterExitCap diffs
423− -- If not all the diffs have an enter-exit cap and there is no set state cap then filter out
424− -- all unsupported diffs and just apply the rest
441+ -- If not all the diffs have an enter-exit cap and there is no
442+ -- set state cap then filter out all unsupported diffs and just
443+ -- apply the rest
425444 ( True, False ) -> EnterExitSeq $ map enterExitCap
426445 $ filter (not . noEnterExitCap) diffs
427− -- if not all the diffs have an enter-exit can and there is a set state cap then just use
428− -- the set state cap.
446+ -- if not all the diffs have an enter-exit can and there is a
447+ -- set state cap then just use the set state cap.
429448 ( True, True ) -> SetState $ stateForStyle s
430449 where
431450 noEnterExitCap ApplyStandout = isNothing $ enterStandout caps