dap: Fully extract template parameter prompts

This commit is contained in:
Blaž Hrastnik 2021-11-07 18:12:30 +09:00
parent 3b8d5102ac
commit 5938ab1bf1
3 changed files with 86 additions and 92 deletions

View File

@ -3,7 +3,7 @@ use crate::{
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<DebugConfigCompletion>,
config_name: String,
mut params: Vec<String>,
) -> 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(..);

View File

@ -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 @@ use helix_core::{
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 std::{borrow::Cow, collections::HashMap, path::PathBuf};
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<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
@ -815,79 +812,6 @@ impl EditorView {
);
}
fn debug_parameter_prompt(
completions: Vec<DebugConfigCompletion>,
config_name: String,
mut params: Vec<String>,
) -> 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 @@ impl EditorView {
cxt: &mut commands::Context,
event: KeyEvent,
) -> Option<KeymapResult> {
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());

View File

@ -24,7 +24,7 @@ use anyhow::Error;
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<dap::Client>,
pub debugger_events: SelectAll<UnboundedReceiverStream<dap::Payload>>,
pub breakpoints: HashMap<PathBuf, Vec<dap::SourceBreakpoint>>,
pub debug_config_completions: Vec<DebugConfigCompletion>,
pub clipboard_provider: Box<dyn ClipboardProvider>,
@ -172,7 +171,6 @@ impl Editor {
debugger: None,
debugger_events: SelectAll::new(),
breakpoints: HashMap::new(),
debug_config_completions: Vec::new(),
syn_loader: config_loader,
theme_loader: themes,
registers: Registers::default(),