Function syntect_tui::into_span

source ·
pub fn into_span<'a>(
    (style, content): (Style, &'a str)
) -> Result<Span<'a>, SyntectTuiError>
Expand description

Converts a line segment highlighed using syntect::easy::HighlightLines::highlight_line into a ratatui::text::Span.

Syntect colours are RGBA while Ratatui colours are RGB, so colour conversion is lossy. However, if a Syntect colour’s alpha value is 0, then we preserve this to some degree by returning a value of None for that colour (i.e. its colourless).

Additionally, syntect::highlighting::Style does not support underlines having a different color than the text it is applied to, unlike ratatui::style::Style. Because of this the underline_color is set to match the foreground.

§Examples

Basic usage:

let input_text = "hello";
let input_style = syntect::highlighting::Style {
    foreground: syntect::highlighting::Color { r: 255, g: 0, b: 0, a: 255 },
    background: syntect::highlighting::Color { r: 0, g: 0, b: 0, a: 0 },
    font_style: syntect::highlighting::FontStyle::BOLD
};
let expected_style = ratatui::style::Style {
    fg: Some(ratatui::style::Color::Rgb(255, 0, 0)),
    bg: None,
    underline_color: Some(ratatui::style::Color::Rgb(255, 0, 0)),
    add_modifier: ratatui::style::Modifier::BOLD,
    sub_modifier: ratatui::style::Modifier::empty()
};
let expected_span = ratatui::text::Span::styled(input_text, expected_style);
let actual_span = syntect_tui::into_span((input_style, input_text)).unwrap();
assert_eq!(expected_span, actual_span);

Here’s a more complex example that builds upon syntect’s own example for HighlightLines:

use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{ThemeSet, Style};
use syntect::util::LinesWithEndings;
use syntect_tui::into_span;

let ps = SyntaxSet::load_defaults_newlines();
let ts = ThemeSet::load_defaults();
let syntax = ps.find_syntax_by_extension("rs").unwrap();
let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
let s = "pub struct Wow { hi: u64 }\nfn blah() -> u64 {}";
for line in LinesWithEndings::from(s) { // LinesWithEndings enables use of newlines mode
    let line_spans: Vec<ratatui::text::Span> =
        h.highlight_line(line, &ps)
         .unwrap()
         .into_iter()
         .filter_map(|segment| into_span(segment).ok())
         .collect();
    let spans = ratatui::text::Line::from(line_spans);
    print!("{:?}", spans);
}

§Errors

Can return SyntectTuiError::UnknownFontStyle if the input FontStyle is not supported.

All explicit compositions of BOLD, ITALIC & UNDERLINE are supported, however, implicit bitflag coercions are not. For example, even though FontStyle::from_bits(3) is coerced to Some(FontStyle::BOLD | FontStyle::ITALIC), we ignore this result as it would be a pain to handle all implicit coercions.