on master help sign in
prompt: If submitting empty prompt, use default (last used)
commitb14c258a2c447b892c89d3e68ef4c9a74effca85 authorBlaž Hrastnik <blaz@mxxn.io> dateTue 7 Jun 2022, 00:08 (4 years ago) parent8351a82
4 files changed+39−18
helix-core/src/register.rs+4 helix-term/src/commands.rs+4−4 helix-term/src/ui/mod.rs+7−12 helix-term/src/ui/prompt.rs+24−2
helix-core/src/register.rs+4
@@ -69,6 +69,10 @@ impl Registers {
6969 self.get(name).map(|reg| reg.read())
7070 }
7171
72+ pub fn first(&self, name: char) -> Option<&String> {
73+ self.read(name).and_then(|entries| entries.first())
74+ }
75+
7276 pub fn inner(&self) -> &HashMap<char, Register> {
7377 &self.inner
7478 }
helix-term/src/commands.rs+4−4
@@ -1488,7 +1488,7 @@ fn select_regex(cx: &mut Context) {
14881488 Some(reg),
14891489 ui::completers::none,
14901490 move |view, doc, regex, event| {
1491− if event != PromptEvent::Update {
1491+ if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
14921492 return;
14931493 }
14941494 let text = doc.text().slice(..);
@@ -1509,7 +1509,7 @@ fn split_selection(cx: &mut Context) {
15091509 Some(reg),
15101510 ui::completers::none,
15111511 move |view, doc, regex, event| {
1512− if event != PromptEvent::Update {
1512+ if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
15131513 return;
15141514 }
15151515 let text = doc.text().slice(..);
@@ -1657,7 +1657,7 @@ fn searcher(cx: &mut Context, direction: Direction) {
16571657 .collect()
16581658 },
16591659 move |view, doc, regex, event| {
1660− if event != PromptEvent::Update {
1660+ if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
16611661 return;
16621662 }
16631663 search_impl(
@@ -3563,7 +3563,7 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
35633563 Some(reg),
35643564 ui::completers::none,
35653565 move |view, doc, regex, event| {
3566− if event != PromptEvent::Update {
3566+ if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
35673567 return;
35683568 }
35693569 let text = doc.text().slice(..);
helix-term/src/ui/mod.rs+7−12
@@ -63,18 +63,8 @@ pub fn regex_prompt(
6363 doc.set_selection(view.id, snapshot.clone());
6464 view.offset = offset_snapshot;
6565 }
66− PromptEvent::Validate => match Regex::new(input) {
67− Ok(regex) => {
68− let (view, doc) = current!(cx.editor);
69− // Equivalent to push_jump to store selection just before jump
70− view.jumps.push((doc_id, snapshot.clone()));
71− fun(view, doc, regex, event);
72− }
73− Err(_err) => (), // TODO: mark command line as error
74− },
75−
76− PromptEvent::Update => {
77− // skip empty input, TODO: trigger default
66+ PromptEvent::Update | PromptEvent::Validate => {
67+ // skip empty input
7868 if input.is_empty() {
7969 return;
8070 }
@@ -96,6 +86,11 @@ pub fn regex_prompt(
9686 // revert state to what it was before the last update
9787 doc.set_selection(view.id, snapshot.clone());
9888
89+ if event == PromptEvent::Validate {
90+ // Equivalent to push_jump to store selection just before jump
91+ view.jumps.push((doc_id, snapshot.clone()));
92+ }
93+
9994 fun(view, doc, regex, event);
10095
10196 view.ensure_cursor_in_view(doc, config.scrolloff);
helix-term/src/ui/prompt.rs+24−2
@@ -442,10 +442,21 @@ impl Prompt {
442442 let line = area.height - 1;
443443 // render buffer text
444444 surface.set_string(area.x, area.y + line, &self.prompt, prompt_color);
445+
446+ let input: Cow<str> = if self.line.is_empty() {
447+ // latest value in the register list
448+ self.history_register
449+ .and_then(|reg| cx.editor.registers.first(reg).cloned()) // TODO: can we avoid cloning?
450+ .map(|entry| entry.into())
451+ .unwrap_or_else(|| Cow::from(""))
452+ } else {
453+ self.line.as_str().into()
454+ };
455+
445456 surface.set_string(
446457 area.x + self.prompt.len() as u16,
447458 area.y + line,
448− &self.line,
459+ &input,
449460 prompt_color,
450461 );
451462 }
@@ -510,7 +521,18 @@ impl Component for Prompt {
510521 self.recalculate_completion(cx.editor);
511522 self.exit_selection();
512523 } else {
513− (self.callback_fn)(cx, &self.line, PromptEvent::Validate);
524+ // handle executing with last command in history if nothing entered
525+ let input: Cow<str> = if self.line.is_empty() {
526+ // latest value in the register list
527+ self.history_register
528+ .and_then(|reg| cx.editor.registers.first(reg).cloned())
529+ .map(|entry| entry.into())
530+ .unwrap_or_else(|| Cow::from(""))
531+ } else {
532+ self.line.as_str().into()
533+ };
534+
535+ (self.callback_fn)(cx, &input, PromptEvent::Validate);
514536
515537 if let Some(register) = self.history_register {
516538 // store in history