inline_completion.rs

  1use gpui::{AppContext, Model, ModelContext};
  2use language::Buffer;
  3use std::ops::Range;
  4
  5// TODO: Find a better home for `Direction`.
  6//
  7// This should live in an ancestor crate of `editor` and `inline_completion`,
  8// but at time of writing there isn't an obvious spot.
  9#[derive(Copy, Clone, PartialEq, Eq)]
 10pub enum Direction {
 11    Prev,
 12    Next,
 13}
 14
 15#[derive(Clone)]
 16pub struct InlineCompletion {
 17    pub edits: Vec<(Range<language::Anchor>, String)>,
 18}
 19
 20pub trait InlineCompletionProvider: 'static + Sized {
 21    fn name() -> &'static str;
 22    fn display_name() -> &'static str;
 23    fn show_completions_in_menu() -> bool;
 24    fn show_completions_in_normal_mode() -> bool;
 25    fn is_enabled(
 26        &self,
 27        buffer: &Model<Buffer>,
 28        cursor_position: language::Anchor,
 29        cx: &AppContext,
 30    ) -> bool;
 31    fn is_refreshing(&self) -> bool;
 32    fn refresh(
 33        &mut self,
 34        buffer: Model<Buffer>,
 35        cursor_position: language::Anchor,
 36        debounce: bool,
 37        cx: &mut ModelContext<Self>,
 38    );
 39    fn needs_terms_acceptance(&self, _cx: &AppContext) -> bool {
 40        false
 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, cx: &mut ModelContext<Self>);
 51    fn suggest(
 52        &mut self,
 53        buffer: &Model<Buffer>,
 54        cursor_position: language::Anchor,
 55        cx: &mut ModelContext<Self>,
 56    ) -> Option<InlineCompletion>;
 57}
 58
 59pub trait InlineCompletionProviderHandle {
 60    fn name(&self) -> &'static str;
 61    fn display_name(&self) -> &'static str;
 62    fn is_enabled(
 63        &self,
 64        buffer: &Model<Buffer>,
 65        cursor_position: language::Anchor,
 66        cx: &AppContext,
 67    ) -> bool;
 68    fn show_completions_in_menu(&self) -> bool;
 69    fn show_completions_in_normal_mode(&self) -> bool;
 70    fn needs_terms_acceptance(&self, cx: &AppContext) -> bool;
 71    fn is_refreshing(&self, cx: &AppContext) -> bool;
 72    fn refresh(
 73        &self,
 74        buffer: Model<Buffer>,
 75        cursor_position: language::Anchor,
 76        debounce: bool,
 77        cx: &mut AppContext,
 78    );
 79    fn cycle(
 80        &self,
 81        buffer: Model<Buffer>,
 82        cursor_position: language::Anchor,
 83        direction: Direction,
 84        cx: &mut AppContext,
 85    );
 86    fn accept(&self, cx: &mut AppContext);
 87    fn discard(&self, cx: &mut AppContext);
 88    fn suggest(
 89        &self,
 90        buffer: &Model<Buffer>,
 91        cursor_position: language::Anchor,
 92        cx: &mut AppContext,
 93    ) -> Option<InlineCompletion>;
 94}
 95
 96impl<T> InlineCompletionProviderHandle for Model<T>
 97where
 98    T: InlineCompletionProvider,
 99{
100    fn name(&self) -> &'static str {
101        T::name()
102    }
103
104    fn display_name(&self) -> &'static str {
105        T::display_name()
106    }
107
108    fn show_completions_in_menu(&self) -> bool {
109        T::show_completions_in_menu()
110    }
111
112    fn show_completions_in_normal_mode(&self) -> bool {
113        T::show_completions_in_normal_mode()
114    }
115
116    fn is_enabled(
117        &self,
118        buffer: &Model<Buffer>,
119        cursor_position: language::Anchor,
120        cx: &AppContext,
121    ) -> bool {
122        self.read(cx).is_enabled(buffer, cursor_position, cx)
123    }
124
125    fn needs_terms_acceptance(&self, cx: &AppContext) -> bool {
126        self.read(cx).needs_terms_acceptance(cx)
127    }
128
129    fn is_refreshing(&self, cx: &AppContext) -> bool {
130        self.read(cx).is_refreshing()
131    }
132
133    fn refresh(
134        &self,
135        buffer: Model<Buffer>,
136        cursor_position: language::Anchor,
137        debounce: bool,
138        cx: &mut AppContext,
139    ) {
140        self.update(cx, |this, cx| {
141            this.refresh(buffer, cursor_position, debounce, cx)
142        })
143    }
144
145    fn cycle(
146        &self,
147        buffer: Model<Buffer>,
148        cursor_position: language::Anchor,
149        direction: Direction,
150        cx: &mut AppContext,
151    ) {
152        self.update(cx, |this, cx| {
153            this.cycle(buffer, cursor_position, direction, cx)
154        })
155    }
156
157    fn accept(&self, cx: &mut AppContext) {
158        self.update(cx, |this, cx| this.accept(cx))
159    }
160
161    fn discard(&self, cx: &mut AppContext) {
162        self.update(cx, |this, cx| this.discard(cx))
163    }
164
165    fn suggest(
166        &self,
167        buffer: &Model<Buffer>,
168        cursor_position: language::Anchor,
169        cx: &mut AppContext,
170    ) -> Option<InlineCompletion> {
171        self.update(cx, |this, cx| this.suggest(buffer, cursor_position, cx))
172    }
173}