Eliminate GPUI View, ViewContext, and WindowContext types (#22632)
There's still a bit more work to do on this, but this PR is compiling (with warnings) after eliminating the key types. When the tasks below are complete, this will be the new narrative for GPUI: - `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit of state, and if `T` implements `Render`, then `Entity<T>` implements `Element`. - `&mut App` This replaces `AppContext` and represents the app. - `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It is provided by the framework when updating an entity. - `&mut Window` Broken out of `&mut WindowContext` which no longer exists. Every method that once took `&mut WindowContext` now takes `&mut Window, &mut App` and every method that took `&mut ViewContext<T>` now takes `&mut Window, &mut Context<T>` Not pictured here are the two other failed attempts. It's been quite a month! Tasks: - [x] Remove `View`, `ViewContext`, `WindowContext` and thread through `Window` - [x] [@cole-miller @mikayla-maki] Redraw window when entities change - [x] [@cole-miller @mikayla-maki] Get examples and Zed running - [x] [@cole-miller @mikayla-maki] Fix Zed rendering - [x] [@mikayla-maki] Fix todo! macros and comments - [x] Fix a bug where the editor would not be redrawn because of view caching - [x] remove publicness window.notify() and replace with `AppContext::notify` - [x] remove `observe_new_window_models`, replace with `observe_new_models` with an optional window - [x] Fix a bug where the project panel would not be redrawn because of the wrong refresh() call being used - [x] Fix the tests - [x] Fix warnings by eliminating `Window` params or using `_` - [x] Fix conflicts - [x] Simplify generic code where possible - [x] Rename types - [ ] Update docs ### issues post merge - [x] Issues switching between normal and insert mode - [x] Assistant re-rendering failure - [x] Vim test failures - [x] Mac build issue Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Joseph <joseph@zed.dev> Co-authored-by: max <max@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev> Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local> Co-authored-by: Mikayla <mikayla.c.maki@gmail.com> Co-authored-by: joão <joao@zed.dev>
This commit is contained in:
parent
21b4a0d50e
commit
6fca1d2b0b
648 changed files with 36248 additions and 28208 deletions
|
@ -7,9 +7,7 @@ use editor::{
|
|||
scroll::Autoscroll,
|
||||
Bias, Editor, ToPoint,
|
||||
};
|
||||
use gpui::{
|
||||
actions, impl_internal_actions, Action, AppContext, Global, ViewContext, WindowContext,
|
||||
};
|
||||
use gpui::{actions, impl_internal_actions, Action, App, Context, Global, Window};
|
||||
use language::Point;
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use regex::Regex;
|
||||
|
@ -101,27 +99,27 @@ impl Deref for WrappedAction {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
||||
Vim::action(editor, cx, |vim, _: &VisualCommand, cx| {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
Vim::action(editor, cx, |vim, _: &VisualCommand, window, cx| {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
command_palette::CommandPalette::toggle(workspace, "'<,'>", cx);
|
||||
command_palette::CommandPalette::toggle(workspace, "'<,'>", window, cx);
|
||||
})
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &ShellCommand, cx| {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
Vim::action(editor, cx, |vim, _: &ShellCommand, window, cx| {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
command_palette::CommandPalette::toggle(workspace, "'<,'>!", cx);
|
||||
command_palette::CommandPalette::toggle(workspace, "'<,'>!", window, cx);
|
||||
})
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, _: &CountCommand, cx| {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
Vim::action(editor, cx, |vim, _: &CountCommand, window, cx| {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
let count = Vim::take_count(cx).unwrap_or(1);
|
||||
|
@ -131,27 +129,27 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
".".to_string()
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
command_palette::CommandPalette::toggle(workspace, &n, cx);
|
||||
command_palette::CommandPalette::toggle(workspace, &n, window, cx);
|
||||
})
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &GoToLine, cx| {
|
||||
vim.switch_mode(Mode::Normal, false, cx);
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let buffer_row = action.range.head().buffer_row(vim, editor, cx)?;
|
||||
Vim::action(editor, cx, |vim, action: &GoToLine, window, cx| {
|
||||
vim.switch_mode(Mode::Normal, false, window, cx);
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let buffer_row = action.range.head().buffer_row(vim, editor, window, cx)?;
|
||||
let current = editor.selections.newest::<Point>(cx);
|
||||
let target = snapshot
|
||||
.buffer_snapshot
|
||||
.clip_point(Point::new(buffer_row.0, current.head().column), Bias::Left);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
|
||||
s.select_ranges([target..target]);
|
||||
});
|
||||
|
||||
anyhow::Ok(())
|
||||
});
|
||||
if let Some(e @ Err(_)) = result {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -161,10 +159,10 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
}
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &YankCommand, cx| {
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
if let Ok(range) = action.range.buffer_range(vim, editor, cx) {
|
||||
Vim::action(editor, cx, |vim, action: &YankCommand, window, cx| {
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
if let Ok(range) = action.range.buffer_range(vim, editor, window, cx) {
|
||||
let end = if range.end < snapshot.buffer_snapshot.max_row() {
|
||||
Point::new(range.end.0 + 1, 0)
|
||||
} else {
|
||||
|
@ -181,21 +179,21 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
});
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |_, action: &WithCount, cx| {
|
||||
Vim::action(editor, cx, |_, action: &WithCount, window, cx| {
|
||||
for _ in 0..action.count {
|
||||
cx.dispatch_action(action.action.boxed_clone())
|
||||
window.dispatch_action(action.action.boxed_clone(), cx)
|
||||
}
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &WithRange, cx| {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
action.range.buffer_range(vim, editor, cx)
|
||||
Vim::action(editor, cx, |vim, action: &WithRange, window, cx| {
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
action.range.buffer_range(vim, editor, window, cx)
|
||||
});
|
||||
|
||||
let range = match result {
|
||||
None => return,
|
||||
Some(e @ Err(_)) => {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -207,24 +205,24 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
};
|
||||
|
||||
let previous_selections = vim
|
||||
.update_editor(cx, |_, editor, cx| {
|
||||
.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let selections = action.restore_selection.then(|| {
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchor_ranges()
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
editor.change_selections(None, cx, |s| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
let end = Point::new(range.end.0, s.buffer().line_len(range.end));
|
||||
s.select_ranges([end..Point::new(range.start.0, 0)]);
|
||||
});
|
||||
selections
|
||||
})
|
||||
.flatten();
|
||||
cx.dispatch_action(action.action.boxed_clone());
|
||||
cx.defer(move |vim, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.change_selections(None, cx, |s| {
|
||||
window.dispatch_action(action.action.boxed_clone(), cx);
|
||||
cx.defer_in(window, move |vim, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
if let Some(previous_selections) = previous_selections {
|
||||
s.select_ranges(previous_selections);
|
||||
} else {
|
||||
|
@ -237,12 +235,12 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
});
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &OnMatchingLines, cx| {
|
||||
action.run(vim, cx)
|
||||
Vim::action(editor, cx, |vim, action: &OnMatchingLines, window, cx| {
|
||||
action.run(vim, window, cx)
|
||||
});
|
||||
|
||||
Vim::action(editor, cx, |vim, action: &ShellExec, cx| {
|
||||
action.run(vim, cx)
|
||||
Vim::action(editor, cx, |vim, action: &ShellExec, window, cx| {
|
||||
action.run(vim, window, cx)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -306,7 +304,7 @@ impl VimCommand {
|
|||
&self,
|
||||
mut query: &str,
|
||||
range: &Option<CommandRange>,
|
||||
cx: &AppContext,
|
||||
cx: &App,
|
||||
) -> Option<Box<dyn Action>> {
|
||||
let has_bang = query.ends_with('!');
|
||||
if has_bang {
|
||||
|
@ -463,9 +461,10 @@ impl Position {
|
|||
&self,
|
||||
vim: &Vim,
|
||||
editor: &mut Editor,
|
||||
cx: &mut WindowContext,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Result<MultiBufferRow> {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let target = match self {
|
||||
Position::Line { row, offset } => {
|
||||
if let Some(anchor) = editor.active_excerpt(cx).and_then(|(_, buffer, _)| {
|
||||
|
@ -524,11 +523,12 @@ impl CommandRange {
|
|||
&self,
|
||||
vim: &Vim,
|
||||
editor: &mut Editor,
|
||||
cx: &mut WindowContext,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Result<Range<MultiBufferRow>> {
|
||||
let start = self.start.buffer_row(vim, editor, cx)?;
|
||||
let start = self.start.buffer_row(vim, editor, window, cx)?;
|
||||
let end = if let Some(end) = self.end.as_ref() {
|
||||
end.buffer_row(vim, editor, cx)?
|
||||
end.buffer_row(vim, editor, window, cx)?
|
||||
} else {
|
||||
start
|
||||
};
|
||||
|
@ -552,7 +552,7 @@ impl CommandRange {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_commands(_: &AppContext) -> Vec<VimCommand> {
|
||||
fn generate_commands(_: &App) -> Vec<VimCommand> {
|
||||
vec![
|
||||
VimCommand::new(
|
||||
("w", "rite"),
|
||||
|
@ -758,7 +758,7 @@ struct VimCommands(Vec<VimCommand>);
|
|||
unsafe impl Sync for VimCommands {}
|
||||
impl Global for VimCommands {}
|
||||
|
||||
fn commands(cx: &AppContext) -> &Vec<VimCommand> {
|
||||
fn commands(cx: &App) -> &Vec<VimCommand> {
|
||||
static COMMANDS: OnceLock<VimCommands> = OnceLock::new();
|
||||
&COMMANDS
|
||||
.get_or_init(|| VimCommands(generate_commands(cx)))
|
||||
|
@ -797,7 +797,7 @@ fn wrap_count(action: Box<dyn Action>, range: &CommandRange) -> Option<Box<dyn A
|
|||
})
|
||||
}
|
||||
|
||||
pub fn command_interceptor(mut input: &str, cx: &AppContext) -> Option<CommandInterceptResult> {
|
||||
pub fn command_interceptor(mut input: &str, cx: &App) -> Option<CommandInterceptResult> {
|
||||
// NOTE: We also need to support passing arguments to commands like :w
|
||||
// (ideally with filename autocompletion).
|
||||
while input.starts_with(':') {
|
||||
|
@ -939,7 +939,7 @@ impl OnMatchingLines {
|
|||
mut chars: Peekable<Chars>,
|
||||
invert: bool,
|
||||
range: CommandRange,
|
||||
cx: &AppContext,
|
||||
cx: &App,
|
||||
) -> Option<Self> {
|
||||
let delimiter = chars.next().filter(|c| {
|
||||
!c.is_alphanumeric() && *c != '"' && *c != '|' && *c != '\'' && *c != '!'
|
||||
|
@ -981,15 +981,15 @@ impl OnMatchingLines {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn run(&self, vim: &mut Vim, cx: &mut ViewContext<Vim>) {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
self.range.buffer_range(vim, editor, cx)
|
||||
pub fn run(&self, vim: &mut Vim, window: &mut Window, cx: &mut Context<Vim>) {
|
||||
let result = vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
self.range.buffer_range(vim, editor, window, cx)
|
||||
});
|
||||
|
||||
let range = match result {
|
||||
None => return,
|
||||
Some(e @ Err(_)) => {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -1006,7 +1006,7 @@ impl OnMatchingLines {
|
|||
let mut regexes = match Regex::new(&self.search) {
|
||||
Ok(regex) => vec![(regex, !self.invert)],
|
||||
e @ Err(_) => {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -1028,15 +1028,16 @@ impl OnMatchingLines {
|
|||
regexes.push((regex, !inner.invert))
|
||||
}
|
||||
|
||||
if let Some(pane) = vim.pane(cx) {
|
||||
if let Some(pane) = vim.pane(window, cx) {
|
||||
pane.update(cx, |pane, cx| {
|
||||
if let Some(search_bar) = pane.toolbar().read(cx).item_of_type::<BufferSearchBar>()
|
||||
{
|
||||
search_bar.update(cx, |search_bar, cx| {
|
||||
if search_bar.show(cx) {
|
||||
if search_bar.show(window, cx) {
|
||||
let _ = search_bar.search(
|
||||
&last_pattern,
|
||||
Some(SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
@ -1045,15 +1046,15 @@ impl OnMatchingLines {
|
|||
});
|
||||
};
|
||||
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let mut row = range.start.0;
|
||||
|
||||
let point_range = Point::new(range.start.0, 0)
|
||||
..snapshot
|
||||
.buffer_snapshot
|
||||
.clip_point(Point::new(range.end.0 + 1, 0), Bias::Left);
|
||||
cx.spawn(|editor, mut cx| async move {
|
||||
cx.spawn_in(window, |editor, mut cx| async move {
|
||||
let new_selections = cx
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
|
@ -1088,15 +1089,15 @@ impl OnMatchingLines {
|
|||
return;
|
||||
}
|
||||
editor
|
||||
.update(&mut cx, |editor, cx| {
|
||||
editor.start_transaction_at(Instant::now(), cx);
|
||||
editor.change_selections(None, cx, |s| {
|
||||
.update_in(&mut cx, |editor, window, cx| {
|
||||
editor.start_transaction_at(Instant::now(), window, cx);
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.replace_cursors_with(|_| new_selections);
|
||||
});
|
||||
cx.dispatch_action(action);
|
||||
cx.defer(move |editor, cx| {
|
||||
window.dispatch_action(action, cx);
|
||||
cx.defer_in(window, move |editor, window, cx| {
|
||||
let newest = editor.selections.newest::<Point>(cx).clone();
|
||||
editor.change_selections(None, cx, |s| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select(vec![newest]);
|
||||
});
|
||||
editor.end_transaction_at(Instant::now(), cx);
|
||||
|
@ -1117,17 +1118,22 @@ pub struct ShellExec {
|
|||
}
|
||||
|
||||
impl Vim {
|
||||
pub fn cancel_running_command(&mut self, cx: &mut ViewContext<Self>) {
|
||||
pub fn cancel_running_command(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.running_command.take().is_some() {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(cx, |editor, _| {
|
||||
self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
editor.transact(window, cx, |editor, _window, _cx| {
|
||||
editor.clear_row_highlights::<ShellExec>();
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_shell_command(&mut self, command: &str, cx: &mut ViewContext<Self>) -> String {
|
||||
fn prepare_shell_command(
|
||||
&mut self,
|
||||
command: &str,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> String {
|
||||
let mut ret = String::new();
|
||||
// N.B. non-standard escaping rules:
|
||||
// * !echo % => "echo README.md"
|
||||
|
@ -1145,7 +1151,7 @@ impl Vim {
|
|||
}
|
||||
match c {
|
||||
'%' => {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
self.update_editor(window, cx, |_, editor, _window, cx| {
|
||||
if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
|
||||
if let Some(file) = buffer.read(cx).file() {
|
||||
if let Some(local) = file.as_local() {
|
||||
|
@ -1173,21 +1179,22 @@ impl Vim {
|
|||
&mut self,
|
||||
motion: Motion,
|
||||
times: Option<usize>,
|
||||
cx: &mut ViewContext<Vim>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Vim>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
let Some(workspace) = self.workspace(cx) else {
|
||||
let Some(workspace) = self.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let command = self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let text_layout_details = editor.text_layout_details(cx);
|
||||
let text_layout_details = editor.text_layout_details(window);
|
||||
let mut range = motion
|
||||
.range(&snapshot, start.clone(), times, false, &text_layout_details)
|
||||
.unwrap_or(start.range());
|
||||
if range.start != start.start {
|
||||
editor.change_selections(None, cx, |s| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_ranges([
|
||||
range.start.to_point(&snapshot)..range.start.to_point(&snapshot)
|
||||
]);
|
||||
|
@ -1204,7 +1211,7 @@ impl Vim {
|
|||
});
|
||||
if let Some(command) = command {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
command_palette::CommandPalette::toggle(workspace, &command, cx);
|
||||
command_palette::CommandPalette::toggle(workspace, &command, window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1213,20 +1220,21 @@ impl Vim {
|
|||
&mut self,
|
||||
object: Object,
|
||||
around: bool,
|
||||
cx: &mut ViewContext<Vim>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Vim>,
|
||||
) {
|
||||
self.stop_recording(cx);
|
||||
let Some(workspace) = self.workspace(cx) else {
|
||||
let Some(workspace) = self.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
let command = self.update_editor(cx, |_, editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
let command = self.update_editor(window, cx, |_, editor, window, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let start = editor.selections.newest_display(cx);
|
||||
let range = object
|
||||
.range(&snapshot, start.clone(), around)
|
||||
.unwrap_or(start.range());
|
||||
if range.start != start.start {
|
||||
editor.change_selections(None, cx, |s| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_ranges([
|
||||
range.start.to_point(&snapshot)..range.start.to_point(&snapshot)
|
||||
]);
|
||||
|
@ -1240,7 +1248,7 @@ impl Vim {
|
|||
});
|
||||
if let Some(command) = command {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
command_palette::CommandPalette::toggle(workspace, &command, cx);
|
||||
command_palette::CommandPalette::toggle(workspace, &command, window, cx);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1265,13 +1273,13 @@ impl ShellExec {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn run(&self, vim: &mut Vim, cx: &mut ViewContext<Vim>) {
|
||||
let Some(workspace) = vim.workspace(cx) else {
|
||||
pub fn run(&self, vim: &mut Vim, window: &mut Window, cx: &mut Context<Vim>) {
|
||||
let Some(workspace) = vim.workspace(window) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let project = workspace.read(cx).project().clone();
|
||||
let command = vim.prepare_shell_command(&self.command, cx);
|
||||
let command = vim.prepare_shell_command(&self.command, window, cx);
|
||||
|
||||
if self.range.is_none() && !self.is_read {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
|
@ -1305,10 +1313,10 @@ impl ShellExec {
|
|||
let mut input_snapshot = None;
|
||||
let mut input_range = None;
|
||||
let mut needs_newline_prefix = false;
|
||||
vim.update_editor(cx, |vim, editor, cx| {
|
||||
vim.update_editor(window, cx, |vim, editor, window, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let range = if let Some(range) = self.range.clone() {
|
||||
let Some(range) = range.buffer_range(vim, editor, cx).log_err() else {
|
||||
let Some(range) = range.buffer_range(vim, editor, window, cx).log_err() else {
|
||||
return;
|
||||
};
|
||||
Point::new(range.start.0, 0)
|
||||
|
@ -1364,10 +1372,10 @@ impl ShellExec {
|
|||
};
|
||||
let is_read = self.is_read;
|
||||
|
||||
let task = cx.spawn(|vim, mut cx| async move {
|
||||
let task = cx.spawn_in(window, |vim, mut cx| async move {
|
||||
let Some(mut running) = process.spawn().log_err() else {
|
||||
vim.update(&mut cx, |vim, cx| {
|
||||
vim.cancel_running_command(cx);
|
||||
vim.update_in(&mut cx, |vim, window, cx| {
|
||||
vim.cancel_running_command(window, cx);
|
||||
})
|
||||
.log_err();
|
||||
return;
|
||||
|
@ -1395,8 +1403,8 @@ impl ShellExec {
|
|||
.await;
|
||||
|
||||
let Some(output) = output.log_err() else {
|
||||
vim.update(&mut cx, |vim, cx| {
|
||||
vim.cancel_running_command(cx);
|
||||
vim.update_in(&mut cx, |vim, window, cx| {
|
||||
vim.cancel_running_command(window, cx);
|
||||
})
|
||||
.log_err();
|
||||
return;
|
||||
|
@ -1411,12 +1419,12 @@ impl ShellExec {
|
|||
text.push('\n');
|
||||
}
|
||||
|
||||
vim.update(&mut cx, |vim, cx| {
|
||||
vim.update_editor(cx, |_, editor, cx| {
|
||||
editor.transact(cx, |editor, cx| {
|
||||
vim.update_in(&mut cx, |vim, window, cx| {
|
||||
vim.update_editor(window, cx, |_, editor, window, cx| {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.edit([(range.clone(), text)], cx);
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
|
||||
let point = if is_read {
|
||||
let point = range.end.to_point(&snapshot);
|
||||
Point::new(point.row.saturating_sub(1), 0)
|
||||
|
@ -1428,7 +1436,7 @@ impl ShellExec {
|
|||
})
|
||||
})
|
||||
});
|
||||
vim.cancel_running_command(cx);
|
||||
vim.cancel_running_command(window, cx);
|
||||
})
|
||||
.log_err();
|
||||
});
|
||||
|
@ -1445,9 +1453,8 @@ mod test {
|
|||
test::{NeovimBackedTestContext, VimTestContext},
|
||||
};
|
||||
use editor::Editor;
|
||||
use gpui::TestAppContext;
|
||||
use gpui::{Context, TestAppContext};
|
||||
use indoc::indoc;
|
||||
use ui::ViewContext;
|
||||
use workspace::Workspace;
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1545,7 +1552,7 @@ mod test {
|
|||
async fn test_command_write(cx: &mut TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
let path = Path::new("/root/dir/file.rs");
|
||||
let fs = cx.workspace(|workspace, cx| workspace.project().read(cx).fs().clone());
|
||||
let fs = cx.workspace(|workspace, _, cx| workspace.project().read(cx).fs().clone());
|
||||
|
||||
cx.simulate_keystrokes("i @ escape");
|
||||
cx.simulate_keystrokes(": w enter");
|
||||
|
@ -1573,13 +1580,13 @@ mod test {
|
|||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.simulate_keystrokes(": n e w enter");
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.simulate_keystrokes(": q enter");
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 1));
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 1));
|
||||
cx.simulate_keystrokes(": n e w enter");
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.simulate_keystrokes(": q a enter");
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 0));
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 0));
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
|
@ -1641,7 +1648,7 @@ mod test {
|
|||
workspace: &mut Workspace,
|
||||
expected_path: &str,
|
||||
expected_text: &str,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
let active_editor = workspace.active_item_as::<Editor>(cx).unwrap();
|
||||
|
||||
|
@ -1665,12 +1672,12 @@ mod test {
|
|||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
// Assert base state, that we're in /root/dir/file.rs
|
||||
cx.workspace(|workspace, cx| {
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file.rs", "", cx);
|
||||
});
|
||||
|
||||
// Insert a new file
|
||||
let fs = cx.workspace(|workspace, cx| workspace.project().read(cx).fs().clone());
|
||||
let fs = cx.workspace(|workspace, _, cx| workspace.project().read(cx).fs().clone());
|
||||
fs.as_fake()
|
||||
.insert_file("/root/dir/file2.rs", "This is file2.rs".as_bytes().to_vec())
|
||||
.await;
|
||||
|
@ -1685,13 +1692,14 @@ mod test {
|
|||
cx.simulate_keystrokes("g f");
|
||||
|
||||
// We now have two items
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.workspace(|workspace, cx| {
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 2));
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file2.rs", "This is file2.rs", cx);
|
||||
});
|
||||
|
||||
// Update editor to point to `file2.rs`
|
||||
cx.editor = cx.workspace(|workspace, cx| workspace.active_item_as::<Editor>(cx).unwrap());
|
||||
cx.editor =
|
||||
cx.workspace(|workspace, _, cx| workspace.active_item_as::<Editor>(cx).unwrap());
|
||||
|
||||
// Put the path to the third file into the currently open buffer,
|
||||
// but remove its suffix, because we want that lookup to happen automatically.
|
||||
|
@ -1701,8 +1709,8 @@ mod test {
|
|||
cx.simulate_keystrokes("g f");
|
||||
|
||||
// We now have three items
|
||||
cx.workspace(|workspace, cx| assert_eq!(workspace.items(cx).count(), 3));
|
||||
cx.workspace(|workspace, cx| {
|
||||
cx.workspace(|workspace, _, cx| assert_eq!(workspace.items(cx).count(), 3));
|
||||
cx.workspace(|workspace, _, cx| {
|
||||
assert_active_item(workspace, "/root/dir/file3.rs", "go to file3", cx);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue