Insert completion text on enter
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
071a55a7ab
commit
8d2b7ba032
4 changed files with 64 additions and 14 deletions
|
@ -117,7 +117,8 @@ action!(Unfold);
|
|||
action!(FoldSelectedRanges);
|
||||
action!(Scroll, Vector2F);
|
||||
action!(Select, SelectPhase);
|
||||
action!(ShowAutocomplete);
|
||||
action!(ShowCompletions);
|
||||
action!(ConfirmCompletion);
|
||||
|
||||
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
|
||||
path_openers.push(Box::new(items::BufferOpener));
|
||||
|
@ -133,6 +134,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
|
|||
Input("\n".into()),
|
||||
Some("Editor && mode == auto_height"),
|
||||
),
|
||||
Binding::new("enter", ConfirmCompletion, Some("Editor && completing")),
|
||||
Binding::new("tab", Tab, Some("Editor")),
|
||||
Binding::new("shift-tab", Outdent, Some("Editor")),
|
||||
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
||||
|
@ -225,7 +227,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
|
|||
Binding::new("alt-cmd-[", Fold, Some("Editor")),
|
||||
Binding::new("alt-cmd-]", Unfold, Some("Editor")),
|
||||
Binding::new("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
|
||||
Binding::new("ctrl-space", ShowAutocomplete, Some("Editor")),
|
||||
Binding::new("ctrl-space", ShowCompletions, Some("Editor")),
|
||||
]);
|
||||
|
||||
cx.add_action(Editor::open_new);
|
||||
|
@ -290,6 +292,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
|
|||
cx.add_action(Editor::unfold);
|
||||
cx.add_action(Editor::fold_selected_ranges);
|
||||
cx.add_action(Editor::show_completions);
|
||||
cx.add_action(Editor::confirm_completion);
|
||||
}
|
||||
|
||||
trait SelectionExt {
|
||||
|
@ -425,7 +428,7 @@ struct BracketPairState {
|
|||
}
|
||||
|
||||
struct CompletionState {
|
||||
completions: Arc<[Completion]>,
|
||||
completions: Arc<[Completion<Anchor>]>,
|
||||
selected_item: usize,
|
||||
list: UniformListState,
|
||||
}
|
||||
|
@ -1102,6 +1105,11 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn cancel(&mut self, _: &Cancel, cx: &mut ViewContext<Self>) {
|
||||
if self.completion_state.take().is_some() {
|
||||
cx.notify();
|
||||
return;
|
||||
}
|
||||
|
||||
if self.mode != EditorMode::Full {
|
||||
cx.propagate_action();
|
||||
return;
|
||||
|
@ -1506,7 +1514,7 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
fn show_completions(&mut self, _: &ShowAutocomplete, cx: &mut ViewContext<Self>) {
|
||||
fn show_completions(&mut self, _: &ShowCompletions, cx: &mut ViewContext<Self>) {
|
||||
let position = self
|
||||
.newest_selection::<usize>(&self.buffer.read(cx).read(cx))
|
||||
.head();
|
||||
|
@ -1533,6 +1541,23 @@ impl Editor {
|
|||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn confirm_completion(&mut self, _: &ConfirmCompletion, cx: &mut ViewContext<Self>) {
|
||||
if let Some(completion_state) = self.completion_state.take() {
|
||||
if let Some(completion) = completion_state
|
||||
.completions
|
||||
.get(completion_state.selected_item)
|
||||
{
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit_with_autoindent(
|
||||
[completion.old_range.clone()],
|
||||
completion.new_text.clone(),
|
||||
cx,
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_completions(&self) -> bool {
|
||||
self.completion_state.is_some()
|
||||
}
|
||||
|
@ -4180,6 +4205,9 @@ impl View for Editor {
|
|||
EditorMode::Full => "full",
|
||||
};
|
||||
cx.map.insert("mode".into(), mode.into());
|
||||
if self.completion_state.is_some() {
|
||||
cx.set.insert("completing".into());
|
||||
}
|
||||
cx
|
||||
}
|
||||
}
|
||||
|
|
|
@ -852,12 +852,34 @@ impl MultiBuffer {
|
|||
&self,
|
||||
position: T,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<Completion>>>
|
||||
) -> Task<Result<Vec<Completion<Anchor>>>>
|
||||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
let (buffer, text_anchor) = self.text_anchor_for_position(position, cx);
|
||||
buffer.update(cx, |buffer, cx| buffer.completions(text_anchor, cx))
|
||||
let snapshot = self.snapshot(cx);
|
||||
let anchor = snapshot.anchor_before(position);
|
||||
let buffer = self.buffers.borrow()[&anchor.buffer_id].buffer.clone();
|
||||
let completions =
|
||||
buffer.update(cx, |buffer, cx| buffer.completions(anchor.text_anchor, cx));
|
||||
cx.foreground().spawn(async move {
|
||||
completions.await.map(|completions| {
|
||||
completions
|
||||
.into_iter()
|
||||
.map(|completion| Completion {
|
||||
old_range: snapshot.anchor_in_excerpt(
|
||||
anchor.excerpt_id.clone(),
|
||||
completion.old_range.start,
|
||||
)
|
||||
..snapshot.anchor_in_excerpt(
|
||||
anchor.excerpt_id.clone(),
|
||||
completion.old_range.end,
|
||||
),
|
||||
new_text: completion.new_text,
|
||||
lsp_completion: completion.lsp_completion,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {
|
||||
|
|
|
@ -114,10 +114,10 @@ pub struct Diagnostic {
|
|||
pub is_disk_based: bool,
|
||||
}
|
||||
|
||||
pub struct Completion {
|
||||
old_range: Range<Anchor>,
|
||||
new_text: String,
|
||||
lsp_completion: lsp::CompletionItem,
|
||||
pub struct Completion<T> {
|
||||
pub old_range: Range<T>,
|
||||
pub new_text: String,
|
||||
pub lsp_completion: lsp::CompletionItem,
|
||||
}
|
||||
|
||||
struct LanguageServerState {
|
||||
|
@ -1622,7 +1622,7 @@ impl Buffer {
|
|||
&self,
|
||||
position: T,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<Completion>>>
|
||||
) -> Task<Result<Vec<Completion<Anchor>>>>
|
||||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
|
@ -2424,7 +2424,7 @@ impl Default for Diagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl<T> Completion<T> {
|
||||
pub fn label(&self) -> &str {
|
||||
&self.lsp_completion.label
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ mod admin;
|
|||
mod api;
|
||||
mod assets;
|
||||
mod auth;
|
||||
mod careers;
|
||||
mod community;
|
||||
mod db;
|
||||
mod env;
|
||||
|
@ -12,7 +13,6 @@ mod home;
|
|||
mod releases;
|
||||
mod rpc;
|
||||
mod team;
|
||||
mod careers;
|
||||
|
||||
use self::errors::TideResultExt as _;
|
||||
use ::rpc::Peer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue