From d58850f19418bec6ab162269b985aaa7b2547181 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Wed, 11 May 2022 15:21:22 +0800 Subject: [PATCH 1/8] support insert register in prompt --- book/src/keymap.md | 1 + helix-term/src/ui/prompt.rs | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 9d5d08417789..e56eeefc41ec 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -367,6 +367,7 @@ Keys to use within prompt, Remapping currently not supported. | `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later | | `Ctrl-p`, `Up` | Select previous history | | `Ctrl-n`, `Down` | Select next history | +| `Ctrl-r` | Insert the content of the register selected by following input char | | `Tab` | Select next completion item | | `BackTab` | Select previous completion item | | `Enter` | Open selected | diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index ef08edf2d836..b971885a9f79 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -28,6 +28,7 @@ pub struct Prompt { completion_fn: Box Vec>, callback_fn: Box, pub doc_fn: Box Option>>, + selecting_register: bool, } #[derive(Clone, Copy, PartialEq)] @@ -78,6 +79,7 @@ impl Prompt { completion_fn: Box::new(completion_fn), callback_fn: Box::new(callback_fn), doc_fn: Box::new(|_| None), + selecting_register: false, } } @@ -538,17 +540,33 @@ impl Component for Prompt { (self.callback_fn)(cx, &self.line, PromptEvent::Update) } ctrl!('q') => self.exit_selection(), + ctrl!('r') => { + self.selecting_register = true; + (self.callback_fn)(cx, &self.line, PromptEvent::Update); + return EventResult::Consumed(None); + } // any char event that's not mapped to any other combo KeyEvent { code: KeyCode::Char(c), modifiers: _, } => { - self.insert_char(c, cx); + if self.selecting_register { + self.insert_str( + cx.editor + .registers + .read(c) + .and_then(|r| r.first()) + .map_or("", |r| r.as_str()), + ); + } else { + self.insert_char(c, cx); + } (self.callback_fn)(cx, &self.line, PromptEvent::Update); } _ => (), }; + self.selecting_register = false; EventResult::Consumed(None) } From 97c341c618a34569d7db652a9ae3e5aba9ba57c8 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Wed, 11 May 2022 15:53:02 +0800 Subject: [PATCH 2/8] use next_char_handler instead of a flag --- helix-term/src/ui/prompt.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index b971885a9f79..71abff13dbb4 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -28,7 +28,7 @@ pub struct Prompt { completion_fn: Box Vec>, callback_fn: Box, pub doc_fn: Box Option>>, - selecting_register: bool, + next_char_handler: Option>, } #[derive(Clone, Copy, PartialEq)] @@ -79,7 +79,7 @@ impl Prompt { completion_fn: Box::new(completion_fn), callback_fn: Box::new(callback_fn), doc_fn: Box::new(|_| None), - selecting_register: false, + next_char_handler: None, } } @@ -193,6 +193,13 @@ impl Prompt { } pub fn insert_char(&mut self, c: char, cx: &Context) { + if let Some(handler) = &self.next_char_handler.take() { + handler(self, c, cx); + + self.next_char_handler = None; + return; + } + self.line.insert(self.cursor, c); let mut cursor = GraphemeCursor::new(self.cursor, self.line.len(), false); if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) { @@ -541,7 +548,16 @@ impl Component for Prompt { } ctrl!('q') => self.exit_selection(), ctrl!('r') => { - self.selecting_register = true; + self.next_char_handler = Some(Box::new(|prompt, c, context| { + prompt.insert_str( + context + .editor + .registers + .read(c) + .and_then(|r| r.first()) + .map_or("", |r| r.as_str()), + ); + })); (self.callback_fn)(cx, &self.line, PromptEvent::Update); return EventResult::Consumed(None); } @@ -550,23 +566,12 @@ impl Component for Prompt { code: KeyCode::Char(c), modifiers: _, } => { - if self.selecting_register { - self.insert_str( - cx.editor - .registers - .read(c) - .and_then(|r| r.first()) - .map_or("", |r| r.as_str()), - ); - } else { - self.insert_char(c, cx); - } + self.insert_char(c, cx); (self.callback_fn)(cx, &self.line, PromptEvent::Update); } _ => (), }; - self.selecting_register = false; EventResult::Consumed(None) } From 88e05778e337904987caaa514bc66619426b23c1 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Wed, 11 May 2022 16:03:19 +0800 Subject: [PATCH 3/8] Fix clippy issue --- helix-term/src/ui/prompt.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 71abff13dbb4..d1f423d1b6da 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -16,6 +16,7 @@ use helix_view::{ }; pub type Completion = (RangeFrom, Cow<'static, str>); +type PromptCharHandler = Box; pub struct Prompt { prompt: Cow<'static, str>, @@ -28,7 +29,7 @@ pub struct Prompt { completion_fn: Box Vec>, callback_fn: Box, pub doc_fn: Box Option>>, - next_char_handler: Option>, + next_char_handler: Option, } #[derive(Clone, Copy, PartialEq)] From 5488344de1c607d44bdf8693287a85b92cb32518 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Fri, 13 May 2022 15:18:54 +0800 Subject: [PATCH 4/8] show autoinfo when inserting register --- helix-term/src/ui/prompt.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index d1f423d1b6da..b745e548b692 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -16,7 +16,7 @@ use helix_view::{ }; pub type Completion = (RangeFrom, Cow<'static, str>); -type PromptCharHandler = Box; +type PromptCharHandler = Box; pub struct Prompt { prompt: Cow<'static, str>, @@ -193,7 +193,7 @@ impl Prompt { } } - pub fn insert_char(&mut self, c: char, cx: &Context) { + pub fn insert_char(&mut self, c: char, cx: &mut Context) { if let Some(handler) = &self.next_char_handler.take() { handler(self, c, cx); @@ -549,7 +549,11 @@ impl Component for Prompt { } ctrl!('q') => self.exit_selection(), ctrl!('r') => { + self.completion = Vec::new(); //clear completions + cx.editor.autoinfo = + Some(helix_view::info::Info::from_registers(&cx.editor.registers)); // show registers info self.next_char_handler = Some(Box::new(|prompt, c, context| { + context.editor.autoinfo = None; prompt.insert_str( context .editor From 1ea83652704da99de8030e24ca877b9697eb56e6 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Fri, 13 May 2022 15:44:01 +0800 Subject: [PATCH 5/8] Revert "show autoinfo when inserting register" This reverts commit 5488344de1c607d44bdf8693287a85b92cb32518. --- helix-term/src/ui/prompt.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index b745e548b692..d1f423d1b6da 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -16,7 +16,7 @@ use helix_view::{ }; pub type Completion = (RangeFrom, Cow<'static, str>); -type PromptCharHandler = Box; +type PromptCharHandler = Box; pub struct Prompt { prompt: Cow<'static, str>, @@ -193,7 +193,7 @@ impl Prompt { } } - pub fn insert_char(&mut self, c: char, cx: &mut Context) { + pub fn insert_char(&mut self, c: char, cx: &Context) { if let Some(handler) = &self.next_char_handler.take() { handler(self, c, cx); @@ -549,11 +549,7 @@ impl Component for Prompt { } ctrl!('q') => self.exit_selection(), ctrl!('r') => { - self.completion = Vec::new(); //clear completions - cx.editor.autoinfo = - Some(helix_view::info::Info::from_registers(&cx.editor.registers)); // show registers info self.next_char_handler = Some(Box::new(|prompt, c, context| { - context.editor.autoinfo = None; prompt.insert_str( context .editor From 209907f35e76e8a31030d1e34141e6e121acdd31 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Fri, 13 May 2022 15:45:25 +0800 Subject: [PATCH 6/8] use completion instead of autoinfo autoinfo is overlapped when using prompt --- helix-term/src/ui/prompt.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index d1f423d1b6da..3216c87957e2 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -549,6 +549,21 @@ impl Component for Prompt { } ctrl!('q') => self.exit_selection(), ctrl!('r') => { + self.completion = cx + .editor + .registers + .inner() + .iter() + .map(|(ch, reg)| { + let content = reg + .read() + .get(0) + .and_then(|s| s.lines().next()) + .map(String::from) + .unwrap_or_default(); + (0.., format!("{} {}", ch, &content).into()) + }) + .collect(); self.next_char_handler = Some(Box::new(|prompt, c, context| { prompt.insert_str( context From 939754921145ba8d64a35e67512efd4f1b23eb66 Mon Sep 17 00:00:00 2001 From: Bob Qi Date: Fri, 13 May 2022 16:11:38 +0800 Subject: [PATCH 7/8] recalculate_completion after inserting register --- helix-term/src/ui/prompt.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 3216c87957e2..d18624f39c22 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -573,6 +573,7 @@ impl Component for Prompt { .and_then(|r| r.first()) .map_or("", |r| r.as_str()), ); + prompt.recalculate_completion(context.editor); })); (self.callback_fn)(cx, &self.line, PromptEvent::Update); return EventResult::Consumed(None); From f6adadee3c6232d24c578a5a866338d01ef8e02c Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 16 May 2022 09:09:04 +0800 Subject: [PATCH 8/8] Update helix-term/src/ui/prompt.rs Co-authored-by: Ivan Tham --- helix-term/src/ui/prompt.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index d18624f39c22..c3c502e0d80d 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -558,8 +558,7 @@ impl Component for Prompt { let content = reg .read() .get(0) - .and_then(|s| s.lines().next()) - .map(String::from) + .and_then(|s| s.lines().next().to_owned()) .unwrap_or_default(); (0.., format!("{} {}", ch, &content).into()) })