mirror of https://github.com/helix-editor/helix
support insert register in prompt (#2458)
* support insert register in prompt
* use next_char_handler instead of a flag
* Fix clippy issue
* show autoinfo when inserting register
* Revert "show autoinfo when inserting register"
This reverts commit 5488344de1
.
* use completion instead of autoinfo
autoinfo is overlapped when using prompt
* recalculate_completion after inserting register
* Update helix-term/src/ui/prompt.rs
Co-authored-by: Ivan Tham <pickfire@riseup.net>
Co-authored-by: Ivan Tham <pickfire@riseup.net>
pull/2445/head
parent
8958bf0a92
commit
6462542fc5
|
@ -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-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
|
||||||
| `Ctrl-p`, `Up` | Select previous history |
|
| `Ctrl-p`, `Up` | Select previous history |
|
||||||
| `Ctrl-n`, `Down` | Select next 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 |
|
| `Tab` | Select next completion item |
|
||||||
| `BackTab` | Select previous completion item |
|
| `BackTab` | Select previous completion item |
|
||||||
| `Enter` | Open selected |
|
| `Enter` | Open selected |
|
||||||
|
|
|
@ -16,6 +16,7 @@ use helix_view::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Completion = (RangeFrom<usize>, Cow<'static, str>);
|
pub type Completion = (RangeFrom<usize>, Cow<'static, str>);
|
||||||
|
type PromptCharHandler = Box<dyn Fn(&mut Prompt, char, &Context)>;
|
||||||
|
|
||||||
pub struct Prompt {
|
pub struct Prompt {
|
||||||
prompt: Cow<'static, str>,
|
prompt: Cow<'static, str>,
|
||||||
|
@ -28,6 +29,7 @@ pub struct Prompt {
|
||||||
completion_fn: Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>,
|
completion_fn: Box<dyn FnMut(&Editor, &str) -> Vec<Completion>>,
|
||||||
callback_fn: Box<dyn FnMut(&mut Context, &str, PromptEvent)>,
|
callback_fn: Box<dyn FnMut(&mut Context, &str, PromptEvent)>,
|
||||||
pub doc_fn: Box<dyn Fn(&str) -> Option<Cow<str>>>,
|
pub doc_fn: Box<dyn Fn(&str) -> Option<Cow<str>>>,
|
||||||
|
next_char_handler: Option<PromptCharHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
@ -78,6 +80,7 @@ impl Prompt {
|
||||||
completion_fn: Box::new(completion_fn),
|
completion_fn: Box::new(completion_fn),
|
||||||
callback_fn: Box::new(callback_fn),
|
callback_fn: Box::new(callback_fn),
|
||||||
doc_fn: Box::new(|_| None),
|
doc_fn: Box::new(|_| None),
|
||||||
|
next_char_handler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +194,13 @@ impl Prompt {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_char(&mut self, c: char, cx: &Context) {
|
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);
|
self.line.insert(self.cursor, c);
|
||||||
let mut cursor = GraphemeCursor::new(self.cursor, self.line.len(), false);
|
let mut cursor = GraphemeCursor::new(self.cursor, self.line.len(), false);
|
||||||
if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {
|
if let Ok(Some(pos)) = cursor.next_boundary(&self.line, 0) {
|
||||||
|
@ -538,6 +548,35 @@ impl Component for Prompt {
|
||||||
(self.callback_fn)(cx, &self.line, PromptEvent::Update)
|
(self.callback_fn)(cx, &self.line, PromptEvent::Update)
|
||||||
}
|
}
|
||||||
ctrl!('q') => self.exit_selection(),
|
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().to_owned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
(0.., format!("{} {}", ch, &content).into())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
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()),
|
||||||
|
);
|
||||||
|
prompt.recalculate_completion(context.editor);
|
||||||
|
}));
|
||||||
|
(self.callback_fn)(cx, &self.line, PromptEvent::Update);
|
||||||
|
return EventResult::Consumed(None);
|
||||||
|
}
|
||||||
// any char event that's not mapped to any other combo
|
// any char event that's not mapped to any other combo
|
||||||
KeyEvent {
|
KeyEvent {
|
||||||
code: KeyCode::Char(c),
|
code: KeyCode::Char(c),
|
||||||
|
|
Loading…
Reference in New Issue