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 cycle(
 40        &mut self,
 41        buffer: Model<Buffer>,
 42        cursor_position: language::Anchor,
 43        direction: Direction,
 44        cx: &mut ModelContext<Self>,
 45    );
 46    fn accept(&mut self, cx: &mut ModelContext<Self>);
 47    fn discard(&mut self, cx: &mut ModelContext<Self>);
 48    fn suggest(
 49        &mut self,
 50        buffer: &Model<Buffer>,
 51        cursor_position: language::Anchor,
 52        cx: &mut ModelContext<Self>,
 53    ) -> Option<InlineCompletion>;
 54}
 55
 56pub trait InlineCompletionProviderHandle {
 57    fn name(&self) -> &'static str;
 58    fn display_name(&self) -> &'static str;
 59    fn is_enabled(
 60        &self,
 61        buffer: &Model<Buffer>,
 62        cursor_position: language::Anchor,
 63        cx: &AppContext,
 64    ) -> bool;
 65    fn show_completions_in_menu(&self) -> bool;
 66    fn show_completions_in_normal_mode(&self) -> bool;
 67    fn is_refreshing(&self, cx: &AppContext) -> bool;
 68    fn refresh(
 69        &self,
 70        buffer: Model<Buffer>,
 71        cursor_position: language::Anchor,
 72        debounce: bool,
 73        cx: &mut AppContext,
 74    );
 75    fn cycle(
 76        &self,
 77        buffer: Model<Buffer>,
 78        cursor_position: language::Anchor,
 79        direction: Direction,
 80        cx: &mut AppContext,
 81    );
 82    fn accept(&self, cx: &mut AppContext);
 83    fn discard(&self, cx: &mut AppContext);
 84    fn suggest(
 85        &self,
 86        buffer: &Model<Buffer>,
 87        cursor_position: language::Anchor,
 88        cx: &mut AppContext,
 89    ) -> Option<InlineCompletion>;
 90}
 91
 92impl<T> InlineCompletionProviderHandle for Model<T>
 93where
 94    T: InlineCompletionProvider,
 95{
 96    fn name(&self) -> &'static str {
 97        T::name()
 98    }
 99
100    fn display_name(&self) -> &'static str {
101        T::display_name()
102    }
103
104    fn show_completions_in_menu(&self) -> bool {
105        T::show_completions_in_menu()
106    }
107
108    fn show_completions_in_normal_mode(&self) -> bool {
109        T::show_completions_in_normal_mode()
110    }
111
112    fn is_enabled(
113        &self,
114        buffer: &Model<Buffer>,
115        cursor_position: language::Anchor,
116        cx: &AppContext,
117    ) -> bool {
118        self.read(cx).is_enabled(buffer, cursor_position, cx)
119    }
120
121    fn is_refreshing(&self, cx: &AppContext) -> bool {
122        self.read(cx).is_refreshing()
123    }
124
125    fn refresh(
126        &self,
127        buffer: Model<Buffer>,
128        cursor_position: language::Anchor,
129        debounce: bool,
130        cx: &mut AppContext,
131    ) {
132        self.update(cx, |this, cx| {
133            this.refresh(buffer, cursor_position, debounce, cx)
134        })
135    }
136
137    fn cycle(
138        &self,
139        buffer: Model<Buffer>,
140        cursor_position: language::Anchor,
141        direction: Direction,
142        cx: &mut AppContext,
143    ) {
144        self.update(cx, |this, cx| {
145            this.cycle(buffer, cursor_position, direction, cx)
146        })
147    }
148
149    fn accept(&self, cx: &mut AppContext) {
150        self.update(cx, |this, cx| this.accept(cx))
151    }
152
153    fn discard(&self, cx: &mut AppContext) {
154        self.update(cx, |this, cx| this.discard(cx))
155    }
156
157    fn suggest(
158        &self,
159        buffer: &Model<Buffer>,
160        cursor_position: language::Anchor,
161        cx: &mut AppContext,
162    ) -> Option<InlineCompletion> {
163        self.update(cx, |this, cx| this.suggest(buffer, cursor_position, cx))
164    }
165}