on c384656 help sign in
vty/src/Graphics/Text/Width.hs
65 lines 2.0 kB history raw
1-- Copyright 2009 Corey O'Connor
2{-# OPTIONS_GHC -D_XOPEN_SOURCE #-}
3{-# LANGUAGE ForeignFunctionInterface #-}
4module Graphics.Text.Width
5 ( wcwidth
6 , wcswidth
7 , wctwidth
8 , wctlwidth
9 , safeWcwidth
10 , safeWcswidth
11 , safeWctwidth
12 , safeWctlwidth
13 )
14where
16import Data.List (foldl')
17import qualified Data.Text as T
18import qualified Data.Text.Lazy as TL
20foreign import ccall unsafe "vty_mk_wcwidth" wcwidth :: Char -> Int
22wcswidth :: String -> Int
23wcswidth = foldl' (\l c -> wcwidth c + l) 0
24{-# INLINE [1] wcswidth #-}
26wctwidth :: T.Text -> Int
27wctwidth = T.foldl' (\l c -> wcwidth c + l) 0
28{-# INLINE [1] wctwidth #-}
30wctlwidth :: TL.Text -> Int
31wctlwidth = TL.foldl' (\l c -> wcwidth c + l) 0
32{-# INLINE [1] wctlwidth #-}
34{-# RULES
35"wcswidth/unpack" forall x. wcswidth (T.unpack x) = wctwidth x
36"wcswidth/lazy-unpack" forall x. wcswidth (TL.unpack x) = wctlwidth x
37 #-}
39-- XXX: Characters with unknown widths occupy 1 column?
40--
41-- Not sure if this is actually correct. I presume there is a
42-- replacement character that is output by the terminal instead of the
43-- character and this replacement character is 1 column wide. If this is
44-- not true for all terminals then a per-terminal replacement character
45-- width needs to be implemented.
47-- | Returns the display width of a character. Assumes all characters
48-- with unknown widths are 0 width.
49safeWcwidth :: Char -> Int
50safeWcwidth = max 0 . wcwidth
52-- | Returns the display width of a string. Assumes all characters with
53-- unknown widths are 0 width.
54safeWcswidth :: String -> Int
55safeWcswidth = foldl' (\l c -> safeWcwidth c + l) 0
57-- | Returns the display width of a text. Assumes all characters with
58-- unknown widths are 0 width.
59safeWctwidth :: T.Text -> Int
60safeWctwidth = T.foldl' (\l c -> safeWcwidth c + l) 0
62-- | Returns the display width of a lazy text. Assumes all characters
63-- with unknown widths are 0 width.
64safeWctlwidth :: TL.Text -> Int
65safeWctlwidth = TL.foldl' (\l c -> safeWcwidth c + l) 0