Repository: sharkdp/bat
File: src/main.rs (Rust)

Code before:
}

pub fn list_languages(assets: &HighlightingAssets, term_width: usize) {
    let mut languages = assets
        .syntax_set
        .syntaxes()
        .iter()
        .filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty())
        .collect::<Vec<_>>();
    languages.sort_by_key(|lang| lang.name.to_uppercase());

    let longest = languages
        .iter()
        .map(|syntax| syntax.name.len())
        .max()
        .unwrap_or(32); // Fallback width if they have no language definitions.

    let comma_separator = ", ";
    let separator = " ";
    // Line-wrapping for the possible file extension overflow.
    let desired_width = term_width - longest - separator.len();

    for lang in languages {
        print!("{:width$}{}", lang.name, separator, width = longest);

        // Number of characters on this line so far, wrap before `desired_width`
        let mut num_chars = 0;

        let mut extension = lang.file_extensions.iter().peekable();
        while let Some(word) = extension.next() {
            // If we can't fit this word in, then create a line break and align it in.
            let new_chars = word.len() + comma_separator.len();
            if num_chars + new_chars >= desired_width {
                num_chars = 0;
                print!("\n{:width$}{}", "", separator, width = longest);
            }

            num_chars += new_chars;
            print!("{}", Green.paint(&word[..]));
            if extension.peek().is_some() {
                print!("{}", comma_separator);
            }
        }
        println!();
    }
}

pub fn list_themes(assets: &HighlightingAssets, cfg: &Config) {
    let themes = &assets.theme_set.themes;
    let mut config = cfg.clone();
    let mut style = HashSet::new();

Review comment (suggestion):
We call stdout() multiple times here. It might make sense to get [a lock on stdout](https://doc.rust-lang.org/stable/std/io/struct.Stdout.html#method.lock) and just print to that handle.

Edit: I have fixed that in a subsequent commit

Code after:

    Ok(())
}

pub fn list_languages(assets: &HighlightingAssets, term_width: usize) -> Result<()> {
    let mut languages = assets
        .syntax_set
        .syntaxes()
        .iter()
        .filter(|syntax| !syntax.hidden && !syntax.file_extensions.is_empty())
        .collect::<Vec<_>>();
    languages.sort_by_key(|lang| lang.name.to_uppercase());

    let longest = languages
        .iter()
        .map(|syntax| syntax.name.len())
        .max()
        .unwrap_or(32); // Fallback width if they have no language definitions.

    let comma_separator = ", ";
    let separator = " ";
    // Line-wrapping for the possible file extension overflow.
    let desired_width = term_width - longest - separator.len();

    for lang in languages {
        write!(
            stdout(),
            "{:width$}{}",
            lang.name,
            separator,
            width = longest
        )?;

        // Number of characters on this line so far, wrap before `desired_width`
        let mut num_chars = 0;

        let mut extension = lang.file_extensions.iter().peekable();
        while let Some(word) = extension.next() {
            // If we can't fit this word in, then create a line break and align it in.
            let new_chars = word.len() + comma_separator.len();
            if num_chars + new_chars >= desired_width {
                num_chars = 0;
                write!(stdout(), "\n{:width$}{}", "", separator, width = longest)?;
            }

            num_chars += new_chars;
            write!(stdout(), "{}", Green.paint(&word[..]))?;
            if extension.peek().is_some() {
                write!(stdout(), "{}", comma_separator)?;
            }
        }