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