{-# LANGUAGE CPP #-}-- | Working with escape sequencesmoduleGeneral.EscCodes(Color (..),checkEscCodes ,removeEscCodes ,escWindowTitle ,escCursorUp ,escClearLine ,escForeground ,escNormal )whereimportData.CharimportSystem.IOimportSystem.EnvironmentimportSystem.IO.Unsafe#ifdef mingw32_HOST_OS importData.WordimportData.BitsimportForeign.PtrimportForeign.StorableimportForeign.Marshal.Alloc#endif checkEscCodes::IOBoolcheckEscCodes =returncheckEscCodesOnce {-# NOINLINEcheckEscCodesOnce#-}checkEscCodesOnce::BoolcheckEscCodesOnce =unsafePerformIO$dohdl <-hIsTerminalDevicestdoutenv <-maybeFalse(/="dumb")<$>lookupEnv"TERM"ifhdl &&env thenreturnTrueelse#ifdef mingw32_HOST_OS checkEscCodesWindows#else returnFalse#endif #ifdef mingw32_HOST_OS #ifdef x86_64_HOST_ARCH #define CALLCONV ccall #else #define CALLCONV stdcall #endif foreignimportCALLCONVunsafe"Windows.h GetStdHandle"c_GetStdHandle::Word32->IO(Ptr())foreignimportCALLCONVunsafe"Windows.h GetConsoleMode"c_GetConsoleModule::Ptr()->PtrWord32->IOBoolforeignimportCALLCONVunsafe"Windows.h SetConsoleMode"c_SetConsoleMode::Ptr()->Word32->IOBoolc_STD_OUTPUT_HANDLE=4294967285::Word32-- (-11) for some reasonc_ENABLE_VIRTUAL_TERMINAL_PROCESSING=0x0004::Word32-- | Try and get the handle attributes, if they are all satisifed, return True.-- If they aren't, try and set it to emulated mode.checkEscCodesWindows::IOBoolcheckEscCodesWindows=doh<-c_GetStdHandlec_STD_OUTPUT_HANDLE-- might return INVALID_HANDLE_VALUE, but then the next step will happily failmode<-alloca$\v->dob<-c_GetConsoleModulehvifbthenJust<$>peekvelsereturnNothingcasemodeofNothing->returnFalseJustmode->doletmodeNew=mode.|.c_ENABLE_VIRTUAL_TERMINAL_PROCESSINGifmode==modeNewthenreturnTrueelsedoc_SetConsoleModehmodeNew#endif removeEscCodes::String->StringremoveEscCodes ('\ESC':'[':xs )=removeEscCodes $drop1$dropWhile(not.isAlpha)xs removeEscCodes(x :xs )=x :removeEscCodes xs removeEscCodes[]=[]escWindowTitle::String->StringescWindowTitle x ="\ESC]0;"++x ++"\BEL"escCursorUp::Int->StringescCursorUp i ="\ESC["++showi ++"A"escClearLine::StringescClearLine ="\ESC[K"dataColor =Black |Red |Green |Yellow |Blue |Magenta |Cyan |White deriving(Show,Enum)escForeground::Color ->StringescForeground x ="\ESC["++show(30+fromEnumx )++"m"escNormal::StringescNormal ="\ESC[0m"