editor: Add Organize Imports Action (#25793)
Closes #10004 This PR adds support for the organize imports action. Previously, you had to manually configure it in the settings and then use format to run it. Note: Default key binding will be `alt-shift-o` which is similar to VSCode's organize import. Also, because `cmd-shift-o` is taken by outline picker. Todo: - [x] Initial working - [x] Handle remote - [x] Handle multi buffer - [x] Can we make it generic for executing any code action? Release Notes: - Added `editor:OrganizeImports` action to organize imports (sort, remove unused, etc) for supported LSPs. You can trigger it by using the `alt-shift-o` key binding.
This commit is contained in:
parent
e4e758db3a
commit
fad4df5e70
10 changed files with 408 additions and 4 deletions
|
@ -120,8 +120,8 @@ use task::{ResolvedTask, TaskTemplate, TaskVariables};
|
|||
use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight};
|
||||
pub use lsp::CompletionContext;
|
||||
use lsp::{
|
||||
CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity, InsertTextFormat,
|
||||
LanguageServerId, LanguageServerName,
|
||||
CodeActionKind, CompletionItemKind, CompletionTriggerKind, DiagnosticSeverity,
|
||||
InsertTextFormat, LanguageServerId, LanguageServerName,
|
||||
};
|
||||
|
||||
use language::BufferSnapshot;
|
||||
|
@ -203,6 +203,7 @@ pub(crate) const CURSORS_VISIBLE_FOR: Duration = Duration::from_millis(2000);
|
|||
#[doc(hidden)]
|
||||
pub const CODE_ACTIONS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(250);
|
||||
|
||||
pub(crate) const CODE_ACTION_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(5);
|
||||
pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
|
@ -12494,7 +12495,6 @@ impl Editor {
|
|||
buffer.push_transaction(&transaction.0, cx);
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
|
@ -12503,6 +12503,60 @@ impl Editor {
|
|||
})
|
||||
}
|
||||
|
||||
fn organize_imports(
|
||||
&mut self,
|
||||
_: &OrganizeImports,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
let project = match &self.project {
|
||||
Some(project) => project.clone(),
|
||||
None => return None,
|
||||
};
|
||||
Some(self.perform_code_action_kind(
|
||||
project,
|
||||
CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
|
||||
window,
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
fn perform_code_action_kind(
|
||||
&mut self,
|
||||
project: Entity<Project>,
|
||||
kind: CodeActionKind,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
let buffer = self.buffer.clone();
|
||||
let buffers = buffer.read(cx).all_buffers();
|
||||
let mut timeout = cx.background_executor().timer(CODE_ACTION_TIMEOUT).fuse();
|
||||
let apply_action = project.update(cx, |project, cx| {
|
||||
project.apply_code_action_kind(buffers, kind, true, cx)
|
||||
});
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
let transaction = futures::select_biased! {
|
||||
() = timeout => {
|
||||
log::warn!("timed out waiting for executing code action");
|
||||
None
|
||||
}
|
||||
transaction = apply_action.log_err().fuse() => transaction,
|
||||
};
|
||||
buffer
|
||||
.update(&mut cx, |buffer, cx| {
|
||||
// check if we need this
|
||||
if let Some(transaction) = transaction {
|
||||
if !buffer.is_singleton() {
|
||||
buffer.push_transaction(&transaction.0, cx);
|
||||
}
|
||||
}
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn restart_language_server(
|
||||
&mut self,
|
||||
_: &RestartLanguageServer,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue