Merge branch 'main' into implicit-ancestry

This commit is contained in:
Antonio Scandurra 2023-05-04 14:39:58 +02:00
commit da19edc3e3
33 changed files with 746 additions and 392 deletions

View file

@ -52,8 +52,8 @@ use itertools::Itertools;
pub use language::{char_kind, CharKind};
use language::{
AutoindentMode, BracketPair, Buffer, CodeAction, CodeLabel, Completion, CursorShape,
Diagnostic, DiagnosticSeverity, IndentKind, IndentSize, Language, OffsetRangeExt, OffsetUtf16,
Point, Selection, SelectionGoal, TransactionId,
Diagnostic, DiagnosticSeverity, File, IndentKind, IndentSize, Language, OffsetRangeExt,
OffsetUtf16, Point, Selection, SelectionGoal, TransactionId,
};
use link_go_to_definition::{
hide_link_definition, show_link_definition, LinkDefinitionKind, LinkGoToDefinitionState,
@ -1380,6 +1380,10 @@ impl Editor {
self.buffer.read(cx).language_at(point, cx)
}
pub fn file_at<'a, T: ToOffset>(&self, point: T, cx: &'a AppContext) -> Option<Arc<dyn File>> {
self.buffer.read(cx).read(cx).file_at(point).cloned()
}
pub fn active_excerpt(
&self,
cx: &AppContext,
@ -1423,13 +1427,19 @@ impl Editor {
}
}
pub fn set_keymap_context_layer<Tag: 'static>(&mut self, context: KeymapContext) {
pub fn set_keymap_context_layer<Tag: 'static>(
&mut self,
context: KeymapContext,
cx: &mut ViewContext<Self>,
) {
self.keymap_context_layers
.insert(TypeId::of::<Tag>(), context);
cx.notify();
}
pub fn remove_keymap_context_layer<Tag: 'static>(&mut self) {
pub fn remove_keymap_context_layer<Tag: 'static>(&mut self, cx: &mut ViewContext<Self>) {
self.keymap_context_layers.remove(&TypeId::of::<Tag>());
cx.notify();
}
pub fn set_input_enabled(&mut self, input_enabled: bool) {
@ -2949,11 +2959,7 @@ impl Editor {
let snapshot = self.buffer.read(cx).snapshot(cx);
let cursor = self.selections.newest_anchor().head();
let language_name = snapshot.language_at(cursor).map(|language| language.name());
if !cx
.global::<Settings>()
.show_copilot_suggestions(language_name.as_deref())
{
if !self.is_copilot_enabled_at(cursor, &snapshot, cx) {
self.clear_copilot_suggestions(cx);
return None;
}
@ -3104,6 +3110,25 @@ impl Editor {
}
}
fn is_copilot_enabled_at(
&self,
location: Anchor,
snapshot: &MultiBufferSnapshot,
cx: &mut ViewContext<Self>,
) -> bool {
let settings = cx.global::<Settings>();
let path = snapshot.file_at(location).map(|file| file.path());
let language_name = snapshot
.language_at(location)
.map(|language| language.name());
if !settings.show_copilot_suggestions(language_name.as_deref(), path.map(|p| p.as_ref())) {
return false;
}
true
}
fn has_active_copilot_suggestion(&self, cx: &AppContext) -> bool {
self.display_map.read(cx).has_suggestion()
}
@ -6865,6 +6890,9 @@ impl Editor {
self.language_at(0, cx)
.map(|language| language.name())
.as_deref(),
self.file_at(0, cx)
.map(|file| file.path().clone())
.as_deref(),
),
};
telemetry.report_clickhouse_event(event, settings.telemetry())
@ -7137,28 +7165,26 @@ impl View for Editor {
false
}
fn keymap_context(&self, _: &AppContext) -> KeymapContext {
let mut context = Self::default_keymap_context();
fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
Self::reset_to_default_keymap_context(keymap);
let mode = match self.mode {
EditorMode::SingleLine => "single_line",
EditorMode::AutoHeight { .. } => "auto_height",
EditorMode::Full => "full",
};
context.add_key("mode", mode);
keymap.add_key("mode", mode);
if self.pending_rename.is_some() {
context.add_identifier("renaming");
keymap.add_identifier("renaming");
}
match self.context_menu.as_ref() {
Some(ContextMenu::Completions(_)) => context.add_identifier("showing_completions"),
Some(ContextMenu::CodeActions(_)) => context.add_identifier("showing_code_actions"),
Some(ContextMenu::Completions(_)) => keymap.add_identifier("showing_completions"),
Some(ContextMenu::CodeActions(_)) => keymap.add_identifier("showing_code_actions"),
None => {}
}
for layer in self.keymap_context_layers.values() {
context.extend(layer);
keymap.extend(layer);
}
context
}
fn text_for_range(&self, range_utf16: Range<usize>, cx: &AppContext) -> Option<String> {

View file

@ -6387,6 +6387,97 @@ async fn test_copilot_multibuffer(
});
}
#[gpui::test]
async fn test_copilot_disabled_globs(
deterministic: Arc<Deterministic>,
cx: &mut gpui::TestAppContext,
) {
let (copilot, copilot_lsp) = Copilot::fake(cx);
cx.update(|cx| {
let mut settings = Settings::test(cx);
settings.copilot.disabled_globs = vec![glob::Pattern::new(".env*").unwrap()];
cx.set_global(settings);
cx.set_global(copilot)
});
let fs = FakeFs::new(cx.background());
fs.insert_tree(
"/test",
json!({
".env": "SECRET=something\n",
"README.md": "hello\n"
}),
)
.await;
let project = Project::test(fs, ["/test".as_ref()], cx).await;
let private_buffer = project
.update(cx, |project, cx| {
project.open_local_buffer("/test/.env", cx)
})
.await
.unwrap();
let public_buffer = project
.update(cx, |project, cx| {
project.open_local_buffer("/test/README.md", cx)
})
.await
.unwrap();
let multibuffer = cx.add_model(|cx| {
let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(
private_buffer.clone(),
[ExcerptRange {
context: Point::new(0, 0)..Point::new(1, 0),
primary: None,
}],
cx,
);
multibuffer.push_excerpts(
public_buffer.clone(),
[ExcerptRange {
context: Point::new(0, 0)..Point::new(1, 0),
primary: None,
}],
cx,
);
multibuffer
});
let (_, editor) = cx.add_window(|cx| build_editor(multibuffer, cx));
let mut copilot_requests = copilot_lsp
.handle_request::<copilot::request::GetCompletions, _, _>(move |_params, _cx| async move {
Ok(copilot::request::GetCompletionsResult {
completions: vec![copilot::request::Completion {
text: "next line".into(),
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(1, 0)),
..Default::default()
}],
})
});
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |selections| {
selections.select_ranges([Point::new(0, 0)..Point::new(0, 0)])
});
editor.next_copilot_suggestion(&Default::default(), cx);
});
deterministic.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
assert!(copilot_requests.try_next().is_err());
editor.update(cx, |editor, cx| {
editor.change_selections(None, cx, |s| {
s.select_ranges([Point::new(2, 0)..Point::new(2, 0)])
});
editor.next_copilot_suggestion(&Default::default(), cx);
});
deterministic.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
assert!(copilot_requests.try_next().is_ok());
}
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
let point = DisplayPoint::new(row as u32, column as u32);
point..point

