diff --git a/crates/editor/src/code_context_menus.rs b/crates/editor/src/code_context_menus.rs index f033d06905..0f78fe6883 100644 --- a/crates/editor/src/code_context_menus.rs +++ b/crates/editor/src/code_context_menus.rs @@ -225,7 +225,7 @@ pub struct CompletionsMenu { scroll_handle: UniformListScrollHandle, // The `ScrollHandle` used on the Markdown documentation rendered on the // side of the completions menu. - pub(crate) scroll_handle_aside: ScrollHandle, + pub scroll_handle_aside: ScrollHandle, resolve_completions: bool, show_completion_documentation: bool, last_rendered_range: Rc>>>, diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 5709bb4cda..b31963c9c8 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -24071,119 +24071,6 @@ async fn test_newline_replacement_in_single_line(cx: &mut TestAppContext) { }); } -#[gpui::test] -async fn test_completion_menu_scroll_aside(cx: &mut TestAppContext) { - init_test(cx, |_| {}); - - // In order to be able to test the shortcuts that should allow the user to - // scroll the aside content of the completions menu, we first need to load - // the keymap file, otherwise simulating the keystrokes will not actually - // dispatching the necessary action. - cx.update(|cx| { - let default_key_bindings = settings::KeymapFile::load_asset_allow_partial_failure( - "keymaps/default-macos.json", - cx, - ) - .expect("Should be able to load deafult MacOS Keymap"); - - cx.bind_keys(default_key_bindings); - }); - - // Setup the completion to be provided by the LSP so we can set the - // completion item's documentation with a string long enough to overflow the - // assigned vertical space. - let mut cx = EditorLspTestContext::new_rust( - lsp::ServerCapabilities { - completion_provider: Some(lsp::CompletionOptions { - trigger_characters: Some(vec![".".to_string()]), - ..Default::default() - }), - ..Default::default() - }, - cx, - ) - .await; - - cx.lsp - .set_request_handler::(move |_, _| async move { - Ok(Some(lsp::CompletionResponse::Array(vec![ - lsp::CompletionItem { - label: "Test Item".to_string(), - documentation: Some(lsp::Documentation::String( - "This is some very long documentation content that will be displayed in the aside panel for scrolling.\n".repeat(50) - )), - ..Default::default() - }, - ]))) - }); - - cx.set_state("variableˇ"); - cx.simulate_keystroke("."); - cx.executor().run_until_parked(); - - // Verify that the completion menu is visible before attempting to scroll - // it's aside content. - let mut initial_offset: Pixels = px(0.0); - - cx.update_editor(|editor, _, _| { - let binding = editor.context_menu.borrow(); - let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { - panic!("Should have completions menu open"); - }; - - assert_eq!(completion_menu_entries(&menu), &["Test Item"]); - initial_offset = menu.scroll_handle_aside.offset().y; - }); - - // The `ctrl-e` shortcut should scroll the completion menu's aside content - // down, so the updated offset should be lower than the initial offset. - cx.simulate_keystroke("ctrl-e"); - cx.update_editor(|editor, _, _| { - let binding = editor.context_menu.borrow(); - let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { - panic!("Should have completions menu open"); - }; - - assert!(menu.scroll_handle_aside.offset().y < initial_offset); - }); - - // The `ctrl-y` shortcut should do the inverse scrolling as `ctrl-e`, so the - // offset should now be the same as the initial offset. - cx.simulate_keystroke("ctrl-y"); - cx.update_editor(|editor, _, _| { - let binding = editor.context_menu.borrow(); - let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { - panic!("Should have completions menu open"); - }; - - assert_eq!(menu.scroll_handle_aside.offset().y, initial_offset); - }); - - // The `ctrl-d` shortcut should scroll the completion menu's aside content - // down, so the updated offset should be lower than the initial offset. - cx.simulate_keystroke("ctrl-d"); - cx.update_editor(|editor, _, _| { - let binding = editor.context_menu.borrow(); - let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { - panic!("Should have completions menu open"); - }; - - assert!(menu.scroll_handle_aside.offset().y < initial_offset); - }); - - // The `ctrl-u` shortcut should do the inverse scrolling as `ctrl-u`, so the - // offset should now be the same as the initial offset. - cx.simulate_keystroke("ctrl-u"); - cx.update_editor(|editor, _, _| { - let binding = editor.context_menu.borrow(); - let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { - panic!("Should have completions menu open"); - }; - - assert_eq!(menu.scroll_handle_aside.offset().y, initial_offset); - }); -} - #[track_caller] fn extract_color_inlays(editor: &Editor, cx: &App) -> Vec { editor diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index ce04b621cb..84376719d1 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -8,13 +8,15 @@ use collections::HashMap; use command_palette::CommandPalette; use editor::{ AnchorRangeExt, DisplayPoint, Editor, EditorMode, MultiBuffer, actions::DeleteLine, - display_map::DisplayRow, test::editor_test_context::EditorTestContext, + code_context_menus::CodeContextMenu, display_map::DisplayRow, + test::editor_test_context::EditorTestContext, }; use futures::StreamExt; -use gpui::{KeyBinding, Modifiers, MouseButton, TestAppContext}; +use gpui::{KeyBinding, Modifiers, MouseButton, TestAppContext, px}; use language::Point; pub use neovim_backed_test_context::*; use settings::SettingsStore; +use ui::Pixels; use util::test::marked_text_ranges; pub use vim_test_context::*; @@ -971,6 +973,87 @@ async fn test_comma_w(cx: &mut gpui::TestAppContext) { .assert_eq("hellˇo hello\nhello hello"); } +#[gpui::test] +async fn test_completion_menu_scroll_aside(cx: &mut TestAppContext) { + let mut cx = VimTestContext::new_typescript(cx).await; + + cx.lsp + .set_request_handler::(move |_, _| async move { + Ok(Some(lsp::CompletionResponse::Array(vec![ + lsp::CompletionItem { + label: "Test Item".to_string(), + documentation: Some(lsp::Documentation::String( + "This is some very long documentation content that will be displayed in the aside panel for scrolling.\n".repeat(50) + )), + ..Default::default() + }, + ]))) + }); + + cx.set_state("variableˇ", Mode::Insert); + cx.simulate_keystroke("."); + cx.executor().run_until_parked(); + + let mut initial_offset: Pixels = px(0.0); + + cx.update_editor(|editor, _, _| { + let binding = editor.context_menu().borrow(); + let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { + panic!("Should have completions menu open"); + }; + + initial_offset = menu.scroll_handle_aside.offset().y; + }); + + // The `ctrl-e` shortcut should scroll the completion menu's aside content + // down, so the updated offset should be lower than the initial offset. + cx.simulate_keystroke("ctrl-e"); + cx.update_editor(|editor, _, _| { + let binding = editor.context_menu().borrow(); + let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { + panic!("Should have completions menu open"); + }; + + assert!(menu.scroll_handle_aside.offset().y < initial_offset); + }); + + // The `ctrl-y` shortcut should do the inverse scrolling as `ctrl-e`, so the + // offset should now be the same as the initial offset. + cx.simulate_keystroke("ctrl-y"); + cx.update_editor(|editor, _, _| { + let binding = editor.context_menu().borrow(); + let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { + panic!("Should have completions menu open"); + }; + + assert_eq!(menu.scroll_handle_aside.offset().y, initial_offset); + }); + + // The `ctrl-d` shortcut should scroll the completion menu's aside content + // down, so the updated offset should be lower than the initial offset. + cx.simulate_keystroke("ctrl-d"); + cx.update_editor(|editor, _, _| { + let binding = editor.context_menu().borrow(); + let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { + panic!("Should have completions menu open"); + }; + + assert!(menu.scroll_handle_aside.offset().y < initial_offset); + }); + + // The `ctrl-u` shortcut should do the inverse scrolling as `ctrl-u`, so the + // offset should now be the same as the initial offset. + cx.simulate_keystroke("ctrl-u"); + cx.update_editor(|editor, _, _| { + let binding = editor.context_menu().borrow(); + let Some(CodeContextMenu::Completions(menu)) = binding.as_ref() else { + panic!("Should have completions menu open"); + }; + + assert_eq!(menu.scroll_handle_aside.offset().y, initial_offset); + }); +} + #[gpui::test] async fn test_rename(cx: &mut gpui::TestAppContext) { let mut cx = VimTestContext::new_typescript(cx).await; diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index 904e48e5a3..b205c8dd16 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -49,6 +49,10 @@ impl VimTestContext { Self::new_with_lsp( EditorLspTestContext::new_typescript( lsp::ServerCapabilities { + completion_provider: Some(lsp::CompletionOptions { + trigger_characters: Some(vec![".".to_string()]), + ..Default::default() + }), rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions { prepare_provider: Some(true), work_done_progress_options: Default::default(),