Add editor action to manually invoke buffer format
This commit is contained in:
parent
955ebc5499
commit
f3395cf4fd
9 changed files with 124 additions and 33 deletions
|
@ -19,6 +19,7 @@ use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
|
|||
pub use display_map::DisplayPoint;
|
||||
use display_map::*;
|
||||
pub use element::*;
|
||||
use futures::FutureExt;
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
actions,
|
||||
|
@ -49,7 +50,7 @@ pub use multi_buffer::{
|
|||
};
|
||||
use multi_buffer::{MultiBufferChunks, ToOffsetUtf16};
|
||||
use ordered_float::OrderedFloat;
|
||||
use project::{LocationLink, Project, ProjectPath, ProjectTransaction};
|
||||
use project::{FormatTrigger, LocationLink, Project, ProjectPath, ProjectTransaction};
|
||||
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::Settings;
|
||||
|
@ -76,6 +77,8 @@ const MAX_LINE_LEN: usize = 1024;
|
|||
const MIN_NAVIGATION_HISTORY_ROW_DELTA: i64 = 10;
|
||||
const MAX_SELECTION_HISTORY_LEN: usize = 1024;
|
||||
|
||||
pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
|
||||
#[derive(Clone, Deserialize, PartialEq, Default)]
|
||||
pub struct SelectNext {
|
||||
#[serde(default)]
|
||||
|
@ -204,6 +207,7 @@ actions!(
|
|||
OpenExcerpts,
|
||||
RestartLanguageServer,
|
||||
Hover,
|
||||
Format,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -310,6 +314,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
|||
cx.add_action(Editor::toggle_code_actions);
|
||||
cx.add_action(Editor::open_excerpts);
|
||||
cx.add_action(Editor::jump);
|
||||
cx.add_async_action(Editor::format);
|
||||
cx.add_action(Editor::restart_language_server);
|
||||
cx.add_action(Editor::show_character_palette);
|
||||
cx.add_async_action(Editor::confirm_completion);
|
||||
|
@ -5173,6 +5178,43 @@ impl Editor {
|
|||
self.pending_rename.as_ref()
|
||||
}
|
||||
|
||||
fn format(&mut self, _: &Format, cx: &mut ViewContext<'_, Self>) -> Option<Task<Result<()>>> {
|
||||
let project = match &self.project {
|
||||
Some(project) => project,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
let buffer = self.buffer().clone();
|
||||
let buffers = buffer.read(cx).all_buffers();
|
||||
|
||||
let mut timeout = cx.background().timer(FORMAT_TIMEOUT).fuse();
|
||||
let format = project.update(cx, |project, cx| {
|
||||
project.format(buffers, true, FormatTrigger::Manual, cx)
|
||||
});
|
||||
|
||||
Some(cx.spawn(|_, mut cx| async move {
|
||||
let transaction = futures::select_biased! {
|
||||
_ = timeout => {
|
||||
log::warn!("timed out waiting for formatting");
|
||||
None
|
||||
}
|
||||
transaction = format.log_err().fuse() => transaction,
|
||||
};
|
||||
|
||||
buffer.update(&mut cx, |buffer, cx| {
|
||||
if let Some(transaction) = transaction {
|
||||
if !buffer.is_singleton() {
|
||||
buffer.push_transaction(&transaction.0);
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
||||
fn restart_language_server(&mut self, _: &RestartLanguageServer, cx: &mut ViewContext<Self>) {
|
||||
if let Some(project) = self.project.clone() {
|
||||
self.buffer.update(cx, |multi_buffer, cx| {
|
||||
|
@ -10087,7 +10129,7 @@ mod tests {
|
|||
unreachable!()
|
||||
});
|
||||
let save = cx.update(|cx| editor.save(project.clone(), cx));
|
||||
cx.foreground().advance_clock(items::FORMAT_TIMEOUT);
|
||||
cx.foreground().advance_clock(super::FORMAT_TIMEOUT);
|
||||
cx.foreground().start_waiting();
|
||||
save.await.unwrap();
|
||||
assert_eq!(
|
||||
|
@ -10203,7 +10245,7 @@ mod tests {
|
|||
},
|
||||
);
|
||||
let save = cx.update(|cx| editor.save(project.clone(), cx));
|
||||
cx.foreground().advance_clock(items::FORMAT_TIMEOUT);
|
||||
cx.foreground().advance_clock(super::FORMAT_TIMEOUT);
|
||||
cx.foreground().start_waiting();
|
||||
save.await.unwrap();
|
||||
assert_eq!(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
display_map::ToDisplayPoint, link_go_to_definition::hide_link_definition,
|
||||
movement::surrounding_word, Anchor, Autoscroll, Editor, Event, ExcerptId, MultiBuffer,
|
||||
MultiBufferSnapshot, NavigationData, ToPoint as _,
|
||||
MultiBufferSnapshot, NavigationData, ToPoint as _, FORMAT_TIMEOUT,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::FutureExt;
|
||||
|
@ -10,7 +10,7 @@ use gpui::{
|
|||
RenderContext, Subscription, Task, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use language::{Bias, Buffer, File as _, OffsetRangeExt, SelectionGoal};
|
||||
use project::{File, Project, ProjectEntryId, ProjectPath};
|
||||
use project::{File, FormatTrigger, Project, ProjectEntryId, ProjectPath};
|
||||
use rpc::proto::{self, update_view};
|
||||
use settings::Settings;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -20,7 +20,6 @@ use std::{
|
|||
fmt::Write,
|
||||
ops::Range,
|
||||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use text::{Point, Selection};
|
||||
use util::TryFutureExt;
|
||||
|
@ -30,7 +29,6 @@ use workspace::{
|
|||
ToolbarItemLocation,
|
||||
};
|
||||
|
||||
pub const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
pub const MAX_TAB_TITLE_LEN: usize = 24;
|
||||
|
||||
impl FollowableItem for Editor {
|
||||
|
@ -409,7 +407,9 @@ impl Item for Editor {
|
|||
let buffer = self.buffer().clone();
|
||||
let buffers = buffer.read(cx).all_buffers();
|
||||
let mut timeout = cx.background().timer(FORMAT_TIMEOUT).fuse();
|
||||
let format = project.update(cx, |project, cx| project.format(buffers, true, cx));
|
||||
let format = project.update(cx, |project, cx| {
|
||||
project.format(buffers, true, FormatTrigger::Save, cx)
|
||||
});
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
let transaction = futures::select_biased! {
|
||||
_ = timeout => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue