Defaults in completions, better schema
This commit is contained in:
parent
f53d8411cb
commit
b42631942b
7 changed files with 88 additions and 58 deletions
|
@ -5,7 +5,6 @@ use crate::{
|
||||||
Rope, RopeSlice, Tendril,
|
Rope, RopeSlice, Tendril,
|
||||||
};
|
};
|
||||||
|
|
||||||
use helix_dap::DebugAdapterConfig;
|
|
||||||
pub use helix_syntax::get_language;
|
pub use helix_syntax::get_language;
|
||||||
|
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
|
@ -69,6 +68,41 @@ pub struct LanguageServerConfiguration {
|
||||||
pub args: Vec<String>,
|
pub args: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct AdvancedCompletion {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub completion: Option<String>,
|
||||||
|
pub default: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "kebab-case", untagged)]
|
||||||
|
pub enum DebugConfigCompletion {
|
||||||
|
Named(String),
|
||||||
|
Advanced(AdvancedCompletion),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct DebugTemplate {
|
||||||
|
pub name: String,
|
||||||
|
pub request: String,
|
||||||
|
pub completion: Vec<DebugConfigCompletion>,
|
||||||
|
pub args: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
pub struct DebugAdapterConfig {
|
||||||
|
pub name: String,
|
||||||
|
pub transport: String,
|
||||||
|
pub command: String,
|
||||||
|
pub args: Vec<String>,
|
||||||
|
pub port_arg: Option<String>,
|
||||||
|
pub templates: Vec<DebugTemplate>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct IndentationConfiguration {
|
pub struct IndentationConfiguration {
|
||||||
|
|
|
@ -38,28 +38,24 @@ pub struct Client {
|
||||||
impl Client {
|
impl Client {
|
||||||
// Spawn a process and communicate with it by either TCP or stdio
|
// Spawn a process and communicate with it by either TCP or stdio
|
||||||
pub async fn process(
|
pub async fn process(
|
||||||
cfg: DebugAdapterConfig,
|
transport: String,
|
||||||
|
command: String,
|
||||||
|
args: Vec<String>,
|
||||||
|
port_arg: Option<String>,
|
||||||
id: usize,
|
id: usize,
|
||||||
) -> Result<(Self, UnboundedReceiver<Payload>)> {
|
) -> Result<(Self, UnboundedReceiver<Payload>)> {
|
||||||
if cfg.transport == "tcp" && cfg.port_arg.is_some() {
|
if transport == "tcp" && port_arg.is_some() {
|
||||||
Self::tcp_process(
|
Self::tcp_process(
|
||||||
&cfg.command,
|
&command,
|
||||||
cfg.args.iter().map(|s| s.as_str()).collect(),
|
args.iter().map(|s| s.as_str()).collect(),
|
||||||
&cfg.port_arg.unwrap(),
|
&port_arg.unwrap(),
|
||||||
id,
|
id,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
} else if cfg.transport == "stdio" {
|
} else if transport == "stdio" {
|
||||||
Self::stdio(
|
Self::stdio(&command, args.iter().map(|s| s.as_str()).collect(), id)
|
||||||
&cfg.command,
|
|
||||||
cfg.args.iter().map(|s| s.as_str()).collect(),
|
|
||||||
id,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
Result::Err(Error::Other(anyhow!(
|
Result::Err(Error::Other(anyhow!("Incorrect transport {}", transport)))
|
||||||
"Incorrect transport {}",
|
|
||||||
cfg.transport
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,6 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::{collections::HashMap, path::PathBuf};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct DebugTemplate {
|
|
||||||
pub name: String,
|
|
||||||
pub request: String,
|
|
||||||
pub completion: Vec<String>,
|
|
||||||
pub args: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct DebugAdapterConfig {
|
|
||||||
pub name: String,
|
|
||||||
pub transport: String,
|
|
||||||
pub command: String,
|
|
||||||
pub args: Vec<String>,
|
|
||||||
pub port_arg: Option<String>,
|
|
||||||
pub templates: Vec<DebugTemplate>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Request {
|
pub trait Request {
|
||||||
type Arguments: serde::de::DeserializeOwned + serde::Serialize;
|
type Arguments: serde::de::DeserializeOwned + serde::Serialize;
|
||||||
|
|
|
@ -4528,7 +4528,13 @@ pub fn dap_start_impl(
|
||||||
|
|
||||||
let result = match socket {
|
let result = match socket {
|
||||||
Some(socket) => block_on(Client::tcp(socket, 0)),
|
Some(socket) => block_on(Client::tcp(socket, 0)),
|
||||||
None => block_on(Client::process(config.clone(), 0)),
|
None => block_on(Client::process(
|
||||||
|
config.transport.clone(),
|
||||||
|
config.command.clone(),
|
||||||
|
config.args.clone(),
|
||||||
|
config.port_arg.clone(),
|
||||||
|
0,
|
||||||
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut debugger, events) = match result {
|
let (mut debugger, events) = match result {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use helix_core::{
|
||||||
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, HighlightEvent},
|
syntax::{self, DebugConfigCompletion, HighlightEvent},
|
||||||
unicode::segmentation::UnicodeSegmentation,
|
unicode::segmentation::UnicodeSegmentation,
|
||||||
unicode::width::UnicodeWidthStr,
|
unicode::width::UnicodeWidthStr,
|
||||||
LineEnding, Position, Range, Selection,
|
LineEnding, Position, Range, Selection,
|
||||||
|
@ -710,28 +710,38 @@ impl EditorView {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_parameter_prompt(
|
fn debug_parameter_prompt(
|
||||||
completions: Vec<String>,
|
completions: Vec<DebugConfigCompletion>,
|
||||||
config_name: String,
|
config_name: String,
|
||||||
mut params: Vec<String>,
|
mut params: Vec<String>,
|
||||||
) -> Prompt {
|
) -> Prompt {
|
||||||
let i = params.len();
|
let i = params.len();
|
||||||
let field_type = completions.get(i).map(|x| x.as_str());
|
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 noop = |_input: &str| Vec::new();
|
||||||
let completer = match field_type {
|
let completer = match &field_type[..] {
|
||||||
Some(field_type) => {
|
"filename" => super::completers::filename,
|
||||||
if field_type.starts_with("filename") {
|
"directory" => super::completers::directory,
|
||||||
super::completers::filename
|
_ => noop,
|
||||||
} else if field_type.starts_with("directory") {
|
|
||||||
super::completers::directory
|
|
||||||
} else {
|
|
||||||
noop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => noop,
|
|
||||||
};
|
};
|
||||||
Prompt::new(
|
Prompt::new(
|
||||||
format!("{}: ", field_type.unwrap_or("arg")),
|
format!("{}: ", name),
|
||||||
None,
|
None,
|
||||||
completer,
|
completer,
|
||||||
move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| {
|
move |cx: &mut crate::compositor::Context, input: &str, event: PromptEvent| {
|
||||||
|
@ -739,7 +749,11 @@ impl EditorView {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.push(input.to_owned());
|
let mut value = input.to_owned();
|
||||||
|
if value.is_empty() {
|
||||||
|
value = default_val.clone();
|
||||||
|
}
|
||||||
|
params.push(value);
|
||||||
|
|
||||||
if params.len() < completions.len() {
|
if params.len() < completions.len() {
|
||||||
let completions = completions.clone();
|
let completions = completions.clone();
|
||||||
|
|
|
@ -22,7 +22,7 @@ use anyhow::Error;
|
||||||
|
|
||||||
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;
|
use helix_core::syntax::{self, DebugConfigCompletion};
|
||||||
use helix_core::Position;
|
use helix_core::Position;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -77,7 +77,7 @@ pub struct Editor {
|
||||||
pub debugger: Option<helix_dap::Client>,
|
pub debugger: Option<helix_dap::Client>,
|
||||||
pub debugger_events: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>,
|
pub debugger_events: SelectAll<UnboundedReceiverStream<helix_dap::Payload>>,
|
||||||
pub debug_config_picker: Option<Vec<String>>,
|
pub debug_config_picker: Option<Vec<String>>,
|
||||||
pub debug_config_completions: Option<Vec<Vec<String>>>,
|
pub debug_config_completions: Option<Vec<Vec<DebugConfigCompletion>>>,
|
||||||
pub variables: Option<Vec<String>>,
|
pub variables: Option<Vec<String>>,
|
||||||
pub variables_page: usize,
|
pub variables_page: usize,
|
||||||
|
|
||||||
|
|
|
@ -173,8 +173,8 @@ args = { mode = "exec", program = "{0}" }
|
||||||
[[language.debugger.templates]]
|
[[language.debugger.templates]]
|
||||||
name = "test"
|
name = "test"
|
||||||
request = "launch"
|
request = "launch"
|
||||||
completion = [ "directory: tests", "directory: cache output" ]
|
completion = [ { name = "tests", completion = "directory", default = "." } ]
|
||||||
args = { mode = "test", program = "{0}", output = "{1}" }
|
args = { mode = "test", program = "{0}" }
|
||||||
|
|
||||||
[[language.debugger.templates]]
|
[[language.debugger.templates]]
|
||||||
name = "attach"
|
name = "attach"
|
||||||
|
|
Loading…
Reference in a new issue