mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-25 05:36:18 +00:00
lsp: Add removeBinding command
Add a command to remove a proerty binding from an element.
This commit is contained in:
parent
3a601ba6ef
commit
b6f36e7ce1
2 changed files with 141 additions and 3 deletions
|
|
@ -683,6 +683,52 @@ pub(crate) fn set_binding<'a>(
|
|||
))
|
||||
}
|
||||
|
||||
fn create_workspace_edit_for_remove_binding<'a>(
|
||||
uri: &lsp_types::Url,
|
||||
version: i32,
|
||||
property: &PropertyInformation,
|
||||
) -> Option<lsp_types::WorkspaceEdit> {
|
||||
property.defined_at.as_ref().map(|defined_at| {
|
||||
let edit = lsp_types::TextEdit { range: defined_at.delete_range, new_text: String::new() };
|
||||
let edits = vec![lsp_types::OneOf::Left(edit)];
|
||||
let text_document_edits = vec![lsp_types::TextDocumentEdit {
|
||||
text_document: lsp_types::OptionalVersionedTextDocumentIdentifier::new(
|
||||
uri.clone(),
|
||||
version,
|
||||
),
|
||||
edits,
|
||||
}];
|
||||
lsp_types::WorkspaceEdit {
|
||||
document_changes: Some(lsp_types::DocumentChanges::Edits(text_document_edits)),
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn remove_binding<'a>(
|
||||
document_cache: &mut DocumentCache,
|
||||
uri: &lsp_types::Url,
|
||||
element: &ElementRc,
|
||||
property_name: &str,
|
||||
) -> Result<WorkspaceEdit, Error> {
|
||||
let property = get_property_information(
|
||||
element,
|
||||
&mut &mut document_cache.offset_to_position_mapper(uri),
|
||||
property_name,
|
||||
)?;
|
||||
|
||||
let workspace_edit = create_workspace_edit_for_remove_binding(
|
||||
uri,
|
||||
document_cache
|
||||
.document_version(uri)
|
||||
.ok_or_else(|| Into::<Error>::into("Document not found in cache"))?,
|
||||
&property,
|
||||
)
|
||||
.ok_or_else(|| Into::<Error>::into("Failed to create workspace edit to remove property"))?;
|
||||
|
||||
Ok(workspace_edit)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -133,17 +133,18 @@ impl Drop for ProgressReporter {
|
|||
}
|
||||
}
|
||||
|
||||
const SHOW_PREVIEW_COMMAND: &str = "showPreview";
|
||||
const QUERY_PROPERTIES_COMMAND: &str = "queryProperties";
|
||||
const REMOVE_BINDING_COMMAND: &str = "removeBinding";
|
||||
const SHOW_PREVIEW_COMMAND: &str = "showPreview";
|
||||
const SET_BINDING_COMMAND: &str = "setBinding";
|
||||
|
||||
fn command_list() -> Vec<String> {
|
||||
let mut result = vec![];
|
||||
|
||||
result.push(QUERY_PROPERTIES_COMMAND.into());
|
||||
result.push(REMOVE_BINDING_COMMAND.into());
|
||||
#[cfg(any(feature = "preview", feature = "preview-lense"))]
|
||||
result.push(SHOW_PREVIEW_COMMAND.into());
|
||||
|
||||
result.push(QUERY_PROPERTIES_COMMAND.into());
|
||||
result.push(SET_BINDING_COMMAND.into());
|
||||
|
||||
result
|
||||
|
|
@ -401,6 +402,9 @@ pub fn register_request_handlers(rh: &mut RequestHandler) {
|
|||
if params.command.as_str() == SET_BINDING_COMMAND {
|
||||
return Ok(Some(set_binding_command(¶ms.arguments, &ctx).await?));
|
||||
}
|
||||
if params.command.as_str() == REMOVE_BINDING_COMMAND {
|
||||
return Ok(Some(remove_binding_command(¶ms.arguments, &ctx).await?));
|
||||
}
|
||||
Ok(None::<serde_json::Value>)
|
||||
});
|
||||
rh.register::<DocumentColor, _>(|params, ctx| async move {
|
||||
|
|
@ -630,6 +634,94 @@ pub async fn set_binding_command(
|
|||
Ok(serde_json::to_value(result).expect("Failed to serialize set_binding result!"))
|
||||
}
|
||||
|
||||
pub async fn remove_binding_command(
|
||||
params: &[serde_json::Value],
|
||||
ctx: &Rc<Context>,
|
||||
) -> Result<serde_json::Value, Error> {
|
||||
use crate::properties;
|
||||
|
||||
let text_document = serde_json::from_value::<lsp_types::OptionalVersionedTextDocumentIdentifier>(
|
||||
params.get(0).ok_or_else(|| "No text document provided")?.clone(),
|
||||
)?;
|
||||
let element_range = serde_json::from_value::<lsp_types::Range>(
|
||||
params.get(1).ok_or_else(|| "No element range provided")?.clone(),
|
||||
)?;
|
||||
let property_name = serde_json::from_value::<String>(
|
||||
params.get(2).ok_or_else(|| "No property name provided")?.clone(),
|
||||
)?;
|
||||
|
||||
let edit = {
|
||||
let document_cache = &mut ctx.document_cache.borrow_mut();
|
||||
let uri = text_document.uri;
|
||||
if let Some(source_version) = text_document.version {
|
||||
if let Some(current_version) = document_cache.document_version(&uri) {
|
||||
if current_version != source_version {
|
||||
return Err(
|
||||
"Document version mismatch. Please refresh your property information"
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Err(
|
||||
format!("Document with uri {} not found in cache", uri.to_string()).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let element =
|
||||
element_at_position(document_cache, &uri, &element_range.start).ok_or_else(|| {
|
||||
format!("No element found at the given start position {:?}", &element_range.start)
|
||||
})?;
|
||||
let node_range = element
|
||||
.borrow()
|
||||
.node
|
||||
.as_ref()
|
||||
.ok_or_else(|| "The element was found, but had no range defined!")?
|
||||
.text_range();
|
||||
|
||||
let (start, end) = {
|
||||
let mut offset_to_position = document_cache.offset_to_position_mapper(&uri);
|
||||
(
|
||||
offset_to_position.map(node_range.start().into()),
|
||||
offset_to_position.map(node_range.end().into()),
|
||||
)
|
||||
};
|
||||
|
||||
if start != element_range.start {
|
||||
return Err(format!(
|
||||
"Element found, but does not start at the expected place (){start:?} != {:?}).",
|
||||
element_range.start
|
||||
)
|
||||
.into());
|
||||
}
|
||||
if end != element_range.end {
|
||||
return Err(format!(
|
||||
"Element found, but does not end at the expected place (){end:?} != {:?}).",
|
||||
element_range.end
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
properties::remove_binding(document_cache, &uri, &element, &property_name)?
|
||||
};
|
||||
|
||||
let response = ctx
|
||||
.server_notifier
|
||||
.send_request::<lsp_types::request::ApplyWorkspaceEdit>(
|
||||
lsp_types::ApplyWorkspaceEditParams { label: Some("set binding".into()), edit },
|
||||
)?
|
||||
.await?;
|
||||
|
||||
if !response.applied {
|
||||
return Err(response
|
||||
.failure_reason
|
||||
.unwrap_or("Operation failed, no specific reason given".into())
|
||||
.into());
|
||||
}
|
||||
|
||||
Ok(serde_json::to_value(()).expect("Failed to serialize ()!"))
|
||||
}
|
||||
|
||||
#[cfg(feature = "preview")]
|
||||
/// Workaround for editor that do not support code action: using the goto definition on a comment
|
||||
/// that says "preview" will show the preview.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue