mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-09 21:26:14 +03:00
Fully disable vim mode on start unless it's enabled
Also: Make some structural adjustments to remove the need for defer. Instead of accessing the global in associated VimState functions, have a single method that allows us to call update instance methods.
This commit is contained in:
parent
30e31f6561
commit
daf999c3be
@ -782,7 +782,7 @@ type GlobalActionCallback = dyn FnMut(&dyn AnyAction, &mut MutableAppContext);
|
|||||||
type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
|
type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext) -> bool>;
|
||||||
type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
|
type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
|
||||||
type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
|
type ObservationCallback = Box<dyn FnMut(&mut MutableAppContext) -> bool>;
|
||||||
type GlobalObservationCallback = Box<dyn FnMut(&mut MutableAppContext)>;
|
type GlobalObservationCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
|
||||||
type ReleaseObservationCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
|
type ReleaseObservationCallback = Box<dyn FnMut(&dyn Any, &mut MutableAppContext)>;
|
||||||
|
|
||||||
pub struct MutableAppContext {
|
pub struct MutableAppContext {
|
||||||
@ -1222,10 +1222,10 @@ impl MutableAppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn observe_global<G, F>(&mut self, observe: F) -> Subscription
|
pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
|
||||||
where
|
where
|
||||||
G: Any,
|
G: Any,
|
||||||
F: 'static + FnMut(&mut MutableAppContext),
|
F: 'static + FnMut(&G, &mut MutableAppContext),
|
||||||
{
|
{
|
||||||
let type_id = TypeId::of::<G>();
|
let type_id = TypeId::of::<G>();
|
||||||
let id = post_inc(&mut self.next_subscription_id);
|
let id = post_inc(&mut self.next_subscription_id);
|
||||||
@ -1234,7 +1234,14 @@ impl MutableAppContext {
|
|||||||
.lock()
|
.lock()
|
||||||
.entry(type_id)
|
.entry(type_id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(id, Some(Box::new(observe)));
|
.insert(
|
||||||
|
id,
|
||||||
|
Some(
|
||||||
|
Box::new(move |global: &dyn Any, cx: &mut MutableAppContext| {
|
||||||
|
observe(global.downcast_ref().unwrap(), cx)
|
||||||
|
}) as GlobalObservationCallback,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
Subscription::GlobalObservation {
|
Subscription::GlobalObservation {
|
||||||
id,
|
id,
|
||||||
@ -2075,10 +2082,10 @@ impl MutableAppContext {
|
|||||||
fn notify_global_observers(&mut self, observed_type_id: TypeId) {
|
fn notify_global_observers(&mut self, observed_type_id: TypeId) {
|
||||||
let callbacks = self.global_observations.lock().remove(&observed_type_id);
|
let callbacks = self.global_observations.lock().remove(&observed_type_id);
|
||||||
if let Some(callbacks) = callbacks {
|
if let Some(callbacks) = callbacks {
|
||||||
if self.cx.globals.contains_key(&observed_type_id) {
|
if let Some(global) = self.cx.globals.remove(&observed_type_id) {
|
||||||
for (id, callback) in callbacks {
|
for (id, callback) in callbacks {
|
||||||
if let Some(mut callback) = callback {
|
if let Some(mut callback) = callback {
|
||||||
callback(self);
|
callback(global.as_ref(), self);
|
||||||
match self
|
match self
|
||||||
.global_observations
|
.global_observations
|
||||||
.lock()
|
.lock()
|
||||||
@ -2095,6 +2102,7 @@ impl MutableAppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.cx.globals.insert(observed_type_id, global);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5232,7 +5240,7 @@ mod tests {
|
|||||||
let observation_count = Rc::new(RefCell::new(0));
|
let observation_count = Rc::new(RefCell::new(0));
|
||||||
let subscription = cx.observe_global::<Global, _>({
|
let subscription = cx.observe_global::<Global, _>({
|
||||||
let observation_count = observation_count.clone();
|
let observation_count = observation_count.clone();
|
||||||
move |_| {
|
move |_, _| {
|
||||||
*observation_count.borrow_mut() += 1;
|
*observation_count.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -5262,7 +5270,7 @@ mod tests {
|
|||||||
let observation_count = Rc::new(RefCell::new(0));
|
let observation_count = Rc::new(RefCell::new(0));
|
||||||
cx.observe_global::<OtherGlobal, _>({
|
cx.observe_global::<OtherGlobal, _>({
|
||||||
let observation_count = observation_count.clone();
|
let observation_count = observation_count.clone();
|
||||||
move |_| {
|
move |_, _| {
|
||||||
*observation_count.borrow_mut() += 1;
|
*observation_count.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -5636,7 +5644,7 @@ mod tests {
|
|||||||
*subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
|
*subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
|
||||||
let observation_count = observation_count.clone();
|
let observation_count = observation_count.clone();
|
||||||
let subscription = subscription.clone();
|
let subscription = subscription.clone();
|
||||||
move |_| {
|
move |_, _| {
|
||||||
subscription.borrow_mut().take();
|
subscription.borrow_mut().take();
|
||||||
*observation_count.borrow_mut() += 1;
|
*observation_count.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
fn editor_created(EditorCreated(editor): &EditorCreated, cx: &mut MutableAppContext) {
|
fn editor_created(EditorCreated(editor): &EditorCreated, cx: &mut MutableAppContext) {
|
||||||
cx.update_default_global(|vim_state: &mut VimState, cx| {
|
cx.update_default_global(|vim_state: &mut VimState, cx| {
|
||||||
vim_state.editors.insert(editor.id(), editor.downgrade());
|
vim_state.editors.insert(editor.id(), editor.downgrade());
|
||||||
VimState::sync_editor_options(cx);
|
vim_state.sync_editor_options(cx);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,21 +24,21 @@ fn editor_focused(EditorFocused(editor): &EditorFocused, cx: &mut MutableAppCont
|
|||||||
Mode::Normal
|
Mode::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
cx.update_default_global(|vim_state: &mut VimState, _| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
vim_state.active_editor = Some(editor.downgrade());
|
state.active_editor = Some(editor.downgrade());
|
||||||
|
state.switch_mode(&SwitchMode(mode), cx);
|
||||||
});
|
});
|
||||||
VimState::switch_mode(&SwitchMode(mode), cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn editor_blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut MutableAppContext) {
|
fn editor_blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut MutableAppContext) {
|
||||||
cx.update_default_global(|vim_state: &mut VimState, _| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
if let Some(previous_editor) = vim_state.active_editor.clone() {
|
if let Some(previous_editor) = state.active_editor.clone() {
|
||||||
if previous_editor == editor.clone() {
|
if previous_editor == editor.clone() {
|
||||||
vim_state.active_editor = None;
|
state.active_editor = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
state.sync_editor_options(cx);
|
||||||
VimState::sync_editor_options(cx);
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn editor_released(EditorReleased(editor): &EditorReleased, cx: &mut MutableAppContext) {
|
fn editor_released(EditorReleased(editor): &EditorReleased, cx: &mut MutableAppContext) {
|
||||||
|
@ -18,11 +18,13 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext<Workspace>) {
|
fn normal_before(_: &mut Workspace, _: &NormalBefore, cx: &mut ViewContext<Workspace>) {
|
||||||
VimState::update_active_editor(cx, |editor, cx| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
|
state.update_active_editor(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, |map, mut cursor, _| {
|
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||||
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
||||||
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
VimState::switch_mode(&SwitchMode(Mode::Normal), cx);
|
state.switch_mode(&SwitchMode(Mode::Normal), cx);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -28,31 +28,39 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn move_left(_: &mut Workspace, _: &MoveLeft, cx: &mut ViewContext<Workspace>) {
|
fn move_left(_: &mut Workspace, _: &MoveLeft, cx: &mut ViewContext<Workspace>) {
|
||||||
VimState::update_active_editor(cx, |editor, cx| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
|
state.update_active_editor(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, |map, mut cursor, _| {
|
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||||
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
*cursor.column_mut() = cursor.column().saturating_sub(1);
|
||||||
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
(map.clip_point(cursor, Bias::Left), SelectionGoal::None)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_down(_: &mut Workspace, _: &MoveDown, cx: &mut ViewContext<Workspace>) {
|
fn move_down(_: &mut Workspace, _: &MoveDown, cx: &mut ViewContext<Workspace>) {
|
||||||
VimState::update_active_editor(cx, |editor, cx| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
|
state.update_active_editor(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, movement::down);
|
editor.move_cursors(cx, movement::down);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_up(_: &mut Workspace, _: &MoveUp, cx: &mut ViewContext<Workspace>) {
|
fn move_up(_: &mut Workspace, _: &MoveUp, cx: &mut ViewContext<Workspace>) {
|
||||||
VimState::update_active_editor(cx, |editor, cx| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
|
state.update_active_editor(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, movement::up);
|
editor.move_cursors(cx, movement::up);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_right(_: &mut Workspace, _: &MoveRight, cx: &mut ViewContext<Workspace>) {
|
fn move_right(_: &mut Workspace, _: &MoveRight, cx: &mut ViewContext<Workspace>) {
|
||||||
VimState::update_active_editor(cx, |editor, cx| {
|
VimState::update_global(cx, |state, cx| {
|
||||||
|
state.update_active_editor(cx, |editor, cx| {
|
||||||
editor.move_cursors(cx, |map, mut cursor, _| {
|
editor.move_cursors(cx, |map, mut cursor, _| {
|
||||||
*cursor.column_mut() += 1;
|
*cursor.column_mut() += 1;
|
||||||
(map.clip_point(cursor, Bias::Right), SelectionGoal::None)
|
(map.clip_point(cursor, Bias::Right), SelectionGoal::None)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,13 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||||||
insert::init(cx);
|
insert::init(cx);
|
||||||
normal::init(cx);
|
normal::init(cx);
|
||||||
|
|
||||||
cx.add_action(|_: &mut Workspace, action: &SwitchMode, cx| VimState::switch_mode(action, cx));
|
cx.add_action(|_: &mut Workspace, action: &SwitchMode, cx| {
|
||||||
|
VimState::update_global(cx, |state, cx| state.switch_mode(action, cx))
|
||||||
|
});
|
||||||
|
|
||||||
cx.observe_global::<Settings, _>(VimState::settings_changed)
|
cx.observe_global::<Settings, _>(|settings, cx| {
|
||||||
|
VimState::update_global(cx, |state, cx| state.set_enabled(settings.vim_mode, cx))
|
||||||
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,62 +39,56 @@ pub struct VimState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VimState {
|
impl VimState {
|
||||||
|
fn update_global<F, S>(cx: &mut MutableAppContext, update: F) -> S
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self, &mut MutableAppContext) -> S,
|
||||||
|
{
|
||||||
|
cx.update_default_global(update)
|
||||||
|
}
|
||||||
|
|
||||||
fn update_active_editor<S>(
|
fn update_active_editor<S>(
|
||||||
|
&self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
update: impl FnOnce(&mut Editor, &mut ViewContext<Editor>) -> S,
|
update: impl FnOnce(&mut Editor, &mut ViewContext<Editor>) -> S,
|
||||||
) -> Option<S> {
|
) -> Option<S> {
|
||||||
cx.global::<Self>()
|
self.active_editor
|
||||||
.active_editor
|
|
||||||
.clone()
|
.clone()
|
||||||
.and_then(|ae| ae.upgrade(cx))
|
.and_then(|ae| ae.upgrade(cx))
|
||||||
.map(|ae| ae.update(cx, update))
|
.map(|ae| ae.update(cx, update))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_mode(SwitchMode(mode): &SwitchMode, cx: &mut MutableAppContext) {
|
fn switch_mode(&mut self, SwitchMode(mode): &SwitchMode, cx: &mut MutableAppContext) {
|
||||||
cx.update_default_global(|this: &mut Self, _| {
|
self.mode = *mode;
|
||||||
this.mode = *mode;
|
self.sync_editor_options(cx);
|
||||||
});
|
|
||||||
|
|
||||||
VimState::sync_editor_options(cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn settings_changed(cx: &mut MutableAppContext) {
|
fn set_enabled(&mut self, enabled: bool, cx: &mut MutableAppContext) {
|
||||||
cx.update_default_global(|this: &mut Self, cx| {
|
if self.enabled != enabled {
|
||||||
let settings = cx.global::<Settings>();
|
self.enabled = enabled;
|
||||||
if this.enabled != settings.vim_mode {
|
self.sync_editor_options(cx);
|
||||||
this.enabled = settings.vim_mode;
|
|
||||||
this.mode = if settings.vim_mode {
|
|
||||||
Mode::Normal
|
|
||||||
} else {
|
|
||||||
Mode::Insert
|
|
||||||
};
|
|
||||||
Self::sync_editor_options(cx);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_editor_options(cx: &mut MutableAppContext) {
|
fn sync_editor_options(&self, cx: &mut MutableAppContext) {
|
||||||
cx.defer(move |cx| {
|
let mode = self.mode;
|
||||||
cx.update_default_global(|this: &mut VimState, cx| {
|
|
||||||
let mode = this.mode;
|
|
||||||
let cursor_shape = mode.cursor_shape();
|
let cursor_shape = mode.cursor_shape();
|
||||||
let keymap_layer_active = this.enabled;
|
for editor in self.editors.values() {
|
||||||
for editor in this.editors.values() {
|
|
||||||
if let Some(editor) = editor.upgrade(cx) {
|
if let Some(editor) = editor.upgrade(cx) {
|
||||||
editor.update(cx, |editor, cx| {
|
editor.update(cx, |editor, cx| {
|
||||||
|
if self.enabled {
|
||||||
editor.set_cursor_shape(cursor_shape, cx);
|
editor.set_cursor_shape(cursor_shape, cx);
|
||||||
editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx);
|
editor.set_clip_at_line_ends(cursor_shape == CursorShape::Block, cx);
|
||||||
editor.set_input_enabled(mode == Mode::Insert);
|
editor.set_input_enabled(mode == Mode::Insert);
|
||||||
if keymap_layer_active {
|
|
||||||
let context_layer = mode.keymap_context_layer();
|
let context_layer = mode.keymap_context_layer();
|
||||||
editor.set_keymap_context_layer::<Self>(context_layer);
|
editor.set_keymap_context_layer::<Self>(context_layer);
|
||||||
} else {
|
} else {
|
||||||
|
editor.set_cursor_shape(CursorShape::Bar, cx);
|
||||||
|
editor.set_clip_at_line_ends(false, cx);
|
||||||
|
editor.set_input_enabled(true);
|
||||||
editor.remove_keymap_context_layer::<Self>();
|
editor.remove_keymap_context_layer::<Self>();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user