获取终端宽度Haskell [英] Get Terminal width Haskell

查看:258
本文介绍了获取终端宽度Haskell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取终端在Haskell中的宽度?

How to get the width of the terminal in Haskell?

我尝试的东西

System.Posix.IOCtl (could not figure out how to get it to work) 

这只能工作unix。

感谢

推荐答案

如果你不想依赖ncurses,根据接受的答案,使用FFI的适当 ioctl()请求取得终端宽度在C?

If you don't want a dependency on ncurses, here's a wrapper of the appropriate ioctl() request using the FFI, based on the accepted answer of Getting terminal width in C?

TermSize.hsc

{-# LANGUAGE ForeignFunctionInterface #-}

module TermSize (getTermSize) where

import Foreign
import Foreign.C.Error
import Foreign.C.Types

#include <sys/ioctl.h>
#include <unistd.h>

-- Trick for calculating alignment of a type, taken from
-- http://www.haskell.org/haskellwiki/FFICookBook#Working_with_structs
#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)

-- The ws_xpixel and ws_ypixel fields are unused, so I've omitted them here.
data WinSize = WinSize { wsRow, wsCol :: CUShort }

instance Storable WinSize 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 $ WinSize row col
  poke ptr (WinSize row col) = do
    (#poke struct winsize, ws_row) ptr row
    (#poke struct winsize, ws_col) ptr col

foreign import ccall "sys/ioctl.h ioctl"
  ioctl :: CInt -> CInt -> Ptr WinSize -> IO CInt

-- | Return current number of (rows, columns) of the terminal.
getTermSize :: IO (Int, Int)
getTermSize = 
  with (WinSize 0 0) $ \ws -> do
    throwErrnoIfMinus1 "ioctl" $
      ioctl (#const STDOUT_FILENO) (#const TIOCGWINSZ) ws
    WinSize row col <- peek ws
    return (fromIntegral row, fromIntegral col)

这使用 hsc2hs 预处理器,以根据C标头找出正确的常数和偏移量,而不是对它们进行硬编码。

This uses the hsc2hs preprocessor to figure out the correct constants and offsets based on the C headers rather than hardcoding them. I think it's packaged with either GHC or the Haskell Platform, so chances are you'll have it already.

如果你使用Cabal,你可以添加 TermSize.hs 到您的 .cabal 文件,它会自动知道如何从 TermSize生成它。 hsc 。否则,您可以手动运行 hsc2hs TermSize.hsc 以生成一个 .hs 文件,然后您可以使用GHC编译。

If you're using Cabal, you can add TermSize.hs to your .cabal file and it'll automatically know how to generate it from TermSize.hsc. Otherwise, you can run hsc2hs TermSize.hsc manually to generate a .hs file which you can then compile with GHC.

这篇关于获取终端宽度Haskell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