From 5938ab1bf1220913f487155ba7e1d9057d03f73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 7 Nov 2021 18:12:30 +0900 Subject: [PATCH] dap: Fully extract template parameter prompts --- helix-term/src/commands/dap.rs | 86 +++++++++++++++++++++++++++++++-- helix-term/src/ui/editor.rs | 88 +--------------------------------- helix-view/src/editor.rs | 4 +- 3 files changed, 86 insertions(+), 92 deletions(-) diff --git a/helix-term/src/commands/dap.rs b/helix-term/src/commands/dap.rs index 43931f73d..de1b2078c 100644 --- a/helix-term/src/commands/dap.rs +++ b/helix-term/src/commands/dap.rs @@ -3,7 +3,7 @@ commands, compositor::Compositor, job::Callback, - ui::{FilePicker, Picker, Popup, Prompt, PromptEvent, Text}, + ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text}, }; use helix_core::{ syntax::{DebugArgumentValue, DebugConfigCompletion}, @@ -325,12 +325,92 @@ pub fn dap_launch(cx: &mut Context) { |template| template.name.as_str().into(), |cx, template, _action| { let completions = template.completion.clone(); - cx.editor.debug_config_completions = completions; - // TODO: need some way to manipulate the compositor to push a new prompt here + let name = template.name.clone(); + let callback = Box::pin(async move { + let call: Callback = + Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { + let prompt = debug_parameter_prompt(completions, name, Vec::new()); + compositor.push(Box::new(prompt)); + }); + Ok(call) + }); + cx.jobs.callback(callback); }, ))); // TODO: wrap in popup with fixed size } +fn debug_parameter_prompt( + completions: Vec, + config_name: String, + mut params: Vec, +) -> Prompt { + let i = params.len(); + let completion = completions.get(i).unwrap(); + let field_type = if let DebugConfigCompletion::Advanced(cfg) = completion { + cfg.completion.clone().unwrap_or_else(|| "".to_owned()) + } else { + "".to_owned() + }; + let name = match completion { + DebugConfigCompletion::Advanced(cfg) => { + cfg.name.clone().unwrap_or_else(|| field_type.to_owned()) + } + DebugConfigCompletion::Named(name) => name.clone(), + }; + let default_val = match completion { + DebugConfigCompletion::Advanced(cfg) => { + cfg.default.clone().unwrap_or_else(|| "".to_owned()) + } + _ => "".to_owned(), + }; + + let noop = |_input: &str| Vec::new(); + let completer = match &field_type[..] { + "filename" => ui::completers::filename, + "directory" => ui::completers::directory, + _ => noop, + }; + Prompt::new( + format!("{}: ", name).into(), + None, + completer, + move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| { + if event != PromptEvent::Validate { + return; + } + + let mut value = input.to_owned(); + if value.is_empty() { + value = default_val.clone(); + } + params.push(value); + + if params.len() < completions.len() { + let completions = completions.clone(); + let config_name = config_name.clone(); + let params = params.clone(); + let callback = Box::pin(async move { + let call: Callback = + Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { + let prompt = debug_parameter_prompt(completions, config_name, params); + compositor.push(Box::new(prompt)); + }); + Ok(call) + }); + cx.jobs.callback(callback); + } else { + commands::dap_start_impl( + cx.editor, + Some(&config_name), + None, + Some(params.iter().map(|x| x.as_str()).collect()), + ); + } + }, + None, + ) +} + pub fn dap_toggle_breakpoint(cx: &mut Context) { let (view, doc) = current!(cx.editor); let text = doc.text().slice(..); diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 4d1430848..3cc4cc4a8 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1,7 +1,6 @@ use crate::{ commands, - compositor::{Component, Compositor, Context, EventResult}, - job::Callback, + compositor::{Component, Context, EventResult}, key, keymap::{KeymapResult, KeymapResultKind, Keymaps}, ui::{Completion, ProgressSpinners}, @@ -11,7 +10,7 @@ coords_at_pos, graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary}, movement::Direction, - syntax::{self, DebugConfigCompletion, HighlightEvent}, + syntax::{self, HighlightEvent}, unicode::segmentation::UnicodeSegmentation, unicode::width::UnicodeWidthStr, LineEnding, Position, Range, Selection, @@ -31,8 +30,6 @@ use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind}; use tui::buffer::Buffer as Surface; -use super::{Prompt, PromptEvent}; - pub struct EditorView { keymaps: Keymaps, on_next_key: Option>, @@ -815,79 +812,6 @@ pub fn render_statusline( ); } - fn debug_parameter_prompt( - completions: Vec, - config_name: String, - mut params: Vec, - ) -> Prompt { - let i = params.len(); - let completion = completions.get(i).unwrap(); - let field_type = if let DebugConfigCompletion::Advanced(cfg) = completion { - cfg.completion.clone().unwrap_or_else(|| "".to_owned()) - } else { - "".to_owned() - }; - let name = match completion { - DebugConfigCompletion::Advanced(cfg) => { - cfg.name.clone().unwrap_or_else(|| field_type.to_owned()) - } - DebugConfigCompletion::Named(name) => name.clone(), - }; - let default_val = match completion { - DebugConfigCompletion::Advanced(cfg) => { - cfg.default.clone().unwrap_or_else(|| "".to_owned()) - } - _ => "".to_owned(), - }; - - let noop = |_input: &str| Vec::new(); - let completer = match &field_type[..] { - "filename" => super::completers::filename, - "directory" => super::completers::directory, - _ => noop, - }; - Prompt::new( - format!("{}: ", name).into(), - None, - completer, - move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| { - if event != PromptEvent::Validate { - return; - } - - let mut value = input.to_owned(); - if value.is_empty() { - value = default_val.clone(); - } - params.push(value); - - if params.len() < completions.len() { - let completions = completions.clone(); - let config_name = config_name.clone(); - let params = params.clone(); - let callback = Box::pin(async move { - let call: Callback = - Box::new(move |_editor: &mut Editor, compositor: &mut Compositor| { - let prompt = - Self::debug_parameter_prompt(completions, config_name, params); - compositor.push(Box::new(prompt)); - }); - Ok(call) - }); - cx.jobs.callback(callback); - } else { - commands::dap_start_impl( - cx.editor, - Some(&config_name), - None, - Some(params.iter().map(|x| x.as_str()).collect()), - ); - } - }, - None, - ) - } - /// Handle events by looking them up in `self.keymaps`. Returns None /// if event was handled (a command was executed or a subkeymap was /// activated). Only KeymapResultKind::{NotFound, Cancelled} is returned @@ -898,14 +822,6 @@ fn handle_keymap_event( cxt: &mut commands::Context, event: KeyEvent, ) -> Option { - if !cxt.editor.debug_config_completions.is_empty() { - let completions = std::mem::take(&mut cxt.editor.debug_config_completions); - // TODO name - let prompt = Self::debug_parameter_prompt(completions, "test".to_string(), Vec::new()); - cxt.push_layer(Box::new(prompt)); - return None; - } - let key_result = self.keymaps.get_mut(&mode).unwrap().get(event); self.autoinfo = key_result.sticky.map(|node| node.infobox()); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index ac2345245..40c65c4c2 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -24,7 +24,7 @@ pub use helix_core::diagnostic::Severity; pub use helix_core::register::Registers; -use helix_core::syntax::{self, DebugConfigCompletion}; +use helix_core::syntax; use helix_core::Position; use helix_dap as dap; @@ -126,7 +126,6 @@ pub struct Editor { pub debugger: Option, pub debugger_events: SelectAll>, pub breakpoints: HashMap>, - pub debug_config_completions: Vec, pub clipboard_provider: Box, @@ -172,7 +171,6 @@ pub fn new( debugger: None, debugger_events: SelectAll::new(), breakpoints: HashMap::new(), - debug_config_completions: Vec::new(), syn_loader: config_loader, theme_loader: themes, registers: Registers::default(),