Haskell 和 Brick 的 RGB 终端颜色
RGB Terminal Colors with Haskell and Brick
我知道 Brick and the VTY hackage do not support escape sequences. VTY 只支持 240 种颜色。
是否有任何解决方法可以使用真正的 RGB 颜色而不弄乱布局?
这是我做的一个例子,但是我无法正确设置边框:
module BrickTest where
import Brick (simpleMain, Widget, str)
import Brick.Widgets.Border (border)
import Text.Printf (printf)
main :: IO ()
main = simpleMain $ colorWidget (255, 0, 0)
type RGB = (Int, Int, Int)
colorWidget :: RGB -> Widget ()
colorWidget (r, g, b) = border $ str (prefix ++ "a" ++ postfix)
where
prefix = printf "\ESC[38;2;%d;%d;%dm" r g b
postfix = "\ESC[0m"
输出:
┌──────────────────┐
│a│
└──────────────────┘
我找到了解决方法。我设法实现了一个可以打印任何字符串的函数 zeroWidthStr
,并且 Brick 处理它时就好像它的宽度为 0。但我无法真正解释它在内部是如何工作的,而且它可能有一些其他的副作用。
module BrickTest where
import Brick (Widget, raw, simpleMain, str,
(<+>))
import Brick.Widgets.Border (border)
import Data.List (intercalate)
import Data.Text.Lazy (pack)
import Graphics.Vty (defAttr)
import Graphics.Vty.Image.Internal (Image (HorizText))
import Text.Printf (printf)
main :: IO ()
main = simpleMain $ colorWidget (255, 0, 0)
type RGB = (Int, Int, Int)
colorWidget :: RGB -> Widget ()
colorWidget (r, g, b) = border $ prefix <+> str "a" <+> postfix
where
prefix = zeroWidthStr $ printf "\ESC[38;2;%d;%d;%dm" r g b
postfix = zeroWidthStr $ "\ESC[0m"
zeroWidthStr :: String -> Widget ()
-- | workaround to print any string in terminal, and hackage Brick (vty) handles it as if it has width 0
zeroWidthStr str = raw image
where
image = HorizText defAttr (pack modStr) 0 0
modStr = str ++ repeatN "\ESC\ESCa" (length str)
repeatN :: String -> Int -> String
repeatN str n = intercalate "" $ take n $ repeat str
输出:
我知道 Brick and the VTY hackage do not support escape sequences. VTY 只支持 240 种颜色。
是否有任何解决方法可以使用真正的 RGB 颜色而不弄乱布局?
这是我做的一个例子,但是我无法正确设置边框:
module BrickTest where
import Brick (simpleMain, Widget, str)
import Brick.Widgets.Border (border)
import Text.Printf (printf)
main :: IO ()
main = simpleMain $ colorWidget (255, 0, 0)
type RGB = (Int, Int, Int)
colorWidget :: RGB -> Widget ()
colorWidget (r, g, b) = border $ str (prefix ++ "a" ++ postfix)
where
prefix = printf "\ESC[38;2;%d;%d;%dm" r g b
postfix = "\ESC[0m"
输出:
┌──────────────────┐
│a│
└──────────────────┘
我找到了解决方法。我设法实现了一个可以打印任何字符串的函数 zeroWidthStr
,并且 Brick 处理它时就好像它的宽度为 0。但我无法真正解释它在内部是如何工作的,而且它可能有一些其他的副作用。
module BrickTest where
import Brick (Widget, raw, simpleMain, str,
(<+>))
import Brick.Widgets.Border (border)
import Data.List (intercalate)
import Data.Text.Lazy (pack)
import Graphics.Vty (defAttr)
import Graphics.Vty.Image.Internal (Image (HorizText))
import Text.Printf (printf)
main :: IO ()
main = simpleMain $ colorWidget (255, 0, 0)
type RGB = (Int, Int, Int)
colorWidget :: RGB -> Widget ()
colorWidget (r, g, b) = border $ prefix <+> str "a" <+> postfix
where
prefix = zeroWidthStr $ printf "\ESC[38;2;%d;%d;%dm" r g b
postfix = zeroWidthStr $ "\ESC[0m"
zeroWidthStr :: String -> Widget ()
-- | workaround to print any string in terminal, and hackage Brick (vty) handles it as if it has width 0
zeroWidthStr str = raw image
where
image = HorizText defAttr (pack modStr) 0 0
modStr = str ++ repeatN "\ESC\ESCa" (length str)
repeatN :: String -> Int -> String
repeatN str n = intercalate "" $ take n $ repeat str
输出: