packages feed

terminal-size 0.2.1.0 → 0.3.4

raw patch · 9 files changed

Files

+ CHANGELOG.markdown view
@@ -0,0 +1,36 @@+0.3.4+=====++  * Provided `hSize` on Windows. (https://github.com/biegunka/terminal-size/pull/18)++0.3.3+=====++  * Fixed ioctl foreign import. (https://github.com/biegunka/terminal-size/pull/16)++  * `#alignment` is a hsc2hs built-in since some unspecified GHC 7.x. (https://github.com/biegunka/terminal-size/pull/12)++  * Captured possible `stty` stderr output with a pipe. (https://github.com/biegunka/terminal-size/pull/13)+++0.3.2.1+=======++  * GHC 7.2 support (https://github.com/biegunka/terminal-size/pull/9)++0.3.2+=====++  * Cygwin/MSYS support (https://github.com/biegunka/terminal-size/pull/8)++0.3.1+=====++  * `Typeable`, `Data`, `Generic`, and `Generic1` instances for `Window`.++0.3.0+=====++  * Windows support (https://github.com/biegunka/terminal-size/pull/4)++  * Added `Eq`, `Foldable` and `Traversable` instances for `Window`
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2013, Matvey Aksenov+Copyright (c) 2013-2015, Matvey Aksenov  All rights reserved. 
+ README.markdown view
@@ -0,0 +1,57 @@+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++Usage+-----++```+>>> 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/Common.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE DeriveTraversable #-}++#if __GLASGOW_HASKELL__ >= 702+#define LANGUAGE_DeriveGeneric+{-# LANGUAGE DeriveGeneric #-}+#endif++module System.Console.Terminal.Common+  ( Window(..)+  ) where++import Data.Data (Typeable, Data)++#if __GLASGOW_HASKELL__ < 710+import Data.Foldable (Foldable)+import Data.Traversable (Traversable)+#endif++#ifdef LANGUAGE_DeriveGeneric+import GHC.Generics+  ( Generic+#if __GLASGOW_HASKELL__ >= 706+  , Generic1+#endif+  )+#endif++-- | Terminal window width and height+data Window a = Window+  { height :: !a+  , width  :: !a+  } deriving+    ( Show, Eq, Read, Data, Typeable+    , Foldable, Functor, Traversable+#ifdef LANGUAGE_DeriveGeneric+    , Generic+#if __GLASGOW_HASKELL__ >= 706+    , Generic1+#endif+#endif+    )
+ src/System/Console/Terminal/Posix.hsc view
@@ -0,0 +1,65 @@+{-# LANGUAGE CApiFFI #-}++module System.Console.Terminal.Posix+  ( size, fdSize, hSize+  ) where++import System.Console.Terminal.Common+import Control.Exception (catch)+import Data.Typeable (cast)+import Foreign+import Foreign.C.Error+import Foreign.C.Types+import GHC.IO.FD (FD(FD, fdFD))+import GHC.IO.Handle.Internals (withHandle_)+import GHC.IO.Handle.Types (Handle, Handle__(Handle__, haDevice))+#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ < 706)+import Prelude hiding (catch)+#endif+import System.Posix.Types (Fd(Fd))++#include <sys/ioctl.h>+#include <unistd.h>++#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ < 800)+#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)+#endif++-- Interesting part of @struct winsize@+data CWin = CWin CUShort CUShort++instance Storable CWin where+  sizeOf _ = (#size struct winsize)+  alignment _ = (#alignment struct winsize)+  peek ptr = do+    row <- (#peek struct winsize, ws_row) ptr+    col <- (#peek struct winsize, ws_col) ptr+    return $ CWin row col+  poke ptr (CWin row col) = do+    (#poke struct winsize, ws_row) ptr row+    (#poke struct winsize, ws_col) ptr col+++fdSize :: Integral n => Fd -> IO (Maybe (Window n))+fdSize (Fd fd) = with (CWin 0 0) $ \ws -> do+  throwErrnoIfMinus1 "ioctl" $+    ioctl fd (#const TIOCGWINSZ) ws+  CWin row col <- peek ws+  return . Just $ Window (fromIntegral row) (fromIntegral col)+ `catch`+  handler+ where+  handler :: IOError -> IO (Maybe (Window h))+  handler _ = return Nothing++foreign import capi "sys/ioctl.h ioctl"+  ioctl :: CInt -> CULong -> Ptr CWin -> IO CInt++size :: Integral n => IO (Maybe (Window n))+size = fdSize (Fd (#const STDOUT_FILENO))++hSize :: Integral n => Handle -> IO (Maybe (Window n))+hSize h = withHandle_ "hSize" h $ \Handle__ { haDevice = dev } ->+  case cast dev of+    Nothing -> return Nothing+    Just FD { fdFD = fd } -> fdSize (Fd fd)
+ src/System/Console/Terminal/Size.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE CPP #-}+{- |+Get terminal window height and width without ncurses dependency++Based on answer by Andreas Hammar at <http://stackoverflow.com/a/12807521/972985>+-}+module System.Console.Terminal.Size+  ( Window(..)+  , size+#if !defined(mingw32_HOST_OS)+  , fdSize+#endif+  , hSize+  ) where++import System.Console.Terminal.Common+#if defined(mingw32_HOST_OS)+import qualified System.Console.Terminal.Windows as Host+#else+import qualified System.Console.Terminal.Posix as Host+import System.Posix.Types(Fd)+#endif+import System.IO(Handle)+++-- | Get terminal window width and height for @stdout@.+--+-- >>> import System.Console.Terminal.Size+-- >>> size+-- Just (Window {height = 60, width = 112})+size :: Integral n => IO (Maybe (Window n))+size = Host.size++#if !defined(mingw32_HOST_OS)+-- | /Not available on Windows:/+-- Get terminal window width and height for a specified file descriptor. If+-- it's not attached to a terminal then 'Nothing' is returned.+--+-- >>> import System.Console.Terminal.Size+-- >>> import System.Posix+-- >>> fdSize stdOutput+-- Just (Window {height = 56, width = 85})+-- >>> fd <- openFd "foo" ReadWrite (Just stdFileMode) defaultFileFlags+-- >>> fdSize fd+-- Nothing+fdSize :: Integral n => Fd -> IO (Maybe (Window n))+fdSize = Host.fdSize+#endif++-- | 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
− src/System/Console/Terminal/Size.hsc
@@ -1,99 +0,0 @@-{- |-Get terminal window height and width without ncurses dependency--Only tested to work on GNU/Linux systems--Based on answer by Andreas Hammar at <http://stackoverflow.com/a/12807521/972985>--}-module System.Console.Terminal.Size-  ( Window(..), size, fdSize, hSize-  ) where--import Control.Exception (catch)-import Data.Typeable (cast)-import Foreign-import Foreign.C.Error-import Foreign.C.Types-import GHC.IO.FD (FD(FD, fdFD))-import GHC.IO.Handle.Internals (withHandle_)-import GHC.IO.Handle.Types (Handle, Handle__(Handle__, haDevice))-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ < 706)-import Prelude hiding (catch)-#endif-import System.Posix.Types (Fd(Fd))--#include <sys/ioctl.h>-#include <unistd.h>---#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)----- Interesting part of @struct winsize@-data CWin = CWin CUShort CUShort--instance Storable CWin where-  sizeOf _ = (#size struct winsize)-  alignment _ = (#alignment struct winsize)-  peek ptr = do-    row <- (#peek struct winsize, ws_row) ptr-    col <- (#peek struct winsize, ws_col) ptr-    return $ CWin row col-  poke ptr (CWin row col) = do-    (#poke struct winsize, ws_row) ptr row-    (#poke struct winsize, ws_col) ptr col----- | Terminal window width and height-data Window a = Window-  { height :: !a-  , width  :: !a-  } deriving (Show, Read)--instance Functor Window where-  fmap f (Window { height = h, width = w }) = Window { height = f h, width = f w }---- | Get terminal window width and height for a specified file descriptor. If--- it's not attached to a terminal then 'Nothing' is returned.------ >>> import System.Console.Terminal.Size--- >>> import System.Posix--- >>> fdSize stdOutput--- Just (Window {height = 56, width = 85})--- >>> fd <- openFd "foo" ReadWrite (Just stdFileMode) defaultFileFlags--- >>> fdSize fd--- Nothing-fdSize :: Integral n => Fd -> IO (Maybe (Window n))-fdSize (Fd fd) = with (CWin 0 0) $ \ws -> do-  throwErrnoIfMinus1 "ioctl" $-    ioctl fd (#const TIOCGWINSZ) ws-  CWin row col <- peek ws-  return . Just $ Window (fromIntegral row) (fromIntegral col)- `catch`-  handler- where-  handler :: IOError -> IO (Maybe (Window h))-  handler _ = return Nothing--foreign import ccall "sys/ioctl.h ioctl"-  ioctl :: CInt -> CInt -> Ptr CWin -> IO CInt---- | Get terminal window width and height for @stdout@.------ >>> import System.Console.Terminal.Size--- >>> size--- Just (Window {height = 60, width = 112})-size :: Integral n => IO (Maybe (Window n))-size = fdSize (Fd (#const STDOUT_FILENO))---- | Same as 'fdSize', but takes 'Handle' instead of 'Fd' (file descriptor).------ >>> 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 h = withHandle_ "hSize" h $ \Handle__ { haDevice = dev } ->-  case cast dev of-    Nothing -> return Nothing-    Just FD { fdFD = fd } -> fdSize (Fd fd)
+ src/System/Console/Terminal/Windows.hs view
@@ -0,0 +1,48 @@+module System.Console.Terminal.Windows(size, hSize) where++import System.Console.Terminal.Common++import System.Exit+import System.IO+import System.IO.Error (catchIOError)+import System.Process+import System.Win32.Console+  ( CONSOLE_SCREEN_BUFFER_INFO(srWindow)+  , SMALL_RECT(..)+  , getConsoleScreenBufferInfo+  )+import System.Win32.Types (HANDLE, withHandleToHANDLE)++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++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,10 +1,8 @@ name:                terminal-size-version:             0.2.1.0+version:             0.3.4 synopsis:            Get terminal window height and width description:-  Get terminal window height and width without ncurses dependency-  .-  Only tested to work on GNU/Linux systems+  Get terminal window height and width without ncurses dependency. license:             BSD3 license-file:        LICENSE author:              Andreas Hammar, Matvey Aksenov@@ -12,16 +10,49 @@ category:            System build-type:          Simple cabal-version:       >= 1.10--library-  default-language:  Haskell2010-  build-depends:     base >= 4 && < 5-  build-tools:       hsc2hs-  hs-source-dirs:    src-  exposed-modules:   System.Console.Terminal.Size-  ghc-options:       -Wall-                     -fno-warn-unused-do-bind+extra-source-files:+  README.markdown+  CHANGELOG.markdown  source-repository head   type:     git   location: https://github.com/biegunka/terminal-size++source-repository this+  type:     git+  location: https://github.com/biegunka/terminal-size+  tag:      0.3.4++library+  default-language:+    Haskell2010++  build-depends:+    base >= 4 && < 5+  if impl(ghc >= 7.2 && < 7.6)+     build-depends:+       ghc-prim+  if os(windows)+     build-depends:+       process,+       Win32 >= 2.13.2.0 && < 2.14++  build-tools:+    hsc2hs+  hs-source-dirs:+    src+  exposed-modules:+    System.Console.Terminal.Size++  other-modules:+    System.Console.Terminal.Common+  if os(Windows)+    other-modules:+      System.Console.Terminal.Windows+  else+    other-modules:+      System.Console.Terminal.Posix++  ghc-options:+    -Wall+    -fno-warn-unused-do-bind