mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-06 02:37:21 +00:00
WIP
This commit is contained in:
parent
bd2527e691
commit
03bcbdc33d
3 changed files with 122 additions and 0 deletions
|
@ -117,6 +117,7 @@ action!(Unfold);
|
||||||
action!(FoldSelectedRanges);
|
action!(FoldSelectedRanges);
|
||||||
action!(Scroll, Vector2F);
|
action!(Scroll, Vector2F);
|
||||||
action!(Select, SelectPhase);
|
action!(Select, SelectPhase);
|
||||||
|
action!(ShowAutocomplete);
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
|
pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpener>>) {
|
||||||
path_openers.push(Box::new(items::BufferOpener));
|
path_openers.push(Box::new(items::BufferOpener));
|
||||||
|
@ -224,6 +225,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-[", Fold, Some("Editor")),
|
||||||
Binding::new("alt-cmd-]", Unfold, Some("Editor")),
|
Binding::new("alt-cmd-]", Unfold, Some("Editor")),
|
||||||
Binding::new("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
|
Binding::new("alt-cmd-f", FoldSelectedRanges, Some("Editor")),
|
||||||
|
Binding::new("ctrl-shift-A", ShowAutocomplete, Some("Editor")),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
cx.add_action(Editor::open_new);
|
cx.add_action(Editor::open_new);
|
||||||
|
@ -287,6 +289,7 @@ pub fn init(cx: &mut MutableAppContext, path_openers: &mut Vec<Box<dyn PathOpene
|
||||||
cx.add_action(Editor::fold);
|
cx.add_action(Editor::fold);
|
||||||
cx.add_action(Editor::unfold);
|
cx.add_action(Editor::unfold);
|
||||||
cx.add_action(Editor::fold_selected_ranges);
|
cx.add_action(Editor::fold_selected_ranges);
|
||||||
|
cx.add_action(Editor::show_autocomplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
trait SelectionExt {
|
trait SelectionExt {
|
||||||
|
@ -1495,6 +1498,15 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_autocomplete(&mut self, _: &ShowAutocomplete, cx: &mut ViewContext<Self>) {
|
||||||
|
let position = self
|
||||||
|
.newest_selection::<usize>(&self.buffer.read(cx).read(cx))
|
||||||
|
.head();
|
||||||
|
self.buffer
|
||||||
|
.update(cx, |buffer, cx| buffer.completions(position, cx))
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
self.select_all(&SelectAll, cx);
|
self.select_all(&SelectAll, cx);
|
||||||
|
|
|
@ -5,6 +5,7 @@ use anyhow::Result;
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||||
|
pub use language::Completion;
|
||||||
use language::{
|
use language::{
|
||||||
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Outline,
|
Buffer, BufferChunks, BufferSnapshot, Chunk, DiagnosticEntry, Event, File, Language, Outline,
|
||||||
OutlineItem, Selection, ToOffset as _, ToPoint as _, TransactionId,
|
OutlineItem, Selection, ToOffset as _, ToPoint as _, TransactionId,
|
||||||
|
@ -847,6 +848,18 @@ impl MultiBuffer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn completions<T>(
|
||||||
|
&self,
|
||||||
|
position: T,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> Task<Result<Vec<Completion>>>
|
||||||
|
where
|
||||||
|
T: ToOffset,
|
||||||
|
{
|
||||||
|
let (buffer, text_anchor) = self.text_anchor_for_position(position, cx);
|
||||||
|
buffer.update(cx, |buffer, cx| buffer.completions(text_anchor, cx))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {
|
pub fn language<'a>(&self, cx: &'a AppContext) -> Option<&'a Arc<Language>> {
|
||||||
self.buffers
|
self.buffers
|
||||||
.borrow()
|
.borrow()
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use futures::FutureExt as _;
|
use futures::FutureExt as _;
|
||||||
|
use fuzzy::StringMatchCandidate;
|
||||||
use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task};
|
use gpui::{fonts::HighlightStyle, AppContext, Entity, ModelContext, MutableAppContext, Task};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use lsp::LanguageServer;
|
use lsp::LanguageServer;
|
||||||
|
@ -114,6 +115,12 @@ pub struct Diagnostic {
|
||||||
pub is_disk_based: bool,
|
pub is_disk_based: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Completion {
|
||||||
|
old_range: Range<Anchor>,
|
||||||
|
new_text: String,
|
||||||
|
lsp_completion: lsp::CompletionItem,
|
||||||
|
}
|
||||||
|
|
||||||
struct LanguageServerState {
|
struct LanguageServerState {
|
||||||
server: Arc<LanguageServer>,
|
server: Arc<LanguageServer>,
|
||||||
latest_snapshot: watch::Sender<Option<LanguageServerSnapshot>>,
|
latest_snapshot: watch::Sender<Option<LanguageServerSnapshot>>,
|
||||||
|
@ -1611,6 +1618,96 @@ impl Buffer {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn completions<T>(
|
||||||
|
&self,
|
||||||
|
position: T,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> Task<Result<Vec<Completion>>>
|
||||||
|
where
|
||||||
|
T: ToOffset,
|
||||||
|
{
|
||||||
|
let file = if let Some(file) = self.file.as_ref() {
|
||||||
|
file
|
||||||
|
} else {
|
||||||
|
return Task::ready(Ok(Default::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(file) = file.as_local() {
|
||||||
|
let server = if let Some(lang) = self.language_server.as_ref() {
|
||||||
|
lang.server.clone()
|
||||||
|
} else {
|
||||||
|
return Task::ready(Ok(Default::default()));
|
||||||
|
};
|
||||||
|
let abs_path = file.abs_path(cx);
|
||||||
|
let position = self.offset_to_point_utf16(position.to_offset(self));
|
||||||
|
|
||||||
|
cx.spawn(|this, mut cx| async move {
|
||||||
|
let t0 = Instant::now();
|
||||||
|
let completions = server
|
||||||
|
.request::<lsp::request::Completion>(lsp::CompletionParams {
|
||||||
|
text_document_position: lsp::TextDocumentPositionParams::new(
|
||||||
|
lsp::TextDocumentIdentifier::new(
|
||||||
|
lsp::Url::from_file_path(abs_path).unwrap(),
|
||||||
|
),
|
||||||
|
position.to_lsp_position(),
|
||||||
|
),
|
||||||
|
context: Default::default(),
|
||||||
|
work_done_progress_params: Default::default(),
|
||||||
|
partial_result_params: Default::default(),
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
dbg!("completions", t0.elapsed());
|
||||||
|
// fuzzy::match_strings(candidates, query, smart_case, max_results, cancel_flag, background)
|
||||||
|
|
||||||
|
let mut completions = if let Some(completions) = completions {
|
||||||
|
match completions {
|
||||||
|
lsp::CompletionResponse::Array(completions) => completions,
|
||||||
|
lsp::CompletionResponse::List(list) => list.items,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update(&mut cx, |this, cx| {
|
||||||
|
this.edit([0..0], "use std::sync::Arc;\n", cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut futures = Vec::new();
|
||||||
|
for completion in completions {
|
||||||
|
futures.push(server.request::<lsp::request::ResolveCompletionItem>(completion));
|
||||||
|
}
|
||||||
|
|
||||||
|
let completions = futures::future::try_join_all(futures).await?;
|
||||||
|
dbg!("resolution", t0.elapsed(), completions);
|
||||||
|
// let candidates = completions
|
||||||
|
// .iter()
|
||||||
|
// .enumerate()
|
||||||
|
// .map(|(id, completion)| {
|
||||||
|
// let text = completion
|
||||||
|
// .filter_text
|
||||||
|
// .clone()
|
||||||
|
// .unwrap_or_else(|| completion.label.clone());
|
||||||
|
// StringMatchCandidate::new(id, text)
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<_>>();
|
||||||
|
// let matches = fuzzy::match_strings(
|
||||||
|
// &candidates,
|
||||||
|
// "Arc",
|
||||||
|
// false,
|
||||||
|
// 100,
|
||||||
|
// &Default::default(),
|
||||||
|
// cx.background(),
|
||||||
|
// )
|
||||||
|
// .await;
|
||||||
|
// dbg!(matches);
|
||||||
|
|
||||||
|
Ok(Default::default())
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Task::ready(Ok(Default::default()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
|
Loading…
Reference in a new issue