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