on master help sign in
Pass through Editor instead of Context
af21e2aBlaž Hrastnik
helix-term/src/commands.rs+10−10
@@ -1435,7 +1435,7 @@ fn select_regex(cx: &mut Context) {
1435 cx,
1435 cx,
1436 "select:".into(),
1436 "select:".into(),
1437 Some(reg),
1437 Some(reg),
1438− |_ctx: &compositor::Context, _input: &str| Vec::new(),
1438+ ui::completers::none,
1439 move |view, doc, regex, event| {
1439 move |view, doc, regex, event| {
1440 if event != PromptEvent::Update {
1440 if event != PromptEvent::Update {
1441 return;
1441 return;
@@ -1458,7 +1458,7 @@ fn split_selection(cx: &mut Context) {
1458 cx,
1458 cx,
1459 "split:".into(),
1459 "split:".into(),
1460 Some(reg),
1460 Some(reg),
1461− |_ctx: &compositor::Context, _input: &str| Vec::new(),
1461+ ui::completers::none,
1462 move |view, doc, regex, event| {
1462 move |view, doc, regex, event| {
1463 if event != PromptEvent::Update {
1463 if event != PromptEvent::Update {
1464 return;
1464 return;
@@ -1600,7 +1600,7 @@ fn searcher(cx: &mut Context, direction: Direction) {
1600 cx,
1600 cx,
1601 "search:".into(),
1601 "search:".into(),
1602 Some(reg),
1602 Some(reg),
1603− move |_ctx: &compositor::Context, input: &str| {
1603+ move |_editor: &Editor, input: &str| {
1604 completions
1604 completions
1605 .iter()
1605 .iter()
1606 .filter(|comp| comp.starts_with(input))
1606 .filter(|comp| comp.starts_with(input))
@@ -1701,7 +1701,7 @@ fn global_search(cx: &mut Context) {
1701 cx,
1701 cx,
1702 "global-search:".into(),
1702 "global-search:".into(),
1703 None,
1703 None,
1704− move |_ctx: &compositor::Context, input: &str| {
1704+ move |_editor: &Editor, input: &str| {
1705 completions
1705 completions
1706 .iter()
1706 .iter()
1707 .filter(|comp| comp.starts_with(input))
1707 .filter(|comp| comp.starts_with(input))
@@ -3298,7 +3298,7 @@ fn command_mode(cx: &mut Context) {
3298 let mut prompt = Prompt::new(
3298 let mut prompt = Prompt::new(
3299 ":".into(),
3299 ":".into(),
3300 Some(':'),
3300 Some(':'),
3301− |ctx: &compositor::Context, input: &str| {
3301+ |editor: &Editor, input: &str| {
3302 static FUZZY_MATCHER: Lazy<fuzzy_matcher::skim::SkimMatcherV2> =
3302 static FUZZY_MATCHER: Lazy<fuzzy_matcher::skim::SkimMatcherV2> =
3303 Lazy::new(fuzzy_matcher::skim::SkimMatcherV2::default);
3303 Lazy::new(fuzzy_matcher::skim::SkimMatcherV2::default);
3304
3304
@@ -3330,7 +3330,7 @@ fn command_mode(cx: &mut Context) {
3330 ..
3330 ..
3331 }) = cmd::TYPABLE_COMMAND_MAP.get(parts[0])
3331 }) = cmd::TYPABLE_COMMAND_MAP.get(parts[0])
3332 {
3332 {
3333− completer(ctx, part)
3333+ completer(editor, part)
3334 .into_iter()
3334 .into_iter()
3335 .map(|(range, file)| {
3335 .map(|(range, file)| {
3336 // offset ranges to input
3336 // offset ranges to input
@@ -5394,7 +5394,7 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
5394 cx,
5394 cx,
5395 if !remove { "keep:" } else { "remove:" }.into(),
5395 if !remove { "keep:" } else { "remove:" }.into(),
5396 Some(reg),
5396 Some(reg),
5397− |_ctx: &compositor::Context, _input: &str| Vec::new(),
5397+ ui::completers::none,
5398 move |view, doc, regex, event| {
5398 move |view, doc, regex, event| {
5399 if event != PromptEvent::Update {
5399 if event != PromptEvent::Update {
5400 return;
5400 return;
@@ -6158,7 +6158,7 @@ fn shell_keep_pipe(cx: &mut Context) {
6158 let prompt = Prompt::new(
6158 let prompt = Prompt::new(
6159 "keep-pipe:".into(),
6159 "keep-pipe:".into(),
6160 Some('|'),
6160 Some('|'),
6161− |_ctx: &compositor::Context, _input: &str| Vec::new(),
6161+ ui::completers::none,
6162 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6162 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6163 let shell = &cx.editor.config.shell;
6163 let shell = &cx.editor.config.shell;
6164 if event != PromptEvent::Validate {
6164 if event != PromptEvent::Validate {
@@ -6254,7 +6254,7 @@ fn shell(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBehavior) {
6254 let prompt = Prompt::new(
6254 let prompt = Prompt::new(
6255 prompt,
6255 prompt,
6256 Some('|'),
6256 Some('|'),
6257− |_ctx: &compositor::Context, _input: &str| Vec::new(),
6257+ ui::completers::none,
6258 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6258 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6259 let shell = &cx.editor.config.shell;
6259 let shell = &cx.editor.config.shell;
6260 if event != PromptEvent::Validate {
6260 if event != PromptEvent::Validate {
@@ -6350,7 +6350,7 @@ fn rename_symbol(cx: &mut Context) {
6350 let prompt = Prompt::new(
6350 let prompt = Prompt::new(
6351 "rename-to:".into(),
6351 "rename-to:".into(),
6352 None,
6352 None,
6353− |_ctx: &compositor::Context, _input: &str| Vec::new(),
6353+ ui::completers::none,
6354 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6354 move |cx: &mut compositor::Context, input: &str, event: PromptEvent| {
6355 if event != PromptEvent::Validate {
6355 if event != PromptEvent::Validate {
6356 return;
6356 return;
helix-term/src/ui/mod.rs+11−13
@@ -22,7 +22,7 @@ pub use text::Text;
22
22
23use helix_core::regex::Regex;
23use helix_core::regex::Regex;
24use helix_core::regex::RegexBuilder;
24use helix_core::regex::RegexBuilder;
25−use helix_view::{Document, View};
25+use helix_view::{Document, Editor, View};
26
26
27use std::path::PathBuf;
27use std::path::PathBuf;
28
28
@@ -30,7 +30,7 @@ pub fn regex_prompt(
30 cx: &mut crate::commands::Context,
30 cx: &mut crate::commands::Context,
31 prompt: std::borrow::Cow<'static, str>,
31 prompt: std::borrow::Cow<'static, str>,
32 history_register: Option<char>,
32 history_register: Option<char>,
33− completion_fn: impl FnMut(&crate::compositor::Context, &str) -> Vec<prompt::Completion> + 'static,
33+ completion_fn: impl FnMut(&Editor, &str) -> Vec<prompt::Completion> + 'static,
34 fun: impl Fn(&mut View, &mut Document, Regex, PromptEvent) + 'static,
34 fun: impl Fn(&mut View, &mut Document, Regex, PromptEvent) + 'static,
35) -> Prompt {
35) -> Prompt {
36 let (view, doc) = current!(cx.editor);
36 let (view, doc) = current!(cx.editor);
@@ -168,26 +168,24 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi
168}
168}
169
169
170pub mod completers {
170pub mod completers {
171− use crate::compositor::Context;
172 use crate::ui::prompt::Completion;
171 use crate::ui::prompt::Completion;
173 use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
172 use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
174 use fuzzy_matcher::FuzzyMatcher;
173 use fuzzy_matcher::FuzzyMatcher;
175 use helix_view::document::SCRATCH_BUFFER_NAME;
174 use helix_view::document::SCRATCH_BUFFER_NAME;
176− use helix_view::editor::Config;
177 use helix_view::theme;
175 use helix_view::theme;
176+ use helix_view::{editor::Config, Editor};
178 use once_cell::sync::Lazy;
177 use once_cell::sync::Lazy;
179 use std::borrow::Cow;
178 use std::borrow::Cow;
180 use std::cmp::Reverse;
179 use std::cmp::Reverse;
181
180
182− pub type Completer = fn(&Context, &str) -> Vec<Completion>;
181+ pub type Completer = fn(&Editor, &str) -> Vec<Completion>;
183
182
184− pub fn none(_cx: &Context, _input: &str) -> Vec<Completion> {
183+ pub fn none(_editor: &Editor, _input: &str) -> Vec<Completion> {
185 Vec::new()
184 Vec::new()
186 }
185 }
187
186
188− pub fn buffer(cx: &Context, input: &str) -> Vec<Completion> {
187+ pub fn buffer(editor: &Editor, input: &str) -> Vec<Completion> {
189− let mut names: Vec<_> = cx
188+ let mut names: Vec<_> = editor
190− .editor
191 .documents
189 .documents
192 .iter()
190 .iter()
193 .map(|(_id, doc)| {
191 .map(|(_id, doc)| {
@@ -214,7 +212,7 @@ pub mod completers {
214 names
212 names
215 }
213 }
216
214
217− pub fn theme(_cx: &Context, input: &str) -> Vec<Completion> {
215+ pub fn theme(_editor: &Editor, input: &str) -> Vec<Completion> {
218 let mut names = theme::Loader::read_names(&helix_core::runtime_dir().join("themes"));
216 let mut names = theme::Loader::read_names(&helix_core::runtime_dir().join("themes"));
219 names.extend(theme::Loader::read_names(
217 names.extend(theme::Loader::read_names(
220 &helix_core::config_dir().join("themes"),
218 &helix_core::config_dir().join("themes"),
@@ -242,7 +240,7 @@ pub mod completers {
242 names
240 names
243 }
241 }
244
242
245− pub fn setting(_cx: &Context, input: &str) -> Vec<Completion> {
243+ pub fn setting(_editor: &Editor, input: &str) -> Vec<Completion> {
246 static KEYS: Lazy<Vec<String>> = Lazy::new(|| {
244 static KEYS: Lazy<Vec<String>> = Lazy::new(|| {
247 serde_json::to_value(Config::default())
245 serde_json::to_value(Config::default())
248 .unwrap()
246 .unwrap()
@@ -267,7 +265,7 @@ pub mod completers {
267 .collect()
265 .collect()
268 }
266 }
269
267
270− pub fn filename(_cx: &Context, input: &str) -> Vec<Completion> {
268+ pub fn filename(_editor: &Editor, input: &str) -> Vec<Completion> {
271 filename_impl(input, |entry| {
269 filename_impl(input, |entry| {
272 let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
270 let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
273
271
@@ -279,7 +277,7 @@ pub mod completers {
279 })
277 })
280 }
278 }
281
279
282− pub fn directory(_cx: &Context, input: &str) -> Vec<Completion> {
280+ pub fn directory(_editor: &Editor, input: &str) -> Vec<Completion> {
283 filename_impl(input, |entry| {
281 filename_impl(input, |entry| {
284 let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
282 let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir());
285
283
helix-term/src/ui/picker.rs+2−2
@@ -1,7 +1,7 @@
1use crate::{
1use crate::{
2 compositor::{Component, Compositor, Context, EventResult},
2 compositor::{Component, Compositor, Context, EventResult},
3 ctrl, key, shift,
3 ctrl, key, shift,
4− ui::EditorView,
4+ ui::{self, EditorView},
5};
5};
6use crossterm::event::Event;
6use crossterm::event::Event;
7use tui::{
7use tui::{
@@ -302,7 +302,7 @@ impl<T> Picker<T> {
302 let prompt = Prompt::new(
302 let prompt = Prompt::new(
303 "".into(),
303 "".into(),
304 None,
304 None,
305− |_ctx: &Context, _pattern: &str| Vec::new(),
305+ ui::completers::none,
306 |_editor: &mut Context, _pattern: &str, _event: PromptEvent| {
306 |_editor: &mut Context, _pattern: &str, _event: PromptEvent| {
307 //
307 //
308 },
308 },
helix-term/src/ui/prompt.rs+15−12
@@ -24,7 +24,7 @@ pub struct Prompt {
24 selection: Option<usize>,
24 selection: Option<usize>,
25 history_register: Option<char>,
25 history_register: Option<char>,
26 history_pos: Option<usize>,
26 history_pos: Option<usize>,
27− completion_fn: Box<dyn FnMut(&Context, &str) -> Vec<Completion>>,
27+ completion_fn: Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>,
28 callback_fn: Box<dyn FnMut(&mut Context, &str, PromptEvent)>,
28 callback_fn: Box<dyn FnMut(&mut Context, &str, PromptEvent)>,
29 pub doc_fn: Box<dyn Fn(&str) -> Option<&'static str>>,
29 pub doc_fn: Box<dyn Fn(&str) -> Option<&'static str>>,
30}
30}
@@ -59,7 +59,7 @@ impl Prompt {
59 pub fn new(
59 pub fn new(
60 prompt: Cow<'static, str>,
60 prompt: Cow<'static, str>,
61 history_register: Option<char>,
61 history_register: Option<char>,
62− completion_fn: impl FnMut(&Context, &str) -> Vec<Completion> + 'static,
62+ completion_fn: impl FnMut(&Editor, &str) -> Vec<Completion> + 'static,
63 callback_fn: impl FnMut(&mut Context, &str, PromptEvent) + 'static,
63 callback_fn: impl FnMut(&mut Context, &str, PromptEvent) + 'static,
64 ) -> Self {
64 ) -> Self {
65 Self {
65 Self {
@@ -76,6 +76,10 @@ impl Prompt {
76 }
76 }
77 }
77 }
78
78
79+ pub fn recalculate_completion(&mut self, editor: &Editor) {
80+ self.completion = (self.completion_fn)(editor, &self.line);
81+ }
82+
79 /// Compute the cursor position after applying movement
83 /// Compute the cursor position after applying movement
80 /// Taken from: https://github.com/wez/wezterm/blob/e0b62d07ca9bf8ce69a61e30a3c20e7abc48ce7e/termwiz/src/lineedit/mod.rs#L516-L611
84 /// Taken from: https://github.com/wez/wezterm/blob/e0b62d07ca9bf8ce69a61e30a3c20e7abc48ce7e/termwiz/src/lineedit/mod.rs#L516-L611
81 fn eval_movement(&self, movement: Movement) -> usize {
85 fn eval_movement(&self, movement: Movement) -> usize {
@@ -183,7 +187,7 @@ impl Prompt {
183 if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {
187 if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {
184 self.cursor = pos;
188 self.cursor = pos;
185 }
189 }
186− self.completion = (self.completion_fn)(cx, &self.line);
190+ self.recalculate_completion(cx.editor);
187 self.exit_selection();
191 self.exit_selection();
188 }
192 }
189
193
@@ -211,7 +215,7 @@ impl Prompt {
211 self.cursor = pos;
215 self.cursor = pos;
212
216
213 self.exit_selection();
217 self.exit_selection();
214− self.completion = (self.completion_fn)(cx, &self.line);
218+ self.recalculate_completion(cx.editor);
215 }
219 }
216
220
217 pub fn delete_char_forwards(&mut self, cx: &Context) {
221 pub fn delete_char_forwards(&mut self, cx: &Context) {
@@ -219,7 +223,7 @@ impl Prompt {
219 self.line.replace_range(self.cursor..pos, "");
223 self.line.replace_range(self.cursor..pos, "");
220
224
221 self.exit_selection();
225 self.exit_selection();
222− self.completion = (self.completion_fn)(cx, &self.line);
226+ self.recalculate_completion(cx.editor);
223 }
227 }
224
228
225 pub fn delete_word_backwards(&mut self, cx: &Context) {
229 pub fn delete_word_backwards(&mut self, cx: &Context) {
@@ -228,7 +232,7 @@ impl Prompt {
228 self.cursor = pos;
232 self.cursor = pos;
229
233
230 self.exit_selection();
234 self.exit_selection();
231− self.completion = (self.completion_fn)(cx, &self.line);
235+ self.recalculate_completion(cx.editor);
232 }
236 }
233
237
234 pub fn delete_word_forwards(&mut self, cx: &Context) {
238 pub fn delete_word_forwards(&mut self, cx: &Context) {
@@ -236,7 +240,7 @@ impl Prompt {
236 self.line.replace_range(self.cursor..pos, "");
240 self.line.replace_range(self.cursor..pos, "");
237
241
238 self.exit_selection();
242 self.exit_selection();
239− self.completion = (self.completion_fn)(cx, &self.line);
243+ self.recalculate_completion(cx.editor);
240 }
244 }
241
245
242 pub fn kill_to_start_of_line(&mut self, cx: &Context) {
246 pub fn kill_to_start_of_line(&mut self, cx: &Context) {
@@ -245,7 +249,7 @@ impl Prompt {
245 self.cursor = pos;
249 self.cursor = pos;
246
250
247 self.exit_selection();
251 self.exit_selection();
248− self.completion = (self.completion_fn)(cx, &self.line);
252+ self.recalculate_completion(cx.editor);
249 }
253 }
250
254
251 pub fn kill_to_end_of_line(&mut self, cx: &Context) {
255 pub fn kill_to_end_of_line(&mut self, cx: &Context) {
@@ -253,13 +257,13 @@ impl Prompt {
253 self.line.replace_range(self.cursor..pos, "");
257 self.line.replace_range(self.cursor..pos, "");
254
258
255 self.exit_selection();
259 self.exit_selection();
256− self.completion = (self.completion_fn)(cx, &self.line);
260+ self.recalculate_completion(cx.editor);
257 }
261 }
258
262
259 pub fn clear(&mut self, cx: &Context) {
263 pub fn clear(&mut self, cx: &Context) {
260 self.line.clear();
264 self.line.clear();
261 self.cursor = 0;
265 self.cursor = 0;
262− self.completion = (self.completion_fn)(cx, &self.line);
266+ self.recalculate_completion(cx.editor);
263 self.exit_selection();
267 self.exit_selection();
264 }
268 }
265
269
@@ -474,7 +478,7 @@ impl Component for Prompt {
474 }
478 }
475 key!(Enter) => {
479 key!(Enter) => {
476 if self.selection.is_some() && self.line.ends_with(std::path::MAIN_SEPARATOR) {
480 if self.selection.is_some() && self.line.ends_with(std::path::MAIN_SEPARATOR) {
477− self.completion = (self.completion_fn)(cx, &self.line);
481+ self.recalculate_completion(cx.editor);
478 self.exit_selection();
482 self.exit_selection();
479 } else {
483 } else {
480 (self.callback_fn)(cx, &self.line, PromptEvent::Validate);
484 (self.callback_fn)(cx, &self.line, PromptEvent::Validate);
@@ -525,7 +529,6 @@ impl Component for Prompt {
525 }
529 }
526
530
527 fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
531 fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
528− self.completion = (self.completion_fn)(cx, &self.line);
529 self.render_prompt(area, surface, cx)
532 self.render_prompt(area, surface, cx)
530 }
533 }
531
534