-- Copyright 2009 Corey O'Connor {-# OPTIONS_GHC -D_XOPEN_SOURCE #-} {-# LANGUAGE ForeignFunctionInterface #-} -- | This module provides functions to measure the terminal column width -- of characters and strings. -- -- The functions provided in this module all ultimately make calls to -- the C implementation in @cbits/mk_wcwidth.c@. That code manages some -- global state that carries a table of Unicode character widths. For -- more details, see 'Graphics.Vty.UnicodeWidthTable.Install', the C -- code, and the "Multi-Column Character Support" section of the project -- @README@. module Graphics.Text.Width ( wcwidth , wcswidth , wctwidth , wctlwidth , safeWcwidth , safeWcswidth , safeWctwidth , safeWctlwidth ) where import Data.List (foldl') import qualified Data.Text as T import qualified Data.Text.Lazy as TL foreign import ccall unsafe "vty_mk_wcwidth" wcwidth :: Char -> Int wcswidth :: String -> Int wcswidth = foldl' (\l c -> wcwidth c + l) 0 {-# INLINE [1] wcswidth #-} wctwidth :: T.Text -> Int wctwidth = T.foldl' (\l c -> wcwidth c + l) 0 wctlwidth :: TL.Text -> Int wctlwidth = TL.foldl' (\l c -> wcwidth c + l) 0 {-# RULES "wcswidth/unpack" forall x. wcswidth (T.unpack x) = wctwidth x "wcswidth/lazy-unpack" forall x. wcswidth (TL.unpack x) = wctlwidth x #-} -- | Returns the display width of a character. Assumes all characters -- with unknown widths are 0 width. safeWcwidth :: Char -> Int safeWcwidth = max 0 . wcwidth -- | Returns the display width of a string. Assumes all characters with -- unknown widths are 0 width. safeWcswidth :: String -> Int safeWcswidth = foldl' (\l c -> safeWcwidth c + l) 0 -- | Returns the display width of a text. Assumes all characters with -- unknown widths are 0 width. safeWctwidth :: T.Text -> Int safeWctwidth = T.foldl' (\l c -> safeWcwidth c + l) 0 -- | Returns the display width of a lazy text. Assumes all characters -- with unknown widths are 0 width. safeWctlwidth :: TL.Text -> Int safeWctlwidth = TL.foldl' (\l c -> safeWcwidth c + l) 0