mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-23 01:46:18 +04:00
dap: Fully extract template parameter prompts
This commit is contained in:
parent
3b8d5102ac
commit
5938ab1bf1
@ -3,7 +3,7 @@
|
|||||||
commands,
|
commands,
|
||||||
compositor::Compositor,
|
compositor::Compositor,
|
||||||
job::Callback,
|
job::Callback,
|
||||||
ui::{FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
|
ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent, Text},
|
||||||
};
|
};
|
||||||
use helix_core::{
|
use helix_core::{
|
||||||
syntax::{DebugArgumentValue, DebugConfigCompletion},
|
syntax::{DebugArgumentValue, DebugConfigCompletion},
|
||||||
@ -325,12 +325,92 @@ pub fn dap_launch(cx: &mut Context) {
|
|||||||
|template| template.name.as_str().into(),
|
|template| template.name.as_str().into(),
|
||||||
|cx, template, _action| {
|
|cx, template, _action| {
|
||||||
let completions = template.completion.clone();
|
let completions = template.completion.clone();
|
||||||
cx.editor.debug_config_completions = completions;
|
let name = template.name.clone();
|
||||||
// TODO: need some way to manipulate the compositor to push a new prompt here
|
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
|
))); // 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) {
|
pub fn dap_toggle_breakpoint(cx: &mut Context) {
|
||||||
let (view, doc) = current!(cx.editor);
|
let (view, doc) = current!(cx.editor);
|
||||||
let text = doc.text().slice(..);
|
let text = doc.text().slice(..);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
commands,
|
commands,
|
||||||
compositor::{Component, Compositor, Context, EventResult},
|
compositor::{Component, Context, EventResult},
|
||||||
job::Callback,
|
|
||||||
key,
|
key,
|
||||||
keymap::{KeymapResult, KeymapResultKind, Keymaps},
|
keymap::{KeymapResult, KeymapResultKind, Keymaps},
|
||||||
ui::{Completion, ProgressSpinners},
|
ui::{Completion, ProgressSpinners},
|
||||||
@ -11,7 +10,7 @@
|
|||||||
coords_at_pos,
|
coords_at_pos,
|
||||||
graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary},
|
graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary},
|
||||||
movement::Direction,
|
movement::Direction,
|
||||||
syntax::{self, DebugConfigCompletion, HighlightEvent},
|
syntax::{self, HighlightEvent},
|
||||||
unicode::segmentation::UnicodeSegmentation,
|
unicode::segmentation::UnicodeSegmentation,
|
||||||
unicode::width::UnicodeWidthStr,
|
unicode::width::UnicodeWidthStr,
|
||||||
LineEnding, Position, Range, Selection,
|
LineEnding, Position, Range, Selection,
|
||||||
@ -31,8 +30,6 @@
|
|||||||
use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
|
use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
|
||||||
use tui::buffer::Buffer as Surface;
|
use tui::buffer::Buffer as Surface;
|
||||||
|
|
||||||
use super::{Prompt, PromptEvent};
|
|
||||||
|
|
||||||
pub struct EditorView {
|
pub struct EditorView {
|
||||||
keymaps: Keymaps,
|
keymaps: Keymaps,
|
||||||
on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
|
on_next_key: Option<Box<dyn FnOnce(&mut commands::Context, KeyEvent)>>,
|
||||||
@ -815,79 +812,6 @@ pub fn render_statusline(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
/// Handle events by looking them up in `self.keymaps`. Returns None
|
||||||
/// if event was handled (a command was executed or a subkeymap was
|
/// if event was handled (a command was executed or a subkeymap was
|
||||||
/// activated). Only KeymapResultKind::{NotFound, Cancelled} is returned
|
/// activated). Only KeymapResultKind::{NotFound, Cancelled} is returned
|
||||||
@ -898,14 +822,6 @@ fn handle_keymap_event(
|
|||||||
cxt: &mut commands::Context,
|
cxt: &mut commands::Context,
|
||||||
event: KeyEvent,
|
event: KeyEvent,
|
||||||
) -> Option<KeymapResult> {
|
) -> 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);
|
let key_result = self.keymaps.get_mut(&mode).unwrap().get(event);
|
||||||
self.autoinfo = key_result.sticky.map(|node| node.infobox());
|
self.autoinfo = key_result.sticky.map(|node| node.infobox());
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
pub use helix_core::diagnostic::Severity;
|
pub use helix_core::diagnostic::Severity;
|
||||||
pub use helix_core::register::Registers;
|
pub use helix_core::register::Registers;
|
||||||
use helix_core::syntax::{self, DebugConfigCompletion};
|
use helix_core::syntax;
|
||||||
use helix_core::Position;
|
use helix_core::Position;
|
||||||
use helix_dap as dap;
|
use helix_dap as dap;
|
||||||
|
|
||||||
@ -126,7 +126,6 @@ pub struct Editor {
|
|||||||
pub debugger: Option<dap::Client>,
|
pub debugger: Option<dap::Client>,
|
||||||
pub debugger_events: SelectAll<UnboundedReceiverStream<dap::Payload>>,
|
pub debugger_events: SelectAll<UnboundedReceiverStream<dap::Payload>>,
|
||||||
pub breakpoints: HashMap<PathBuf, Vec<dap::SourceBreakpoint>>,
|
pub breakpoints: HashMap<PathBuf, Vec<dap::SourceBreakpoint>>,
|
||||||
pub debug_config_completions: Vec<DebugConfigCompletion>,
|
|
||||||
|
|
||||||
pub clipboard_provider: Box<dyn ClipboardProvider>,
|
pub clipboard_provider: Box<dyn ClipboardProvider>,
|
||||||
|
|
||||||
@ -172,7 +171,6 @@ pub fn new(
|
|||||||
debugger: None,
|
debugger: None,
|
||||||
debugger_events: SelectAll::new(),
|
debugger_events: SelectAll::new(),
|
||||||
breakpoints: HashMap::new(),
|
breakpoints: HashMap::new(),
|
||||||
debug_config_completions: Vec::new(),
|
|
||||||
syn_loader: config_loader,
|
syn_loader: config_loader,
|
||||||
theme_loader: themes,
|
theme_loader: themes,
|
||||||
registers: Registers::default(),
|
registers: Registers::default(),
|
||||||
|
Loading…
Reference in New Issue
Block a user