+ }
+
+ Ok(())
+ }
+
+ #[tracing::instrument(skip_all)]
+ pub fn on_did_move_files(
+ env: &napi::Env,
+ event: vscode_sys::FileRenameEvent,
+ ) -> Result<(), napi::Error> {
+ let mut extension_state = ExtensionState::get()?;
+ let decoration_change_event_emitter = extension_state
+ .decoration_change_event_emitter
+ .get_inner(env)?;
+
+ for renamed_file in event.get_files()? {
+ let old_uri = renamed_file.get_old_uri()?;
+ let new_uri = renamed_file.get_new_uri()?;
+ let old_absolute_path = Utf8PathBuf::from(old_uri.get_fs_path()?);
+ let new_absolute_path = Utf8PathBuf::from(new_uri.get_fs_path()?);
+
+ // TODO: handle renaming/moves across workspaces
+ if let Some((workspace_path, open_repository)) = extension_state
+ .repositories
+ .get_open_repository_mut(env, &old_uri)?
+ {
+ let old_relative_path =
+ old_absolute_path
+ .strip_prefix(&workspace_path)
+ .map_err(|error| {
+ napi::Error::from_reason(format!(
+ "Path {old_absolute_path} not in {workspace_path}: {error}"
+ ))
+ })?;
+ let new_relative_path =
+ new_absolute_path
+ .strip_prefix(&workspace_path)
+ .map_err(|error| {
+ napi::Error::from_reason(format!(
+ "Path {new_absolute_path} not in {workspace_path}: {error}"
+ ))
+ })?;
+
+ open_repository
+ .repository
+ .move_path(old_relative_path, new_relative_path.to_path_buf())
+ .map_err(|error| {
+ napi::Error::from_reason(format!(
+ "Unable to move {old_absolute_path} to {new_absolute_path}: {error:#?}"
+ ))
+ })?;
+
+ decoration_change_event_emitter.fire(new_uri.inner)?;
+ open_repository.update_resource_states(env, &workspace_path)?;
+ } else {
+ tracing::info!(
+ message = "Ignoring move outside of workspace",
+ ?old_absolute_path,
+ ?new_absolute_path
+ );
+ }