@@ -1,3 +1,7 @@
1use helix_core::{
5use helix_core::{
2 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes, indent,
6 comment, coords_at_pos, find_first_non_whitespace_char, find_root, graphemes, indent,
3 indent::IndentStyle,
7 indent::IndentStyle,
@@ -24,13 +28,11 @@ use helix_lsp::{
25use insert::*;
29use insert::*;
26use movement::Movement;
30use movement::Movement;
27−use serde_json::Value;
29use crate::{
32use crate::{
30 compositor::{self, Component, Compositor},
33 compositor::{self, Component, Compositor},
31 ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent},
34 ui::{self, FilePicker, Picker, Popup, Prompt, PromptEvent},
33−use tokio_stream::wrappers::UnboundedReceiverStream;
35use crate::job::{self, Job, Jobs};
37use crate::job::{self, Job, Jobs};
36use futures_util::FutureExt;
38use futures_util::FutureExt;
@@ -4490,366 +4492,3 @@ fn suspend(_cx: &mut Context) {
4490 #[cfg(not(windows))]
4492 #[cfg(not(windows))]
4491 signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();
4493 signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap();
4495−pub fn dap_start_impl(
4496− editor: &mut Editor,
4497− name: Option<&str>,
4498− socket: Option<std::net::SocketAddr>,
4499− params: Option<Vec<&str>>,
4501− use helix_dap::Client;
4502− use helix_lsp::block_on;
4503− use serde_json::to_value;
4505− let (_, doc) = current!(editor);
4507− let path = match doc.path() {
4508− Some(path) => path.to_path_buf(),
4510− editor.set_error("Can't start debug: document has no path".to_string());
4515− let config = editor
4517− .language_config_for_file_name(&path)
4518− .and_then(|x| x.debugger.clone());
4519− let config = match config {
4523− "Can't start debug: no debug adapter available for language".to_string(),
4529− let result = match socket {
4530− Some(socket) => block_on(Client::tcp(socket, 0)),
4531− None => block_on(Client::process(
4532− config.transport.clone(),
4533− config.command.clone(),
4534− config.args.clone(),
4535− config.port_arg.clone(),
4540− let (mut debugger, events) = match result {
4543− editor.set_error(format!("Failed to start debug session: {:?}", e));
4548− let request = debugger.initialize(config.name.clone());
4549− if let Err(e) = block_on(request) {
4550− editor.set_error(format!("Failed to initialize debug adapter: {:?}", e));
4554− let start_config = match name {
4555− Some(name) => config.templates.iter().find(|t| t.name == name),
4556− None => config.templates.get(0),
4558− let start_config = match start_config {
4561− editor.set_error("Can't start debug: no debug config with given name".to_string());
4566− let template = start_config.args.clone();
4567− let mut args: HashMap<String, Value> = HashMap::new();
4569− if let Some(params) = params {
4570− for (k, t) in template {
4572− for (i, x) in params.iter().enumerate() {
4573− // For param #0 replace {0} in args
4574− value = value.replace(format!("{{{}}}", i).as_str(), x);
4577− if let Ok(integer) = value.parse::<usize>() {
4578− args.insert(k, Value::Number(serde_json::Number::from(integer)));
4580− args.insert(k, Value::String(value));
4585− let args = to_value(args).unwrap();
4587− let result = match &start_config.request[..] {
4588− "launch" => block_on(debugger.launch(args)),
4589− "attach" => block_on(debugger.attach(args)),
4591− editor.set_error("Unsupported request".to_string());
4595− if let Err(e) = result {
4596− editor.set_error(format!("Failed {} target: {:?}", start_config.request, e));
4600− // TODO: either await "initialized" or buffer commands until event is received
4601− editor.debugger = Some(debugger);
4602− let stream = UnboundedReceiverStream::new(events);
4603− editor.debugger_events.push(stream);
4606−fn dap_launch(cx: &mut Context) {
4607− if cx.editor.debugger.is_some() {
4609− .set_error("Can't start debug: debugger is running".to_string());
4613− let (_, doc) = current!(cx.editor);
4614− let path = match doc.path() {
4615− Some(path) => path.to_path_buf(),
4618− .set_error("Can't start debug: document has no path".to_string());
4626− .language_config_for_file_name(&path)
4627− .and_then(|x| x.debugger.clone());
4628− let config = match config {
4631− cx.editor.set_error(
4632− "Can't start debug: no debug adapter available for language".to_string(),
4638− cx.editor.debug_config_picker = Some(config.templates.iter().map(|t| t.name.clone()).collect());
4639− cx.editor.debug_config_completions = Some(
4643− .map(|t| t.completion.clone())
4648−fn dap_toggle_breakpoint(cx: &mut Context) {
4649− use helix_lsp::block_on;
4651− let (view, doc) = current!(cx.editor);
4652− let text = doc.text().slice(..);
4653− let pos = doc.selection(view.id).primary().cursor(text);
4655− let breakpoint = helix_dap::SourceBreakpoint {
4656− line: text.char_to_line(pos) + 1, // convert from 0-indexing to 1-indexing (TODO: could set debugger to 0-indexing on init)
4657− ..Default::default()
4660− let path = match doc.path() {
4661− Some(path) => path.to_path_buf(),
4664− .set_error("Can't set breakpoint: document has no path".to_string());
4669− // TODO: need to map breakpoints over edits and update them?
4670− // we shouldn't really allow editing while debug is running though
4672− if let Some(debugger) = &mut cx.editor.debugger {
4673− let breakpoints = debugger.breakpoints.entry(path.clone()).or_default();
4674− if let Some(pos) = breakpoints.iter().position(|b| b.line == breakpoint.line) {
4675− breakpoints.remove(pos);
4677− breakpoints.push(breakpoint);
4680− let breakpoints = breakpoints.clone();
4682− let request = debugger.set_breakpoints(path, breakpoints);
4683− if let Err(e) = block_on(request) {
4685− .set_error(format!("Failed to set breakpoints: {:?}", e));
4690−fn dap_run(cx: &mut Context) {
4691− use helix_lsp::block_on;
4693− if let Some(debugger) = &mut cx.editor.debugger {
4694− if debugger.is_running {
4696− .set_status("Debuggee is already running".to_owned());
4699− let request = debugger.configuration_done();
4700− if let Err(e) = block_on(request) {
4701− cx.editor.set_error(format!("Failed to run: {:?}", e));
4704− debugger.is_running = true;
4708−fn dap_continue(cx: &mut Context) {
4709− use helix_lsp::block_on;
4711− if let Some(debugger) = &mut cx.editor.debugger {
4712− if debugger.is_running {
4714− .set_status("Debuggee is already running".to_owned());
4718− let request = debugger.continue_thread(debugger.stopped_thread.unwrap());
4719− if let Err(e) = block_on(request) {
4720− cx.editor.set_error(format!("Failed to continue: {:?}", e));
4723− debugger.is_running = true;
4724− debugger.stack_pointer = None;
4728−fn dap_pause(cx: &mut Context) {
4729− use helix_lsp::block_on;
4731− if let Some(debugger) = &mut cx.editor.debugger {
4732− if !debugger.is_running {
4733− cx.editor.set_status("Debuggee is not running".to_owned());
4737− // FIXME: correct number here
4738− let request = debugger.pause(0);
4739− if let Err(e) = block_on(request) {
4740− cx.editor.set_error(format!("Failed to pause: {:?}", e));
4745−fn dap_step_in(cx: &mut Context) {
4746− use helix_lsp::block_on;
4748− if let Some(debugger) = &mut cx.editor.debugger {
4749− if debugger.is_running {
4751− .set_status("Debuggee is already running".to_owned());
4755− let request = debugger.step_in(debugger.stopped_thread.unwrap());
4756− if let Err(e) = block_on(request) {
4757− cx.editor.set_error(format!("Failed to step: {:?}", e));
4762−fn dap_step_out(cx: &mut Context) {
4763− use helix_lsp::block_on;
4765− if let Some(debugger) = &mut cx.editor.debugger {
4766− if debugger.is_running {
4768− .set_status("Debuggee is already running".to_owned());
4772− let request = debugger.step_out(debugger.stopped_thread.unwrap());
4773− if let Err(e) = block_on(request) {
4774− cx.editor.set_error(format!("Failed to step: {:?}", e));
4779−fn dap_next(cx: &mut Context) {
4780− use helix_lsp::block_on;
4782− if let Some(debugger) = &mut cx.editor.debugger {
4783− if debugger.is_running {
4785− .set_status("Debuggee is already running".to_owned());
4789− let request = debugger.next(debugger.stopped_thread.unwrap());
4790− if let Err(e) = block_on(request) {
4791− cx.editor.set_error(format!("Failed to step: {:?}", e));
4796−fn dap_variables(cx: &mut Context) {
4797− use helix_lsp::block_on;
4799− if let Some(debugger) = &mut cx.editor.debugger {
4800− if debugger.is_running {
4802− .set_status("Cannot access variables while target is running".to_owned());
4805− if debugger.stack_pointer.is_none() {
4807− .set_status("Cannot find current stack pointer to access variables".to_owned());
4811− let frame_id = debugger.stack_pointer.clone().unwrap().id;
4812− let scopes = match block_on(debugger.scopes(frame_id)) {
4816− .set_error(format!("Failed to get scopes: {:?}", e));
4820− let mut variables = Vec::new();
4822− for scope in scopes.iter() {
4823− let response = block_on(debugger.variables(scope.variables_reference));
4825− if let Ok(vars) = response {
4827− let prefix = match var.data_type {
4828− Some(data_type) => format!("{} ", data_type),
4829− None => "".to_owned(),
4831− variables.push(format!("{}{} = {}\n", prefix, var.name, var.value));
4836− if !variables.is_empty() {
4837− cx.editor.variables = Some(variables);
4838− cx.editor.variables_page = 0;
4843−fn dap_terminate(cx: &mut Context) {
4844− use helix_lsp::block_on;
4846− if let Some(debugger) = &mut cx.editor.debugger {
4847− let request = debugger.disconnect();
4848− if let Err(e) = block_on(request) {
4850− .set_error(format!("Failed to disconnect: {:?}", e));
4853− cx.editor.debugger = None;