From c111b332c789d30cdb22cfd8858ca8cc6117c61c Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 17:08:22 -0700 Subject: [PATCH 01/19] create stub `System.Terminal` module --- src/System/Terminal.hsc | 9 +++++++++ stack.cabal | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/System/Terminal.hsc diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc new file mode 100644 index 0000000000..ffde47b034 --- /dev/null +++ b/src/System/Terminal.hsc @@ -0,0 +1,9 @@ +{-# LANGUAGE ForeignFunctionInterface #-} + +module System.Terminal +( getTerminalWidth +) where + +-- | Get the width, in columns, of the terminal if we can. +getTerminalWidth :: IO (Maybe Int) +getTerminalWidth = pure Nothing diff --git a/stack.cabal b/stack.cabal index 0fab39b501..5738eea124 100644 --- a/stack.cabal +++ b/stack.cabal @@ -187,6 +187,7 @@ library System.Process.PagerEditor System.Process.Read System.Process.Run + System.Terminal other-modules: Hackage.Security.Client.Repository.HttpLib.HttpClient build-depends: Cabal >= 2.0 && < 2.1 , aeson (>= 1.0 && < 1.2) From da253f29b365d464049f4f05b84986f5508c03ae Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 17:15:11 -0700 Subject: [PATCH 02/19] prepare for protecting windows from POSIX-only term detection --- src/System/Terminal.hsc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc index ffde47b034..3e5efd97ce 100644 --- a/src/System/Terminal.hsc +++ b/src/System/Terminal.hsc @@ -1,4 +1,7 @@ +{-# LANGUAGE CPP #-} +#ifndef WINDOWS {-# LANGUAGE ForeignFunctionInterface #-} +#endif module System.Terminal ( getTerminalWidth @@ -6,4 +9,8 @@ module System.Terminal -- | Get the width, in columns, of the terminal if we can. getTerminalWidth :: IO (Maybe Int) +#ifndef WINDOWS getTerminalWidth = pure Nothing +#else +getTerminalWidth = pure Nothing +#endif From 0cf7ba9f5f17f7250a243ceb99d5f8869e28f852 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 17:26:23 -0700 Subject: [PATCH 03/19] create type to store C's winsize struct Just does the part we actually care about, the width in columns --- src/System/Terminal.hsc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc index 3e5efd97ce..f9025cd129 100644 --- a/src/System/Terminal.hsc +++ b/src/System/Terminal.hsc @@ -7,6 +7,22 @@ module System.Terminal ( getTerminalWidth ) where +import Foreign +import Foreign.C.Types + +#include +#include + +newtype WindowWidth = WindowWidth CUShort + deriving (Eq, Ord, Show) + +instance Storable WindowWidth where + sizeOf _ = (#size struct winsize) + alignment _ = (#alignment struct winsize) + peek p = WindowWidth <$> (#peek struct winsize, ws_col) p + poke p (WindowWidth w) = do + (#poke struct winsize, ws_col) p w + -- | Get the width, in columns, of the terminal if we can. getTerminalWidth :: IO (Maybe Int) #ifndef WINDOWS From 2910f35d383e29cbc1de3f5f9cde3d32252db90f Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 17:35:47 -0700 Subject: [PATCH 04/19] implement `getTerminalWidth` --- src/System/Terminal.hsc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc index f9025cd129..0bcfd2884d 100644 --- a/src/System/Terminal.hsc +++ b/src/System/Terminal.hsc @@ -23,10 +23,20 @@ instance Storable WindowWidth where poke p (WindowWidth w) = do (#poke struct winsize, ws_col) p w +foreign import ccall "sys/ioctl.h ioctl" + ioctl :: CInt -> CInt -> Ptr WindowWidth -> IO CInt + -- | Get the width, in columns, of the terminal if we can. getTerminalWidth :: IO (Maybe Int) #ifndef WINDOWS -getTerminalWidth = pure Nothing +getTerminalWidth = + alloca $ \p -> do + errno <- ioctl (#const STDOUT_FILENO) (#const TIOCGWINSZ) p + if errno < 0 + then return Nothing + else do + WindowWidth w <- peek p + return . Just . fromIntegral $ w #else getTerminalWidth = pure Nothing #endif From 72de4929d01cdf73489652d027fa6970fcbb5de4 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 17:36:41 -0700 Subject: [PATCH 05/19] wrap more stuff in windows check --- src/System/Terminal.hsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc index 0bcfd2884d..b6ed5f4d76 100644 --- a/src/System/Terminal.hsc +++ b/src/System/Terminal.hsc @@ -7,6 +7,7 @@ module System.Terminal ( getTerminalWidth ) where +#ifndef WINDOWS import Foreign import Foreign.C.Types @@ -25,6 +26,7 @@ instance Storable WindowWidth where foreign import ccall "sys/ioctl.h ioctl" ioctl :: CInt -> CInt -> Ptr WindowWidth -> IO CInt +#endif -- | Get the width, in columns, of the terminal if we can. getTerminalWidth :: IO (Maybe Int) From b2cb9467849fec156f07af58326bee7deff2f5c5 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Tue, 29 Aug 2017 20:38:31 -0700 Subject: [PATCH 06/19] require hsc2hs build tool --- stack.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/stack.cabal b/stack.cabal index 5738eea124..22fddf593e 100644 --- a/stack.cabal +++ b/stack.cabal @@ -268,6 +268,7 @@ library , store-core >= 0.4 && < 0.5 , annotated-wl-pprint , file-embed >= 0.0.10 + build-tools: hsc2hs >= 0.68 if os(windows) cpp-options: -DWINDOWS build-depends: Win32 From 2855cbc2a01c87673a98dd5769f4835f759ee001 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Wed, 30 Aug 2017 00:01:11 -0700 Subject: [PATCH 07/19] make low-level print funcs take terminal width as a param --- src/Stack/PrettyPrint.hs | 2 +- src/Text/PrettyPrint/Leijen/Extended.hs | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Stack/PrettyPrint.hs b/src/Stack/PrettyPrint.hs index e2a51db7a9..207e17e0a4 100644 --- a/src/Stack/PrettyPrint.hs +++ b/src/Stack/PrettyPrint.hs @@ -51,7 +51,7 @@ displayWithColor => a -> m T.Text displayWithColor x = do useAnsi <- liftM logUseColor $ view logOptionsL - return $ if useAnsi then displayAnsi x else displayPlain x + return $ (if useAnsi then displayAnsi else displayPlain) 120 x -- TODO: switch to using implicit callstacks once 7.8 support is dropped diff --git a/src/Text/PrettyPrint/Leijen/Extended.hs b/src/Text/PrettyPrint/Leijen/Extended.hs index d811e85ac2..e958b141a0 100644 --- a/src/Text/PrettyPrint/Leijen/Extended.hs +++ b/src/Text/PrettyPrint/Leijen/Extended.hs @@ -176,24 +176,24 @@ instance HasAnsiAnn AnsiAnn where instance HasAnsiAnn () where getAnsiAnn _ = mempty -displayPlain :: Display a => a -> T.Text -displayPlain = LT.toStrict . displayAnsiSimple . renderDefault . fmap (const mempty) . display +displayPlain :: Display a => Int -> a -> T.Text +displayPlain w = LT.toStrict . displayAnsiSimple . renderDefault w . fmap (const mempty) . display -- TODO: tweak these settings more? -- TODO: options for settings if this is released as a lib -renderDefault :: Doc a -> SimpleDoc a -renderDefault = renderPretty 1 120 +renderDefault :: Int -> Doc a -> SimpleDoc a +renderDefault = renderPretty 1 -displayAnsi :: (Display a, HasAnsiAnn (Ann a)) => a -> T.Text -displayAnsi = LT.toStrict . displayAnsiSimple . renderDefault . toAnsiDoc . display +displayAnsi :: (Display a, HasAnsiAnn (Ann a)) => Int -> a -> T.Text +displayAnsi w = LT.toStrict . displayAnsiSimple . renderDefault w . toAnsiDoc . display hDisplayAnsi :: (Display a, HasAnsiAnn (Ann a), MonadIO m) - => Handle -> a -> m () -hDisplayAnsi h x = liftIO $ do + => Handle -> Int -> a -> m () +hDisplayAnsi h w x = liftIO $ do useAnsi <- hSupportsANSI h - T.hPutStr h $ if useAnsi then displayAnsi x else displayPlain x + T.hPutStr h $ if useAnsi then displayAnsi w x else displayPlain w x displayAnsiSimple :: SimpleDoc AnsiAnn -> LT.Text displayAnsiSimple doc = From 54ad0f37cca4f01155ae72febade7f74f6cef186 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Wed, 30 Aug 2017 18:04:59 -0700 Subject: [PATCH 08/19] add a command-line option to set/override the terminal width --- src/Stack/Options/GlobalParser.hs | 5 +++++ src/Stack/Types/Config.hs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/Stack/Options/GlobalParser.hs b/src/Stack/Options/GlobalParser.hs index e329b56d88..0f96239412 100644 --- a/src/Stack/Options/GlobalParser.hs +++ b/src/Stack/Options/GlobalParser.hs @@ -40,6 +40,10 @@ globalOptsParser currentDir kind defLogLevel = completeWith ["always", "never", "auto"] <> help "Specify when to use color in output; WHEN is 'always', 'never', or 'auto'" <> hide)) <*> + optionalFirst (option auto + (long "terminal-width" <> + metavar "INT" <> + help "Specify the width of the terminal, used for pretty-print messages")) <*> optionalFirst (strOption (long "stack-yaml" <> @@ -64,6 +68,7 @@ globalOptsFromMonoid defaultTerminal GlobalOptsMonoid{..} = GlobalOpts , globalCompiler = getFirst globalMonoidCompiler , globalTerminal = fromFirst defaultTerminal globalMonoidTerminal , globalColorWhen = fromFirst ColorAuto globalMonoidColorWhen + , globalTermWidth = getFirst globalMonoidTermWidth , globalStackYaml = maybe SYLDefault SYLOverride $ getFirst globalMonoidStackYaml } initOptsParser :: Parser InitOpts diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index 51bd8576e4..1f233b984f 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -442,6 +442,7 @@ data GlobalOpts = GlobalOpts , globalCompiler :: !(Maybe (CompilerVersion 'CVWanted)) -- ^ Compiler override , globalTerminal :: !Bool -- ^ We're in a terminal? , globalColorWhen :: !ColorWhen -- ^ When to use ansi terminal colors + , globalTermWidth :: !(Maybe Int) -- ^ Terminal width override , globalStackYaml :: !(StackYamlLoc FilePath) -- ^ Override project stack.yaml } deriving (Show) @@ -465,6 +466,7 @@ data GlobalOptsMonoid = GlobalOptsMonoid , globalMonoidCompiler :: !(First (CompilerVersion 'CVWanted)) -- ^ Compiler override , globalMonoidTerminal :: !(First Bool) -- ^ We're in a terminal? , globalMonoidColorWhen :: !(First ColorWhen) -- ^ When to use ansi colors + , globalMonoidTermWidth :: !(First Int) -- ^ Terminal width override , globalMonoidStackYaml :: !(First FilePath) -- ^ Override project stack.yaml } deriving (Show, Generic) From 83a018e010e1420d65d1b3ffb746e0213aeee229 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Wed, 30 Aug 2017 23:15:55 -0700 Subject: [PATCH 09/19] add the term width stuff to LogOptions Includes actually querying the terminal width automatically when it's not overriden. --- src/Stack/Runners.hs | 1 + src/Stack/Types/Runner.hs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Stack/Runners.hs b/src/Stack/Runners.hs index 6628bf4215..b7711d91bc 100644 --- a/src/Stack/Runners.hs +++ b/src/Stack/Runners.hs @@ -214,6 +214,7 @@ withRunnerGlobal GlobalOpts{..} = withRunner globalTimeInLog globalTerminal globalColorWhen + globalTermWidth (isJust globalReExecVersion) withMiniConfigAndLock diff --git a/src/Stack/Types/Runner.hs b/src/Stack/Types/Runner.hs index bd5ec43725..8edac7cb47 100644 --- a/src/Stack/Types/Runner.hs +++ b/src/Stack/Types/Runner.hs @@ -45,6 +45,7 @@ import System.Console.ANSI import System.FilePath import System.IO import System.Log.FastLogger +import System.Terminal -- | Monadic environment. data Runner = Runner @@ -77,6 +78,7 @@ newtype Sticky = Sticky data LogOptions = LogOptions { logUseColor :: Bool + , logTermWidth :: Int , logUseUnicode :: Bool , logUseTime :: Bool , logMinLevel :: LogLevel @@ -243,19 +245,24 @@ withRunner :: MonadIO m -> Bool -- ^ use time? -> Bool -- ^ terminal? -> ColorWhen + -> Maybe Int -- ^ terminal width override -> Bool -- ^ reexec? -> (Runner -> m a) -> m a -withRunner logLevel useTime terminal colorWhen reExec inner = do +withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do useColor <- case colorWhen of ColorNever -> return False ColorAlways -> return True ColorAuto -> liftIO $ hSupportsANSI stderr + termWidth <- case widthOverride >>= checkWidth of + Nothing -> fromMaybe 100 <$> liftIO getTerminalWidth + Just w -> return w canUseUnicode <- liftIO getCanUseUnicode withSticky terminal $ \sticky -> inner Runner { runnerReExec = reExec , runnerLogOptions = LogOptions { logUseColor = useColor + , logTermWidth = termWidth , logUseUnicode = canUseUnicode , logUseTime = useTime , logMinLevel = logLevel @@ -264,6 +271,9 @@ withRunner logLevel useTime terminal colorWhen reExec inner = do , runnerTerminal = terminal , runnerSticky = sticky } + where checkWidth w + | w < 20 = Nothing + | otherwise = Just w -- | Taken from GHC: determine if we should use Unicode syntax getCanUseUnicode :: IO Bool From d95758c5b8961912f1ee20680c4ce3adede959f3 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Wed, 30 Aug 2017 23:17:16 -0700 Subject: [PATCH 10/19] replace terminal width numbers with named constants --- src/Stack/Constants.hs | 8 ++++++++ src/Stack/Types/Runner.hs | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs index 8f66db4e0f..b0a6a6bd31 100644 --- a/src/Stack/Constants.hs +++ b/src/Stack/Constants.hs @@ -28,6 +28,8 @@ module Stack.Constants ,platformVariantEnvVar ,compilerOptionsCabalFlag ,ghcColorForceFlag + ,minTerminalWidth + ,defaultTerminalWidth ) where @@ -216,3 +218,9 @@ compilerOptionsCabalFlag Ghcjs = "--ghcjs-options" ghcColorForceFlag :: String ghcColorForceFlag = "-fdiagnostics-color=always" + +minTerminalWidth :: Int +minTerminalWidth = 20 + +defaultTerminalWidth :: Int +defaultTerminalWidth = 100 diff --git a/src/Stack/Types/Runner.hs b/src/Stack/Types/Runner.hs index 8edac7cb47..9f39452500 100644 --- a/src/Stack/Types/Runner.hs +++ b/src/Stack/Types/Runner.hs @@ -41,6 +41,7 @@ import Language.Haskell.TH import Language.Haskell.TH.Syntax (lift) import Lens.Micro import Stack.Prelude hiding (lift) +import Stack.Constants import System.Console.ANSI import System.FilePath import System.IO @@ -255,7 +256,7 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do ColorAlways -> return True ColorAuto -> liftIO $ hSupportsANSI stderr termWidth <- case widthOverride >>= checkWidth of - Nothing -> fromMaybe 100 <$> liftIO getTerminalWidth + Nothing -> fromMaybe defaultTerminalWidth <$> liftIO getTerminalWidth Just w -> return w canUseUnicode <- liftIO getCanUseUnicode withSticky terminal $ \sticky -> inner Runner @@ -272,7 +273,7 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do , runnerSticky = sticky } where checkWidth w - | w < 20 = Nothing + | w < minTerminalWidth = Nothing | otherwise = Just w -- | Taken from GHC: determine if we should use Unicode syntax From a20048981acf2d2f5e8ae01bb35b8f25886ccf74 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Wed, 30 Aug 2017 23:33:22 -0700 Subject: [PATCH 11/19] use the terminal width when pretty-printing --- src/Stack/PrettyPrint.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stack/PrettyPrint.hs b/src/Stack/PrettyPrint.hs index 207e17e0a4..3b308f72a2 100644 --- a/src/Stack/PrettyPrint.hs +++ b/src/Stack/PrettyPrint.hs @@ -51,7 +51,8 @@ displayWithColor => a -> m T.Text displayWithColor x = do useAnsi <- liftM logUseColor $ view logOptionsL - return $ (if useAnsi then displayAnsi else displayPlain) 120 x + termWidth <- liftM logTermWidth $ view logOptionsL + return $ (if useAnsi then displayAnsi else displayPlain) termWidth x -- TODO: switch to using implicit callstacks once 7.8 support is dropped From 9d10d34e2d2e4ea03a15b6c2121f1e74ecd4b443 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 00:34:01 -0700 Subject: [PATCH 12/19] improve terminal-width min/max behavior - implement a maximum - clip to the range instead of just ignoring invalid values - actually check the detected width too, not just a user-supplied one --- src/Stack/Constants.hs | 4 ++++ src/Stack/Types/Runner.hs | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs index b0a6a6bd31..2f9c3b4367 100644 --- a/src/Stack/Constants.hs +++ b/src/Stack/Constants.hs @@ -29,6 +29,7 @@ module Stack.Constants ,compilerOptionsCabalFlag ,ghcColorForceFlag ,minTerminalWidth + ,maxTerminalWidth ,defaultTerminalWidth ) where @@ -222,5 +223,8 @@ ghcColorForceFlag = "-fdiagnostics-color=always" minTerminalWidth :: Int minTerminalWidth = 20 +maxTerminalWidth :: Int +maxTerminalWidth = 200 + defaultTerminalWidth :: Int defaultTerminalWidth = 100 diff --git a/src/Stack/Types/Runner.hs b/src/Stack/Types/Runner.hs index 9f39452500..7fefff1f1c 100644 --- a/src/Stack/Types/Runner.hs +++ b/src/Stack/Types/Runner.hs @@ -255,9 +255,9 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do ColorNever -> return False ColorAlways -> return True ColorAuto -> liftIO $ hSupportsANSI stderr - termWidth <- case widthOverride >>= checkWidth of - Nothing -> fromMaybe defaultTerminalWidth <$> liftIO getTerminalWidth - Just w -> return w + termWidth <- clipWidth <$> maybe (fromMaybe defaultTerminalWidth + <$> liftIO getTerminalWidth) + pure widthOverride canUseUnicode <- liftIO getCanUseUnicode withSticky terminal $ \sticky -> inner Runner { runnerReExec = reExec @@ -272,9 +272,10 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do , runnerTerminal = terminal , runnerSticky = sticky } - where checkWidth w - | w < minTerminalWidth = Nothing - | otherwise = Just w + where clipWidth w + | w < minTerminalWidth = minTerminalWidth + | w > maxTerminalWidth = maxTerminalWidth + | otherwise = w -- | Taken from GHC: determine if we should use Unicode syntax getCanUseUnicode :: IO Bool From cc94e9eca10fef5889ae008af39a38bdf707a953 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 00:35:01 -0700 Subject: [PATCH 13/19] use a more reasonable minimum terminal width --- src/Stack/Constants.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs index 2f9c3b4367..3cfc7cd0bc 100644 --- a/src/Stack/Constants.hs +++ b/src/Stack/Constants.hs @@ -221,7 +221,7 @@ ghcColorForceFlag :: String ghcColorForceFlag = "-fdiagnostics-color=always" minTerminalWidth :: Int -minTerminalWidth = 20 +minTerminalWidth = 40 maxTerminalWidth :: Int maxTerminalWidth = 200 From 0f607b3d0c2e7211281e6564bd4613f86c6b332b Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 02:04:47 -0700 Subject: [PATCH 14/19] fix test compilations due to terminal width --- src/test/Stack/ConfigSpec.hs | 2 +- src/test/Stack/NixSpec.hs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/Stack/ConfigSpec.hs b/src/test/Stack/ConfigSpec.hs index 576c862a03..4d6cd62502 100644 --- a/src/test/Stack/ConfigSpec.hs +++ b/src/test/Stack/ConfigSpec.hs @@ -76,7 +76,7 @@ spec = beforeAll setup $ do describe "loadConfig" $ do let loadConfig' inner = - withRunner logLevel True False ColorAuto False $ \runner -> do + withRunner logLevel True False ColorAuto Nothing False $ \runner -> do lc <- runRIO runner $ loadConfig mempty Nothing SYLDefault inner lc -- TODO(danburton): make sure parent dirs also don't have config file diff --git a/src/test/Stack/NixSpec.hs b/src/test/Stack/NixSpec.hs index 410cfb4b79..870ca9e3be 100644 --- a/src/test/Stack/NixSpec.hs +++ b/src/test/Stack/NixSpec.hs @@ -46,7 +46,7 @@ setup = unsetEnv "STACK_YAML" spec :: Spec spec = beforeAll setup $ do let loadConfig' cmdLineArgs = - withRunner LevelDebug True False ColorAuto False $ \runner -> + withRunner LevelDebug True False ColorAuto Nothing False $ \runner -> runRIO runner $ loadConfig cmdLineArgs Nothing SYLDefault inTempDir test = do currentDirectory <- getCurrentDirectory From baf9a6ba09cdb3351a77ccc80f43bc7c94ebd9c2 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 11:02:27 -0700 Subject: [PATCH 15/19] pin hsc2hs as an extra-dep Hopefully this will get it built automatically on appveyor when we need it. --- stack.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/stack.yaml b/stack.yaml index 42e341e260..edbb2335dd 100644 --- a/stack.yaml +++ b/stack.yaml @@ -24,3 +24,4 @@ extra-deps: - path-io-1.3.3 - extra-1.6 - monad-logger-0.3.25 +- hsc2hs-0.68.2 From 1d5a7bc2daec55ef3151ff34392b56d4c460c47d Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 11:30:30 -0700 Subject: [PATCH 16/19] manually force appveyor to install hsc2hs first --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index ed2d3fd4b3..2a4c76852e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,4 +20,5 @@ test_script: - stack setup > nul # The ugly echo "" hack is to avoid complaints about 0 being an invalid file # descriptor +- stack install hsc2hs - echo "" | stack --no-terminal test --jobs 1 From 43cd310a8b87bcd9e7a6b29b8ed470865046b387 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 13:39:34 -0700 Subject: [PATCH 17/19] stop trying to use hsc2hs on windows We're not actually using it on windows anyway, and it's causing problems on appveyor. --- appveyor.yml | 1 - src/Stack/Types/Runner.hs | 5 +++++ src/System/Terminal.hsc | 9 --------- stack.cabal | 4 ++-- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2a4c76852e..ed2d3fd4b3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,5 +20,4 @@ test_script: - stack setup > nul # The ugly echo "" hack is to avoid complaints about 0 being an invalid file # descriptor -- stack install hsc2hs - echo "" | stack --no-terminal test --jobs 1 diff --git a/src/Stack/Types/Runner.hs b/src/Stack/Types/Runner.hs index 7fefff1f1c..2bb74639f0 100644 --- a/src/Stack/Types/Runner.hs +++ b/src/Stack/Types/Runner.hs @@ -46,7 +46,9 @@ import System.Console.ANSI import System.FilePath import System.IO import System.Log.FastLogger +#ifndef WINDOWS import System.Terminal +#endif -- | Monadic environment. data Runner = Runner @@ -276,6 +278,9 @@ withRunner logLevel useTime terminal colorWhen widthOverride reExec inner = do | w < minTerminalWidth = minTerminalWidth | w > maxTerminalWidth = maxTerminalWidth | otherwise = w +#ifdef WINDOWS + getTerminalWidth = pure Nothing +#endif -- | Taken from GHC: determine if we should use Unicode syntax getCanUseUnicode :: IO Bool diff --git a/src/System/Terminal.hsc b/src/System/Terminal.hsc index b6ed5f4d76..3ca408d91c 100644 --- a/src/System/Terminal.hsc +++ b/src/System/Terminal.hsc @@ -1,13 +1,9 @@ -{-# LANGUAGE CPP #-} -#ifndef WINDOWS {-# LANGUAGE ForeignFunctionInterface #-} -#endif module System.Terminal ( getTerminalWidth ) where -#ifndef WINDOWS import Foreign import Foreign.C.Types @@ -26,11 +22,9 @@ instance Storable WindowWidth where foreign import ccall "sys/ioctl.h ioctl" ioctl :: CInt -> CInt -> Ptr WindowWidth -> IO CInt -#endif -- | Get the width, in columns, of the terminal if we can. getTerminalWidth :: IO (Maybe Int) -#ifndef WINDOWS getTerminalWidth = alloca $ \p -> do errno <- ioctl (#const STDOUT_FILENO) (#const TIOCGWINSZ) p @@ -39,6 +33,3 @@ getTerminalWidth = else do WindowWidth w <- peek p return . Just . fromIntegral $ w -#else -getTerminalWidth = pure Nothing -#endif diff --git a/stack.cabal b/stack.cabal index 22fddf593e..418be1b9fb 100644 --- a/stack.cabal +++ b/stack.cabal @@ -187,7 +187,6 @@ library System.Process.PagerEditor System.Process.Read System.Process.Run - System.Terminal other-modules: Hackage.Security.Client.Repository.HttpLib.HttpClient build-depends: Cabal >= 2.0 && < 2.1 , aeson (>= 1.0 && < 1.2) @@ -268,7 +267,6 @@ library , store-core >= 0.4 && < 0.5 , annotated-wl-pprint , file-embed >= 0.0.10 - build-tools: hsc2hs >= 0.68 if os(windows) cpp-options: -DWINDOWS build-depends: Win32 @@ -276,6 +274,8 @@ library build-depends: unix >= 2.7.0.1 , pid1 >= 0.1 && < 0.2 , bindings-uname >= 0.1 + build-tools: hsc2hs >= 0.68 + exposed-modules: System.Terminal default-language: Haskell2010 executable stack From c8c4f9499dab470041c55d6837f94a8e92b4f0fd Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 14:17:53 -0700 Subject: [PATCH 18/19] document some constants --- src/Stack/Constants.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Stack/Constants.hs b/src/Stack/Constants.hs index 3cfc7cd0bc..eb14e1477a 100644 --- a/src/Stack/Constants.hs +++ b/src/Stack/Constants.hs @@ -217,14 +217,20 @@ compilerOptionsCabalFlag :: WhichCompiler -> String compilerOptionsCabalFlag Ghc = "--ghc-options" compilerOptionsCabalFlag Ghcjs = "--ghcjs-options" +-- | The flag to pass to GHC when we want to force its output to be +-- colorized. ghcColorForceFlag :: String ghcColorForceFlag = "-fdiagnostics-color=always" +-- | The minimum allowed terminal width. Used for pretty-printing. minTerminalWidth :: Int minTerminalWidth = 40 +-- | The maximum allowed terminal width. Used for pretty-printing. maxTerminalWidth :: Int maxTerminalWidth = 200 +-- | The default terminal width. Used for pretty-printing when we can't +-- automatically detect it and when the user doesn't supply one. defaultTerminalWidth :: Int defaultTerminalWidth = 100 From e4ba9d986ee415186deeeed2c0073bfc183b7ebb Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Thu, 31 Aug 2017 14:42:52 -0700 Subject: [PATCH 19/19] add term-width changes to the changelog --- ChangeLog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 0ba781cda0..d0541843fa 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -39,6 +39,12 @@ Behavior changes: * Addition of `stack build --copy-compiler-tool`, to allow tools like intero to be installed globally for a particular compiler. [#2643](https://github.com/commercialhaskell/stack/issues/2643) +* Stack will now try to detect the width of the running terminal + (only on POSIX for the moment) and use that to better display + output messages. Work is ongoing, so some messages will not + be optimal yet. The terminal width can be overriden with the + new `--terminal-width` command-line option (this works even on + non-POSIX). Other enhancements: