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