Skip to content

Commit

Permalink
Fix #166 On Unix-like OS, use unsafePerformIO (lookupEnv "TERM")
Browse files Browse the repository at this point in the history
  • Loading branch information
mpilgrem committed Apr 21, 2024
1 parent 6bcbe9f commit fe8ffdc
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions ansi-terminal/unix/System/Console/ANSI/Internal.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE Safe #-}
{-# LANGUAGE Trustworthy #-}

module System.Console.ANSI.Internal
( getReportedCursorPosition
Expand All @@ -11,6 +11,7 @@ import Data.List ( uncons )
import Data.Maybe ( fromMaybe, mapMaybe )
import System.Environment ( lookupEnv )
import System.IO ( Handle, hIsTerminalDevice, hIsWritable )
import System.IO.Unsafe ( unsafePerformIO )
import System.Timeout ( timeout )

import System.Console.ANSI.Types ( ConsoleLayer (..) )
Expand Down Expand Up @@ -72,8 +73,18 @@ hSupportsANSI :: Handle -> IO Bool
-- (https://github.com/hspec/hspec/commit/d932f03317e0e2bd08c85b23903fb8616ae642bd)
hSupportsANSI h = (&&) <$> hIsWritable h <*> hSupportsANSI'
where
hSupportsANSI' = (&&) <$> hIsTerminalDevice h <*> isNotDumb
isNotDumb = (/= Just "dumb") <$> lookupEnv "TERM"
hSupportsANSI' = (&& isNotDumb) <$> hIsTerminalDevice h

hNowSupportsANSI :: Handle -> IO Bool
hNowSupportsANSI = hSupportsANSI

-- | This function assumes that once it is first established whether or not the
-- TERM environment variable exists with contents dumb, that will not change.
-- This approach is taken because the use of C function setenv() in one thread
-- can cause other threads calling C function getenv() to crash. On Unix-like
-- operating systems, System.Environment.lookupEnv is implemented using C
-- function getenv().
isNotDumb :: Bool
isNotDumb = unsafePerformIO (lookupEnv "TERM") /= Just "dumb"

{-# NOINLINE isNotDumb #-}

0 comments on commit fe8ffdc

Please sign in to comment.