From dd74ff42394ac2f309108ccc0f53674cfaa8525b Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Mon, 24 Jan 2022 20:05:26 -0800 Subject: [PATCH] fix for macos finder issue (#1162) * attempt fix for finder issue * pull command creation functions out and implement macos exists and which * remove macos hack * refactor platform specific startup code * fix wsl command issue Co-authored-by: Keith Simmons --- src/bridge/command.rs | 121 ++++++++++++++++++++++++++++++++++++++++++ src/bridge/mod.rs | 102 ++--------------------------------- src/main.rs | 24 --------- 3 files changed, 126 insertions(+), 121 deletions(-) create mode 100644 src/bridge/command.rs diff --git a/src/bridge/command.rs b/src/bridge/command.rs new file mode 100644 index 0000000..d0dd99c --- /dev/null +++ b/src/bridge/command.rs @@ -0,0 +1,121 @@ +use std::{ + env, + path::Path, + process::{Command as StdCommand, Stdio}, +}; + +use log::{error, info, warn}; +use tokio::process::Command as TokioCommand; + +use crate::{cmd_line::CmdLineSettings, settings::*}; + +pub fn create_nvim_command() -> TokioCommand { + let mut cmd = build_nvim_cmd(); + + info!("Starting neovim with: {:?}", cmd); + + #[cfg(not(debug_assertions))] + cmd.stderr(Stdio::piped()); + + #[cfg(debug_assertions)] + cmd.stderr(Stdio::inherit()); + + #[cfg(windows)] + set_windows_creation_flags(&mut cmd); + + dbg!(cmd) +} + +#[cfg(target_os = "windows")] +fn set_windows_creation_flags(cmd: &mut TokioCommand) { + cmd.creation_flags(0x0800_0000); // CREATE_NO_WINDOW +} + +fn build_nvim_cmd() -> TokioCommand { + if let Some(path) = SETTINGS.get::().neovim_bin { + if platform_exists(&path) { + return build_nvim_cmd_with_args(&path); + } else { + warn!("NEOVIM_BIN is invalid falling back to first bin in PATH"); + } + } + if let Some(path) = platform_which("nvim") { + build_nvim_cmd_with_args(&path) + } else { + error!("nvim not found!"); + std::process::exit(1); + } +} + +// Creates a shell command if needed on this platform (wsl or macos) +fn create_platform_shell_command(command: String) -> Option { + if cfg!(target_os = "windows") && SETTINGS.get::().wsl { + let mut result = StdCommand::new("wsl"); + result.args(&["$SHELL", "-lic"]); + result.arg(command); + + Some(result) + } else if cfg!(target_os = "macos") { + let shell = env::var("SHELL").unwrap(); + let mut result = StdCommand::new(shell); + result.args(&["-lic"]); + result.arg(command); + Some(result) + } else { + None + } +} + +fn platform_exists(bin: &str) -> bool { + if let Some(mut exists_command) = create_platform_shell_command(format!("exists -x {}", bin)) { + if let Ok(output) = exists_command.output() { + output.status.success() + } else { + error!("Exists failed"); + std::process::exit(1); + } + } else { + Path::new(&bin).exists() + } +} + +fn platform_which(bin: &str) -> Option { + if let Some(mut which_command) = create_platform_shell_command(format!("which {}", bin)) { + if let Ok(output) = which_command.output() { + if output.status.success() { + let nvim_path = String::from_utf8(output.stdout).unwrap(); + return Some(nvim_path.trim().to_owned()); + } else { + return None; + } + } + } + + // Platform command failed, fallback to which crate + if let Ok(path) = which::which(bin) { + path.into_os_string().into_string().ok() + } else { + None + } +} + +fn build_nvim_cmd_with_args(bin: &str) -> TokioCommand { + let mut args = vec!["--embed".to_string()]; + args.extend(SETTINGS.get::().neovim_args); + let args_str = args.join(" "); + + if cfg!(target_os = "windows") && SETTINGS.get::().wsl { + let mut cmd = TokioCommand::new("wsl"); + cmd.args(&["$SHELL", "-lc", &format!("{} {}", bin, args_str)]); + cmd + } else if cfg!(target_os = "macos") { + let shell = env::var("SHELL").unwrap(); + let mut cmd = TokioCommand::new(shell); + cmd.args(&["-lc", &format!("{} {}", bin, args_str)]); + cmd + } else { + let mut cmd = TokioCommand::new(bin); + cmd.arg(args_str); + cmd + } +} diff --git a/src/bridge/mod.rs b/src/bridge/mod.rs index cffe233..180748c 100644 --- a/src/bridge/mod.rs +++ b/src/bridge/mod.rs @@ -1,4 +1,5 @@ mod clipboard; +mod command; pub mod create; mod events; mod handler; @@ -6,17 +7,17 @@ mod setup; mod tx_wrapper; mod ui_commands; -use std::{path::Path, process::Stdio, sync::Arc, thread}; +use std::{process::exit, sync::Arc, thread}; -use log::{error, info, warn}; +use log::{error, info}; use nvim_rs::UiAttachOptions; -use tokio::process::Command; use crate::{ cmd_line::CmdLineSettings, error_handling::ResultPanicExplanation, running_tracker::*, settings::*, }; +use command::create_nvim_command; pub use events::*; use handler::NeovimHandler; use setup::setup_neovide_specific_state; @@ -56,7 +57,7 @@ async fn start_neovim_runtime() { Ok("1") => {} // This is just a guard _ => { error!("Neovide requires nvim version 0.4 or higher. Download the latest version here https://github.com/neovim/neovim/wiki/Installing-Neovim"); - std::process::exit(0); + exit(0); } } @@ -98,96 +99,3 @@ async fn start_neovim_runtime() { }; RUNNING_TRACKER.quit("neovim processed failed"); } - -#[cfg(windows)] -fn set_windows_creation_flags(cmd: &mut Command) { - cmd.creation_flags(0x0800_0000); // CREATE_NO_WINDOW -} - -fn build_nvim_cmd_with_args(bin: &str) -> Command { - let mut args = vec!["--embed".to_string()]; - args.extend(SETTINGS.get::().neovim_args); - - #[cfg(windows)] - if SETTINGS.get::().wsl { - let mut cmd = Command::new("wsl"); - let argstring = format!("{} {}", bin.trim(), args.join(" ")); - cmd.args(&["$SHELL", "-lc", &argstring]); - return cmd; - } - let mut cmd = Command::new(bin); - cmd.args(args); - cmd -} - -fn platform_exists(bin: &str) -> bool { - #[cfg(windows)] - if SETTINGS.get::().wsl { - if let Ok(output) = std::process::Command::new("wsl") - .args(&["$SHELL", "-lic"]) - .arg(format!("exists -x {}", bin)) - .output() - { - return output.status.success(); - } else { - error!("wsl exists failed"); - std::process::exit(1); - } - } - Path::new(&bin).exists() -} - -fn platform_which(bin: &str) -> Option { - #[cfg(windows)] - if SETTINGS.get::().wsl { - if let Ok(output) = std::process::Command::new("wsl") - .args(&["$SHELL", "-lic"]) - .arg(format!("which {}", bin)) - .output() - { - if output.status.success() { - return Some(String::from_utf8(output.stdout).unwrap()); - } else { - return None; - } - } - } - if let Ok(path) = which::which(bin) { - path.into_os_string().into_string().ok() - } else { - None - } -} - -fn build_nvim_cmd() -> Command { - if let Some(path) = SETTINGS.get::().neovim_bin { - if platform_exists(&path) { - return build_nvim_cmd_with_args(&path); - } else { - warn!("NEOVIM_BIN is invalid falling back to first bin in PATH"); - } - } - if let Some(path) = platform_which("nvim") { - build_nvim_cmd_with_args(&path) - } else { - error!("nvim not found!"); - std::process::exit(1); - } -} - -pub fn create_nvim_command() -> Command { - let mut cmd = build_nvim_cmd(); - - info!("Starting neovim with: {:?}", cmd); - - #[cfg(not(debug_assertions))] - cmd.stderr(Stdio::piped()); - - #[cfg(debug_assertions)] - cmd.stderr(Stdio::inherit()); - - #[cfg(windows)] - set_windows_creation_flags(&mut cmd); - - cmd -} diff --git a/src/main.rs b/src/main.rs index 8953956..8cc8eb0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -132,9 +132,6 @@ fn main() { #[cfg(target_os = "windows")] windows_fix_dpi(); - #[cfg(target_os = "macos")] - handle_macos(); - WindowSettings::register(); RendererSettings::register(); CursorSettings::register(); @@ -198,27 +195,6 @@ fn windows_fix_dpi() { } } -#[cfg(target_os = "macos")] -fn handle_macos() { - use std::env; - - if env::var_os("TERM").is_none() { - let shell = env::var("SHELL").unwrap(); - // printenv is the proper way to print env variables. using echo $PATH would break Fish. - let cmd = "printenv PATH"; - if let Ok(path) = std::process::Command::new(shell) - .arg("-lic") // interactive login shell, this simulates opening a real terminal emulator - .arg(cmd) - .output() - { - env::set_var( - "PATH", - std::str::from_utf8(&path.stdout).unwrap().trim_end(), - ); - } - } -} - #[cfg(target_os = "windows")] fn windows_attach_to_console() { // Attach to parent console tip found here: https://github.com/rust-lang/rust/issues/67159#issuecomment-987882771