Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有Haskell和Brick的RGB端子颜色_Haskell_Terminal_Rgb_Tui - Fatal编程技术网

带有Haskell和Brick的RGB端子颜色

带有Haskell和Brick的RGB端子颜色,haskell,terminal,rgb,tui,Haskell,Terminal,Rgb,Tui,我知道和黑客不支持转义序列。仅支持240种颜色 是否有任何解决办法,以使用真正的RGB颜色,而不是混乱的布局 这是我举的一个例子,但我无法正确地确定边界: 模块砖块测试,其中 导入Brick(simpleMain、Widget、str) 导入Brick.Widgets.Border(边框) 导入Text.Printf(Printf) main::IO() main=simpleMain$colorWidget(255,0,0) 类型RGB=(Int,Int,Int) colorWidget::R

我知道和黑客不支持转义序列。仅支持240种颜色

是否有任何解决办法,以使用真正的RGB颜色,而不是混乱的布局

这是我举的一个例子,但我无法正确地确定边界:

模块砖块测试,其中
导入Brick(simpleMain、Widget、str)
导入Brick.Widgets.Border(边框)
导入Text.Printf(Printf)
main::IO()
main=simpleMain$colorWidget(255,0,0)
类型RGB=(Int,Int,Int)
colorWidget::RGB->Widget()
colorWidget(r,g,b)=边框$str(前缀++“a”++后缀)
哪里
前缀=printf“\ESC[38;2;%d;%d;%dm”r g b
后缀=“\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(Widget、raw、simpleMain、str、,
())
导入Brick.Widgets.Border(边框)
导入数据列表(插入)
导入Data.Text.Lazy(包)
导入图形.Vty(defAttr)
导入Graphics.Vty.Image.Internal(图像(水平文本))
导入Text.Printf(Printf)
main::IO()
main=simpleMain$colorWidget(255,0,0)
类型RGB=(Int,Int,Int)
colorWidget::RGB->Widget()
colorWidget(r,g,b)=边框$prefix str“a”后缀
哪里
前缀=zeroWidthStr$printf“\ESC[38;2;%d;%d;%dm”r g b
后缀=zeroWidthStr$“\ESC[0m”
zeroWidthStr::字符串->小部件()
--|在终端中打印任何字符串的变通方法,hackage Brick(vty)将其处理为宽度为0
zeroWidthStr=原始图像
哪里
image=HorizText defAttr(pack modStr)0
modStr=str++repeatN“\ESC\ESCa”(长度str)
repeatN::String->Int->String
repeatN str n=插入“$take n$repeat str”
输出:

┌──────────────────┐
│a│
└──────────────────┘

Brick支持ANSI终端转义码,也支持Vty:(这在具有的Brick中使用)。ISO颜色完全是用来摆脱程序员自己指定ANSI终端转义序列的。@WillemVanOnsem但只支持240种颜色,而不是大多数现代终端应用程序支持的256^3种颜色。当您可以添加自己的转义码时,您可以告诉终端执行其支持的任何操作。@Carl escape代码可以插入,但它总是会弄乱布局。因为上面提到的黑客不支持转义序列。这就是我试图找到解决方法的原因。我认为你可以使用
raw
HorizText
,但不要使用
modStr
之类的东西,而是使用
HorizText-defAttr(pack-str)outputWidth charWidth
其中
str
包含转义序列,但是
outputWidth
charWidth
是从
Strip
中剥离转义序列计算出来的,使用例如
stripEscapes=Graphics.Vty.Image.safe\u wcswidth.Data.Text.unpack.Data.String.AnsiEscapeCodes.Strip.Text.stripAnsiEscapeCodes.Data.Text.pack
。注意
charWidth
应为≥1.我认为这在语义上也更合适,因为您真正要做的就是设置每个可见字符的显示宽度。对不起,这应该是
safe\wcswidth.stripeescapes
where
stripeescapes=…
@JonPurdy您的意思是这样的吗?
outputWidth=stripeescapes str;charWidth=outputWidth;stripeescapes=safeWcswidth.unpack.stripAnsiEscapeCodes.pack
我的意思是
stripeescapes=unpack.stripAnsiEscapeCodes.pack
(或者您可以添加一个不必经过
Text
)和
outputWidth=safe\u wcswidth(stripes str)的版本
。当然,您可以使用函数剥离转义符并计算宽度,然后将其称为其他函数,如
getOutputWidth