inline_completion.rs

  1use gpui::{AppContext, Model, ModelContext};
  2use language::Buffer;
  3use std::ops::Range;
  4use text::{Anchor, Rope};
  5
  6// TODO: Find a better home for `Direction`.
  7//
  8// This should live in an ancestor crate of `editor` and `inline_completion`,
  9// but at time of writing there isn't an obvious spot.
 10#[derive(Copy, Clone, PartialEq, Eq)]
 11pub enum Direction {
 12    Prev,
 13    Next,
 14}
 15
 16pub enum InlayProposal {
 17    Hint(Anchor, project::InlayHint),
 18    Suggestion(Anchor, Rope),
 19}
 20
 21pub struct CompletionProposal {
 22    pub inlays: Vec<InlayProposal>,
 23    pub text: Rope,
 24    pub delete_range: Option<Range<Anchor>>,
 25}
 26
 27pub trait InlineCompletionProvider: 'static + Sized {
 28    fn name() -> &'static str;
 29    fn is_enabled(
 30        &self,
 31        buffer: &Model<Buffer>,
 32        cursor_position: language::Anchor,
 33        cx: &AppContext,
 34    ) -> bool;
 35    fn refresh(
 36        &mut self,
 37        buffer: Model<Buffer>,
 38        cursor_position: language::Anchor,
 39        debounce: bool,
 40        cx: &mut ModelContext<Self>,
 41    );
 42    fn cycle(
 43        &mut self,
 44        buffer: Model<Buffer>,
 45        cursor_position: language::Anchor,
 46        direction: Direction,
 47        cx: &mut ModelContext<Self>,
 48    );
 49    fn accept(&mut self, cx: &mut ModelContext<Self>);
 50    fn discard(&mut self, should_report_inline_completion_event: bool, cx: &mut ModelContext<Self>);
 51    fn active_completion_text<'a>(
 52        &'a self,
 53        buffer: &Model<Buffer>,
 54        cursor_position: language::Anchor,
 55        cx: &'a AppContext,
 56    ) -> Option<CompletionProposal>;
 57}
 58
 59pub trait InlineCompletionProviderHandle {
 60    fn is_enabled(
 61        &self,
 62        buffer: &Model<Buffer>,
 63        cursor_position: language::Anchor,
 64        cx: &AppContext,
 65    ) -> bool;
 66    fn refresh(
 67        &self,
 68        buffer: Model<Buffer>,
 69        cursor_position: language::Anchor,
 70        debounce: bool,
 71        cx: &mut AppContext,
 72    );
 73    fn cycle(
 74        &self,
 75        buffer: Model<Buffer>,
 76        cursor_position: language::Anchor,
 77        direction: Direction,
 78        cx: &mut AppContext,
 79    );
 80    fn accept(&self, cx: &mut AppContext);
 81    fn discard(&self, should_report_inline_completion_event: bool, cx: &mut AppContext);
 82    fn active_completion_text<'a>(
 83        &'a self,
 84        buffer: &Model<Buffer>,
 85        cursor_position: language::Anchor,
 86        cx: &'a AppContext,
 87    ) -> Option<CompletionProposal>;
 88}
 89
 90impl<T> InlineCompletionProviderHandle for Model<T>
 91where
 92    T: InlineCompletionProvider,
 93{
 94    fn is_enabled(
 95        &self,
 96        buffer: &Model<Buffer>,
 97        cursor_position: language::Anchor,
 98        cx: &AppContext,
 99    ) -> bool {
100        self.read(cx).is_enabled(buffer, cursor_position, cx)
101    }
102
103    fn refresh(
104        &self,
105        buffer: Model<Buffer>,
106        cursor_position: language::Anchor,
107        debounce: bool,
108        cx: &mut AppContext,
109    ) {
110        self.update(cx, |this, cx| {
111            this.refresh(buffer, cursor_position, debounce, cx)
112        })
113    }
114
115    fn cycle(
116        &self,
117        buffer: Model<Buffer>,
118        cursor_position: language::Anchor,
119        direction: Direction,
120        cx: &mut AppContext,
121    ) {
122        self.update(cx, |this, cx| {
123            this.cycle(buffer, cursor_position, direction, cx)
124        })
125    }
126
127    fn accept(&self, cx: &mut AppContext) {
128        self.update(cx, |this, cx| this.accept(cx))
129    }
130
131    fn discard(&self, should_report_inline_completion_event: bool, cx: &mut AppContext) {
132        self.update(cx, |this, cx| {
133            this.discard(should_report_inline_completion_event, cx)
134        })
135    }
136
137    fn active_completion_text<'a>(
138        &'a self,
139        buffer: &Model<Buffer>,
140        cursor_position: language::Anchor,
141        cx: &'a AppContext,
142    ) -> Option<CompletionProposal> {
143        self.read(cx)
144            .active_completion_text(buffer, cursor_position, cx)
145    }
146}