use iri_string::types::{UriAbsoluteStr, UriAbsoluteString};
use pijul_extension::path_state::{PathState, TrackedState};
use crate::event_loop::ExtensionState;
use crate::vscode_sys;
pub type DeferredPromise = napi::JsDeferred<
Option<vscode_sys::reference::FileDecorationRef>,
Box<
dyn FnOnce(
napi::Env,
)
-> Result<Option<vscode_sys::reference::FileDecorationRef>, napi::Error>,
>,
>;
#[tracing::instrument(skip(deferred_promise, extension_state))]
pub async fn handle(
uri: UriAbsoluteString,
deferred_promise: DeferredPromise,
extension_state: &ExtensionState,
) {
let optional_path_state = get_decoration(&uri, extension_state);
tracing::debug!(message = "Providing file decoration", ?optional_path_state);
deferred_promise.resolve(Box::new(move |env| {
let Some(path_state) = optional_path_state else {
return Ok(None);
};
let (badge, tooltip, color_id) = match path_state {
PathState::Untracked => ("U", "Untracked", "pijul.decorations.path.untracked"),
PathState::Tracked(modified_state) => match modified_state {
TrackedState::Added => ("A", "Added", "pijul.decorations.path.added"),
TrackedState::Removed => ("RM", "Removed", "pijul.decorations.path.removed"),
TrackedState::Modified => ("M", "Modified", "pijul.decorations.path.modified"),
TrackedState::Moved => ("MV", "Moved", "pijul.decorations.path.moved"),
TrackedState::ModifiedAndMoved => (
"M,MV",
"Modified, Moved",
"pijul.decorations.path.modifiedAndMoved",
),
},
};
let color = vscode_sys::ThemeColor::new(&env, color_id)?;
let path_decoration = vscode_sys::FileDecoration::new(&env, badge, tooltip, &color)?;
Ok(Some(path_decoration.create_ref()?))
}));
}
#[tracing::instrument(skip(extension_state))]
fn get_decoration(uri: &UriAbsoluteStr, extension_state: &ExtensionState) -> Option<PathState> {
let Some((_repository_path, relative_path, repository)) = extension_state.get_repository(uri)
else {
tracing::info!(message = "No matching repository for path");
return None;
};
repository.repository.get_path_state(relative_path)
}