packages feed

terminal-size 0.3.3 → 0.3.4

raw patch · 5 files changed

+98/−63 lines, 5 filesdep +Win32

Dependencies added: Win32

Files

CHANGELOG.markdown view
@@ -1,3 +1,8 @@+0.3.4+=====++  * Provided `hSize` on Windows. (https://github.com/biegunka/terminal-size/pull/18)+ 0.3.3 ===== 
README.markdown view
@@ -1,7 +1,7 @@ terminal-size ============= -[![Hackage](https://budueba.com/hackage/terminal-size)](https://hackage.haskell.org/package/terminal-size)+[![Hackage](https://img.shields.io/hackage/v/terminal-size.svg?style=flat)](https://hackage.haskell.org/package/terminal-size) [![Build Status](https://travis-ci.org/biegunka/terminal-size.png)](https://travis-ci.org/biegunka/terminal-size)  Get terminal window width and height@@ -13,4 +13,45 @@ >>> import System.Console.Terminal.Size >>> size Just (Window {height = 60, width = 112})+```++Test+----++Compile test.hs and run it in a terminal. Here is what I get on Linux:++```+> ghc test.hs+> ./test+With redirected stdin+  hSize stdin = Nothing+  hSize stdout = Just (Window {height = 19, width = 87})+  hSize stderr = Just (Window {height = 19, width = 87})+With redirected stdout+  hSize stdin = Just (Window {height = 19, width = 87})+  hSize stdout = Nothing+  hSize stderr = Just (Window {height = 19, width = 87})+With redirected stderr+  hSize stdin = Just (Window {height = 19, width = 87})+  hSize stdout = Just (Window {height = 19, width = 87})+  hSize stderr = Nothing+```++On MINGW/MSYS the output is the same.++On Windows with cmd.exe I get++```+With redirected stdin+  hSize stdin = Nothing+  hSize stdout = Just (Window {height = 40, width = 164})+  hSize stderr = Just (Window {height = 40, width = 164})+With redirected stdout+  hSize stdin = Nothing+  hSize stdout = Nothing+  hSize stderr = Just (Window {height = 40, width = 164})+With redirected stderr+  hSize stdin = Nothing+  hSize stdout = Just (Window {height = 40, width = 164})+  hSize stderr = Nothing ```
src/System/Console/Terminal/Size.hs view
@@ -9,8 +9,8 @@   , size #if !defined(mingw32_HOST_OS)   , fdSize-  , hSize #endif+  , hSize   ) where  import System.Console.Terminal.Common@@ -19,8 +19,8 @@ #else import qualified System.Console.Terminal.Posix as Host import System.Posix.Types(Fd)-import System.IO(Handle) #endif+import System.IO(Handle)   -- | Get terminal window width and height for @stdout@.@@ -45,14 +45,17 @@ -- Nothing fdSize :: Integral n => Fd -> IO (Maybe (Window n)) fdSize = Host.fdSize+#endif --- | /Not available on Windows:/---   Same as 'fdSize', but takes 'Handle' instead of 'Fd' (file descriptor).+-- | Same as 'fdSize', but takes 'Handle' instead of 'Fd' (file descriptor). --+-- Note that on Windows with shells that use the native console API (cmd.exe,+-- PowerShell) this works only for output handles like 'stdout' and 'stderr';+-- for input handles like 'stdin' it always returns 'Nothing'.+-- -- >>> import System.Console.Terminal.Size -- >>> import System.IO -- >>> hSize stdout -- Just (Window {height = 56, width = 85}) hSize :: Integral n => Handle -> IO (Maybe (Window n)) hSize = Host.hSize-#endif
src/System/Console/Terminal/Windows.hs view
@@ -1,63 +1,48 @@--module System.Console.Terminal.Windows(size) where+module System.Console.Terminal.Windows(size, hSize) where  import System.Console.Terminal.Common -import Control.Monad-import Data.Word-import Foreign.Ptr-import Foreign.Storable-import Foreign.Marshal.Alloc import System.Exit import System.IO+import System.IO.Error (catchIOError) import System.Process--type HANDLE = Ptr ()--data CONSOLE_SCREEN_BUFFER_INFO--sizeCONSOLE_SCREEN_BUFFER_INFO :: Int-sizeCONSOLE_SCREEN_BUFFER_INFO = 22--posCONSOLE_SCREEN_BUFFER_INFO_srWindow :: Int-posCONSOLE_SCREEN_BUFFER_INFO_srWindow = 10 -- 4 x Word16 Left,Top,Right,Bottom--c_STD_OUTPUT_HANDLE :: Word32-c_STD_OUTPUT_HANDLE = -11--foreign import stdcall unsafe "windows.h GetConsoleScreenBufferInfo"-    c_GetConsoleScreenBufferInfo :: HANDLE -> Ptr CONSOLE_SCREEN_BUFFER_INFO -> IO Bool+import System.Win32.Console+  ( CONSOLE_SCREEN_BUFFER_INFO(srWindow)+  , SMALL_RECT(..)+  , getConsoleScreenBufferInfo+  )+import System.Win32.Types (HANDLE, withHandleToHANDLE) -foreign import stdcall unsafe "windows.h GetStdHandle"-    c_GetStdHandle :: Word32 -> IO HANDLE+size :: Integral n => IO (Maybe (Window n))+size = hSize stdout +hSize :: Integral n => Handle -> IO (Maybe (Window n))+hSize hdl =+    withHandleToHANDLE hdl nativeSize+    `catchIOError` \_ -> do+        -- Fallback to use for Cygwin or MSYS+        let stty = (shell "stty size") {+              std_in  = UseHandle hdl+            , std_out = CreatePipe+            , std_err = CreatePipe+            }+        (_, mbStdout, _, rStty) <- createProcess stty+        exStty <- waitForProcess rStty+        case exStty of+            ExitFailure _ -> return Nothing+            ExitSuccess ->+                maybe (return Nothing)+                      (\out -> do+                          sizeStr <- hGetContents out+                          let [r, c] = map read $ words sizeStr :: [Int]+                          return $ Just $ Window (fromIntegral r) (fromIntegral c)+                      )+                      mbStdout -size :: Integral n => IO (Maybe (Window n))-size = do-    hdl <- c_GetStdHandle c_STD_OUTPUT_HANDLE-    allocaBytes sizeCONSOLE_SCREEN_BUFFER_INFO $ \p -> do-        b <- c_GetConsoleScreenBufferInfo hdl p-        if not b-            then do -- This could happen on Cygwin or MSYS-                let stty = (shell "stty size") {-                      std_in  = UseHandle stdin-                    , std_out = CreatePipe-                    , std_err = CreatePipe-                    }-                (_, mbStdout, _, rStty) <- createProcess stty-                exStty <- waitForProcess rStty-                case exStty of-                    ExitFailure _ -> return Nothing-                    ExitSuccess ->-                        maybe (return Nothing)-                              (\hSize -> do-                                  sizeStr <- hGetContents hSize-                                  let [r, c] = map read $ words sizeStr :: [Int]-                                  return $ Just $ Window (fromIntegral r) (fromIntegral c)-                              )-                              mbStdout-            else do-                [left,top,right,bottom] <- forM [0..3] $ \i -> do-                    v <- peekByteOff p ((i*2) + posCONSOLE_SCREEN_BUFFER_INFO_srWindow)-                    return $ fromIntegral (v :: Word16)-                return $ Just $ Window (1+bottom-top) (1+right-left)+nativeSize :: Integral n => HANDLE -> IO (Maybe (Window n))+nativeSize hdl = do+    rect <- srWindow <$> getConsoleScreenBufferInfo hdl+    return $ Just $ Window+        { height = fromIntegral (1 + bottomPos rect - topPos rect)+        , width = fromIntegral (1 + rightPos rect - leftPos rect)+        }
terminal-size.cabal view
@@ -1,5 +1,5 @@ name:                terminal-size-version:             0.3.3+version:             0.3.4 synopsis:            Get terminal window height and width description:   Get terminal window height and width without ncurses dependency.@@ -21,7 +21,7 @@ source-repository this   type:     git   location: https://github.com/biegunka/terminal-size-  tag:      0.3.3+  tag:      0.3.4  library   default-language:@@ -34,7 +34,8 @@        ghc-prim   if os(windows)      build-depends:-       process+       process,+       Win32 >= 2.13.2.0 && < 2.14    build-tools:     hsc2hs