diff --git a/Cargo.lock b/Cargo.lock index bf01504ed..e5ffee0bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,7 +324,7 @@ dependencies = [ [[package]] name = "helix-dap" -version = "0.3.0" +version = "0.4.0" dependencies = [ "anyhow", "fern", @@ -375,6 +375,7 @@ dependencies = [ "futures-util", "fuzzy-matcher", "helix-core", + "helix-dap", "helix-lsp", "helix-tui", "helix-view", @@ -416,6 +417,7 @@ dependencies = [ "encoding_rs", "futures-util", "helix-core", + "helix-dap", "helix-lsp", "helix-tui", "log", @@ -423,6 +425,7 @@ dependencies = [ "serde", "slotmap", "tokio", + "tokio-stream", "toml", "url", "which", diff --git a/helix-dap/Cargo.toml b/helix-dap/Cargo.toml index ce1e2d16f..7582067e6 100644 --- a/helix-dap/Cargo.toml +++ b/helix-dap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-dap" -version = "0.3.0" +version = "0.4.0" authors = ["Blaž Hrastnik "] edition = "2018" license = "MPL-2.0" diff --git a/helix-dap/src/client.rs b/helix-dap/src/client.rs index 0f23dd15a..baf924b95 100644 --- a/helix-dap/src/client.rs +++ b/helix-dap/src/client.rs @@ -186,12 +186,12 @@ async fn request( &self, arguments: R::Arguments, ) -> Result { - let (callback_rx, mut callback_tx) = channel(1); + let (callback_tx, mut callback_rx) = channel(1); let arguments = Some(serde_json::to_value(arguments)?); let req = Request { - back_ch: Some(callback_rx), + back_ch: Some(callback_tx), seq: self.next_request_id(), command: R::COMMAND.to_string(), arguments, @@ -201,7 +201,7 @@ async fn request( .send(req) .expect("Failed to send request to debugger"); - let response = callback_tx.recv().await.unwrap()?; + let response = callback_rx.recv().await.unwrap()?; let response = serde_json::from_value(response.body.unwrap_or_default())?; Ok(response) } @@ -209,7 +209,7 @@ async fn request( pub fn capabilities(&self) -> &DebuggerCapabilities { self.capabilities .as_ref() - .expect("language server not yet initialized!") + .expect("debugger not yet initialized!") } pub async fn initialize(&mut self, adapter_id: String) -> Result<()> { @@ -240,21 +240,19 @@ pub async fn disconnect(&mut self) -> Result<()> { } pub async fn launch(&mut self, args: serde_json::Value) -> Result<()> { - let mut initialized = self.listen_for_event("initialized".to_owned()).await; + // TODO: buffer these until initialized arrives - let res = self.request::(args); - let ev = initialized.recv(); - join!(res, ev).0?; + let response = self.request::(args).await?; + log::error!("launch response {}", response); Ok(()) } pub async fn attach(&mut self, args: serde_json::Value) -> Result<()> { - let mut initialized = self.listen_for_event("initialized".to_owned()).await; + // TODO: buffer these until initialized arrives - let res = self.request::(args); - let ev = initialized.recv(); - join!(res, ev).0?; + let response = self.request::(args).await?; + log::error!("attach response {}", response); Ok(()) } diff --git a/helix-dap/src/transport.rs b/helix-dap/src/transport.rs index bca1351c7..062e04478 100644 --- a/helix-dap/src/transport.rs +++ b/helix-dap/src/transport.rs @@ -159,20 +159,17 @@ async fn send_string_to_server( } fn process_response(res: Response) -> Result { - match res.success { - true => { - info!("<- DAP success in response to {}", res.request_seq); + if res.success { + info!("<- DAP success in response to {}", res.request_seq); - Ok(res) - } - false => { - error!( - "<- DAP error {:?} ({:?}) for command #{} {}", - res.message, res.body, res.request_seq, res.command - ); + Ok(res) + } else { + error!( + "<- DAP error {:?} ({:?}) for command #{} {}", + res.message, res.body, res.request_seq, res.command + ); - Err(Error::Other(anyhow::format_err!("{:?}", res.body))) - } + Err(Error::Other(anyhow::format_err!("{:?}", res.body))) } } diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 409fd6435..63f27cf8e 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -24,4 +24,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" tokio = { version = "1.9", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } -tokio-stream = "0.1.7" +tokio-stream = "0.1" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index b42daff6c..6ed60e028 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -24,6 +24,7 @@ path = "src/main.rs" helix-core = { version = "0.4", path = "../helix-core" } helix-view = { version = "0.4", path = "../helix-view" } helix-lsp = { version = "0.4", path = "../helix-lsp" } +helix-dap = { version = "0.4", path = "../helix-dap" } anyhow = "1" once_cell = "1.8" diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 3d59c33a7..59072a090 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -245,6 +245,15 @@ pub fn handle_terminal_events(&mut self, event: Option anyhow::Result<()> { + use helix_dap::Client; + use helix_lsp::block_on; + use serde_json::to_value; + let (_, doc) = current!(cx.editor); + + // look up config for filetype + // if multiple available, open picker + + log::error!("1"); + + let client = Client::tcp_process("dlv", vec!["dap"], "-l 127.0.0.1:{}", 0); + let mut client = block_on(client)?; + log::error!("2"); + + let request = client.initialize("go".to_owned()); + let _ = block_on(request)?; + log::error!("3"); + + let mut args = HashMap::new(); + args.insert("mode", "debug"); + // args.insert("program", "path/to/program"); + + let request = client.launch(to_value(args)?); + let _ = block_on(request)?; + + log::error!("4"); + doc.debugger = Some(client); + Ok(()) + } + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2138,6 +2173,13 @@ fn tree_sitter_scopes( doc: "Display tree sitter scopes, primarily for theming and development.", fun: tree_sitter_scopes, completer: None, + }, + TypableCommand { + name: "debug", + alias: None, + doc: "Start a debug session.", + fun: debug, + completer: None, } ]; diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 29cfe047e..b39915845 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -18,6 +18,7 @@ bitflags = "1.3" anyhow = "1" helix-core = { version = "0.4", path = "../helix-core" } helix-lsp = { version = "0.4", path = "../helix-lsp"} +helix-dap = { version = "0.4", path = "../helix-dap"} crossterm = { version = "0.20", optional = true } # Conversion traits @@ -25,6 +26,7 @@ once_cell = "1.8" url = "2" tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } +tokio-stream = "0.1" futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false } slotmap = "1" diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index ff0c8bf47..3e8ed21cc 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -100,6 +100,7 @@ pub struct Document { diagnostics: Vec, language_server: Option>, + pub debugger: Option, } use std::fmt; @@ -425,6 +426,7 @@ pub fn from(text: Rope, encoding: Option<&'static encoding_rs::Encoding>) -> Sel history: Cell::new(History::default()), last_saved_revision: 0, language_server: None, + debugger: None, line_ending: DEFAULT_LINE_ENDING, } } diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index ec80580eb..7b9f34fc6 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -7,6 +7,9 @@ }; use futures_util::future; +use futures_util::stream::select_all::SelectAll; +use tokio_stream::wrappers::UnboundedReceiverStream; + use std::{ path::{Path, PathBuf}, sync::Arc, @@ -70,6 +73,7 @@ pub struct Editor { pub registers: Registers, pub theme: Theme, pub language_servers: helix_lsp::Registry, + pub debuggers: SelectAll>, pub clipboard_provider: Box, pub syn_loader: Arc, @@ -107,6 +111,7 @@ pub fn new( selected_register: RegisterSelection::default(), theme: themes.default(), language_servers, + debuggers: SelectAll::new(), syn_loader: config_loader, theme_loader: themes, registers: Registers::default(),