use eure::query::{GetSemanticTokens, TextFile, TextFileContent};
use eure::query_flow::{DurabilityLevel, QueryRuntimeBuilder};
use nu_ansi_term::Color;
use std::io::{self, Write};
use crate::util::{display_path, handle_query_error, read_input};
#[derive(clap::Args)]
pub struct Args {
pub file: Option<String>,
}
pub fn run(args: Args) {
let contents = match read_input(args.file.as_deref()) {
Ok(c) => c,
Err(e) => {
eprintln!("{e}");
std::process::exit(1);
}
};
let runtime = QueryRuntimeBuilder::new().build();
let file = TextFile::from_path(display_path(args.file.as_deref()).into());
runtime.resolve_asset(
file.clone(),
TextFileContent::Content(contents.clone()),
DurabilityLevel::Static,
);
let tokens = match runtime.query(GetSemanticTokens::new(file)) {
Ok(result) => result,
Err(e) => handle_query_error(&runtime, e),
};
let mut stdout = io::stdout().lock();
let mut pos = 0usize;
for token in tokens.iter() {
let start = token.start as usize;
let end = start + token.length as usize;
if pos < start {
let _ = write!(stdout, "{}", &contents[pos..start]);
}
let text = &contents[start..end];
let color = token_type_to_color(token.token_type);
let _ = write!(stdout, "{}", color.paint(text));
pos = end;
}
if pos < contents.len() {
let _ = write!(stdout, "{}", &contents[pos..]);
}
let _ = stdout.flush();
}
fn token_type_to_color(token_type: eure::query::SemanticTokenType) -> Color {
use eure::query::SemanticTokenType;
match token_type {
SemanticTokenType::Keyword => Color::Purple,
SemanticTokenType::Number => Color::Cyan,
SemanticTokenType::String => Color::Green,
SemanticTokenType::Comment => Color::DarkGray,
SemanticTokenType::Operator => Color::White,
SemanticTokenType::Property => Color::Yellow,
SemanticTokenType::Punctuation => Color::LightGray,
SemanticTokenType::Macro => Color::LightCyan,
SemanticTokenType::Decorator => Color::Magenta,
SemanticTokenType::SectionMarker => Color::LightRed,
SemanticTokenType::ExtensionMarker => Color::LightMagenta,
SemanticTokenType::ExtensionIdent => Color::LightPurple,
}
}