inline_completion.rs

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