on master help sign in
Make external terminal provider configurable
cb7615eBlaž Hrastnik
helix-view/src/clipboard.rs+7−1
@@ -139,7 +139,7 @@ pub fn get_clipboard_provider() -> Box<dyn ClipboardProvider> {
139 }
139 }
140}
140}
141
141
142−mod provider {
142+pub mod provider {
143 use super::{ClipboardProvider, ClipboardType};
143 use super::{ClipboardProvider, ClipboardType};
144 use anyhow::Result;
144 use anyhow::Result;
145 use std::borrow::Cow;
145 use std::borrow::Cow;
@@ -164,6 +164,12 @@ mod provider {
164 }
164 }
165 }
165 }
166
166
167+ impl Default for NopProvider {
168+ fn default() -> Self {
169+ Self::new()
170+ }
171+ }
172+
167 #[cfg(not(target_os = "windows"))]
173 #[cfg(not(target_os = "windows"))]
168 impl ClipboardProvider for NopProvider {
174 impl ClipboardProvider for NopProvider {
169 fn name(&self) -> Cow<str> {
175 fn name(&self) -> Cow<str> {
helix-view/src/editor.rs+48
@@ -157,6 +157,7 @@ pub struct Config {
157 #[serde(default)]
157 #[serde(default)]
158 pub search: SearchConfig,
158 pub search: SearchConfig,
159 pub lsp: LspConfig,
159 pub lsp: LspConfig,
160+ pub terminal: Option<TerminalConfig>,
160 /// Column numbers at which to draw the rulers. Default to `[]`, meaning no rulers.
161 /// Column numbers at which to draw the rulers. Default to `[]`, meaning no rulers.
161 pub rulers: Vec<u16>,
162 pub rulers: Vec<u16>,
162 #[serde(default)]
163 #[serde(default)]
@@ -167,6 +168,52 @@ pub struct Config {
167 pub color_modes: bool,
168 pub color_modes: bool,
168}
169}
169
170
171+#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
172+#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
173+pub struct TerminalConfig {
174+ pub command: String,
175+ #[serde(default)]
176+ #[serde(skip_serializing_if = "Vec::is_empty")]
177+ pub args: Vec<String>,
178+}
179+
180+#[cfg(windows)]
181+pub fn get_terminal_provider() -> Option<TerminalConfig> {
182+ use crate::clipboard::provider::command::exists;
183+
184+ if exists("wt") {
185+ return Some(TerminalConfig {
186+ command: "wt".to_string(),
187+ args: vec![
188+ "new-tab".to_string(),
189+ "--title".to_string(),
190+ "DEBUG".to_string(),
191+ "cmd".to_string(),
192+ "/C".to_string(),
193+ ],
194+ });
195+ }
196+
197+ return Some(TerminalConfig {
198+ command: "conhost".to_string(),
199+ args: vec!["cmd".to_string(), "/C".to_string()],
200+ });
201+}
202+
203+#[cfg(not(any(windows, target_os = "wasm32")))]
204+pub fn get_terminal_provider() -> Option<TerminalConfig> {
205+ use crate::clipboard::provider::command::{env_var_is_set, exists};
206+
207+ if env_var_is_set("TMUX") && exists("tmux") {
208+ return Some(TerminalConfig {
209+ command: "tmux".to_string(),
210+ args: vec!["split-window".to_string()],
211+ });
212+ }
213+
214+ None
215+}
216+
170#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
217#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
171#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
218#[serde(default, rename_all = "kebab-case", deny_unknown_fields)]
172pub struct LspConfig {
219pub struct LspConfig {
@@ -497,6 +544,7 @@ impl Default for Config {
497 true_color: false,
544 true_color: false,
498 search: SearchConfig::default(),
545 search: SearchConfig::default(),
499 lsp: LspConfig::default(),
546 lsp: LspConfig::default(),
547+ terminal: get_terminal_provider(),
500 rulers: Vec::new(),
548 rulers: Vec::new(),
501 whitespace: WhitespaceConfig::default(),
549 whitespace: WhitespaceConfig::default(),
502 indent_guides: IndentGuidesConfig::default(),
550 indent_guides: IndentGuidesConfig::default(),
helix-view/src/handlers/dap.rs+26−27
@@ -5,7 +5,6 @@ use helix_dap::{self as dap, Client, Payload, Request, ThreadId};
5use helix_lsp::block_on;
5use helix_lsp::block_on;
6use log::warn;
6use log::warn;
7use std::fmt::Write;
7use std::fmt::Write;
8−use std::io::ErrorKind;
9use std::path::PathBuf;
8use std::path::PathBuf;
10
9
11#[macro_export]
10#[macro_export]
@@ -287,32 +286,32 @@ impl Editor {
287 serde_json::from_value(request.arguments.unwrap_or_default()).unwrap();
286 serde_json::from_value(request.arguments.unwrap_or_default()).unwrap();
288 // TODO: no unwrap
287 // TODO: no unwrap
289
288
290− let process = if cfg!(windows) {
289+ let config = match self.config().terminal.clone() {
291− std::process::Command::new("wt")
290+ Some(config) => config,
292− .arg("new-tab")
291+ None => {
293− .arg("--title")
292+ self.set_error("No external terminal defined");
294− .arg("DEBUG")
293+ return true;
295− .arg("cmd")
294+ }
296− .arg("/C")
295+ };
297− .arg(arguments.args.join(" "))
296+
298− .spawn()
297+ // Re-borrowing debugger to avoid issues when loading config
299− .unwrap_or_else(|error| match error.kind() {
298+ let debugger = match self.debugger.as_mut() {
299+ Some(debugger) => debugger,
300+ None => return false,
301+ };
302+
300− ErrorKind::NotFound => std::process::Command::new("conhost")
303+ let process = match std::process::Command::new(config.command)
301− .arg("cmd")
304+ .args(config.args)
302− .arg("/C")
303− .arg(arguments.args.join(" "))
305+ .arg(arguments.args.join(" "))
304− .spawn()
306+ .spawn()
305− .unwrap(),
307+ {
308+ Ok(process) => process,
309+ Err(err) => {
306− // TODO replace the pretty print {:?} with a regular format {}
310+ // TODO replace the pretty print {:?} with a regular format {}
307− // when the MSRV is raised to 1.60.0
311+ // when the MSRV is raised to 1.60.0
308− e => panic!("Error to start debug console: {:?}", e),
312+ self.set_error(format!("Error starting external terminal: {:?}", err));
309− })
313+ return true;
310− } else {
314+ }
311− std::process::Command::new("tmux")
312− .arg("split-window")
313− .arg(arguments.args.join(" "))
314− .spawn()
315− .unwrap()
316 };
315 };
317
316
318 let _ = debugger
317 let _ = debugger