diff --git a/Cargo.lock b/Cargo.lock index 0d9eab4b0579..9c4b0a09b27e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -635,6 +635,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1446,15 +1455,15 @@ dependencies = [ [[package]] name = "lsp-types" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984" +checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071" dependencies = [ "bitflags 1.3.2", + "fluent-uri", "serde", "serde_json", "serde_repr", - "url", ] [[package]] diff --git a/crates/ide-assists/src/assist_config.rs b/crates/ide-assists/src/assist_config.rs index 636acf3f0088..c0bd7f5f7d01 100644 --- a/crates/ide-assists/src/assist_config.rs +++ b/crates/ide-assists/src/assist_config.rs @@ -1,12 +1,8 @@ //! Settings for tweaking assists. -//! -//! The fun thing here is `SnippetCap` -- this type can only be created in this -//! module, and we use to statically check that we only produce snippet -//! assists if we are allowed to. use hir::FindPathConfig; use ide_db::{ - SnippetCap, + WorkspaceSnippetCap, assists::ExprFillDefaultMode, imports::{import_assets::ImportPathConfig, insert_use::InsertUseConfig}, rename::RenameConfig, @@ -16,7 +12,7 @@ use crate::AssistKind; #[derive(Clone, Debug, PartialEq, Eq)] pub struct AssistConfig { - pub snippet_cap: Option, + pub workspace_snippet_cap: Option, pub allowed: Option>, pub insert_use: InsertUseConfig, pub prefer_no_std: bool, diff --git a/crates/ide-assists/src/handlers/add_label_to_loop.rs b/crates/ide-assists/src/handlers/add_label_to_loop.rs index 41e9b6cc8453..1ab4cb88360a 100644 --- a/crates/ide-assists/src/handlers/add_label_to_loop.rs +++ b/crates/ide-assists/src/handlers/add_label_to_loop.rs @@ -53,8 +53,11 @@ pub(crate) fn add_label_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>) -> O ]; editor.insert_all(Position::before(&loop_kw), elements); - if let Some(cap) = ctx.config.snippet_cap { - editor.add_annotation(label.syntax(), builder.make_placeholder_snippet(cap)); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + editor.add_annotation( + label.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } let loop_body = loop_expr.loop_body().and_then(|it| it.stmt_list()); @@ -94,8 +97,11 @@ fn insert_label_after_token( let elements = vec![make.whitespace(" ").into(), label.syntax().clone().into()]; editor.insert_all(Position::after(token), elements); - if let Some(cap) = ctx.config.snippet_cap { - editor.add_annotation(label.syntax(), builder.make_placeholder_snippet(cap)); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + editor.add_annotation( + label.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } } diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index d1f1f9f12338..43821a0c8e20 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -200,7 +200,7 @@ fn add_missing_impl_members_inner( first_new_item = assoc_item_list.assoc_items().next(); } - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { let mut placeholder = None; if let DefaultMethods::No = mode && let Some(ast::AssocItem::Fn(func)) = &first_new_item @@ -211,10 +211,10 @@ fn add_missing_impl_members_inner( } if let Some(macro_call) = placeholder { - let placeholder = edit.make_placeholder_snippet(cap); + let placeholder = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(macro_call.syntax(), placeholder); } else if let Some(first_new_item) = first_new_item { - let tabstop = edit.make_tabstop_before(cap); + let tabstop = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(first_new_item.syntax(), tabstop); }; }; diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 3c33ddec3162..6c9957b49da3 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -278,22 +278,31 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) arms_edit.add_comma_after_last_arm(ctx, &make, &editor); arms_edit.append_arms(&missing_arms, &make, &editor); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { if let Some(it) = missing_arms .first() .and_then(|arm| arm.syntax().descendants().find_map(ast::WildcardPat::cast)) { - editor.add_annotation(it.syntax(), builder.make_placeholder_snippet(cap)); + editor.add_annotation( + it.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } for arm in &missing_arms { if let Some(expr) = arm.expr() { - editor.add_annotation(expr.syntax(), builder.make_placeholder_snippet(cap)); + editor.add_annotation( + expr.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } } if let Some(arm) = missing_arms.last() { - editor.add_annotation(arm.syntax(), builder.make_tabstop_after(cap)); + editor.add_annotation( + arm.syntax(), + builder.make_tabstop_after(workspace_snippet_cap), + ); } } diff --git a/crates/ide-assists/src/handlers/add_turbo_fish.rs b/crates/ide-assists/src/handlers/add_turbo_fish.rs index dcd2124f7beb..8f49f9ab6ec7 100644 --- a/crates/ide-assists/src/handlers/add_turbo_fish.rs +++ b/crates/ide-assists/src/handlers/add_turbo_fish.rs @@ -112,10 +112,10 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti placeholder_ty.syntax().clone().into(), ]; editor.insert_all(Position::after(pat.syntax()), elements); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { editor.add_annotation( placeholder_ty.syntax(), - builder.make_placeholder_snippet(cap), + builder.make_placeholder_snippet(workspace_snippet_cap), ); } } @@ -173,9 +173,12 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } }; - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { for arg in fish_head.generic_args() { - editor.add_annotation(arg.syntax(), builder.make_placeholder_snippet(cap)); + editor.add_annotation( + arg.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } } builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs b/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs index 18f3ced41402..ce25b11afa71 100644 --- a/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs +++ b/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs @@ -94,11 +94,11 @@ pub(crate) fn convert_from_to_tryfrom(acc: &mut Assists, ctx: &AssistContext<'_> make.ty_alias(None, "Error", None, None, None, Some((make.ty("()"), None))); let error_type = ast::AssocItem::TypeAlias(error_type_alias); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let ast::AssocItem::TypeAlias(type_alias) = &error_type && let Some(ty) = type_alias.ty() { - let placeholder = builder.make_placeholder_snippet(cap); + let placeholder = builder.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(ty.syntax(), placeholder); } diff --git a/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/crates/ide-assists/src/handlers/destructure_tuple_binding.rs index b0f257e0028f..c9ef8d0479e2 100644 --- a/crates/ide-assists/src/handlers/destructure_tuple_binding.rs +++ b/crates/ide-assists/src/handlers/destructure_tuple_binding.rs @@ -192,10 +192,10 @@ fn edit_tuple_assignment( .and_then(ast::RecordPatField::for_field_name) .is_some_and(|field| field.colon_token().is_none()); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { // place cursor on first tuple name if let Some(ast::Pat::IdentPat(first_pat)) = tuple_pat.fields().next() { - let annotation = edit.make_tabstop_before(cap); + let annotation = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation( first_pat.name().expect("first ident pattern should have a name").syntax(), annotation, diff --git a/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs b/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs index c87ded9dc47b..3657d3f248af 100644 --- a/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs +++ b/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs @@ -134,7 +134,7 @@ pub(crate) fn extract_expressions_from_format_string( let new_tt = make.token_tree(tt_delimiter, new_tt_bits); editor.replace(tt.syntax(), new_tt.syntax()); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { // Add placeholder snippets over placeholder args for pos in placeholder_indexes { // Skip the opening delimiter @@ -145,7 +145,7 @@ pub(crate) fn extract_expressions_from_format_string( }; if stdx::always!(placeholder.kind() == T![_]) { - let annotation = edit.make_placeholder_snippet(cap); + let annotation = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(placeholder, annotation); } } @@ -154,7 +154,7 @@ pub(crate) fn extract_expressions_from_format_string( if let Some(NodeOrToken::Token(literal)) = new_tt.token_trees_and_tokens().nth(1 + format_string_index) { - let annotation = edit.make_tabstop_after(cap); + let annotation = edit.make_tabstop_after(workspace_snippet_cap); editor.add_annotation(literal, annotation); } } @@ -179,7 +179,7 @@ fn format_str_index( #[cfg(test)] mod tests { use super::*; - use crate::tests::{check_assist, check_assist_no_snippet_cap}; + use crate::tests::{check_assist, check_assist_no_workspace_snippet_cap}; #[test] fn multiple_middle_arg() { @@ -347,7 +347,7 @@ fn main() { #[test] fn without_snippets() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( extract_expressions_from_format_string, r#" //- minicore: fmt diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index 4219e6845fad..ed7912485243 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -177,10 +177,10 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let fn_def = format_function(ctx, module, &fun, old_indent).clone_for_update(); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(name) = fn_def.name() { - builder.add_tabstop_before(cap, name); + builder.add_tabstop_before(workspace_snippet_cap, name); } // FIXME: wrap non-adt types diff --git a/crates/ide-assists/src/handlers/extract_type_alias.rs b/crates/ide-assists/src/handlers/extract_type_alias.rs index eda35eba45c9..80bb7f9556cd 100644 --- a/crates/ide-assists/src/handlers/extract_type_alias.rs +++ b/crates/ide-assists/src/handlers/extract_type_alias.rs @@ -87,10 +87,13 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) -> let ty_alias = make.ty_alias(None, name, generic_params, None, None, Some((resolved_ty, None))); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(name) = ty_alias.name() { - editor.add_annotation(name.syntax(), builder.make_tabstop_before(cap)); + editor.add_annotation( + name.syntax(), + builder.make_tabstop_before(workspace_snippet_cap), + ); } let indent = IndentLevel::from_node(node); diff --git a/crates/ide-assists/src/handlers/extract_variable.rs b/crates/ide-assists/src/handlers/extract_variable.rs index c5c57c76b47c..82db7b5c5891 100644 --- a/crates/ide-assists/src/handlers/extract_variable.rs +++ b/crates/ide-assists/src/handlers/extract_variable.rs @@ -211,8 +211,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op let pat_name = make.name(&var_name); let name_expr = make.expr_path(make.ident_path(&var_name)); - if let Some(cap) = ctx.config.snippet_cap { - let tabstop = edit.make_tabstop_before(cap); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + let tabstop = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(pat_name.syntax().clone(), tabstop); } diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs index d8714dd49c2d..0691153fb37d 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs @@ -102,8 +102,11 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) ); } - if let Some(cap) = ctx.config.snippet_cap { - editor.add_annotation(missing_visibility.syntax(), builder.make_tabstop_before(cap)); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + editor.add_annotation( + missing_visibility.syntax(), + builder.make_tabstop_before(workspace_snippet_cap), + ); } builder.add_file_edits(target_file, editor); diff --git a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs index 0bb90f187c68..b7a5a5aa30e0 100644 --- a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs +++ b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs @@ -130,10 +130,10 @@ pub(crate) fn generate_blanket_trait_impl( ], ); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(self_ty) = impl_.self_ty() { - builder.add_tabstop_before(cap, self_ty); + builder.add_tabstop_before(workspace_snippet_cap, self_ty); } builder.add_file_edits(ctx.vfs_file_id(), editor); }, diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs index 9486aa6f0195..ba5fc2b6dd2a 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -222,10 +222,10 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' } }; - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(fn_) = fn_ { - let tabstop = edit.make_tabstop_before(cap); + let tabstop = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(fn_.syntax(), tabstop); } edit.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/generate_derive.rs b/crates/ide-assists/src/handlers/generate_derive.rs index 0129b1db396b..3e8c8a6ed9eb 100644 --- a/crates/ide-assists/src/handlers/generate_derive.rs +++ b/crates/ide-assists/src/handlers/generate_derive.rs @@ -26,7 +26,7 @@ use crate::{AssistContext, AssistId, Assists}; // } // ``` pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> { - let cap = ctx.config.snippet_cap?; + let workspace_snippet_cap = ctx.config.workspace_snippet_cap?; let nominal = ctx.find_node_at_offset::()?; let target = nominal.syntax().text_range(); let derive_attr = nominal @@ -76,7 +76,7 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt .r_paren_token() .expect("make::attr_outer was expected to have a R_PAREN"); - let tabstop_before = edit.make_tabstop_before(cap); + let tabstop_before = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(delimiter, tabstop_before); edit.add_file_edits(ctx.vfs_file_id(), editor); @@ -84,7 +84,7 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt Some(_) => { // Just move the cursor. edit.add_tabstop_before_token( - cap, + workspace_snippet_cap, delimiter.expect("Right delim token could not be found."), ); } diff --git a/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/crates/ide-assists/src/handlers/generate_fn_type_alias.rs index 55e508381134..50a7bcb90eb5 100644 --- a/crates/ide-assists/src/handlers/generate_fn_type_alias.rs +++ b/crates/ide-assists/src/handlers/generate_fn_type_alias.rs @@ -111,10 +111,13 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ], ); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(name) = ty_alias.name() { - editor.add_annotation(name.syntax(), builder.make_placeholder_snippet(cap)); + editor.add_annotation( + name.syntax(), + builder.make_placeholder_snippet(workspace_snippet_cap), + ); } builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 6ef492619b50..fd6f9e0483b7 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -3,7 +3,7 @@ use hir::{ TypeInfo, }; use ide_db::{ - FileId, FxHashMap, FxHashSet, RootDatabase, SnippetCap, + FileId, FxHashMap, FxHashSet, RootDatabase, WorkspaceSnippetCap, defs::{Definition, NameRefClass}, famous_defs::FamousDefs, helpers::is_editable_crate, @@ -186,7 +186,7 @@ fn add_func_to_accumulator( let target = function_builder.target.clone(); let edition = function_builder.target_edition; - let func = function_builder.render(ctx.config.snippet_cap, edit); + let func = function_builder.render(ctx.config.workspace_snippet_cap, edit); if let Some(adt) = adt_info .and_then(|adt_info| if adt_info.impl_exists { None } else { Some(adt_info.adt) }) @@ -358,7 +358,11 @@ impl FunctionBuilder { }) } - fn render(self, cap: Option, edit: &mut SourceChangeBuilder) -> ast::Fn { + fn render( + self, + workspace_snippet_cap: Option, + edit: &mut SourceChangeBuilder, + ) -> ast::Fn { let visibility = match self.visibility { Visibility::None => None, Visibility::Crate => Some(make::visibility_pub_crate()), @@ -390,19 +394,19 @@ impl FunctionBuilder { .tail_expr() .expect("function body should have a tail expression"); - if let Some(cap) = cap { + if let Some(workspace_snippet_cap) = workspace_snippet_cap { if self.should_focus_return_type { // Focus the return type if there is one match ret_type { Some(ret_type) => { - edit.add_placeholder_snippet(cap, ret_type); + edit.add_placeholder_snippet(workspace_snippet_cap, ret_type); } None => { - edit.add_placeholder_snippet(cap, tail_expr); + edit.add_placeholder_snippet(workspace_snippet_cap, tail_expr); } } } else { - edit.add_placeholder_snippet(cap, tail_expr); + edit.add_placeholder_snippet(workspace_snippet_cap, tail_expr); } } diff --git a/crates/ide-assists/src/handlers/generate_getter_or_setter.rs b/crates/ide-assists/src/handlers/generate_getter_or_setter.rs index b884581041f4..8e65485a76dc 100644 --- a/crates/ide-assists/src/handlers/generate_getter_or_setter.rs +++ b/crates/ide-assists/src/handlers/generate_getter_or_setter.rs @@ -442,11 +442,11 @@ fn build_source_change( let items = items(ctx, info_of_record_fields, &assist_info, editor.make()); impl_def.assoc_item_list().unwrap().add_items(&editor, items.clone()); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(ast::AssocItem::Fn(fn_)) = items.last() && let Some(name) = fn_.name() { - let tabstop = builder.make_tabstop_before(cap); + let tabstop = builder.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(name.syntax(), tabstop); } @@ -472,12 +472,12 @@ fn build_source_change( vec![make.whitespace("\n\n").into(), impl_def.syntax().clone().into()], ); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(assoc_list) = impl_def.assoc_item_list() && let Some(ast::AssocItem::Fn(fn_)) = assoc_list.assoc_items().last() && let Some(name) = fn_.name() { - let tabstop = builder.make_tabstop_before(cap); + let tabstop = builder.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(name.syntax().clone(), tabstop); } @@ -486,7 +486,9 @@ fn build_source_change( #[cfg(test)] mod tests_getter { - use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable}; + use crate::tests::{ + check_assist, check_assist_no_workspace_snippet_cap, check_assist_not_applicable, + }; use super::*; @@ -534,8 +536,8 @@ impl Context { } #[test] - fn test_generate_getter_from_field_no_snippet_cap() { - check_assist_no_snippet_cap( + fn test_generate_getter_from_field_no_workspace_snippet_cap() { + check_assist_no_workspace_snippet_cap( generate_getter, r#" struct Context { @@ -555,7 +557,7 @@ impl Context { "#, ); - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_getter_mut, r#" struct Context { @@ -633,8 +635,8 @@ impl Context { } #[test] - fn test_generate_getter_from_field_with_visibility_marker_no_snippet_cap() { - check_assist_no_snippet_cap( + fn test_generate_getter_from_field_with_visibility_marker_no_workspace_snippet_cap() { + check_assist_no_workspace_snippet_cap( generate_getter, r#" pub(crate) struct Context { @@ -691,8 +693,8 @@ impl Context { } #[test] - fn test_multiple_generate_getter_no_snippet_cap() { - check_assist_no_snippet_cap( + fn test_multiple_generate_getter_no_workspace_snippet_cap() { + check_assist_no_workspace_snippet_cap( generate_getter, r#" struct Context { diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs index c5a46f6981f5..a8797b2208d7 100644 --- a/crates/ide-assists/src/handlers/generate_impl.rs +++ b/crates/ide-assists/src/handlers/generate_impl.rs @@ -65,10 +65,10 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio let impl_ = insert_impl(&editor, &impl_, &nominal); // Add a tabstop after the left curly brace - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) { - let tabstop = edit.make_tabstop_after(cap); + let tabstop = edit.make_tabstop_after(workspace_snippet_cap); editor.add_annotation(l_curly, tabstop); } edit.add_file_edits(ctx.vfs_file_id(), editor); @@ -112,14 +112,14 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> let impl_ = generate_trait_impl_intransitive(make, &nominal, make.ty_placeholder()); let impl_ = insert_impl(&editor, &impl_, &nominal); // Make the trait type a placeholder snippet - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { if let Some(trait_) = impl_.trait_() { - let placeholder = edit.make_placeholder_snippet(cap); + let placeholder = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(trait_.syntax(), placeholder); } if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) { - let tabstop = edit.make_tabstop_after(cap); + let tabstop = edit.make_tabstop_after(workspace_snippet_cap); editor.add_annotation(l_curly, tabstop); } } @@ -212,28 +212,28 @@ pub(crate) fn generate_impl_trait(acc: &mut Assists, ctx: &AssistContext<'_>) -> let impl_ = insert_impl(&editor, &impl_, &trait_); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { if let Some(generics) = impl_.trait_().and_then(|it| it.generic_arg_list()) { for generic in generics.generic_args() { - let placeholder = edit.make_placeholder_snippet(cap); + let placeholder = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(generic.syntax(), placeholder); } } if let Some(ty) = impl_.self_ty() { - let placeholder = edit.make_placeholder_snippet(cap); + let placeholder = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(ty.syntax(), placeholder); } if let Some(expr) = impl_.assoc_item_list().and_then(|it| it.assoc_items().find_map(extract_expr)) { - let tabstop = edit.make_tabstop_before(cap); + let tabstop = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(expr.syntax(), tabstop); } else if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) { - let tabstop = edit.make_tabstop_after(cap); + let tabstop = edit.make_tabstop_after(workspace_snippet_cap); editor.add_annotation(l_curly, tabstop); } } diff --git a/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs b/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs index acf0819222d5..d19fc64ffe65 100644 --- a/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs +++ b/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs @@ -88,8 +88,8 @@ pub(crate) fn generate_mut_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_> ], ); - if let Some(cap) = ctx.config.snippet_cap { - let tabstop_before = edit.make_tabstop_before(cap); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + let tabstop_before = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(new_impl.syntax(), tabstop_before); } @@ -471,7 +471,7 @@ impl AsRef$0 for [T; 3] {} fn no_snippets() { check_assist_with_config( generate_mut_trait_impl, - AssistConfig { snippet_cap: None, ..TEST_CONFIG }, + AssistConfig { workspace_snippet_cap: None, ..TEST_CONFIG }, r#" //- minicore: index pub enum Axis { X = 0, Y = 1, Z = 2 } diff --git a/crates/ide-assists/src/handlers/generate_new.rs b/crates/ide-assists/src/handlers/generate_new.rs index 520709adc5e2..3948c35821e9 100644 --- a/crates/ide-assists/src/handlers/generate_new.rs +++ b/crates/ide-assists/src/handlers/generate_new.rs @@ -195,7 +195,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option }; if let Some(fn_) = contain_fn.descendants().find_map(ast::Fn::cast) - && let Some(cap) = ctx.config.snippet_cap + && let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { match strukt.kind() { StructKind::Tuple(_) => { @@ -215,7 +215,8 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option for (struct_arg, fn_param) in struct_args.zip(fn_params.params()) { if let Some(fn_pat) = fn_param.pat() { let fn_pat = fn_pat.syntax().clone(); - let placeholder = builder.make_placeholder_snippet(cap); + let placeholder = + builder.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation_all(vec![struct_arg, fn_pat], placeholder) } } @@ -226,7 +227,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option // Add a tabstop before the name if let Some(name) = fn_.name() { - let tabstop_before = builder.make_tabstop_before(cap); + let tabstop_before = builder.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(name.syntax(), tabstop_before); } } diff --git a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs index 049398de8c55..bd37bec67a32 100644 --- a/crates/ide-assists/src/handlers/generate_trait_from_impl.rs +++ b/crates/ide-assists/src/handlers/generate_trait_from_impl.rs @@ -152,8 +152,8 @@ pub(crate) fn generate_trait_from_impl(acc: &mut Assists, ctx: &AssistContext<'_ ); // Link the trait name & trait ref names together as a placeholder snippet group - if let Some(cap) = ctx.config.snippet_cap { - let placeholder = builder.make_placeholder_snippet(cap); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + let placeholder = builder.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(trait_name.syntax(), placeholder); editor.add_annotation(trait_name_ref.syntax(), placeholder); } @@ -222,7 +222,9 @@ fn strip_body(editor: &SyntaxEditor, item: &ast::AssocItem) { #[cfg(test)] mod tests { use super::*; - use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable}; + use crate::tests::{ + check_assist, check_assist_no_workspace_snippet_cap, check_assist_not_applicable, + }; #[test] fn test_trigger_when_cursor_on_header() { @@ -241,7 +243,7 @@ impl Foo { $0 #[test] fn test_assoc_item_fn() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo(f64); @@ -268,7 +270,7 @@ impl Add for Foo { #[test] fn test_remove_doc_comments() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo(f64); @@ -304,7 +306,7 @@ impl Add for Foo { #[test] fn test_assoc_item_macro() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo; @@ -339,7 +341,7 @@ impl NewTrait for Foo { #[test] fn test_assoc_item_const() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo; @@ -362,7 +364,7 @@ impl NewTrait for Foo { #[test] fn test_impl_with_generics() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo([i32; N]); @@ -390,7 +392,7 @@ impl NewTrait for Foo { #[test] fn test_trait_items_should_not_have_vis() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" struct Foo; @@ -427,7 +429,7 @@ impl Emp$0tyImpl{} #[test] fn test_not_top_level_impl() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" mod a { @@ -450,7 +452,7 @@ mod a { #[test] fn test_multi_fn_impl_not_suggest_trait_name() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( generate_trait_from_impl, r#" impl S$0 { @@ -471,7 +473,7 @@ impl NewTrait for S { } #[test] - fn test_snippet_cap_is_some() { + fn test_workspace_snippet_cap_is_some() { check_assist( generate_trait_from_impl, r#" diff --git a/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs b/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs index 95f223420b0b..f4f055f9e322 100644 --- a/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs +++ b/crates/ide-assists/src/handlers/introduce_named_type_parameter.rs @@ -54,8 +54,11 @@ pub(crate) fn introduce_named_type_parameter( editor.replace(impl_trait_type.syntax(), new_ty.syntax()); editor.add_generic_param(&fn_, type_param.clone().into()); - if let Some(cap) = ctx.config.snippet_cap { - editor.add_annotation(type_param.syntax(), builder.make_tabstop_before(cap)); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { + editor.add_annotation( + type_param.syntax(), + builder.make_tabstop_before(workspace_snippet_cap), + ); } builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/promote_local_to_const.rs b/crates/ide-assists/src/handlers/promote_local_to_const.rs index ed61d32eb657..9282efaeae9c 100644 --- a/crates/ide-assists/src/handlers/promote_local_to_const.rs +++ b/crates/ide-assists/src/handlers/promote_local_to_const.rs @@ -90,8 +90,10 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>) let item = make.item_const(None, None, make.name(&name), make.ty(&ty), initializer); - if let Some((cap, name)) = ctx.config.snippet_cap.zip(item.name()) { - let tabstop = edit.make_tabstop_before(cap); + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap + && let Some(name) = item.name() + { + let tabstop = edit.make_tabstop_before(workspace_snippet_cap); editor.add_annotation(name.syntax().clone(), tabstop); } diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs index 751cd42f6e8d..657e5c5d14dc 100644 --- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs @@ -155,22 +155,22 @@ fn add_assist( (generate_trait_impl(make, impl_is_unsafe, adt, trait_path), None) }; - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { if let Some(first_assoc_item) = first_assoc_item { if let ast::AssocItem::Fn(ref func) = first_assoc_item && let Some(m) = func.syntax().descendants().find_map(ast::MacroCall::cast) && m.syntax().text() == "todo!()" { // Make the `todo!()` a placeholder - builder.add_placeholder_snippet(cap, m); + builder.add_placeholder_snippet(workspace_snippet_cap, m); } else { // If we haven't already added a snippet, add a tabstop before the generated function - builder.add_tabstop_before(cap, first_assoc_item); + builder.add_tabstop_before(workspace_snippet_cap, first_assoc_item); } } else if let Some(l_curly) = impl_def.assoc_item_list().and_then(|it| it.l_curly_token()) { - builder.add_tabstop_after_token(cap, l_curly); + builder.add_tabstop_after_token(workspace_snippet_cap, l_curly); } } @@ -287,7 +287,9 @@ fn update_attribute( #[cfg(test)] mod tests { - use crate::tests::{check_assist, check_assist_no_snippet_cap, check_assist_not_applicable}; + use crate::tests::{ + check_assist, check_assist_no_workspace_snippet_cap, check_assist_not_applicable, + }; use super::*; @@ -317,7 +319,7 @@ impl core::fmt::Debug for Foo { } #[test] fn add_custom_impl_without_snippet() { - check_assist_no_snippet_cap( + check_assist_no_workspace_snippet_cap( replace_derive_with_manual_impl, r#" //- minicore: fmt, derive diff --git a/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs index 802d5f72b997..204b99b428c4 100644 --- a/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs +++ b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs @@ -72,12 +72,12 @@ pub(crate) fn replace_is_method_with_if_let_method( let pat = make.tuple_struct_pat(make.ident_path(text), [pat]).into(); let let_expr = make.expr_let(pat, receiver); - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(ast::Pat::TupleStructPat(pat)) = let_expr.pat() && let Some(first_var) = pat.fields().next() && predicate.is_none() { - let placeholder = edit.make_placeholder_snippet(cap); + let placeholder = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(first_var.syntax(), placeholder); } diff --git a/crates/ide-assists/src/handlers/unwrap_return_type.rs b/crates/ide-assists/src/handlers/unwrap_return_type.rs index 1fe9ea4eb875..6809ece71a6d 100644 --- a/crates/ide-assists/src/handlers/unwrap_return_type.rs +++ b/crates/ide-assists/src/handlers/unwrap_return_type.rs @@ -149,10 +149,10 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> let new_tail_expr = make.expr_unit(); editor.replace(path_expr.syntax(), new_tail_expr.syntax()); - if let Some(cap) = ctx.config.snippet_cap { + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap { editor.add_annotation( new_tail_expr.syntax(), - builder.make_placeholder_snippet(cap), + builder.make_placeholder_snippet(workspace_snippet_cap), ); final_placeholder = Some(new_tail_expr); @@ -162,10 +162,13 @@ pub(crate) fn unwrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> } } - if let Some(cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(final_placeholder) = final_placeholder { - editor.add_annotation(final_placeholder.syntax(), builder.make_tabstop_after(cap)); + editor.add_annotation( + final_placeholder.syntax(), + builder.make_tabstop_after(workspace_snippet_cap), + ); } builder.add_file_edits(ctx.vfs_file_id(), editor); diff --git a/crates/ide-assists/src/handlers/wrap_return_type.rs b/crates/ide-assists/src/handlers/wrap_return_type.rs index 81aa068aedea..b747fd4ba67c 100644 --- a/crates/ide-assists/src/handlers/wrap_return_type.rs +++ b/crates/ide-assists/src/handlers/wrap_return_type.rs @@ -147,12 +147,13 @@ pub(crate) fn wrap_return_type(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op ast::GenericArg::LifetimeArg(_) => false, _ => true, }); - if let Some(error_type_arg) = error_type_arg - && let Some(cap) = ctx.config.snippet_cap + + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap + && let Some(error_type_arg) = error_type_arg { editor.add_annotation( error_type_arg.syntax(), - builder.make_placeholder_snippet(cap), + builder.make_placeholder_snippet(workspace_snippet_cap), ); } } diff --git a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 635fab857d08..15ffb8aecf1e 100644 --- a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -214,10 +214,10 @@ fn wrap_derive( ], ); - if let Some(snippet_cap) = ctx.config.snippet_cap + if let Some(workspace_snippet_cap) = ctx.config.workspace_snippet_cap && let Some(cfg_predicate) = meta.cfg_predicate() { - let tabstop = edit.make_placeholder_snippet(snippet_cap); + let tabstop = edit.make_placeholder_snippet(workspace_snippet_cap); editor.add_annotation(cfg_predicate.syntax(), tabstop); } edit.add_file_edits(ctx.vfs_file_id(), editor); @@ -249,10 +249,10 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec { + match ctx.config.completion_snippet_cap { + Some(completion_snippet_cap) => { if incomplete_let && snippet.ends_with('}') { // complete block expression snippets with a trailing semicolon, if inside an incomplete let cov_mark::hit!(let_semi); - item.insert_snippet(cap, format!("{snippet};")); + item.insert_snippet(completion_snippet_cap, format!("{snippet};")); } else { - item.insert_snippet(cap, snippet); + item.insert_snippet(completion_snippet_cap, snippet); } } None => { @@ -191,9 +191,10 @@ impl Completions { let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw, ctx.edition); - match ctx.config.snippet_cap { - Some(cap) => item.insert_snippet(cap, snippet), - None => item.insert_text(if snippet.contains('$') { kw } else { snippet }), + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + item.insert_snippet(completion_snippet_cap, snippet) + } else { + item.insert_text(if snippet.contains('$') { kw } else { snippet }) }; item.add_to(self, ctx.db); } diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index da1e664f961c..a7eba4761db6 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -178,8 +178,10 @@ pub(crate) fn complete_attribute_path( item.lookup_by(lookup); } - if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) { - item.insert_snippet(cap, snippet); + if let Some(snippet) = snippet + && let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap + { + item.insert_snippet(completion_snippet_cap, snippet); } if is_inner || !attr_completion.prefer_inner { diff --git a/crates/ide-completion/src/completions/attribute/cfg.rs b/crates/ide-completion/src/completions/attribute/cfg.rs index 0d36fb7a405b..d0ce91af7f36 100644 --- a/crates/ide-completion/src/completions/attribute/cfg.rs +++ b/crates/ide-completion/src/completions/attribute/cfg.rs @@ -61,7 +61,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { hir::CfgAtom::Flag(key) => (key.as_str(), "".into()), hir::CfgAtom::KeyValue { key, .. } => ( key.as_str(), - if ctx.config.snippet_cap.is_some() { + if ctx.config.completion_snippet_cap.is_some() { SmolStr::from_iter([key.as_str(), " = $0"]) } else { SmolStr::default() @@ -77,10 +77,10 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { s, ctx.edition, ); - if let Some(cap) = ctx.config.snippet_cap + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap && !snippet.is_empty() { - item.insert_snippet(cap, snippet); + item.insert_snippet(completion_snippet_cap, snippet); } acc.add(item.build(ctx.db)); }), diff --git a/crates/ide-completion/src/completions/attribute/diagnostic.rs b/crates/ide-completion/src/completions/attribute/diagnostic.rs index 8adc97423909..5d1288e0804c 100644 --- a/crates/ide-completion/src/completions/attribute/diagnostic.rs +++ b/crates/ide-completion/src/completions/attribute/diagnostic.rs @@ -45,8 +45,10 @@ pub(super) fn complete_on_unimplemented( if let Some(lookup) = attr.lookup { item.lookup_by(lookup); } - if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) { - item.insert_snippet(cap, snippet); + if let Some(snippet) = attr.snippet + && let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap + { + item.insert_snippet(completion_snippet_cap, snippet); } item.add_to(acc, ctx.db); } diff --git a/crates/ide-completion/src/completions/attribute/repr.rs b/crates/ide-completion/src/completions/attribute/repr.rs index cb7ccf737312..b9cfcd6f8aa0 100644 --- a/crates/ide-completion/src/completions/attribute/repr.rs +++ b/crates/ide-completion/src/completions/attribute/repr.rs @@ -39,8 +39,10 @@ pub(super) fn complete_repr( if let Some(lookup) = lookup { item.lookup_by(lookup); } - if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) { - item.insert_snippet(cap, snippet); + if let Some(snippet) = snippet + && let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap + { + item.insert_snippet(completion_snippet_cap, snippet); } item.add_to(acc, ctx.db); } diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 4072f05a41f4..c255c672ee73 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -233,15 +233,15 @@ fn add_function_impl_( get_transformed_fn(ctx, source.value, impl_def, async_sugaring) { let function_decl = function_declaration(ctx, &transformed_fn, source.file_id.macro_file()); - match ctx.config.snippet_cap { - Some(cap) => { - let snippet = format!("{function_decl} {{\n $0\n}}"); - item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet)); - } - None => { - let header = format!("{function_decl} {{"); - item.text_edit(TextEdit::replace(replacement_range, header)); - } + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + let snippet = format!("{function_decl} {{\n $0\n}}"); + item.snippet_edit( + completion_snippet_cap, + TextEdit::replace(replacement_range, snippet), + ); + } else { + let header = format!("{function_decl} {{"); + item.text_edit(TextEdit::replace(replacement_range, header)); }; item.add_to(acc, ctx.db); } @@ -427,15 +427,15 @@ fn add_type_alias_impl( }) .unwrap_or_default(); - match ctx.config.snippet_cap { - Some(cap) => { - let snippet = format!("{decl}$0{wc};"); - item.snippet_edit(cap, TextEdit::replace(replacement_range, snippet)); - } - None => { - decl.push_str(&wc); - item.text_edit(TextEdit::replace(replacement_range, decl)); - } + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + let snippet = format!("{decl}$0{wc};"); + item.snippet_edit( + completion_snippet_cap, + TextEdit::replace(replacement_range, snippet), + ); + } else { + decl.push_str(&wc); + item.text_edit(TextEdit::replace(replacement_range, decl)); }; item.add_to(acc, ctx.db); } @@ -473,12 +473,13 @@ fn add_const_impl( exact_name_match: true, ..Default::default() }); - match ctx.config.snippet_cap { - Some(cap) => item.snippet_edit( - cap, + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + item.snippet_edit( + completion_snippet_cap, TextEdit::replace(replacement_range, format!("{replacement}$0;")), - ), - None => item.text_edit(TextEdit::replace(replacement_range, replacement)), + ) + } else { + item.text_edit(TextEdit::replace(replacement_range, replacement)) }; item.add_to(acc, ctx.db); } diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 82baf885ddc6..e68d03aab606 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -5,7 +5,7 @@ mod format_like; use base_db::SourceDatabase; use hir::{ItemInNs, Semantics}; use ide_db::{ - RootDatabase, SnippetCap, + CompletionSnippetCap, RootDatabase, documentation::{Documentation, HasDocs}, imports::insert_use::ImportScope, syntax_helpers::suggest_name::NameGenerator, @@ -57,14 +57,14 @@ pub(crate) fn complete_postfix( let receiver_text = get_receiver_text(&ctx.sema, dot_receiver, receiver_is_ambiguous_float_literal); - let cap = match ctx.config.snippet_cap { - Some(it) => it, - None => return, + let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap else { + return; }; - let postfix_snippet = match build_postfix_snippet_builder(ctx, cap, dot_receiver) { - Some(it) => it, - None => return, + let Some(postfix_snippet) = + build_postfix_snippet_builder(ctx, completion_snippet_cap, dot_receiver) + else { + return; }; let semi = if expr_ctx.in_block_expr && ctx.token.next_token().is_none_or(|it| it.kind() != T![;]) { @@ -100,11 +100,11 @@ pub(crate) fn complete_postfix( let (dot_receiver_including_refs, prefix) = include_references(&receiver_accessor); let mut receiver_text = receiver_text; receiver_text.insert_str(0, &prefix); - let postfix_snippet = - match build_postfix_snippet_builder(ctx, cap, &dot_receiver_including_refs) { - Some(it) => it, - None => return, - }; + let Some(postfix_snippet) = + build_postfix_snippet_builder(ctx, completion_snippet_cap, &dot_receiver_including_refs) + else { + return; + }; if !ctx.config.snippets.is_empty() { add_custom_postfix_completions(acc, ctx, &postfix_snippet, &receiver_text); @@ -310,7 +310,14 @@ pub(crate) fn complete_postfix( if let ast::Expr::Literal(literal) = dot_receiver.clone() && let Some(literal_text) = ast::String::cast(literal.token()) { - add_format_like_completions(acc, ctx, dot_receiver, cap, &literal_text, semi); + add_format_like_completions( + acc, + ctx, + dot_receiver, + completion_snippet_cap, + &literal_text, + semi, + ); } postfix_snippet("return", "return expr", &format!("return {receiver_text}{semi}")) @@ -446,7 +453,7 @@ fn include_references(initial_element: &ast::Expr) -> (ast::Expr, String) { fn build_postfix_snippet_builder<'ctx>( ctx: &'ctx CompletionContext<'_>, - cap: SnippetCap, + completion_snippet_cap: CompletionSnippetCap, receiver: &'ctx ast::Expr, ) -> Option Builder + 'ctx> { let receiver_range = ctx.sema.original_range_opt(receiver.syntax())?.range; @@ -462,7 +469,7 @@ fn build_postfix_snippet_builder<'ctx>( // can't be annotated for the closure, hence fix it by constructing it without the Option first fn build<'ctx>( ctx: &'ctx CompletionContext<'_>, - cap: SnippetCap, + completion_snippet_cap: CompletionSnippetCap, delete_range: TextRange, ) -> impl Fn(&str, &str, &str) -> Builder + 'ctx { move |label, detail, snippet| { @@ -473,7 +480,7 @@ fn build_postfix_snippet_builder<'ctx>( label, ctx.edition, ); - item.detail(detail).snippet_edit(cap, edit); + item.detail(detail).snippet_edit(completion_snippet_cap, edit); let postfix_match = if ctx.original_token.text() == label { cov_mark::hit!(postfix_exact_match_is_high_priority); Some(CompletionRelevancePostfixMatch::Exact) @@ -486,7 +493,7 @@ fn build_postfix_snippet_builder<'ctx>( item } } - Some(build(ctx, cap, delete_range)) + Some(build(ctx, completion_snippet_cap, delete_range)) } fn add_custom_postfix_completions( diff --git a/crates/ide-completion/src/completions/postfix/format_like.rs b/crates/ide-completion/src/completions/postfix/format_like.rs index 85a8899fd10b..0dfcc9718163 100644 --- a/crates/ide-completion/src/completions/postfix/format_like.rs +++ b/crates/ide-completion/src/completions/postfix/format_like.rs @@ -17,7 +17,7 @@ // ![Format String Completion](https://user-images.githubusercontent.com/48062697/113020656-b560f500-917a-11eb-87de-02991f61beb8.gif) use ide_db::{ - SnippetCap, + CompletionSnippetCap, syntax_helpers::format_string_exprs::{Arg, parse_format_exprs, with_placeholders}, }; use syntax::{AstToken, ast}; @@ -46,14 +46,15 @@ pub(crate) fn add_format_like_completions( acc: &mut Completions, ctx: &CompletionContext<'_>, dot_receiver: &ast::Expr, - cap: SnippetCap, + completion_snippet_cap: CompletionSnippetCap, receiver_text: &ast::String, semi: &str, ) { - let postfix_snippet = match build_postfix_snippet_builder(ctx, cap, dot_receiver) { - Some(it) => it, - None => return, - }; + let postfix_snippet = + match build_postfix_snippet_builder(ctx, completion_snippet_cap, dot_receiver) { + Some(it) => it, + None => return, + }; if let Ok((mut out, mut exprs)) = parse_format_exprs(receiver_text.text()) { // Escape any snippet bits in the out text and any of the exprs. diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs index 12c564af5cba..62f843348e54 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -149,8 +149,6 @@ fn complete_fields( #[cfg(test)] mod tests { - use ide_db::SnippetCap; - use crate::{ CompletionConfig, tests::{TEST_CONFIG, check_edit, check_edit_with_config}, @@ -210,7 +208,7 @@ fn baz() { #[test] fn enum_variant_no_snippets() { - let conf = CompletionConfig { snippet_cap: SnippetCap::new(false), ..TEST_CONFIG }; + let conf = CompletionConfig { completion_snippet_cap: None, ..TEST_CONFIG }; // tuple variant check_edit_with_config( conf.clone(), diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs index 04450aea75bf..323bd1ecaf70 100644 --- a/crates/ide-completion/src/completions/snippet.rs +++ b/crates/ide-completion/src/completions/snippet.rs @@ -1,6 +1,8 @@ //! This file provides snippet completions, like `pd` => `eprintln!(...)`. -use ide_db::{SnippetCap, documentation::Documentation, imports::insert_use::ImportScope}; +use ide_db::{ + CompletionSnippetCap, documentation::Documentation, imports::insert_use::ImportScope, +}; use crate::{ CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope, @@ -21,21 +23,22 @@ pub(crate) fn complete_expr_snippet( return; } - let cap = match ctx.config.snippet_cap { - Some(it) => it, - None => return, + let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap else { + return; }; if !ctx.config.snippets.is_empty() { - add_custom_completions(acc, ctx, cap, SnippetScope::Expr); + add_custom_completions(acc, ctx, completion_snippet_cap, SnippetScope::Expr); } if in_block_expr { - snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc, ctx.db); - snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc, ctx.db); + snippet(ctx, completion_snippet_cap, "pd", "eprintln!(\"$0 = {:?}\", $0);") + .add_to(acc, ctx.db); + snippet(ctx, completion_snippet_cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);") + .add_to(acc, ctx.db); let item = snippet( ctx, - cap, + completion_snippet_cap, "macro_rules", "\ macro_rules! $1 { @@ -60,20 +63,19 @@ pub(crate) fn complete_item_snippet( if !ctx.qualifier_ctx.none() { return; } - let cap = match ctx.config.snippet_cap { - Some(it) => it, - None => return, + let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap else { + return; }; if !ctx.config.snippets.is_empty() { - add_custom_completions(acc, ctx, cap, SnippetScope::Item); + add_custom_completions(acc, ctx, completion_snippet_cap, SnippetScope::Item); } // Test-related snippets shouldn't be shown in blocks. if let ItemListKind::SourceFile | ItemListKind::Module = kind { let mut item = snippet( ctx, - cap, + completion_snippet_cap, "tmod (Test module)", "\ #[cfg(test)] @@ -91,7 +93,7 @@ mod tests { let mut item = snippet( ctx, - cap, + completion_snippet_cap, "tfn (Test function)", "\ #[test] @@ -104,7 +106,7 @@ fn ${1:feature}() { let item = snippet( ctx, - cap, + completion_snippet_cap, "macro_rules", "\ macro_rules! $1 { @@ -117,17 +119,22 @@ macro_rules! $1 { } } -fn snippet(ctx: &CompletionContext<'_>, cap: SnippetCap, label: &str, snippet: &str) -> Builder { +fn snippet( + ctx: &CompletionContext<'_>, + completion_snippet_cap: CompletionSnippetCap, + label: &str, + snippet: &str, +) -> Builder { let mut item = CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label, ctx.edition); - item.insert_snippet(cap, snippet); + item.insert_snippet(completion_snippet_cap, snippet); item } fn add_custom_completions( acc: &mut Completions, ctx: &CompletionContext<'_>, - cap: SnippetCap, + completion_snippet_cap: CompletionSnippetCap, scope: SnippetScope, ) -> Option<()> { ImportScope::find_insert_use_container(&ctx.token.parent()?, &ctx.sema)?; @@ -138,7 +145,7 @@ fn add_custom_completions( None => return, }; let body = snip.snippet(); - let mut builder = snippet(ctx, cap, trigger, &body); + let mut builder = snippet(ctx, completion_snippet_cap, trigger, &body); builder.documentation(Documentation::new_owned(format!("```rust\n{body}\n```"))); for import in imports.into_iter() { builder.add_import(import); diff --git a/crates/ide-completion/src/config.rs b/crates/ide-completion/src/config.rs index 80c1572972ce..588e72105f6d 100644 --- a/crates/ide-completion/src/config.rs +++ b/crates/ide-completion/src/config.rs @@ -6,7 +6,7 @@ use hir::FindPathConfig; use ide_db::{ - SnippetCap, + CompletionSnippetCap, imports::{import_assets::ImportPathConfig, insert_use::InsertUseConfig}, ra_fixture::RaFixtureConfig, }; @@ -26,7 +26,7 @@ pub struct CompletionConfig<'a> { pub full_function_signatures: bool, pub callable: Option, pub add_semicolon_to_unit: bool, - pub snippet_cap: Option, + pub completion_snippet_cap: Option, pub insert_use: InsertUseConfig, pub prefer_no_std: bool, pub prefer_prelude: bool, diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index 6abf4f632aa8..cc0aebdc02b8 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -3,10 +3,9 @@ use std::{fmt, mem}; use hir::Mutability; -use ide_db::text_edit::TextEdit; +use ide_db::{CompletionSnippetCap, text_edit::TextEdit}; use ide_db::{ - RootDatabase, SnippetCap, SymbolKind, documentation::Documentation, - imports::import_assets::LocatedImport, + RootDatabase, SymbolKind, documentation::Documentation, imports::import_assets::LocatedImport, }; use itertools::Itertools; use macros::UpmapFromRaFixture; @@ -653,10 +652,9 @@ impl Builder { } pub(crate) fn insert_snippet( &mut self, - cap: SnippetCap, + _completion_snippet_cap: CompletionSnippetCap, snippet: impl Into, ) -> &mut Builder { - let _ = cap; self.is_snippet = true; self.insert_text(snippet) } @@ -664,7 +662,11 @@ impl Builder { self.text_edit = Some(edit); self } - pub(crate) fn snippet_edit(&mut self, _cap: SnippetCap, edit: TextEdit) -> &mut Builder { + pub(crate) fn snippet_edit( + &mut self, + _completion_snippet_cap: CompletionSnippetCap, + edit: TextEdit, + ) -> &mut Builder { self.is_snippet = true; self.text_edit(edit) } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index a636c0603ba5..41d750294f01 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -13,7 +13,7 @@ pub(crate) mod variant; use hir::{AsAssocItem, HasAttrs, HirDisplay, Impl, ModuleDef, ScopeDef, Type}; use ide_db::text_edit::TextEdit; use ide_db::{ - RootDatabase, SnippetCap, SymbolKind, + CompletionSnippetCap, RootDatabase, SymbolKind, documentation::{Documentation, HasDocs}, helpers::item_name, imports::import_assets::LocatedImport, @@ -67,8 +67,8 @@ impl<'a> RenderContext<'a> { self } - fn snippet_cap(&self) -> Option { - self.completion.config.snippet_cap + fn completion_snippet_cap(&self) -> Option { + self.completion.config.completion_snippet_cap } fn db(&self) -> &'a RootDatabase { @@ -327,7 +327,9 @@ pub(crate) fn render_expr( expr.gen_source_code(&ctx.scope, &mut snippet_formatter, cfg, ctx.display_target).ok()? ); let edit = TextEdit::replace(source_range, snippet); - item.snippet_edit(ctx.config.snippet_cap?, edit); + if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + item.snippet_edit(completion_snippet_cap, edit); + } item.documentation(Documentation::new_owned(String::from( "Autogenerated expression by term search", ))); @@ -430,7 +432,7 @@ fn render_resolution_path( let completion = ctx.completion; let module = completion.module; - let cap = ctx.snippet_cap(); + let completion_snippet_cap = ctx.completion_snippet_cap(); let db = completion.db; let config = completion.config; let requires_import = import_to_add.is_some(); @@ -444,7 +446,7 @@ fn render_resolution_path( path_ctx, PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. } ) && config.callable.is_some(); - if type_path_no_ty_args && let Some(cap) = cap { + if type_path_no_ty_args && let Some(completion_snippet_cap) = completion_snippet_cap { let has_non_default_type_params = match resolution { ScopeDef::ModuleDef(hir::ModuleDef::Adt(it)) => it.has_non_default_type_params(db), ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(it)) => { @@ -459,7 +461,7 @@ fn render_resolution_path( item.lookup_by(name.clone()) .label(SmolStr::from_iter([&name, "<…>"])) .trigger_call_info() - .insert_snippet(cap, ""); // set is snippet + .insert_snippet(completion_snippet_cap, ""); // set is snippet } } adds_ret_type_arrow(completion, path_ctx, &mut item, insert_text.into()); @@ -607,8 +609,8 @@ pub(crate) fn render_type_keyword_snippet( let insert_text = if !snippet.contains('$') { item.insert_text(snippet); snippet - } else if let Some(cap) = ctx.config.snippet_cap { - item.insert_snippet(cap, snippet); + } else if let Some(completion_snippet_cap) = ctx.config.completion_snippet_cap { + item.insert_snippet(completion_snippet_cap, snippet); snippet } else { label diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index 18151cffcd39..ee5aef7bb79d 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -1,7 +1,7 @@ //! Renderer for function calls. use hir::{AsAssocItem, HirDisplay, db::HirDatabase}; -use ide_db::{SnippetCap, SymbolKind}; +use ide_db::{CompletionSnippetCap, SymbolKind}; use itertools::Itertools; use stdx::{format_to, to_lower_snake_case}; use syntax::{AstNode, SmolStr, ToSmolStr, format_smolstr}; @@ -87,21 +87,21 @@ fn render( } }); - let (has_dot_receiver, has_call_parens, cap) = match func_kind { + let (has_dot_receiver, has_call_parens, completion_snippet_cap) = match func_kind { FuncKind::Function(&PathCompletionCtx { kind: PathKind::Expr { .. }, has_call_parens, .. - }) => (false, has_call_parens, ctx.completion.config.snippet_cap), + }) => (false, has_call_parens, ctx.completion.config.completion_snippet_cap), FuncKind::Method(&DotAccess { kind: DotAccessKind::Method, .. }, _) => { - (true, true, ctx.completion.config.snippet_cap) + (true, true, ctx.completion.config.completion_snippet_cap) } FuncKind::Method(DotAccess { kind: DotAccessKind::Field { .. }, .. }, _) => { - (true, false, ctx.completion.config.snippet_cap) + (true, false, ctx.completion.config.completion_snippet_cap) } _ => (false, false, None), }; - let complete_call_parens = cap + let complete_call_parens = completion_snippet_cap .filter(|_| !has_call_parens) .and_then(|cap| Some((cap, params(ctx.completion, func, &func_kind, has_dot_receiver)?))); @@ -151,11 +151,11 @@ fn render( .detail(detail) .lookup_by(name.as_str().to_smolstr()); - if let Some((cap, (self_param, params))) = complete_call_parens { + if let Some((completion_snippet_cap, (self_param, params))) = complete_call_parens { add_call_parens( &mut item, completion, - cap, + completion_snippet_cap, call, escaped_call, self_param, @@ -211,7 +211,7 @@ fn compute_return_type_match( pub(super) fn add_call_parens<'b>( builder: &'b mut Builder, ctx: &CompletionContext<'_>, - cap: SnippetCap, + completion_snippet_cap: CompletionSnippetCap, name: SmolStr, escaped_name: SmolStr, self_param: Option, @@ -283,7 +283,9 @@ pub(super) fn add_call_parens<'b>( } } } - builder.label(SmolStr::from_iter([&name, label_suffix])).insert_snippet(cap, snippet) + builder + .label(SmolStr::from_iter([&name, label_suffix])) + .insert_snippet(completion_snippet_cap, snippet) } fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type<'_>) -> &'static str { diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs index b7de3da468dd..674b23d71503 100644 --- a/crates/ide-completion/src/render/literal.rs +++ b/crates/ide-completion/src/render/literal.rs @@ -77,14 +77,14 @@ fn render( qualified_name.display_verbatim(ctx.db()).to_string(), qualified_name.display(ctx.db(), completion.edition).to_string(), ); - let snippet_cap = ctx.snippet_cap(); + let completion_snippet_cap = ctx.completion_snippet_cap(); let mut rendered = match kind { StructKind::Tuple if should_add_parens => { - render_tuple_lit(completion, snippet_cap, &fields, &escaped_qualified_name) + render_tuple_lit(completion, completion_snippet_cap, &fields, &escaped_qualified_name) } StructKind::Record if should_add_parens => { - render_record_lit(completion, snippet_cap, &fields, &escaped_qualified_name) + render_record_lit(completion, completion_snippet_cap, &fields, &escaped_qualified_name) } _ => RenderedLiteral { literal: escaped_qualified_name.clone(), @@ -92,7 +92,7 @@ fn render( }, }; - if snippet_cap.is_some() { + if completion_snippet_cap.is_some() { rendered.literal.push_str("$0"); } @@ -100,7 +100,7 @@ fn render( if !should_add_parens { kind = StructKind::Unit; } - let label = format_literal_label(&qualified_name, kind, snippet_cap); + let label = format_literal_label(&qualified_name, kind, completion_snippet_cap); let lookup = if qualified { format_literal_lookup( &short_qualified_name.display(ctx.db(), completion.edition).to_string(), @@ -120,10 +120,11 @@ fn render( item.lookup_by(lookup); item.detail(rendered.detail); - match snippet_cap { - Some(snippet_cap) => item.insert_snippet(snippet_cap, rendered.literal).trigger_call_info(), - None => item.insert_text(rendered.literal), - }; + if let Some(completion_snippet_cap) = completion_snippet_cap { + item.insert_snippet(completion_snippet_cap, rendered.literal).trigger_call_info(); + } else { + item.insert_text(rendered.literal); + } item.set_documentation(thing.docs(db)).set_deprecated(thing.is_deprecated(&ctx)); diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs index ff4cf9a75b60..111248d38ffa 100644 --- a/crates/ide-completion/src/render/macro_.rs +++ b/crates/ide-completion/src/render/macro_.rs @@ -69,20 +69,19 @@ fn render( .set_documentation(docs) .set_relevance(ctx.completion_relevance()); - match ctx.snippet_cap() { - Some(cap) if needs_bang && !has_call_parens => { - let snippet = format!("{escaped_name}!{bra}$0{ket}"); - let lookup = banged_name(name); - item.insert_snippet(cap, snippet).lookup_by(lookup); - } - _ if needs_bang => { - item.insert_text(banged_name(&escaped_name)).lookup_by(banged_name(name)); - } - _ => { - cov_mark::hit!(dont_insert_macro_call_parens_unnecessary); - item.insert_text(escaped_name); - } - }; + if let Some(completion_snippet_cap) = ctx.completion_snippet_cap() + && needs_bang + && !has_call_parens + { + let snippet = format!("{escaped_name}!{bra}$0{ket}"); + let lookup = banged_name(name); + item.insert_snippet(completion_snippet_cap, snippet).lookup_by(lookup); + } else if needs_bang { + item.insert_text(banged_name(&escaped_name)).lookup_by(banged_name(name)); + } else { + cov_mark::hit!(dont_insert_macro_call_parens_unnecessary); + item.insert_text(escaped_name); + } if let Some(import_to_add) = ctx.import_to_add { item.add_import(import_to_add); } @@ -98,7 +97,7 @@ fn label( name: &SmolStr, ) -> SmolStr { if needs_bang { - if ctx.snippet_cap().is_some() { + if ctx.completion_snippet_cap().is_some() { format_smolstr!("{name}!{bra}…{ket}",) } else { banged_name(name) diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 022e97e4f760..718e6959bf22 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -1,7 +1,7 @@ //! Renderer for patterns. use hir::{Name, StructKind, db::HirDatabase}; -use ide_db::{SnippetCap, documentation::HasDocs}; +use ide_db::{CompletionSnippetCap, documentation::HasDocs}; use itertools::Itertools; use syntax::{Edition, SmolStr, ToSmolStr}; @@ -34,7 +34,7 @@ pub(crate) fn render_struct_pat( let (name, escaped_name) = (name.as_str(), name.display(ctx.db(), ctx.completion.edition).to_smolstr()); let kind = strukt.kind(ctx.db()); - let label = format_literal_label(name, kind, ctx.snippet_cap()); + let label = format_literal_label(name, kind, ctx.completion_snippet_cap()); let lookup = format_literal_lookup(name, kind); let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?; @@ -78,7 +78,7 @@ pub(crate) fn render_variant_pat( } _ => { let kind = variant.kind(ctx.db()); - let label = format_literal_label(name.as_str(), kind, ctx.snippet_cap()); + let label = format_literal_label(name.as_str(), kind, ctx.completion_snippet_cap()); let lookup = format_literal_lookup(name.as_str(), kind); let pat = render_pat( &ctx, @@ -132,9 +132,10 @@ fn build_completion( .detail(&pat) .lookup_by(lookup) .set_relevance(relevance); - match ctx.snippet_cap() { - Some(snippet_cap) => item.insert_snippet(snippet_cap, pat), - None => item.insert_text(pat), + if let Some(completion_snippet_cap) = ctx.completion_snippet_cap() { + item.insert_snippet(completion_snippet_cap, pat) + } else { + item.insert_text(pat) }; item.build(ctx.db()) } @@ -148,10 +149,12 @@ fn render_pat( fields_omitted: bool, ) -> Option { let mut pat = match kind { - StructKind::Tuple => render_tuple_as_pat(ctx.snippet_cap(), fields, name, fields_omitted), + StructKind::Tuple => { + render_tuple_as_pat(ctx.completion_snippet_cap(), fields, name, fields_omitted) + } StructKind::Record => render_record_as_pat( ctx.db(), - ctx.snippet_cap(), + ctx.completion_snippet_cap(), fields, name, fields_omitted, @@ -174,7 +177,7 @@ fn render_pat( pat.push(' '); pat.push_str(name); } - if ctx.snippet_cap().is_some() { + if ctx.completion_snippet_cap().is_some() { pat.push_str("$0"); } Some(pat) @@ -182,60 +185,54 @@ fn render_pat( fn render_record_as_pat( db: &dyn HirDatabase, - snippet_cap: Option, + completion_snippet_cap: Option, fields: &[hir::Field], name: &str, fields_omitted: bool, edition: Edition, ) -> String { let fields = fields.iter(); - match snippet_cap { - Some(_) => { - format!( - "{name} {{ {}{} }}", - fields.enumerate().format_with(", ", |(idx, field), f| { - f(&format_args!("{}${}", field.name(db).display(db, edition), idx + 1)) - }), - if fields_omitted { ", .." } else { "" }, - name = name - ) - } - None => { - format!( - "{name} {{ {}{} }}", - fields.map(|field| field.name(db).display_no_db(edition).to_smolstr()).format(", "), - if fields_omitted { ", .." } else { "" }, - name = name - ) - } + if completion_snippet_cap.is_some() { + format!( + "{name} {{ {}{} }}", + fields.enumerate().format_with(", ", |(idx, field), f| { + f(&format_args!("{}${}", field.name(db).display(db, edition), idx + 1)) + }), + if fields_omitted { ", .." } else { "" }, + name = name + ) + } else { + format!( + "{name} {{ {}{} }}", + fields.map(|field| field.name(db).display_no_db(edition).to_smolstr()).format(", "), + if fields_omitted { ", .." } else { "" }, + name = name + ) } } fn render_tuple_as_pat( - snippet_cap: Option, + completion_snippet_cap: Option, fields: &[hir::Field], name: &str, fields_omitted: bool, ) -> String { let fields = fields.iter(); - match snippet_cap { - Some(_) => { - format!( - "{name}({}{})", - fields - .enumerate() - .format_with(", ", |(idx, _), f| { f(&format_args!("${}", idx + 1)) }), - if fields_omitted { ", .." } else { "" }, - name = name - ) - } - None => { - format!( - "{name}({}{})", - fields.enumerate().map(|(idx, _)| idx).format(", "), - if fields_omitted { ", .." } else { "" }, - name = name - ) - } + if completion_snippet_cap.is_some() { + format!( + "{name}({}{})", + fields + .enumerate() + .format_with(", ", |(idx, _), f| { f(&format_args!("${}", idx + 1)) }), + if fields_omitted { ", .." } else { "" }, + name = name + ) + } else { + format!( + "{name}({}{})", + fields.enumerate().map(|(idx, _)| idx).format(", "), + if fields_omitted { ", .." } else { "" }, + name = name + ) } } diff --git a/crates/ide-completion/src/render/union_literal.rs b/crates/ide-completion/src/render/union_literal.rs index 7164c94fde94..1bbf1b1f8aa2 100644 --- a/crates/ide-completion/src/render/union_literal.rs +++ b/crates/ide-completion/src/render/union_literal.rs @@ -34,7 +34,7 @@ pub(crate) fn render_union_literal( let label = format_literal_label( &name.display_no_db(ctx.completion.edition).to_smolstr(), StructKind::Record, - ctx.snippet_cap(), + ctx.completion_snippet_cap(), ); let lookup = format_literal_lookup( &name.display_no_db(ctx.completion.edition).to_smolstr(), @@ -56,7 +56,7 @@ pub(crate) fn render_union_literal( return None; } - let literal = if ctx.snippet_cap().is_some() { + let literal = if ctx.completion_snippet_cap().is_some() { format!( "{} {{ ${{1|{}|}}: ${{2:()}} }}$0", escaped_qualified_name, @@ -99,9 +99,10 @@ pub(crate) fn render_union_literal( .detail(detail) .set_relevance(ctx.completion_relevance()); - match ctx.snippet_cap() { - Some(snippet_cap) => item.insert_snippet(snippet_cap, literal).trigger_call_info(), - None => item.insert_text(literal), + if let Some(completion_snippet_cap) = ctx.completion_snippet_cap() { + item.insert_snippet(completion_snippet_cap, literal).trigger_call_info() + } else { + item.insert_text(literal) }; Some(item.build(ctx.db())) diff --git a/crates/ide-completion/src/render/variant.rs b/crates/ide-completion/src/render/variant.rs index ce35ab135f3c..3133b17bf267 100644 --- a/crates/ide-completion/src/render/variant.rs +++ b/crates/ide-completion/src/render/variant.rs @@ -2,7 +2,7 @@ use crate::context::CompletionContext; use hir::{HasAttrs, HasCrate, HasVisibility, HirDisplay, StructKind}; -use ide_db::SnippetCap; +use ide_db::CompletionSnippetCap; use itertools::Itertools; use syntax::SmolStr; @@ -18,11 +18,11 @@ pub(crate) struct RenderedLiteral { /// the `name` argument for an anonymous type. pub(crate) fn render_record_lit( ctx: &CompletionContext<'_>, - snippet_cap: Option, + completion_snippet_cap: Option, fields: &[hir::Field], path: &str, ) -> RenderedLiteral { - if snippet_cap.is_none() { + if completion_snippet_cap.is_none() { return RenderedLiteral { literal: path.to_owned(), detail: path.to_owned() }; } let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| { @@ -39,7 +39,7 @@ pub(crate) fn render_record_lit( f(&format_args!("{}: {fill}", field_name.display(ctx.db, ctx.edition))) } }; - if snippet_cap.is_some() { + if completion_snippet_cap.is_some() { fmt_field(format_args!("${{{}:()}}", idx + 1), format_args!("${}", idx + 1)) } else { fmt_field(format_args!("()"), format_args!("")) @@ -64,15 +64,15 @@ pub(crate) fn render_record_lit( /// the `name` argument for an anonymous type. pub(crate) fn render_tuple_lit( ctx: &CompletionContext<'_>, - snippet_cap: Option, + completion_snippet_cap: Option, fields: &[hir::Field], path: &str, ) -> RenderedLiteral { - if snippet_cap.is_none() { + if completion_snippet_cap.is_none() { return RenderedLiteral { literal: path.to_owned(), detail: path.to_owned() }; } let completions = fields.iter().enumerate().format_with(", ", |(idx, _), f| { - if snippet_cap.is_some() { + if completion_snippet_cap.is_some() { f(&format_args!("${{{}:()}}", idx + 1)) } else { f(&format_args!("()")) @@ -115,9 +115,9 @@ pub(crate) fn visible_fields( pub(crate) fn format_literal_label( name: &str, kind: StructKind, - snippet_cap: Option, + completion_snippet_cap: Option, ) -> SmolStr { - if snippet_cap.is_none() { + if completion_snippet_cap.is_none() { return name.into(); } match kind { diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs index 02e299b2a9c1..3efc65a91968 100644 --- a/crates/ide-completion/src/tests.rs +++ b/crates/ide-completion/src/tests.rs @@ -29,7 +29,7 @@ use expect_test::Expect; use hir::db::HirDatabase; use hir::{PrefixKind, setup_tracing}; use ide_db::{ - FilePosition, RootDatabase, SnippetCap, + CompletionSnippetCap, FilePosition, RootDatabase, imports::insert_use::{ImportGranularity, InsertUseConfig}, ra_fixture::RaFixtureConfig, }; @@ -73,7 +73,7 @@ pub(crate) const TEST_CONFIG: CompletionConfig<'_> = CompletionConfig { full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), add_semicolon_to_unit: true, - snippet_cap: SnippetCap::new(true), + completion_snippet_cap: CompletionSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: PrefixKind::Plain, diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index 6b72a3033990..b35356bb873d 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -335,13 +335,24 @@ impl SymbolKind { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct SnippetCap { +pub struct WorkspaceSnippetCap { _private: (), } -impl SnippetCap { - pub const fn new(allow_snippets: bool) -> Option { - if allow_snippets { Some(SnippetCap { _private: () }) } else { None } +impl WorkspaceSnippetCap { + pub const fn new(allow_snippets: bool) -> Option { + if allow_snippets { Some(Self { _private: () }) } else { None } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct CompletionSnippetCap { + _private: (), +} + +impl CompletionSnippetCap { + pub const fn new(allow_snippets: bool) -> Option { + if allow_snippets { Some(Self { _private: () }) } else { None } } } diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs index 81b679ead233..9bff6fda512f 100644 --- a/crates/ide-db/src/source_change.rs +++ b/crates/ide-db/src/source_change.rs @@ -7,7 +7,7 @@ use std::{collections::hash_map::Entry, fmt, iter, mem}; use crate::imports::insert_use::{ImportScope, ImportScopeKind}; use crate::text_edit::{TextEdit, TextEditBuilder}; -use crate::{SnippetCap, assists::Command, syntax_helpers::tree_diff::diff}; +use crate::{WorkspaceSnippetCap, assists::Command, syntax_helpers::tree_diff::diff}; use base_db::AnchoredPathBuf; use itertools::Itertools; use macros::UpmapFromRaFixture; @@ -294,16 +294,25 @@ impl SourceChangeBuilder { } } - pub fn make_placeholder_snippet(&mut self, _cap: SnippetCap) -> SyntaxAnnotation { - self.add_snippet_annotation(AnnotationSnippet::Over) + pub fn make_placeholder_snippet( + &mut self, + workspace_snippet_cap: WorkspaceSnippetCap, + ) -> SyntaxAnnotation { + self.add_snippet_annotation(workspace_snippet_cap, AnnotationSnippet::Over) } - pub fn make_tabstop_before(&mut self, _cap: SnippetCap) -> SyntaxAnnotation { - self.add_snippet_annotation(AnnotationSnippet::Before) + pub fn make_tabstop_before( + &mut self, + workspace_snippet_cap: WorkspaceSnippetCap, + ) -> SyntaxAnnotation { + self.add_snippet_annotation(workspace_snippet_cap, AnnotationSnippet::Before) } - pub fn make_tabstop_after(&mut self, _cap: SnippetCap) -> SyntaxAnnotation { - self.add_snippet_annotation(AnnotationSnippet::After) + pub fn make_tabstop_after( + &mut self, + workspace_snippet_cap: WorkspaceSnippetCap, + ) -> SyntaxAnnotation { + self.add_snippet_annotation(workspace_snippet_cap, AnnotationSnippet::After) } fn commit(&mut self) { @@ -429,37 +438,37 @@ impl SourceChangeBuilder { } /// Adds a tabstop snippet to place the cursor before `node` - pub fn add_tabstop_before(&mut self, _cap: SnippetCap, node: impl AstNode) { + pub fn add_tabstop_before(&mut self, _cap: WorkspaceSnippetCap, node: impl AstNode) { assert!(node.syntax().parent().is_some()); self.add_snippet(PlaceSnippet::Before(node.syntax().clone().into())); } /// Adds a tabstop snippet to place the cursor after `node` - pub fn add_tabstop_after(&mut self, _cap: SnippetCap, node: impl AstNode) { + pub fn add_tabstop_after(&mut self, _cap: WorkspaceSnippetCap, node: impl AstNode) { assert!(node.syntax().parent().is_some()); self.add_snippet(PlaceSnippet::After(node.syntax().clone().into())); } /// Adds a tabstop snippet to place the cursor before `token` - pub fn add_tabstop_before_token(&mut self, _cap: SnippetCap, token: SyntaxToken) { + pub fn add_tabstop_before_token(&mut self, _cap: WorkspaceSnippetCap, token: SyntaxToken) { assert!(token.parent().is_some()); self.add_snippet(PlaceSnippet::Before(token.into())); } /// Adds a tabstop snippet to place the cursor after `token` - pub fn add_tabstop_after_token(&mut self, _cap: SnippetCap, token: SyntaxToken) { + pub fn add_tabstop_after_token(&mut self, _cap: WorkspaceSnippetCap, token: SyntaxToken) { assert!(token.parent().is_some()); self.add_snippet(PlaceSnippet::After(token.into())); } /// Adds a snippet to move the cursor selected over `node` - pub fn add_placeholder_snippet(&mut self, _cap: SnippetCap, node: impl AstNode) { + pub fn add_placeholder_snippet(&mut self, _cap: WorkspaceSnippetCap, node: impl AstNode) { assert!(node.syntax().parent().is_some()); self.add_snippet(PlaceSnippet::Over(node.syntax().clone().into())) } /// Adds a snippet to move the cursor selected over `token` - pub fn add_placeholder_snippet_token(&mut self, _cap: SnippetCap, token: SyntaxToken) { + pub fn add_placeholder_snippet_token(&mut self, _cap: WorkspaceSnippetCap, token: SyntaxToken) { assert!(token.parent().is_some()); self.add_snippet(PlaceSnippet::Over(token.into())) } @@ -468,7 +477,11 @@ impl SourceChangeBuilder { /// /// This allows for renaming newly generated items without having to go /// through a separate rename step. - pub fn add_placeholder_snippet_group(&mut self, _cap: SnippetCap, nodes: Vec) { + pub fn add_placeholder_snippet_group( + &mut self, + _cap: WorkspaceSnippetCap, + nodes: Vec, + ) { assert!(nodes.iter().all(|node| node.parent().is_some())); self.add_snippet(PlaceSnippet::OverGroup( nodes.into_iter().map(|node| node.into()).collect(), @@ -481,7 +494,11 @@ impl SourceChangeBuilder { self.source_change.is_snippet = true; } - fn add_snippet_annotation(&mut self, kind: AnnotationSnippet) -> SyntaxAnnotation { + fn add_snippet_annotation( + &mut self, + _cap: WorkspaceSnippetCap, + kind: AnnotationSnippet, + ) -> SyntaxAnnotation { let annotation = SyntaxAnnotation::default(); self.snippet_annotations.push((kind, annotation)); self.source_change.is_snippet = true; diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index 09c9f8eab0a0..0260f5f4046f 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs @@ -94,7 +94,7 @@ use hir::{ Crate, DisplayTarget, InFile, Semantics, db::ExpandDatabase, diagnostics::AnyDiagnostic, }; use ide_db::{ - FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, SnippetCap, + FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, Severity, WorkspaceSnippetCap, assists::{Assist, AssistId, AssistResolveStrategy, ExprFillDefaultMode}, base_db::{ReleaseChannel, all_crates, toolchain_channel}, generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup}, @@ -231,7 +231,7 @@ pub struct DiagnosticsConfig { pub expr_fill_default: ExprFillDefaultMode, pub style_lints: bool, // FIXME: We may want to include a whole `AssistConfig` here - pub snippet_cap: Option, + pub workspace_snippet_cap: Option, pub insert_use: InsertUseConfig, pub prefer_no_std: bool, pub prefer_prelude: bool, @@ -254,7 +254,7 @@ impl DiagnosticsConfig { disabled: Default::default(), expr_fill_default: Default::default(), style_lints: true, - snippet_cap: SnippetCap::new(true), + workspace_snippet_cap: WorkspaceSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Item, enforce_granularity: false, diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index da2ec740197e..2b2bf265fb1e 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml @@ -29,7 +29,7 @@ ide-completion.workspace = true indexmap.workspace = true itertools.workspace = true scip = "0.7.1" -lsp-types = { version = "=0.95.0", features = ["proposed"] } +lsp-types = { version = "=0.97.0", features = ["proposed"] } parking_lot = "0.12.4" xflags = "0.3.2" oorandom = "11.1.5" diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 44c442ffd81d..890683233823 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs @@ -14,7 +14,7 @@ use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc}; use anyhow::Context; use lsp_server::Connection; -use paths::Utf8PathBuf; +use paths::{Utf8Component, Utf8PathBuf, Utf8Prefix}; use rust_analyzer::{ cli::flags, config::{Config, ConfigChange, ConfigErrors}, @@ -207,6 +207,7 @@ fn run_server() -> anyhow::Result<()> { tracing::info!("InitializeParams: {}", initialize_params); let lsp_types::InitializeParams { + #[expect(deprecated, reason = "migration TODO")] root_uri, mut capabilities, workspace_folders, @@ -227,9 +228,8 @@ fn run_server() -> anyhow::Result<()> { } let root_path = match root_uri - .and_then(|it| it.to_file_path().ok()) + .map(|it| Utf8PathBuf::from(it.as_str().to_owned())) .map(patch_path_prefix) - .and_then(|it| Utf8PathBuf::from_path_buf(it).ok()) .and_then(|it| AbsPathBuf::try_from(it).ok()) { Some(it) => it, @@ -251,9 +251,8 @@ fn run_server() -> anyhow::Result<()> { .map(|workspaces| { workspaces .into_iter() - .filter_map(|it| it.uri.to_file_path().ok()) + .map(|it| Utf8PathBuf::from(it.uri.to_string())) .map(patch_path_prefix) - .filter_map(|it| Utf8PathBuf::from_path_buf(it).ok()) .filter_map(|it| AbsPathBuf::try_from(it).ok()) .collect::>() }) @@ -325,8 +324,7 @@ fn run_server() -> anyhow::Result<()> { Ok(()) } -fn patch_path_prefix(path: PathBuf) -> PathBuf { - use std::path::{Component, Prefix}; +fn patch_path_prefix(path: Utf8PathBuf) -> Utf8PathBuf { if cfg!(windows) { // VSCode might report paths with the file drive in lowercase, but this can mess // with env vars set by tools and build scripts executed by r-a such that it invalidates @@ -335,17 +333,17 @@ fn patch_path_prefix(path: PathBuf) -> PathBuf { // (doing it conditionally is a pain because std::path::Prefix always reports uppercase letters on windows) let mut comps = path.components(); match comps.next() { - Some(Component::Prefix(prefix)) => { + Some(Utf8Component::Prefix(prefix)) => { let prefix = match prefix.kind() { - Prefix::Disk(d) => { + Utf8Prefix::Disk(d) => { format!("{}:", d.to_ascii_uppercase() as char) } - Prefix::VerbatimDisk(d) => { + Utf8Prefix::VerbatimDisk(d) => { format!(r"\\?\{}:", d.to_ascii_uppercase() as char) } _ => return path, }; - let mut path = PathBuf::new(); + let mut path = Utf8PathBuf::new(); path.push(prefix); path.extend(comps); path diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index bf9a66bf3fc2..32c7d50614fc 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -26,7 +26,7 @@ use ide::{ InlayHintsConfig, LineCol, RaFixtureConfig, RootDatabase, }; use ide_db::{ - EditionedFileId, SnippetCap, + EditionedFileId, WorkspaceSnippetCap, base_db::{SourceDatabase, salsa::Database}, line_index, }; @@ -1337,7 +1337,7 @@ impl flags::AnalysisStats { disable_experimental: false, disabled: Default::default(), expr_fill_default: Default::default(), - snippet_cap: SnippetCap::new(true), + workspace_snippet_cap: WorkspaceSnippetCap::new(true), insert_use: ide_db::imports::insert_use::InsertUseConfig { granularity: ide_db::imports::insert_use::ImportGranularity::Crate, enforce_granularity: true, diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs index 4f6de6850abb..360fcfc36dda 100644 --- a/crates/rust-analyzer/src/cli/lsif.rs +++ b/crates/rust-analyzer/src/cli/lsif.rs @@ -1,7 +1,7 @@ //! LSIF (language server index format) generator -use std::env; use std::time::Instant; +use std::{env, str::FromStr}; use ide::{ Analysis, AnalysisHost, FileId, FileRange, MonikerKind, MonikerResult, PackageInformation, @@ -145,7 +145,7 @@ impl LsifManager<'_, '_> { let path = path.as_path().unwrap(); let doc_id = self.add_vertex(lsif::Vertex::Document(lsif::Document { language_id: "rust".to_owned(), - uri: lsp_types::Url::from_file_path(path).unwrap(), + uri: lsp_types::Uri::from_str(path.as_str()).unwrap(), })); self.file_map.insert(id, doc_id); doc_id @@ -321,7 +321,7 @@ impl flags::Lsif { let mut lsif = LsifManager::new(&analysis, db, &vfs, out); lsif.add_vertex(lsif::Vertex::MetaData(lsif::MetaData { version: String::from("0.5.0"), - project_root: lsp_types::Url::from_file_path(path).unwrap(), + project_root: lsp_types::Uri::from_str(path.as_str()).unwrap(), position_encoding: lsif::Encoding::Utf16, tool_info: Some(lsp_types::lsif::ToolInfo { name: "rust-analyzer".to_owned(), diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 3a88a8fe8480..53df7556c6e7 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -16,7 +16,7 @@ use ide::{ SourceRootId, }; use ide_db::{ - MiniCore, SnippetCap, + MiniCore, assists::ExprFillDefaultMode, imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind}, }; @@ -1839,7 +1839,7 @@ impl Config { pub fn assist(&self, source_root: Option) -> AssistConfig { AssistConfig { - snippet_cap: self.snippet_cap(), + workspace_snippet_cap: self.workspace_snippet_cap(), allowed: None, insert_use: self.insert_use_config(source_root), prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), @@ -1902,7 +1902,7 @@ impl Config { CallableCompletionDef::None => None, }, add_semicolon_to_unit: *self.completion_addSemicolonToUnit(source_root), - snippet_cap: SnippetCap::new(self.completion_snippet()), + completion_snippet_cap: self.completion_snippet_cap(), insert_use: self.insert_use_config(source_root), prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), @@ -1963,7 +1963,7 @@ impl Config { ExprFillDefaultDef::Default => ExprFillDefaultMode::Default, ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore, }, - snippet_cap: self.snippet_cap(), + workspace_snippet_cap: self.workspace_snippet_cap(), insert_use: self.insert_use_config(source_root), prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), @@ -2656,12 +2656,6 @@ impl Config { *self.references_excludeTests() } - pub fn snippet_cap(&self) -> Option { - // FIXME: Also detect the proposed lsp version at caps.workspace.workspaceEdit.snippetEditSupport - // once lsp-types has it. - SnippetCap::new(self.snippet_text_edit()) - } - pub fn call_info(&self) -> CallInfoConfig { CallInfoConfig { params_only: matches!(self.signatureInfo_detail(), SignatureDetail::Parameters), diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs index 8d0f52433e02..39092557c03a 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs @@ -1,7 +1,7 @@ //! Book keeping for keeping diagnostics easily in sync with the client. pub(crate) mod flycheck_to_proto; -use std::mem; +use std::{mem, str::FromStr}; use ide::FileId; use ide_db::{FxHashMap, base_db::DbPanicContext}; @@ -359,7 +359,7 @@ pub(crate) fn convert_diagnostic( severity: Some(lsp::to_proto::diagnostic_severity(d.severity)), code: Some(lsp_types::NumberOrString::String(d.code.as_str().to_owned())), code_description: Some(lsp_types::CodeDescription { - href: lsp_types::Url::parse(&d.code.url()).unwrap(), + href: lsp_types::Uri::from_str(&d.code.url()).unwrap(), }), source: Some("rust-analyzer".to_owned()), message: d.message, diff --git a/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs b/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs index a6d7bcb9c70e..6d534b3e8194 100644 --- a/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs @@ -1,6 +1,8 @@ //! This module provides the functionality needed to convert diagnostics from //! `cargo check` json format to the LSP diagnostic format. +use std::str::FromStr; + use crate::flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan}; use itertools::Itertools; use rustc_hash::FxHashMap; @@ -192,7 +194,7 @@ fn map_rust_child_diagnostic( return MappedRustChildDiagnostic::MessageLine(rd.message.clone()); } - let mut edit_map: FxHashMap> = FxHashMap::default(); + let mut edit_map: FxHashMap> = FxHashMap::default(); let mut suggested_replacements = Vec::new(); let mut is_preferred = true; for &span in &spans { @@ -211,7 +213,7 @@ fn map_rust_child_diagnostic( span.suggestion_applicability, None | Some(Applicability::MaybeIncorrect | Applicability::MachineApplicable) ) { - edit_map.entry(location.uri).or_default().push(edit); + edit_map.entry(location.uri.as_str().to_owned()).or_default().push(edit); } is_preferred &= matches!(span.suggestion_applicability, Some(Applicability::MachineApplicable)); @@ -263,7 +265,7 @@ fn map_rust_child_diagnostic( #[derive(Debug)] pub(crate) struct MappedRustDiagnostic { - pub(crate) url: lsp_types::Url, + pub(crate) url: lsp_types::Uri, pub(crate) diagnostic: lsp_types::Diagnostic, pub(crate) fix: Option>, } @@ -494,7 +496,7 @@ fn rustc_code_description(code: Option<&str>) -> Option) -> Option) -> Option { code.and_then(|code| { - lsp_types::Url::parse(&format!( + lsp_types::Uri::from_str(&format!( "https://rust-lang.github.io/rust-clippy/master/index.html#{code}" )) .ok() diff --git a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt index c3b540e31f77..319b2cefaf15 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/mir/tagset.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/mir/tagset.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "trivially_copy_pass_by_ref", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "trivially_copy_pass_by_ref", + ), + }, + ), }, ), source: Some( @@ -59,17 +64,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/lib.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/lib.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 0, @@ -85,17 +88,15 @@ }, DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/mir/tagset.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/mir/tagset.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 41, @@ -117,17 +118,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/lib.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/lib.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -149,23 +148,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "trivially_copy_pass_by_ref", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "trivially_copy_pass_by_ref", + ), + }, + ), }, ), source: Some( @@ -176,17 +182,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/mir/tagset.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/mir/tagset.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 41, @@ -208,17 +212,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/mir/tagset.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/mir/tagset.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -240,23 +242,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "trivially_copy_pass_by_ref", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "trivially_copy_pass_by_ref", + ), + }, + ), }, ), source: Some( @@ -267,17 +276,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/mir/tagset.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/mir/tagset.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 41, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt index 989e5cf66d86..49c5e4b1a4e4 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", + ), + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0277", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0277", - ), - }, + }, + ), }, ), source: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt index b44569b4931d..9c7c83423fa9 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/path.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/path.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -35,17 +33,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/path.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/path.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 264, @@ -67,17 +63,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/data.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/data.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -102,17 +96,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/path.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/path.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 264, @@ -134,17 +126,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/path.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/path.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -169,17 +159,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/path.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/path.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 271, @@ -195,17 +183,15 @@ }, DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/hir_def/src/data.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/hir_def/src/data.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 79, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt b/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt index df00b330b6e9..ab0a52757bae 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/bin/current.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/bin/current.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", + ), + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0601", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0601", - ), - }, + }, + ), }, ), source: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt index dc36aa761c06..482a193fd8b3 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/ty/list_iter.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/ty/list_iter.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", + ), + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0053", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0053", - ), - }, + }, + ), }, ), source: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt index d557196c2bd2..0ea8f1d345e0 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/runtime/compiler_support.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/runtime/compiler_support.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", + ), + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0308", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0308", - ), - }, + }, + ), }, ), source: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt index a100fa07ffdd..c174ad591296 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/test_diagnostics/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/test_diagnostics/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0308", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0308", + ), + }, + ), }, ), source: Some( @@ -59,17 +64,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/test_diagnostics/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/test_diagnostics/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 3, @@ -91,17 +94,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/test_diagnostics/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/test_diagnostics/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -123,23 +124,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0308", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0308", + ), + }, + ), }, ), source: Some( @@ -150,17 +158,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/crates/test_diagnostics/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/crates/test_diagnostics/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 3, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt index 1c5c33622349..d423d0fee74d 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -39,17 +37,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -75,17 +71,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -114,17 +108,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -170,17 +162,7 @@ SnippetWorkspaceEdit { changes: Some( { - Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }: [ + "/test/driver/subcommand/repl.rs": [ TextEdit { range: Range { start: Position { diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt index 3ab3412d971b..cfe1eefafe8d 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -39,17 +37,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -75,17 +71,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -114,17 +108,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -170,17 +162,7 @@ SnippetWorkspaceEdit { changes: Some( { - Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }: [ + "/test/driver/subcommand/repl.rs": [ TextEdit { range: Range { start: Position { diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt index 0702420aa5f9..6de7eb028dac 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -39,17 +37,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -75,17 +71,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -114,17 +108,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/driver/subcommand/repl.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 290, @@ -170,17 +162,7 @@ SnippetWorkspaceEdit { changes: Some( { - Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/driver/subcommand/repl.rs", - query: None, - fragment: None, - }: [ + "/test/driver/subcommand/repl.rs": [ TextEdit { range: Range { start: Position { diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt index 8ec92888ce11..316d335dbc08 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/ty/select.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/ty/select.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0061", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0061", + ), + }, + ), }, ), source: Some( @@ -59,17 +64,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/ty/select.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/ty/select.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 218, @@ -91,17 +94,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/ty/select.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/ty/select.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -123,23 +124,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "doc.rust-lang.org", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/error-index.html", - query: None, - fragment: Some( - "E0061", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "doc.rust-lang.org", + data: RegName( + "doc.rust-lang.org", + ), + }, + port: None, + }, + ), + path: "/error-index.html", + query: None, + fragment: Some( + "E0061", + ), + }, + ), }, ), source: Some( @@ -150,17 +158,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/compiler/ty/select.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/compiler/ty/select.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 103, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt index 4365e450df1f..3a3b6cc0e644 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt @@ -1,16 +1,14 @@ [ MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -32,23 +30,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "let_and_return", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "let_and_return", + ), + }, + ), }, ), source: Some( @@ -59,17 +64,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 2, @@ -85,17 +88,15 @@ }, DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 2, @@ -117,17 +118,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -149,23 +148,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "let_and_return", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "let_and_return", + ), + }, + ), }, ), source: Some( @@ -176,17 +182,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 3, @@ -208,17 +212,15 @@ fix: None, }, MappedRustDiagnostic { - url: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + url: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), diagnostic: Diagnostic { range: Range { start: Position { @@ -240,23 +242,30 @@ ), code_description: Some( CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "rust-lang.github.io", + href: Uri( + Uri { + scheme: Some( + "https", ), - ), - port: None, - path: "/rust-clippy/master/index.html", - query: None, - fragment: Some( - "let_and_return", - ), - }, + authority: Some( + Authority { + userinfo: None, + host: Host { + text: "rust-lang.github.io", + data: RegName( + "rust-lang.github.io", + ), + }, + port: None, + }, + ), + path: "/rust-clippy/master/index.html", + query: None, + fragment: Some( + "let_and_return", + ), + }, + ), }, ), source: Some( @@ -267,17 +276,15 @@ [ DiagnosticRelatedInformation { location: Location { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }, + uri: Uri( + Uri { + scheme: None, + authority: None, + path: "/test/src/main.rs", + query: None, + fragment: None, + }, + ), range: Range { start: Position { line: 3, @@ -333,17 +340,7 @@ SnippetWorkspaceEdit { changes: Some( { - Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/test/src/main.rs", - query: None, - fragment: None, - }: [ + "/test/src/main.rs": [ TextEdit { range: Range { start: Position { diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index afd4162de622..bd10dbe798b0 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -18,7 +18,7 @@ use ide_db::{ }; use itertools::Itertools; use load_cargo::SourceRootConfig; -use lsp_types::{SemanticTokens, Url}; +use lsp_types::{SemanticTokens, Uri}; use parking_lot::{ MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard, @@ -97,7 +97,7 @@ pub(crate) struct GlobalState { pub(crate) source_root_config: SourceRootConfig, /// A mapping that maps a local source root's `SourceRootId` to it parent's `SourceRootId`, if it has one. pub(crate) local_roots_parent_map: Arc>, - pub(crate) semantic_tokens_cache: Arc>>, + pub(crate) semantic_tokens_cache: Arc>>, // status pub(crate) shutdown_requested: bool, @@ -209,7 +209,7 @@ pub(crate) struct GlobalStateSnapshot { pub(crate) analysis: Analysis, pub(crate) check_fixes: CheckFixes, mem_docs: MemDocs, - pub(crate) semantic_tokens_cache: Arc>>, + pub(crate) semantic_tokens_cache: Arc>>, vfs: Arc)>>, pub(crate) workspaces: Arc>, // used to signal semantic highlighting to fall back to syntax based highlighting until @@ -647,7 +647,7 @@ impl GlobalState { pub(crate) fn publish_diagnostics( &mut self, - uri: Url, + uri: Uri, version: Option, mut diagnostics: Vec, ) { @@ -744,11 +744,11 @@ impl GlobalStateSnapshot { } /// Returns `None` if the file was excluded. - pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result> { + pub(crate) fn url_to_file_id(&self, url: &Uri) -> anyhow::Result> { url_to_file_id(&self.vfs_read(), url) } - pub(crate) fn file_id_to_url(&self, id: FileId) -> Url { + pub(crate) fn file_id_to_url(&self, id: FileId) -> Uri { file_id_to_url(&self.vfs_read(), id) } @@ -768,12 +768,12 @@ impl GlobalStateSnapshot { Some(self.mem_docs.get(self.vfs_read().file_path(file_id))?.version) } - pub(crate) fn url_file_version(&self, url: &Url) -> Option { + pub(crate) fn url_file_version(&self, url: &Uri) -> Option { let path = from_proto::vfs_path(url).ok()?; Some(self.mem_docs.get(&path)?.version) } - pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Url { + pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Uri { let mut base = self.vfs_read().file_path(path.anchor).clone(); base.pop(); let path = base.join(&path.path).unwrap(); @@ -898,14 +898,14 @@ impl GlobalStateSnapshot { } } -pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url { +pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Uri { let path = vfs.file_path(id); let path = path.as_path().unwrap(); url_from_abs_path(path) } /// Returns `None` if the file was excluded. -pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result> { +pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Uri) -> anyhow::Result> { let path = from_proto::vfs_path(url)?; vfs_path_to_file_id(vfs, &path) } diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index 09b6794e4f43..64902be7abb2 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -4,6 +4,7 @@ use std::{ ops::{Deref, Not as _}, panic::UnwindSafe, + str::FromStr, }; use itertools::Itertools; @@ -260,8 +261,8 @@ pub(crate) fn handle_did_change_workspace_folders( let config = Arc::make_mut(&mut state.config); for workspace in params.event.removed { - let Ok(path) = workspace.uri.to_file_path() else { continue }; - let Ok(path) = Utf8PathBuf::from_path_buf(path) else { continue }; + let path = workspace.uri.to_string(); + let Ok(path) = Utf8PathBuf::from_str(&path); let Ok(path) = AbsPathBuf::try_from(path) else { continue }; config.remove_workspace(&path); } @@ -270,8 +271,8 @@ pub(crate) fn handle_did_change_workspace_folders( .event .added .into_iter() - .filter_map(|it| it.uri.to_file_path().ok()) - .filter_map(|it| Utf8PathBuf::from_path_buf(it).ok()) + .map(|it| it.uri.to_string()) + .filter_map(|it| Utf8PathBuf::from_str(&it).ok()) .filter_map(|it| AbsPathBuf::try_from(it).ok()); config.add_workspaces(added); diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 0c1c067ffa91..d7db6191c43e 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -1,7 +1,7 @@ //! This module is responsible for implementing handlers for Language Server //! Protocol. This module specifically handles requests. -use std::{fs, io::Write as _, ops::Not, process::Stdio}; +use std::{fs, io::Write as _, ops::Not, process::Stdio, str::FromStr}; use anyhow::Context; @@ -22,7 +22,7 @@ use lsp_types::{ InlayHintParams, Location, LocationLink, Position, PrepareRenameResponse, Range, RenameParams, ResourceOp, ResourceOperationKind, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult, - SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit, + SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Uri, WorkspaceEdit, }; use paths::Utf8PathBuf; use project_model::{CargoWorkspace, ManifestPath, ProjectWorkspaceKind, TargetKind}; @@ -87,7 +87,7 @@ pub(crate) fn handle_analyzer_status( match from_proto::file_id(&snap, &tdi.uri) { Ok(Some(it)) => file_id = Some(it), Ok(None) => {} - Err(_) => format_to!(buf, "file {} not found in vfs", tdi.uri), + Err(_) => format_to!(buf, "file {} not found in vfs", tdi.uri.to_string()), } } @@ -649,7 +649,7 @@ pub(crate) fn handle_document_symbol( fn flatten_document_symbol( symbol: &lsp_types::DocumentSymbol, container_name: Option, - url: &Url, + url: &Uri, res: &mut Vec, ) { #[allow(deprecated)] @@ -772,41 +772,43 @@ pub(crate) fn handle_will_rename_files( let source_changes: Vec = params .files .into_iter() - .filter_map(|file_rename| { - let from = Url::parse(&file_rename.old_uri).ok()?; - let to = Url::parse(&file_rename.new_uri).ok()?; - - let from_path = from.to_file_path().ok()?; - let to_path = to.to_file_path().ok()?; - - // Limit to single-level moves for now. - match (from_path.parent(), to_path.parent()) { - (Some(p1), Some(p2)) if p1 == p2 => { - if from_path.is_dir() { - // add '/' to end of url -- from `file://path/to/folder` to `file://path/to/folder/` - let mut old_folder_name = from_path.file_stem()?.to_str()?.to_owned(); - old_folder_name.push('/'); - let from_with_trailing_slash = from.join(&old_folder_name).ok()?; - - let imitate_from_url = from_with_trailing_slash.join("mod.rs").ok()?; - let new_file_name = to_path.file_name()?.to_str()?; - Some(( - snap.url_to_file_id(&imitate_from_url).ok()?, - new_file_name.to_owned(), - )) - } else { - let old_name = from_path.file_stem()?.to_str()?; - let new_name = to_path.file_stem()?.to_str()?; - match (old_name, new_name) { - ("mod", _) => None, - (_, "mod") => None, - _ => Some((snap.url_to_file_id(&from).ok()?, new_name.to_owned())), + .filter_map( + |file_rename| -> Option<(std::option::Option, std::string::String)> { + let from = Uri::from_str(&file_rename.old_uri).ok()?; + let to = Uri::from_str(&file_rename.new_uri).ok()?; + + let from_path = Utf8PathBuf::from_str(&from.to_string()).ok()?; + let to_path = Utf8PathBuf::from_str(&to.to_string()).ok()?; + + // Limit to single-level moves for now. + match (from_path.parent(), to_path.parent()) { + (Some(p1), Some(p2)) if p1 == p2 => { + if from_path.is_dir() { + // add '/' to end of url -- from `file://path/to/folder` to `file://path/to/folder/` + let file_stem = from_path.file_stem()?; + let mut old_folder_name = file_stem.to_owned(); + old_folder_name.push('/'); + let from_with_trailing_slash = from_path.join(&old_folder_name); + + let imitate_from_url = from_with_trailing_slash.join("mod.rs"); + let new_file_name = to_path.file_name()?.to_owned(); + let uri = Uri::from_str(imitate_from_url.as_str()).ok()?; + let vfs_path = from_proto::vfs_path(&uri).ok()?; + Some((snap.vfs_path_to_file_id(&vfs_path).ok()?, new_file_name)) + } else { + let old_name = from_path.file_stem()?.to_owned(); + let new_name = to_path.file_stem()?.to_owned(); + match (old_name.as_str(), new_name.as_str()) { + ("mod", _) => None, + (_, "mod") => None, + _ => Some((snap.url_to_file_id(&from).ok()?, new_name)), + } } } + _ => None, } - _ => None, - } - }) + }, + ) .filter_map(|(file_id, new_name)| { let file_id = file_id?; let source_root = snap.analysis.source_root_id(file_id).ok(); @@ -903,14 +905,11 @@ pub(crate) fn handle_parent_module( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result> { let _p = tracing::info_span!("handle_parent_module").entered(); - if let Ok(file_path) = ¶ms.text_document.uri.to_file_path() { + if let Ok(file_path) = &Utf8PathBuf::from_str(params.text_document.uri.as_str()) { if file_path.file_name().unwrap_or_default() == "Cargo.toml" { // search workspaces for parent packages or fallback to workspace root - let abs_path_buf = match Utf8PathBuf::from_path_buf(file_path.to_path_buf()) - .ok() - .map(AbsPathBuf::try_from) - { - Some(Ok(abs_path_buf)) => abs_path_buf, + let abs_path_buf = match AbsPathBuf::try_from(file_path.to_owned()) { + Ok(abs_path_buf) => abs_path_buf, _ => return Ok(None), }; @@ -2077,8 +2076,8 @@ pub(crate) fn handle_open_docs( }; }; - let web = remote_urls.web_url.and_then(|it| Url::parse(&it).ok()); - let local = remote_urls.local_url.and_then(|it| Url::parse(&it).ok()); + let web = remote_urls.web_url.and_then(|it| Uri::from_str(&it).ok()); + let local = remote_urls.local_url.and_then(|it| Uri::from_str(&it).ok()); if snap.config.local_docs() { Ok(ExternalDocsResponse::WithLocal(ExternalDocsPair { web, local })) @@ -2371,17 +2370,21 @@ fn run_rustfmt( // try to chdir to the file so we can respect `rustfmt.toml` // FIXME: use `rustfmt --config-path` once // https://github.com/rust-lang/rustfmt/issues/4660 gets fixed - let current_dir = match text_document.uri.to_file_path() { + let current_dir = match Utf8PathBuf::from_str(text_document.uri.as_str()) { Ok(mut path) => { // pop off file name - if path.pop() && path.is_dir() { path } else { std::env::current_dir()? } + if path.pop() && path.is_dir() { + path + } else { + Utf8PathBuf::from_path_buf(std::env::current_dir()?).unwrap() + } } Err(_) => { tracing::error!( text_document = ?text_document.uri, "Unable to get path, rustfmt.toml might be ignored" ); - std::env::current_dir()? + Utf8PathBuf::from_path_buf(std::env::current_dir()?).unwrap() } }; @@ -2454,9 +2457,7 @@ fn run_rustfmt( let cmd_path = if command.contains(std::path::MAIN_SEPARATOR) || (cfg!(windows) && command.contains('/')) { - let project_root = Utf8PathBuf::from_path_buf(current_dir.clone()) - .ok() - .and_then(|p| AbsPathBuf::try_from(p).ok()); + let project_root = AbsPathBuf::try_from(current_dir.clone()); let project_root = project_root .as_ref() .map(|dir| snap.config.workspace_root_for(dir)) @@ -2633,10 +2634,10 @@ fn crate_path(root_file_path: &VfsPath) -> Option { None } -fn to_url(path: VfsPath) -> Option { +fn to_url(path: VfsPath) -> Option { let path = path.as_path()?; let str_path = path.as_os_str().to_str()?; - Url::from_file_path(str_path).ok() + Uri::from_str(str_path).ok() } fn resource_ops_supported(config: &Config, kind: ResourceOperationKind) -> anyhow::Result<()> { diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs index af449c473a85..82103be566e1 100644 --- a/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -16,7 +16,7 @@ use ide::{ FilePosition, RaFixtureConfig, TextSize, }; use ide_db::{ - SnippetCap, + CompletionSnippetCap, WorkspaceSnippetCap, imports::insert_use::{ImportGranularity, InsertUseConfig}, }; use project_model::CargoConfig; @@ -171,7 +171,7 @@ fn integrated_completion_benchmark() { term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), - snippet_cap: SnippetCap::new(true), + completion_snippet_cap: CompletionSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: hir::PrefixKind::ByCrate, @@ -226,7 +226,7 @@ fn integrated_completion_benchmark() { term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), - snippet_cap: SnippetCap::new(true), + completion_snippet_cap: CompletionSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: hir::PrefixKind::ByCrate, @@ -279,7 +279,7 @@ fn integrated_completion_benchmark() { term_search_fuel: 200, full_function_signatures: false, callable: Some(CallableSnippets::FillArguments), - snippet_cap: SnippetCap::new(true), + completion_snippet_cap: CompletionSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, prefix_kind: hir::PrefixKind::ByCrate, @@ -356,7 +356,7 @@ fn integrated_diagnostics_benchmark() { disabled: Default::default(), expr_fill_default: Default::default(), style_lints: false, - snippet_cap: SnippetCap::new(true), + workspace_snippet_cap: WorkspaceSnippetCap::new(true), insert_use: InsertUseConfig { granularity: ImportGranularity::Crate, enforce_granularity: false, diff --git a/crates/rust-analyzer/src/lsp/capabilities.rs b/crates/rust-analyzer/src/lsp/capabilities.rs index 3ad4cb70b419..91793bf7fb04 100644 --- a/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/crates/rust-analyzer/src/lsp/capabilities.rs @@ -1,6 +1,6 @@ //! Advertises the capabilities of the LSP Server. use ide::{CompletionFieldsToResolve, InlayFieldsToResolve}; -use ide_db::{FxHashSet, line_index::WideEncoding}; +use ide_db::{CompletionSnippetCap, FxHashSet, WorkspaceSnippetCap, line_index::WideEncoding}; use lsp_types::{ CallHierarchyServerCapability, CodeActionKind, CodeActionOptions, CodeActionProviderCapability, CodeLensOptions, CompletionOptions, CompletionOptionsCompletionItem, DeclarationCapability, @@ -178,6 +178,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { }, )), inline_completion_provider: None, + notebook_document_sync: None, } } @@ -454,8 +455,16 @@ impl ClientCapabilities { self.experimental_bool("serverStatusNotification") } - pub fn snippet_text_edit(&self) -> bool { - self.experimental_bool("snippetTextEdit") + pub fn workspace_snippet_cap(&self) -> Option { + WorkspaceSnippetCap::new(self.experimental_bool("snippetTextEdit")) + // switch when updating to lsp-types 0.98, assuming the feature lands + // self.0 + // .workspace + // .as_ref()? + // .workspace_edit + // .as_ref()? + // .snippet_edit_support + // .and_then(WorkspaceSnippetCap::new) } pub fn hover_actions(&self) -> bool { @@ -471,18 +480,16 @@ impl ClientCapabilities { self.experimental_bool("testExplorer") } - pub fn completion_snippet(&self) -> bool { - (|| -> _ { - self.0 - .text_document - .as_ref()? - .completion - .as_ref()? - .completion_item - .as_ref()? - .snippet_support - })() - .unwrap_or_default() + pub fn completion_snippet_cap(&self) -> Option { + self.0 + .text_document + .as_ref()? + .completion + .as_ref()? + .completion_item + .as_ref()? + .snippet_support + .and_then(CompletionSnippetCap::new) } pub fn semantic_tokens_refresh(&self) -> bool { diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs index 5d0d9209de2f..0eeac3e70f46 100644 --- a/crates/rust-analyzer/src/lsp/ext.rs +++ b/crates/rust-analyzer/src/lsp/ext.rs @@ -8,7 +8,7 @@ use std::ops; -use lsp_types::Url; +use lsp_types::Uri; use lsp_types::request::Request; use lsp_types::{ CodeActionKind, DocumentOnTypeFormattingParams, PartialResultParams, Position, Range, @@ -64,7 +64,7 @@ pub struct AnalyzerStatusParams { pub struct CrateInfoResult { pub name: Option, pub version: Option, - pub path: Url, + pub path: Uri, } pub enum FetchDependencyList {} @@ -612,7 +612,7 @@ pub struct CodeActionData { #[serde(rename_all = "camelCase")] pub struct SnippetWorkspaceEdit { #[serde(skip_serializing_if = "Option::is_none")] - pub changes: Option>>, + pub changes: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub document_changes: Option>, #[serde(skip_serializing_if = "Option::is_none")] @@ -710,7 +710,7 @@ impl Request for ExternalDocs { #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] #[serde(untagged)] pub enum ExternalDocsResponse { - Simple(Option), + Simple(Option), WithLocal(ExternalDocsPair), } @@ -723,8 +723,8 @@ impl Default for ExternalDocsResponse { #[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct ExternalDocsPair { - pub web: Option, - pub local: Option, + pub web: Option, + pub local: Option, } pub enum OpenCargoToml {} diff --git a/crates/rust-analyzer/src/lsp/from_proto.rs b/crates/rust-analyzer/src/lsp/from_proto.rs index 333826a1790e..745fd28e825b 100644 --- a/crates/rust-analyzer/src/lsp/from_proto.rs +++ b/crates/rust-analyzer/src/lsp/from_proto.rs @@ -1,4 +1,6 @@ //! Conversion lsp_types types to rust-analyzer specific ones. +use std::str::FromStr; + use anyhow::format_err; use ide::{Annotation, AnnotationKind, AssistKind, LineCol}; use ide_db::{FileId, FilePosition, FileRange, line_index::WideLineCol}; @@ -12,12 +14,12 @@ use crate::{ lsp_ext, try_default, }; -pub(crate) fn abs_path(url: &lsp_types::Url) -> anyhow::Result { - let path = url.to_file_path().map_err(|()| anyhow::format_err!("url is not a file"))?; - Ok(AbsPathBuf::try_from(Utf8PathBuf::from_path_buf(path).unwrap()).unwrap()) +pub(crate) fn abs_path(url: &lsp_types::Uri) -> anyhow::Result { + let path = url.to_string(); + Ok(AbsPathBuf::try_from(Utf8PathBuf::from_str(&path).unwrap()).unwrap()) } -pub(crate) fn vfs_path(url: &lsp_types::Url) -> anyhow::Result { +pub(crate) fn vfs_path(url: &lsp_types::Uri) -> anyhow::Result { abs_path(url).map(vfs::VfsPath::from) } @@ -65,7 +67,7 @@ pub(crate) fn text_range( /// Returns `None` if the file was excluded. pub(crate) fn file_id( snap: &GlobalStateSnapshot, - url: &lsp_types::Url, + url: &lsp_types::Uri, ) -> anyhow::Result> { snap.url_to_file_id(url) } @@ -93,7 +95,7 @@ pub(crate) fn file_range( /// Returns `None` if the file was excluded. pub(crate) fn file_range_uri( snap: &GlobalStateSnapshot, - document: &lsp_types::Url, + document: &lsp_types::Uri, range: lsp_types::Range, ) -> anyhow::Result> { let file_id = try_default!(file_id(snap, document)?); diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index d857f23b6703..df83966190b1 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -3,6 +3,7 @@ use std::{ iter::once, mem, ops::Not as _, + str::FromStr, sync::atomic::{AtomicU32, Ordering}, }; @@ -198,7 +199,7 @@ pub(crate) fn completion_text_edit( } } -pub(crate) fn snippet_text_edit( +pub(crate) fn snippet_edit_support( line_index: &LineIndex, is_snippet: bool, indel: Indel, @@ -234,7 +235,7 @@ pub(crate) fn snippet_text_edit_vec( text_edit .into_iter() .map(|indel| { - self::snippet_text_edit( + self::snippet_edit_support( line_index, is_snippet, indel, @@ -983,7 +984,7 @@ pub(crate) fn folding_range( } } -pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Url { +pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Uri { snap.file_id_to_url(file_id) } @@ -991,8 +992,8 @@ pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Url /// This will only happen when processing windows paths. /// /// When processing non-windows path, this is essentially the same as `Url::from_file_path`. -pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Url { - let url = lsp_types::Url::from_file_path(path).unwrap(); +pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Uri { + let url = lsp_types::Uri::from_str(path.as_str()).unwrap(); match path.components().next() { Some(Utf8Component::Prefix(prefix)) if matches!(prefix.kind(), Utf8Prefix::Disk(_) | Utf8Prefix::VerbatimDisk(_)) => @@ -1014,9 +1015,9 @@ pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Url { // Note: lowercasing the `path` itself doesn't help, the `Url::parse` // machinery *also* canonicalizes the drive letter. So, just massage the // string in place. - let mut url: String = url.into(); + let mut url: String = url.as_str().to_owned(); url[driver_letter_range].make_ascii_lowercase(); - lsp_types::Url::parse(&url).unwrap() + lsp_types::Uri::from_str(&url).unwrap() } pub(crate) fn optional_versioned_text_document_identifier( @@ -1077,7 +1078,7 @@ pub(crate) fn location_link( fn location_info( snap: &GlobalStateSnapshot, target: NavigationTarget, -) -> Cancellable<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { +) -> Cancellable<(lsp_types::Uri, lsp_types::Range, lsp_types::Range)> { let line_index = snap.file_line_index(target.file_id)?; let target_uri = url(snap, target.file_id); @@ -1165,7 +1166,7 @@ fn merge_text_and_snippet_edits( snippet_range }; - edits.push(snippet_text_edit( + edits.push(snippet_edit_support( line_index, true, Indel { insert: format!("${snippet_index}"), delete: snippet_range }, @@ -1225,7 +1226,7 @@ fn merge_text_and_snippet_edits( // escape any remaining bits escape_prior_bits(&mut new_text, 0); - edits.push(snippet_text_edit( + edits.push(snippet_edit_support( line_index, true, Indel { insert: new_text, delete: current_indel.delete }, @@ -1235,7 +1236,7 @@ fn merge_text_and_snippet_edits( } else { // snippet edit was beyond the current one // since it wasn't consumed, it's available for the next pass - edits.push(snippet_text_edit( + edits.push(snippet_edit_support( line_index, false, current_indel, @@ -1263,7 +1264,7 @@ fn merge_text_and_snippet_edits( snippet_range }; - snippet_text_edit( + snippet_edit_support( line_index, true, Indel { insert: format!("${snippet_index}"), delete: snippet_range }, @@ -1291,7 +1292,7 @@ pub(crate) fn snippet_text_document_edit( let annotation = edit.change_annotation(); edit.into_iter() .map(|it| { - snippet_text_edit( + snippet_edit_support( &line_index, is_snippet, it, @@ -1895,7 +1896,7 @@ pub(crate) mod command { pub(crate) fn show_references( title: String, - uri: &lsp_types::Url, + uri: &lsp_types::Uri, position: lsp_types::Position, locations: Vec, ) -> lsp_types::Command { diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index f5b3658ea90c..605dea477af0 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -99,7 +99,7 @@ impl fmt::Display for Event { #[derive(Debug)] pub(crate) enum DeferredTask { - CheckIfIndexed(lsp_types::Url), + CheckIfIndexed(lsp_types::Uri), CheckProcMacroSources(Vec), } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 1832275eb38d..3937541c67fb 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -13,7 +13,7 @@ //! project is currently loading and we don't have a full project model, we //! still want to respond to various requests. // FIXME: This is a mess that needs some untangling work -use std::{iter, mem, sync::atomic::AtomicUsize}; +use std::{iter, mem, str::FromStr, sync::atomic::AtomicUsize}; use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase}; use ide_db::{ @@ -591,7 +591,7 @@ impl GlobalState { glob_pattern: lsp_types::GlobPattern::Relative( lsp_types::RelativePattern { base_uri: lsp_types::OneOf::Right( - lsp_types::Url::from_file_path(base).unwrap(), + lsp_types::Uri::from_str(base.as_str()).unwrap(), ), pattern: pat.to_owned(), }, diff --git a/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/crates/rust-analyzer/tests/slow-tests/ratoml.rs index dd113babffeb..16dc06e1c617 100644 --- a/crates/rust-analyzer/tests/slow-tests/ratoml.rs +++ b/crates/rust-analyzer/tests/slow-tests/ratoml.rs @@ -1,8 +1,10 @@ +use std::str::FromStr; + use crate::support::{Project, Server}; use crate::testdir::TestDir; use lsp_types::{ DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, - TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem, Url, + TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem, Uri, VersionedTextDocumentIdentifier, notification::{DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument}, }; @@ -17,7 +19,7 @@ use serde_json::json; use test_utils::skip_slow_tests; struct RatomlTest { - urls: Vec, + urls: Vec, server: Server, tmp_path: Utf8PathBuf, } @@ -54,7 +56,7 @@ impl RatomlTest { case } - fn fixture_path(&self, fixture: &str) -> Url { + fn fixture_path(&self, fixture: &str) -> Uri { let mut lines = fixture.trim().split('\n'); let mut path = @@ -81,7 +83,7 @@ impl RatomlTest { path = path.join(piece); } - Url::parse( + Uri::from_str( format!("file://{}", path.into_string().replace("C:\\", "/c:/").replace('\\', "/")) .as_str(), ) diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs index 73904036730b..c9361edf8f0c 100644 --- a/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/crates/rust-analyzer/tests/slow-tests/support.rs @@ -1,6 +1,7 @@ use std::{ cell::{Cell, RefCell}, env, fs, + str::FromStr, sync::Once, time::Duration, }; @@ -9,7 +10,7 @@ use crossbeam_channel::{Receiver, after, select}; use itertools::Itertools; use lsp_server::{Connection, Message, Notification, Request}; use lsp_types::{ - PublishDiagnosticsParams, TextDocumentIdentifier, Url, notification::Exit, request::Shutdown, + PublishDiagnosticsParams, TextDocumentIdentifier, Uri, notification::Exit, request::Shutdown, }; use parking_lot::{Mutex, MutexGuard}; use paths::{Utf8Path, Utf8PathBuf}; @@ -321,7 +322,7 @@ impl Server { pub(crate) fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { let path = self.dir.path().join(rel_path); - TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } + TextDocumentIdentifier { uri: Uri::from_str(path.as_str()).unwrap() } } pub(crate) fn notification(&self, params: N::Params) diff --git a/docs/book/src/contributing/lsp-extensions.md b/docs/book/src/contributing/lsp-extensions.md index 8ba6f6ab531e..860ae6a86e1e 100644 --- a/docs/book/src/contributing/lsp-extensions.md +++ b/docs/book/src/contributing/lsp-extensions.md @@ -1,5 +1,5 @@