View file

@ -10,9 +10,9 @@ use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
pub use language::Completion;
use language::{
char_kind, AutoindentMode, Buffer, BufferChunks, BufferSnapshot, CharKind, Chunk, CursorShape,
DiagnosticEntry, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16, Outline,
OutlineItem, Point, PointUtf16, Selection, TextDimension, ToOffset as _, ToOffsetUtf16 as _,
ToPoint as _, ToPointUtf16 as _, TransactionId, Unclipped,
DiagnosticEntry, File, IndentSize, Language, LanguageScope, OffsetRangeExt, OffsetUtf16,
Outline, OutlineItem, Point, PointUtf16, Selection, TextDimension, ToOffset as _,
ToOffsetUtf16 as _, ToPoint as _, ToPointUtf16 as _, TransactionId, Unclipped,
};
use std::{
borrow::Cow,
@ -2754,6 +2754,11 @@ impl MultiBufferSnapshot {
self.trailing_excerpt_update_count
}
pub fn file_at<'a, T: ToOffset>(&'a self, point: T) -> Option<&'a Arc<dyn File>> {
self.point_to_buffer_offset(point)
.and_then(|(buffer, _)| buffer.file())
}
pub fn language_at<'a, T: ToOffset>(&'a self, point: T) -> Option<&'a Arc<Language>> {
self.point_to_buffer_offset(point)
.and_then(|(buffer, offset)| buffer.language_at(offset))