This was broken by #7647 Release Notes: - N/A
Unified · Split
| @@ -399,6 +399,7 @@ pub struct Editor { · 398 unmodified lines | |||
| 399 | workspace: Option<(WeakView<Workspace>, i64)>, | 399 | workspace: Option<(WeakView<Workspace>, i64)>, |
| 400 | keymap_context_layers: BTreeMap<TypeId, KeyContext>, | 400 | keymap_context_layers: BTreeMap<TypeId, KeyContext>, |
| 401 | input_enabled: bool, | 401 | input_enabled: bool, |
| 402 | use_modal_editing: bool, | ||
| 402 | read_only: bool, | 403 | read_only: bool, |
| 403 | leader_peer_id: Option<PeerId>, | 404 | leader_peer_id: Option<PeerId>, |
| 404 | remote_id: Option<ViewId>, | 405 | remote_id: Option<ViewId>, |
| @@ -1482,6 +1483,7 @@ impl Editor { · 1077 unmodified lines | |||
| 1482 | workspace: None, | 1483 | workspace: None, |
| 1483 | keymap_context_layers: Default::default(), | 1484 | keymap_context_layers: Default::default(), |
| 1484 | input_enabled: true, | 1485 | input_enabled: true, |
| 1486 | use_modal_editing: mode == EditorMode::Full, | ||
| 1485 | read_only: false, | 1487 | read_only: false, |
| 1486 | use_autoclose: true, | 1488 | use_autoclose: true, |
| 1487 | leader_peer_id: None, | 1489 | leader_peer_id: None, |
| @@ -1782,6 +1784,14 @@ impl Editor { · 294 unmodified lines | |||
| 1782 | self.show_copilot_suggestions = show_copilot_suggestions; | 1784 | self.show_copilot_suggestions = show_copilot_suggestions; |
| 1783 | } | 1785 | } |
| 1784 | 1786 | ||
| 1787 | pub fn set_use_modal_editing(&mut self, to: bool) { | ||
| 1788 | self.use_modal_editing = to; | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | pub fn use_modal_editing(&self) -> bool { | ||
| 1792 | self.use_modal_editing | ||
| 1793 | } | ||
| 1794 | |||
| 1785 | fn selections_did_change( | 1795 | fn selections_did_change( |
| 1786 | &mut self, | 1796 | &mut self, |
| 1787 | local: bool, | 1797 | local: bool, |
| @@ -7836,7 +7846,6 @@ impl Editor { · 6048 unmodified lines | |||
| 7836 | Some(rename) | 7846 | Some(rename) |
| 7837 | } | 7847 | } |
| 7838 | 7848 | ||
| 7839 | #[cfg(any(test, feature = "test-support"))] | ||
| 7840 | pub fn pending_rename(&self) -> Option<&RenameState> { | 7849 | pub fn pending_rename(&self) -> Option<&RenameState> { |
| 7841 | self.pending_rename.as_ref() | 7850 | self.pending_rename.as_ref() |
| 7842 | } | 7851 | } |
| @@ -187,6 +187,7 @@ impl FeedbackModal { · 186 unmodified lines | |||
| 187 | editor.set_show_gutter(false, cx); | 187 | editor.set_show_gutter(false, cx); |
| 188 | editor.set_show_copilot_suggestions(false); | 188 | editor.set_show_copilot_suggestions(false); |
| 189 | editor.set_vertical_scroll_margin(5, cx); | 189 | editor.set_vertical_scroll_margin(5, cx); |
| 190 | editor.set_use_modal_editing(false); | ||
| 190 | editor | 191 | editor |
| 191 | }); | 192 | }); |
| 192 | 193 | ||
| @@ -47,6 +47,7 @@ fn blurred(editor: View<Editor>, cx: &mut WindowContext) { · 46 unmodified lines | |||
| 47 | .upgrade() | 47 | .upgrade() |
| 48 | .is_some_and(|previous| previous == editor.clone()) | 48 | .is_some_and(|previous| previous == editor.clone()) |
| 49 | { | 49 | { |
| 50 | vim.sync_vim_settings(cx); | ||
| 50 | vim.clear_operator(cx); | 51 | vim.clear_operator(cx); |
| 51 | } | 52 | } |
| 52 | } | 53 | } |
| @@ -7,6 +7,7 @@ use std::time::Duration; · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | use command_palette::CommandPalette; | 8 | use command_palette::CommandPalette; |
| 9 | use editor::DisplayPoint; | 9 | use editor::DisplayPoint; |
| 10 | use futures::StreamExt; | ||
| 10 | use gpui::KeyBinding; | 11 | use gpui::KeyBinding; |
| 11 | pub use neovim_backed_binding_test_context::*; | 12 | pub use neovim_backed_binding_test_context::*; |
| 12 | pub use neovim_backed_test_context::*; | 13 | pub use neovim_backed_test_context::*; |
| @@ -847,3 +848,39 @@ async fn test_comma_w(cx: &mut gpui::TestAppContext) { · 834 unmodified lines | |||
| 847 | cx.assert_shared_state("hellˇo hello\nhello hello").await; | 848 | cx.assert_shared_state("hellˇo hello\nhello hello").await; |
| 848 | cx.assert_shared_mode(Mode::Insert).await; | 849 | cx.assert_shared_mode(Mode::Insert).await; |
| 849 | } | 850 | } |
| 851 | |||
| 852 | #[gpui::test] | ||
| 853 | async fn test_rename(cx: &mut gpui::TestAppContext) { | ||
| 854 | let mut cx = VimTestContext::new_typescript(cx).await; | ||
| 855 | |||
| 856 | cx.set_state("const beˇfore = 2; console.log(before)", Mode::Normal); | ||
| 857 | let def_range = cx.lsp_range("const «beforeˇ» = 2; console.log(before)"); | ||
| 858 | let tgt_range = cx.lsp_range("const before = 2; console.log(«beforeˇ»)"); | ||
| 859 | let mut prepare_request = | ||
| 860 | cx.handle_request::<lsp::request::PrepareRenameRequest, _, _>(move |_, _, _| async move { | ||
| 861 | Ok(Some(lsp::PrepareRenameResponse::Range(def_range))) | ||
| 862 | }); | ||
| 863 | let mut rename_request = | ||
| 864 | cx.handle_request::<lsp::request::Rename, _, _>(move |url, params, _| async move { | ||
| 865 | Ok(Some(lsp::WorkspaceEdit { | ||
| 866 | changes: Some( | ||
| 867 | [( | ||
| 868 | url.clone(), | ||
| 869 | vec![ | ||
| 870 | lsp::TextEdit::new(def_range, params.new_name.clone()), | ||
| 871 | lsp::TextEdit::new(tgt_range, params.new_name), | ||
| 872 | ], | ||
| 873 | )] | ||
| 874 | .into(), | ||
| 875 | ), | ||
| 876 | ..Default::default() | ||
| 877 | })) | ||
| 878 | }); | ||
| 879 | |||
| 880 | cx.simulate_keystrokes(["c", "d"]); | ||
| 881 | prepare_request.next().await.unwrap(); | ||
| 882 | cx.simulate_input("after"); | ||
| 883 | cx.simulate_keystrokes(["enter"]); | ||
| 884 | rename_request.next().await.unwrap(); | ||
| 885 | cx.assert_state("const afterˇ = 2; console.log(after)", Mode::Normal) | ||
| 886 | } | ||
| @@ -1,11 +1,7 @@ | |||
| 1 | use std::ops::{Deref, DerefMut}; | 1 | use std::ops::{Deref, DerefMut}; |
| 2 | 2 | ||
| 3 | use editor::test::{ | 3 | use editor::test::editor_lsp_test_context::EditorLspTestContext; |
| 4 | editor_lsp_test_context::EditorLspTestContext, editor_test_context::EditorTestContext, | ||
| 5 | }; | ||
| 6 | use futures::Future; | ||
| 7 | use gpui::{Context, View, VisualContext}; | 4 | use gpui::{Context, View, VisualContext}; |
| 8 | use lsp::request; | ||
| 9 | use search::{project_search::ProjectSearchBar, BufferSearchBar}; | 5 | use search::{project_search::ProjectSearchBar, BufferSearchBar}; |
| 10 | 6 | ||
| 11 | use crate::{state::Operator, *}; | 7 | use crate::{state::Operator, *}; |
| @@ -38,7 +34,17 @@ impl VimTestContext { · 26 unmodified lines | |||
| 38 | pub async fn new_typescript(cx: &mut gpui::TestAppContext) -> VimTestContext { | 34 | pub async fn new_typescript(cx: &mut gpui::TestAppContext) -> VimTestContext { |
| 39 | Self::init(cx); | 35 | Self::init(cx); |
| 40 | Self::new_with_lsp( | 36 | Self::new_with_lsp( |
| 41 | EditorLspTestContext::new_typescript(Default::default(), cx).await, | 37 | EditorLspTestContext::new_typescript( |
| 38 | lsp::ServerCapabilities { | ||
| 39 | rename_provider: Some(lsp::OneOf::Right(lsp::RenameOptions { | ||
| 40 | prepare_provider: Some(true), | ||
| 41 | work_done_progress_options: Default::default(), | ||
| 42 | })), | ||
| 43 | ..Default::default() | ||
| 44 | }, | ||
| 45 | cx, | ||
| 46 | ) | ||
| 47 | .await, | ||
| 42 | true, | 48 | true, |
| 43 | ) | 49 | ) |
| 44 | } | 50 | } |
| @@ -149,23 +155,10 @@ impl VimTestContext { · 104 unmodified lines | |||
| 149 | assert_eq!(self.mode(), mode_after, "{}", self.assertion_context()); | 155 | assert_eq!(self.mode(), mode_after, "{}", self.assertion_context()); |
| 150 | assert_eq!(self.active_operator(), None, "{}", self.assertion_context()); | 156 | assert_eq!(self.active_operator(), None, "{}", self.assertion_context()); |
| 151 | } | 157 | } |
| 152 | |||
| 153 | pub fn handle_request<T, F, Fut>( | ||
| 154 | &self, | ||
| 155 | handler: F, | ||
| 156 | ) -> futures::channel::mpsc::UnboundedReceiver<()> | ||
| 157 | where | ||
| 158 | T: 'static + request::Request, | ||
| 159 | T::Params: 'static + Send, | ||
| 160 | F: 'static + Send + FnMut(lsp::Url, T::Params, gpui::AsyncAppContext) -> Fut, | ||
| 161 | Fut: 'static + Send + Future<Output = Result<T::Result>>, | ||
| 162 | { | ||
| 163 | self.cx.handle_request::<T, F, Fut>(handler) | ||
| 164 | } | ||
| 165 | } | 158 | } |
| 166 | 159 | ||
| 167 | impl Deref for VimTestContext { | 160 | impl Deref for VimTestContext { |
| 168 | type Target = EditorTestContext; | 161 | type Target = EditorLspTestContext; |
| 169 | 162 | ||
| 170 | fn deref(&self) -> &Self::Target { | 163 | fn deref(&self) -> &Self::Target { |
| 171 | &self.cx | 164 | &self.cx |
| @@ -198,7 +198,7 @@ impl Vim { · 197 unmodified lines | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | fn activate_editor(&mut self, editor: View<Editor>, cx: &mut WindowContext) { | 200 | fn activate_editor(&mut self, editor: View<Editor>, cx: &mut WindowContext) { |
| 201 | if editor.read(cx).mode() != EditorMode::Full { | 201 | if !editor.read(cx).use_modal_editing() { |
| 202 | return; | 202 | return; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| @@ -575,8 +575,11 @@ impl Vim { · 370 unmodified lines | |||
| 575 | editor.set_input_enabled(!state.vim_controlled()); | 575 | editor.set_input_enabled(!state.vim_controlled()); |
| 576 | editor.set_autoindent(state.should_autoindent()); | 576 | editor.set_autoindent(state.should_autoindent()); |
| 577 | editor.selections.line_mode = matches!(state.mode, Mode::VisualLine); | 577 | editor.selections.line_mode = matches!(state.mode, Mode::VisualLine); |
| 578 | let context_layer = state.keymap_context_layer(); | 578 | if editor.is_focused(cx) { |
| 579 | editor.set_keymap_context_layer::<Self>(context_layer, cx); | 579 | editor.set_keymap_context_layer::<Self>(state.keymap_context_layer(), cx); |
| 580 | } else { | ||
| 581 | editor.remove_keymap_context_layer::<Self>(cx); | ||
| 582 | } | ||
| 580 | }); | 583 | }); |
| 581 | } | 584 | } |
| 582 | 585 | ||