Detailed changes
@@ -365,6 +365,7 @@
"ctrl-alt-b": "branches::OpenRecent",
"ctrl-~": "workspace::NewTerminal",
"ctrl-s": "workspace::Save",
+ "ctrl-k s": "workspace::SaveWithoutFormat",
"ctrl-shift-s": "workspace::SaveAs",
"ctrl-n": "workspace::NewFile",
"ctrl-shift-n": "workspace::NewWindow",
@@ -408,6 +408,7 @@
"alt-cmd-b": "branches::OpenRecent",
"ctrl-~": "workspace::NewTerminal",
"cmd-s": "workspace::Save",
+ "cmd-k s": "workspace::SaveWithoutFormat",
"cmd-shift-s": "workspace::SaveAs",
"cmd-n": "workspace::NewFile",
"cmd-shift-n": "workspace::NewWindow",
@@ -426,8 +427,8 @@
"cmd-j": "workspace::ToggleBottomDock",
"alt-cmd-y": "workspace::CloseAllDocks",
"cmd-shift-f": "pane::DeploySearch",
- "cmd-k cmd-t": "theme_selector::Toggle",
"cmd-k cmd-s": "zed::OpenKeymap",
+ "cmd-k cmd-t": "theme_selector::Toggle",
"cmd-t": "project_symbols::Toggle",
"cmd-p": "file_finder::Toggle",
"cmd-shift-p": "command_palette::Toggle",
@@ -735,8 +735,13 @@ impl Item for ProjectDiagnosticsEditor {
true
}
- fn save(&mut self, project: Model<Project>, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
- self.editor.save(project, cx)
+ fn save(
+ &mut self,
+ format: bool,
+ project: Model<Project>,
+ cx: &mut ViewContext<Self>,
+ ) -> Task<Result<()>> {
+ self.editor.save(format, project, cx)
}
fn save_as(
@@ -5265,7 +5265,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
assert!(cx.read(|cx| editor.is_dirty(cx)));
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
fake_server
.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
@@ -5303,7 +5303,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
unreachable!()
});
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
cx.executor().advance_clock(super::FORMAT_TIMEOUT);
cx.executor().start_waiting();
@@ -5326,7 +5326,7 @@ async fn test_document_format_during_save(cx: &mut gpui::TestAppContext) {
});
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
fake_server
.handle_request::<lsp::request::Formatting, _, _>(move |params, _| async move {
@@ -5379,7 +5379,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
assert!(cx.read(|cx| editor.is_dirty(cx)));
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
fake_server
.handle_request::<lsp::request::RangeFormatting, _, _>(move |params, _| async move {
@@ -5418,7 +5418,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
},
);
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
cx.executor().advance_clock(super::FORMAT_TIMEOUT);
cx.executor().start_waiting();
@@ -5441,7 +5441,7 @@ async fn test_range_format_during_save(cx: &mut gpui::TestAppContext) {
});
let save = editor
- .update(cx, |editor, cx| editor.save(project.clone(), cx))
+ .update(cx, |editor, cx| editor.save(true, project.clone(), cx))
.unwrap();
fake_server
.handle_request::<lsp::request::RangeFormatting, _, _>(move |params, _| async move {
@@ -702,14 +702,21 @@ impl Item for Editor {
}
}
- fn save(&mut self, project: Model<Project>, cx: &mut ViewContext<Self>) -> Task<Result<()>> {
+ fn save(
+ &mut self,
+ format: bool,
+ project: Model<Project>,
+ cx: &mut ViewContext<Self>,
+ ) -> Task<Result<()>> {
self.report_editor_event("save", None, cx);
let buffers = self.buffer().clone().read(cx).all_buffers();
cx.spawn(|this, mut cx| async move {
- this.update(&mut cx, |this, cx| {
- this.perform_format(project.clone(), FormatTrigger::Save, cx)
- })?
- .await?;
+ if format {
+ this.update(&mut cx, |this, cx| {
+ this.perform_format(project.clone(), FormatTrigger::Save, cx)
+ })?
+ .await?;
+ }
if buffers.len() == 1 {
project
@@ -539,11 +539,12 @@ impl Item for ProjectSearchView {
fn save(
&mut self,
+ format: bool,
project: Model<Project>,
cx: &mut ViewContext<Self>,
) -> Task<anyhow::Result<()>> {
self.results_editor
- .update(cx, |editor, cx| editor.save(project, cx))
+ .update(cx, |editor, cx| editor.save(format, project, cx))
}
fn save_as(
@@ -146,7 +146,12 @@ pub trait Item: FocusableView + EventEmitter<Self::Event> {
fn can_save(&self, _cx: &AppContext) -> bool {
false
}
- fn save(&mut self, _project: Model<Project>, _cx: &mut ViewContext<Self>) -> Task<Result<()>> {
+ fn save(
+ &mut self,
+ _format: bool,
+ _project: Model<Project>,
+ _cx: &mut ViewContext<Self>,
+ ) -> Task<Result<()>> {
unimplemented!("save() must be implemented if can_save() returns true")
}
fn save_as(
@@ -258,7 +263,12 @@ pub trait ItemHandle: 'static + Send {
fn is_dirty(&self, cx: &AppContext) -> bool;
fn has_conflict(&self, cx: &AppContext) -> bool;
fn can_save(&self, cx: &AppContext) -> bool;
- fn save(&self, project: Model<Project>, cx: &mut WindowContext) -> Task<Result<()>>;
+ fn save(
+ &self,
+ format: bool,
+ project: Model<Project>,
+ cx: &mut WindowContext,
+ ) -> Task<Result<()>>;
fn save_as(
&self,
project: Model<Project>,
@@ -566,8 +576,13 @@ impl<T: Item> ItemHandle for View<T> {
self.read(cx).can_save(cx)
}
- fn save(&self, project: Model<Project>, cx: &mut WindowContext) -> Task<Result<()>> {
- self.update(cx, |item, cx| item.save(project, cx))
+ fn save(
+ &self,
+ format: bool,
+ project: Model<Project>,
+ cx: &mut WindowContext,
+ ) -> Task<Result<()>> {
+ self.update(cx, |item, cx| item.save(format, project, cx))
}
fn save_as(
@@ -1018,6 +1033,7 @@ pub mod test {
fn save(
&mut self,
+ _: bool,
_: Model<Project>,
_: &mut ViewContext<Self>,
) -> Task<anyhow::Result<()>> {
@@ -44,6 +44,8 @@ pub enum SaveIntent {
/// write all files (even if unchanged)
/// prompt before overwriting on-disk changes
Save,
+ /// same as Save, but without auto formatting
+ SaveWithoutFormat,
/// write any files that have local changes
/// prompt before overwriting on-disk changes
SaveAll,
@@ -1122,7 +1124,7 @@ impl Pane {
})?;
// when saving a single buffer, we ignore whether or not it's dirty.
- if save_intent == SaveIntent::Save {
+ if save_intent == SaveIntent::Save || save_intent == SaveIntent::SaveWithoutFormat {
is_dirty = true;
}
@@ -1136,6 +1138,8 @@ impl Pane {
has_conflict = false;
}
+ let should_format = save_intent != SaveIntent::SaveWithoutFormat;
+
if has_conflict && can_save {
let answer = pane.update(cx, |pane, cx| {
pane.activate_item(item_ix, true, true, cx);
@@ -1147,7 +1151,10 @@ impl Pane {
)
})?;
match answer.await {
- Ok(0) => pane.update(cx, |_, cx| item.save(project, cx))?.await?,
+ Ok(0) => {
+ pane.update(cx, |_, cx| item.save(should_format, project, cx))?
+ .await?
+ }
Ok(1) => pane.update(cx, |_, cx| item.reload(project, cx))?.await?,
_ => return Ok(false),
}
@@ -1179,7 +1186,8 @@ impl Pane {
}
if can_save {
- pane.update(cx, |_, cx| item.save(project, cx))?.await?;
+ pane.update(cx, |_, cx| item.save(should_format, project, cx))?
+ .await?;
} else if can_save_as {
let start_abs_path = project
.update(cx, |project, cx| {
@@ -1211,7 +1219,7 @@ impl Pane {
cx: &mut WindowContext,
) -> Task<Result<()>> {
if Self::can_autosave_item(item, cx) {
- item.save(project, cx)
+ item.save(true, project, cx)
} else {
Task::ready(Ok(()))
}
@@ -106,6 +106,7 @@ actions!(
AddFolderToProject,
Unfollow,
SaveAs,
+ SaveWithoutFormat,
ReloadActiveItem,
ActivatePreviousPane,
ActivateNextPane,
@@ -3532,6 +3533,11 @@ impl Workspace {
.save_active_item(action.save_intent.unwrap_or(SaveIntent::Save), cx)
.detach_and_log_err(cx);
}))
+ .on_action(cx.listener(|workspace, _: &SaveWithoutFormat, cx| {
+ workspace
+ .save_active_item(SaveIntent::SaveWithoutFormat, cx)
+ .detach_and_log_err(cx);
+ }))
.on_action(cx.listener(|workspace, _: &SaveAs, cx| {
workspace
.save_active_item(SaveIntent::SaveAs, cx)
@@ -1979,7 +1979,7 @@ mod tests {
editor.newline(&Default::default(), cx);
editor.move_down(&Default::default(), cx);
editor.move_down(&Default::default(), cx);
- editor.save(project.clone(), cx)
+ editor.save(true, project.clone(), cx)
})
})
.unwrap()