use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Mutex;
use tower_lsp_server::jsonrpc::Result;
use tower_lsp_server::ls_types::*;
use crate::lsp::DocumentState;
use super::super::conversions::{offset_to_position, position_to_offset};
use super::super::helpers;
pub(crate) async fn prepare_rename(
client: &tower_lsp_server::Client,
document_map: Arc<Mutex<HashMap<String, DocumentState>>>,
salsa_db: Arc<Mutex<crate::salsa::SalsaDb>>,
workspace_root: Arc<Mutex<Option<PathBuf>>>,
params: TextDocumentPositionParams,
) -> Result<Option<PrepareRenameResponse>> {
let uri = params.text_document.uri;
let position = params.position;
let _config = helpers::get_config(client, &workspace_root, &uri).await;
let Some(ctx) =
crate::lsp::context::get_open_document_context(&document_map, &salsa_db, &uri).await
else {
return Ok(None);
};
let content = ctx.content.clone();
let parsed_yaml_regions = ctx.parsed_yaml_regions.clone();
let Some(offset) = position_to_offset(&content, position) else {
log::debug!(
"prepare_rename: position_to_offset failed uri={:?} line={} char={}",
uri,
position.line,
position.character
);
return Ok(None);
};
if helpers::is_offset_in_yaml_frontmatter(&parsed_yaml_regions, offset) {
return Ok(None);
}
let root = ctx.syntax_root();
let range = helpers::example_label_range_at_offset(&root, offset)
.or_else(|| helpers::find_symbol_text_range_at_offset(&root, offset));
let Some(range) = range else {
log::debug!(
"prepare_rename: no symbol range uri={:?} line={} char={} offset={}",
uri,
position.line,
position.character,
offset
);
return Ok(None);
};
let start_offset: usize = range.start().into();
let end_offset: usize = range.end().into();
let Some(placeholder) = content.get(start_offset..end_offset) else {
log::debug!(
"prepare_rename: invalid utf8 slice uri={:?} range={}..{}",
uri,
start_offset,
end_offset
);
return Ok(None);
};
let start = offset_to_position(&content, range.start().into());
let end = offset_to_position(&content, range.end().into());
log::debug!(
"prepare_rename: uri={:?} req=({}, {}) offset={} range=({}, {})..({}, {}) placeholder={:?}",
uri,
position.line,
position.character,
offset,
start.line,
start.character,
end.line,
end.character,
placeholder
);
Ok(Some(PrepareRenameResponse::RangeWithPlaceholder {
range: Range { start, end },
placeholder: placeholder.to_string(),
}))
}