英文:
Coloured terminal output not working as it should using the termcolor crate
问题
我一直在使用colorterm crate进行实验。我在VS Code中编写了一个简单的程序:
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor, BufferWriter};
use std::io::Write;
fn main() {
let quote: &str = "A donkey, a donkey, my kingdom for a donkey!";
let colors: Vec<(u8, u8, u8)> = vec![
(50, 168, 82),
(255, 129, 3),
(32, 72, 145),
(237, 226, 17),
(48, 176, 161),
(166, 28, 111),
(230, 18, 36)
];
let mut stdout = StandardStream::stdout(ColorChoice::Always);
for color in colors {
stdout.set_color(ColorSpec::new().set_fg(
Some(Color::Rgb(
color.0,
color.1,
color.2
))
))
.expect("Failed to set color");
write!(&mut stdout, "{}", quote).expect("failed to write");
println!();
}
}
在VS集成终端中测试输出一切正常
然而,当我在我的操作系统终端上测试它(MacOS自带的Terminal.app)时,我得到了以下结果:
结果颜色不正确,在一个实例中是斜体,或者根本没有颜色(嗯,我想是灰色吧)。
我认为这可能不是crate的问题,而是与我的终端配置有关?
我在普通终端中使用Mac OSX
和zsh shell
,没有花哨的配置,但通常我使用oh my zsh
(我尝试在没有oh my zsh的shell上运行它,结果相同)。我的第一感觉是与文档中提到的环境变量有关这里,然而我的TERM设置为xterm-256color。我认为答案可能在VS Code集成终端(肯定有什么对吧?)和普通zsh终端之间的配置差异中。如果有人对这两者之间的差异更熟悉,或者是否遇到过类似的crate问题,或者我完全错过了什么,我将感激不已。
英文:
I have been playing around with the colorterm crate. I've written a simple program in VS code here:
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor, BufferWriter};
use std::io::Write;
fn main() {
let quote: &str = "A donkey, a donkey, my kingdom for a donkey!";
let colors: Vec<(u8, u8, u8)> = vec![
(50, 168, 82),
(255, 129, 3),
(32, 72, 145),
(237, 226, 17),
(48, 176, 161),
(166, 28, 111),
(230, 18, 36)
];
let mut stdout = StandardStream::stdout(ColorChoice::Always);
for color in colors {
stdout.set_color(ColorSpec::new().set_fg(
Some(Color::Rgb(
color.0,
color.1,
color.2
))
))
.expect("Failed to set color");
write!(&mut stdout, "{}", quote).expect("failed to write");
println!();
}
}
Everything was going fine testing the output in the VS integrated terminal
However, when I test it on my OS terminal (the Terminal.app that comes with MacOS) I get the following:
The results have the incorrect colours, are italicised in one instance or have no color (well grey I suppose) at all.
I'm thinking this is less a problem with the crate and more with my terminal config?
I use Mac OSX
with a zsh shell
for my normal terminal, no fancy configs but I do use oh my zsh
normally (I tried this on a shell without oh my zsh and got the same result). My first feeling was that it was something to do with the environment variable mentioned in the docs here however I've got TERM set to xterm-256color. I think the answer may lay in the configuration difference between the VS code integrated terminal (there must be something right?) and the vanilla zsh terminal. If anyone is more familiar with the differences between the two, or if you have encountered any similar problems with the crate, or I am missing something entirely here I would be grateful for some help.
答案1
得分: 0
以下是翻译好的部分:
"Ok, just for completeness I managed to find the answer to this with some digging. The vanilla Terminal.app doesn't support truecolor; checking COLORTERM variables for each terminal (terminal.app, vs code intergrated, and iterm2) clarified this. For terminals that don't support truecolor we can convert our rbg values into a single u8 ansi256 value (for conversion I used this library) and use the appropriate variation of the Color enum to output our coloured content like so:
...
println!("{}", val);
let mut stdout = StandardStream::stdout(ColorChoice::Always);
for color in colors {
let ansi_val: u8 = rgb_to_ansi256(color.0, color.1, color.2);
stdout.set_color(ColorSpec::new().set_fg(
Some(Color::Ansi256(ansi_val))
))
.expect("Failed to set color");
write!(&mut stdout, "{}", quote).expect("failed to write");
println!();
}
希望这有所帮助。
英文:
Ok, just for completeness I managed to find the answer to this with some digging. The vanilla Terminal.app doesn't support truecolor; checking COLORTERM variables for each terminal (terminal.app, vs code intergrated, and iterm2) clarified this. For terminals that don't support truecolor we can convert our rbg values into a single u8 ansi256 value (for conversion I used this library) and use the appropriate variation of the Color enum to output our coloured content like so:
...
println!("{}", val);
let mut stdout = StandardStream::stdout(ColorChoice::Always);
for color in colors {
let ansi_val: u8 = rgb_to_ansi256(color.0, color.1, color.2);
stdout.set_color(ColorSpec::new().set_fg(
Some(Color::Ansi256(ansi_val))
))
.expect("Failed to set color");
write!(&mut stdout, "{}", quote).expect("failed to write");
println!();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论