mirror of
https://github.com/neovide/neovide.git
synced 2026-09-10 07:16:25 -04:00
fix: update neovim listen_addr restart protocol and keep open args per route (#3441)
the old :restart progpath/argv payload is not the protocol anymore see: https://github.com/neovim/neovim/pull/35223 the contract is now simpler: - the server starts the new neovim instance - the UI gets a restart event with the new listen address - the UI follows that address instead of rebuilding argv impl the new protocol exposes the second bug. if a reused Neovide process opens a new embedded window, that route has to start with the files it was actually asked to open, otherwise :restart will attempt to restart the process startup args from the first window, or an empty session.
This commit is contained in:
parent
458bfd0578
commit
32f223ae75
|
|
@ -5,13 +5,35 @@ use std::path::PathBuf;
|
|||
use std::process::Command as StdCommand;
|
||||
use tokio::process::Command as TokioCommand;
|
||||
|
||||
use crate::{
|
||||
bridge::RestartDetails, cmd_line::CmdLineSettings, settings::*, utils::handle_wslpaths,
|
||||
};
|
||||
use crate::{cmd_line::CmdLineSettings, utils::handle_wslpaths};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const FORKED_FROM_TTY_ENV_VAR: &str = "NEOVIDE_FORKED_FROM_TTY";
|
||||
|
||||
/// For route-local startup targets for an embedded nvim instance.
|
||||
///
|
||||
/// we keep these separate from process-global cmd line settings because a reused
|
||||
/// neovide process can open additional windows with their own launch context.
|
||||
/// that context needs to be part of the actual nvim argv so e.g :restart replays
|
||||
/// the same buffers/tabs, instead of only preserving the initial empty startup.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct OpenArgs {
|
||||
pub files_to_open: Vec<String>,
|
||||
pub tabs: bool,
|
||||
}
|
||||
|
||||
/// Mode is how neovide should populate argv when launching an embedded nvim instance.
|
||||
///
|
||||
/// Startup uses the original process command line targets,
|
||||
/// Args uses route-local targets such as macOS handoff new windows,
|
||||
/// None launches a blank embedded instance.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum OpenMode {
|
||||
None,
|
||||
Startup,
|
||||
Args(OpenArgs),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CommandSpec {
|
||||
program: String,
|
||||
|
|
@ -37,28 +59,8 @@ impl CommandSpec {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_restart_nvim_command(
|
||||
settings: &Settings,
|
||||
details: &RestartDetails,
|
||||
cwd: Option<&Path>,
|
||||
) -> TokioCommand {
|
||||
let cmdline_settings = settings.get::<CmdLineSettings>();
|
||||
let spec = create_restart_command_spec(details, &cmdline_settings);
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut cmd = tokio_command_from_spec(spec);
|
||||
if let Some(dir) = command_cwd(&cmdline_settings, cwd) {
|
||||
cmd.current_dir(dir);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
cmd.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW.0);
|
||||
|
||||
cmd
|
||||
}
|
||||
|
||||
pub fn create_blocking_nvim_command(cmdline_settings: &CmdLineSettings, embed: bool) -> StdCommand {
|
||||
let (bin, args) = build_nvim_command_parts(cmdline_settings, embed);
|
||||
let (bin, args) = build_nvim_command_parts(cmdline_settings, embed, OpenMode::Startup);
|
||||
let spec = create_command_spec(&bin, &args, cmdline_settings);
|
||||
let mut cmd = std_command_from_spec(spec);
|
||||
if let Some(dir) = command_cwd(cmdline_settings, None) {
|
||||
|
|
@ -71,8 +73,9 @@ pub fn create_tokio_nvim_command(
|
|||
cmdline_settings: &CmdLineSettings,
|
||||
embed: bool,
|
||||
cwd: Option<&Path>,
|
||||
mode: OpenMode,
|
||||
) -> TokioCommand {
|
||||
let (bin, args) = build_nvim_command_parts(cmdline_settings, embed);
|
||||
let (bin, args) = build_nvim_command_parts(cmdline_settings, embed, mode);
|
||||
let spec = create_command_spec(&bin, &args, cmdline_settings);
|
||||
let mut cmd = tokio_command_from_spec(spec);
|
||||
if let Some(dir) = command_cwd(cmdline_settings, cwd) {
|
||||
|
|
@ -88,6 +91,7 @@ fn command_cwd(settings: &CmdLineSettings, cwd: Option<&Path>) -> Option<PathBuf
|
|||
fn build_nvim_command_parts(
|
||||
cmdline_settings: &CmdLineSettings,
|
||||
embed: bool,
|
||||
mode: OpenMode,
|
||||
) -> (String, Vec<String>) {
|
||||
let bin = cmdline_settings.neovim_bin.clone().unwrap_or_else(|| "nvim".to_owned());
|
||||
let mut args = cmdline_settings.neovim_args.clone();
|
||||
|
|
@ -95,46 +99,21 @@ fn build_nvim_command_parts(
|
|||
append_embed_arg(&mut args);
|
||||
}
|
||||
|
||||
args.extend(build_auto_open_args(cmdline_settings));
|
||||
args.extend(build_open_args(cmdline_settings, mode));
|
||||
|
||||
(bin, args)
|
||||
}
|
||||
|
||||
fn create_restart_command_spec(
|
||||
details: &RestartDetails,
|
||||
cmdline_settings: &CmdLineSettings,
|
||||
) -> CommandSpec {
|
||||
let (program, args) = build_restart_command_parts(details, cmdline_settings);
|
||||
create_command_spec(&program, &args, cmdline_settings)
|
||||
}
|
||||
fn build_open_args(cmdline_settings: &CmdLineSettings, open_mode: OpenMode) -> Vec<String> {
|
||||
let (files_to_open, tabs) = match open_mode {
|
||||
OpenMode::None => return Vec::new(),
|
||||
OpenMode::Startup => (cmdline_settings.files_to_open.clone(), cmdline_settings.tabs),
|
||||
OpenMode::Args(args) => (args.files_to_open, args.tabs),
|
||||
};
|
||||
|
||||
fn build_restart_command_parts(
|
||||
details: &RestartDetails,
|
||||
cmdline_settings: &CmdLineSettings,
|
||||
) -> (String, Vec<String>) {
|
||||
if should_replay_startup_command(cmdline_settings) {
|
||||
return build_nvim_command_parts(cmdline_settings, true);
|
||||
}
|
||||
|
||||
build_inner_restart_command_parts(details)
|
||||
}
|
||||
|
||||
fn should_replay_startup_command(cmdline_settings: &CmdLineSettings) -> bool {
|
||||
cmdline_settings.server.is_none()
|
||||
}
|
||||
|
||||
fn build_inner_restart_command_parts(details: &RestartDetails) -> (String, Vec<String>) {
|
||||
let mut args = details.argv.iter().skip(1).cloned().collect::<Vec<_>>();
|
||||
prepend_embed_arg(&mut args);
|
||||
(details.progpath.clone(), args)
|
||||
}
|
||||
|
||||
fn build_auto_open_args(cmdline_settings: &CmdLineSettings) -> Vec<String> {
|
||||
cmdline_settings
|
||||
.tabs
|
||||
.then(|| "-p".to_string())
|
||||
tabs.then(|| "-p".to_string())
|
||||
.into_iter()
|
||||
.chain(handle_wslpaths(cmdline_settings.files_to_open.clone(), cmdline_settings.wsl))
|
||||
.chain(handle_wslpaths(files_to_open, cmdline_settings.wsl))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
@ -144,12 +123,6 @@ fn append_embed_arg(args: &mut Vec<String>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn prepend_embed_arg(args: &mut Vec<String>) {
|
||||
if !args.iter().any(|arg| arg == "--embed") {
|
||||
args.insert(0, "--embed".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
fn tokio_command_from_spec(spec: CommandSpec) -> TokioCommand {
|
||||
let CommandSpec {
|
||||
program,
|
||||
|
|
@ -274,7 +247,7 @@ fn create_command_spec(
|
|||
mod tests {
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::cmd_line::handle_command_line_arguments;
|
||||
use crate::{cmd_line::handle_command_line_arguments, settings::Settings};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -285,23 +258,38 @@ mod tests {
|
|||
settings.get::<CmdLineSettings>()
|
||||
}
|
||||
|
||||
fn parse_settings(args: &[&str]) -> Settings {
|
||||
let settings = Settings::new();
|
||||
let args = args.iter().map(|arg| arg.to_string()).collect();
|
||||
handle_command_line_arguments(args, &settings).expect("Could not parse arguments");
|
||||
settings
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_nvim_command_parts_places_embed_before_auto_open_args() {
|
||||
let cmdline_settings =
|
||||
parse_cmdline_settings(&["neovide", "./foo.txt", "./bar.md", "--grid=420x240"]);
|
||||
|
||||
let (_, args) = build_nvim_command_parts(&cmdline_settings, true);
|
||||
let (_, args) = build_nvim_command_parts(&cmdline_settings, true, OpenMode::Startup);
|
||||
|
||||
assert_eq!(args, vec!["--embed", "-p", "./foo.txt", "./bar.md"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_nvim_command_parts_skips_auto_open_args_when_requested() {
|
||||
let cmdline_settings =
|
||||
parse_cmdline_settings(&["neovide", "./foo.txt", "./bar.md", "--grid=420x240"]);
|
||||
|
||||
let (_, args) = build_nvim_command_parts(&cmdline_settings, true, OpenMode::None);
|
||||
|
||||
assert_eq!(args, vec!["--embed"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_nvim_command_parts_uses_route_auto_open_args() {
|
||||
let cmdline_settings =
|
||||
parse_cmdline_settings(&["neovide", "./foo.txt", "./bar.md", "--grid=420x240"]);
|
||||
let open_args = OpenArgs { files_to_open: vec!["/tmp/project".to_string()], tabs: false };
|
||||
|
||||
let (_, args) =
|
||||
build_nvim_command_parts(&cmdline_settings, true, OpenMode::Args(open_args));
|
||||
|
||||
assert_eq!(args, vec!["--embed", "/tmp/project"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_nvim_command_parts_preserves_launcher_args_before_embed() {
|
||||
let cmdline_settings = parse_cmdline_settings(&[
|
||||
|
|
@ -314,62 +302,12 @@ mod tests {
|
|||
"nvim",
|
||||
]);
|
||||
|
||||
let (bin, args) = build_nvim_command_parts(&cmdline_settings, true);
|
||||
let (bin, args) = build_nvim_command_parts(&cmdline_settings, true, OpenMode::Startup);
|
||||
|
||||
assert_eq!(bin, "ssh");
|
||||
assert_eq!(args, vec!["my-server", "nvim", "--embed"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_restart_command_parts_replays_original_launcher_command() {
|
||||
let cmdline_settings = parse_cmdline_settings(&[
|
||||
"neovide",
|
||||
"--no-tabs",
|
||||
"--neovim-bin",
|
||||
"ssh",
|
||||
"--",
|
||||
"my-server",
|
||||
"nvim",
|
||||
]);
|
||||
let restart_details = RestartDetails {
|
||||
progpath: "/usr/bin/nvim".to_string(),
|
||||
argv: vec!["nvim".to_string(), "--clean".to_string()],
|
||||
};
|
||||
|
||||
let (program, args) = build_restart_command_parts(&restart_details, &cmdline_settings);
|
||||
|
||||
assert_eq!(program, "ssh");
|
||||
assert_eq!(args, vec!["my-server", "nvim", "--embed"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_restart_command_parts_replays_original_auto_open_args() {
|
||||
let cmdline_settings =
|
||||
parse_cmdline_settings(&["neovide", "./foo.txt", "./bar.md", "--grid=420x240"]);
|
||||
let restart_details = RestartDetails {
|
||||
progpath: "nvim".to_string(),
|
||||
argv: vec!["nvim".to_string(), "--clean".to_string()],
|
||||
};
|
||||
|
||||
let (_, args) = build_restart_command_parts(&restart_details, &cmdline_settings);
|
||||
|
||||
assert_eq!(args, vec!["--embed", "-p", "./foo.txt", "./bar.md"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_restart_command_parts_keeps_embed_before_restart_args_for_server_mode() {
|
||||
let cmdline_settings = parse_cmdline_settings(&["neovide", "--server", "127.0.0.1:7777"]);
|
||||
let restart_details = RestartDetails {
|
||||
progpath: "nvim".to_string(),
|
||||
argv: vec!["nvim".to_string(), "-p".to_string(), "foo.txt".to_string()],
|
||||
};
|
||||
|
||||
let (program, args) = build_restart_command_parts(&restart_details, &cmdline_settings);
|
||||
|
||||
assert_eq!(program, "nvim");
|
||||
assert_eq!(args, vec!["--embed", "-p", "foo.txt"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_cwd_prefers_override() {
|
||||
let cmdline_settings = parse_cmdline_settings(&["neovide", "--chdir", "/random/path"]);
|
||||
|
|
@ -386,31 +324,4 @@ mod tests {
|
|||
|
||||
assert_eq!(command_cwd(&cmdline_settings, None), Some(PathBuf::from("/random/path")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_restart_nvim_command_prefers_route_cwd() {
|
||||
let settings = parse_settings(&["neovide", "--chdir", "/cmdline/cwd"]);
|
||||
let restart_details = RestartDetails {
|
||||
progpath: "nvim".to_string(),
|
||||
argv: vec!["nvim".to_string(), "--clean".to_string()],
|
||||
};
|
||||
|
||||
let command =
|
||||
create_restart_nvim_command(&settings, &restart_details, Some(Path::new("/route/cwd")));
|
||||
|
||||
assert_eq!(command.as_std().get_current_dir(), Some(Path::new("/route/cwd")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_restart_nvim_command_falls_back_to_cmdline_cwd() {
|
||||
let settings = parse_settings(&["neovide", "--chdir", "/cmdline/cwd"]);
|
||||
let restart_details = RestartDetails {
|
||||
progpath: "nvim".to_string(),
|
||||
argv: vec!["nvim".to_string(), "--clean".to_string()],
|
||||
};
|
||||
|
||||
let command = create_restart_nvim_command(&settings, &restart_details, None);
|
||||
|
||||
assert_eq!(command.as_std().get_current_dir(), Some(Path::new("/cmdline/cwd")));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,10 +42,9 @@ use tokio::{
|
|||
};
|
||||
use winit::event_loop::EventLoopProxy;
|
||||
|
||||
pub use command::create_blocking_nvim_command;
|
||||
use command::create_restart_nvim_command;
|
||||
#[cfg(test)]
|
||||
pub use command::create_tokio_nvim_command;
|
||||
pub use command::{OpenArgs, OpenMode, create_blocking_nvim_command};
|
||||
pub use events::*;
|
||||
pub use restart::RestartDetails;
|
||||
pub use session::NeovimWriter;
|
||||
|
|
@ -98,9 +97,10 @@ async fn neovim_instance(
|
|||
settings: &Settings,
|
||||
restart: Option<&RestartDetails>,
|
||||
cwd: Option<&Path>,
|
||||
mode: OpenMode,
|
||||
) -> Result<NeovimInstance> {
|
||||
if let Some(info) = restart {
|
||||
return Ok(NeovimInstance::Embedded(create_restart_nvim_command(settings, info, cwd)));
|
||||
return Ok(NeovimInstance::Server { address: info.listen_addr.clone() });
|
||||
}
|
||||
|
||||
if let Some(address) = settings.get::<CmdLineSettings>().server {
|
||||
|
|
@ -108,7 +108,12 @@ async fn neovim_instance(
|
|||
}
|
||||
|
||||
let cmdline_settings = settings.get::<CmdLineSettings>();
|
||||
Ok(NeovimInstance::Embedded(command::create_tokio_nvim_command(&cmdline_settings, true, cwd)))
|
||||
Ok(NeovimInstance::Embedded(command::create_tokio_nvim_command(
|
||||
&cmdline_settings,
|
||||
true,
|
||||
cwd,
|
||||
mode,
|
||||
)))
|
||||
}
|
||||
|
||||
pub async fn show_error_message(
|
||||
|
|
@ -135,6 +140,7 @@ pub async fn show_error_message(
|
|||
nvim.echo(prepared_lines, true, nvim_dict! {}).await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn create_neovim_session(
|
||||
route_id: RouteId,
|
||||
handler: NeovimHandler,
|
||||
|
|
@ -143,8 +149,9 @@ async fn create_neovim_session(
|
|||
background: &str,
|
||||
restart_details: Option<&RestartDetails>,
|
||||
cwd: Option<&Path>,
|
||||
mode: OpenMode,
|
||||
) -> Result<NeovimSession> {
|
||||
let neovim_instance = neovim_instance(settings.as_ref(), restart_details, cwd).await?;
|
||||
let neovim_instance = neovim_instance(settings.as_ref(), restart_details, cwd, mode).await?;
|
||||
#[allow(unused_mut)]
|
||||
let mut session = NeovimSession::new(neovim_instance, handler.clone())
|
||||
.await
|
||||
|
|
@ -163,8 +170,7 @@ async fn create_neovim_session(
|
|||
|
||||
let cmdline_settings = settings.get::<CmdLineSettings>();
|
||||
|
||||
let remote =
|
||||
cmdline_settings.wsl || (cmdline_settings.server.is_some() && restart_details.is_none());
|
||||
let remote = cmdline_settings.wsl || cmdline_settings.server.is_some();
|
||||
// This is too verbose to keep enabled all the time
|
||||
// log::info!("Api information {:#?}", api_information);
|
||||
setup_neovide_specific_state(&session.neovim, remote, &api_information, &settings).await?;
|
||||
|
|
@ -206,14 +212,15 @@ async fn create_neovim_session(
|
|||
// Triggers loading the user config
|
||||
|
||||
let grid_size = grid_size.map_or(DEFAULT_GRID_SIZE, |v| clamped_grid_size(&v));
|
||||
let res = session
|
||||
session
|
||||
.neovim
|
||||
.ui_attach(grid_size.width as i64, grid_size.height as i64, &options)
|
||||
.await
|
||||
.context("Could not attach ui to neovim process");
|
||||
.context("Could not attach ui to neovim process")?;
|
||||
|
||||
info!("Neovim process attached");
|
||||
res.map(|()| session)
|
||||
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
async fn run(route_id: RouteId, session: NeovimSession, proxy: EventLoopProxy<EventPayload>) {
|
||||
|
|
@ -327,6 +334,7 @@ impl NeovimRuntime {
|
|||
settings: Arc<Settings>,
|
||||
config: &Config,
|
||||
cwd: Option<&Path>,
|
||||
mode: OpenMode,
|
||||
) -> Result<NeovimHandler> {
|
||||
let mut colorscheme_stream = self.colorscheme_stream();
|
||||
let editor_handler = start_editor_handler(
|
||||
|
|
@ -352,6 +360,7 @@ impl NeovimRuntime {
|
|||
&initial_background,
|
||||
None,
|
||||
cwd,
|
||||
mode,
|
||||
)) {
|
||||
Ok(session) => session,
|
||||
Err(err) => {
|
||||
|
|
@ -397,6 +406,7 @@ impl NeovimRuntime {
|
|||
&background,
|
||||
Some(&restart_details),
|
||||
cwd,
|
||||
OpenMode::None,
|
||||
))?;
|
||||
|
||||
self.runtime().spawn(run(route_id, session, event_loop_proxy));
|
||||
|
|
|
|||
|
|
@ -2,24 +2,42 @@ use rmpv::Value;
|
|||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct RestartDetails {
|
||||
pub progpath: String,
|
||||
pub argv: Vec<String>,
|
||||
pub listen_addr: String,
|
||||
}
|
||||
|
||||
impl RestartDetails {
|
||||
pub fn from_values(arguments: &[Value]) -> Option<Self> {
|
||||
if arguments.len() < 2 {
|
||||
return None;
|
||||
match arguments {
|
||||
[listen_addr] => Some(Self { listen_addr: listen_addr.as_str()?.to_string() }),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
let progpath = arguments[0].as_str()?.to_string();
|
||||
let argv = arguments
|
||||
.get(1)?
|
||||
.as_array()?
|
||||
.iter()
|
||||
.filter_map(|value| value.as_str().map(|s| s.to_string()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Some(Self { progpath, argv })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::RestartDetails;
|
||||
use rmpv::Value;
|
||||
|
||||
#[test]
|
||||
fn parses_listen_addr_restart_payload() {
|
||||
let details = RestartDetails::from_values(&[Value::from("/tmp/nvim.sock")]);
|
||||
|
||||
assert_eq!(details, Some(RestartDetails { listen_addr: "/tmp/nvim.sock".to_string() }));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_restart_payload_with_extra_arguments() {
|
||||
let details =
|
||||
RestartDetails::from_values(&[Value::from("/tmp/nvim.sock"), Value::from("echo 1")]);
|
||||
|
||||
assert_eq!(details, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_restart_payload_with_invalid_type() {
|
||||
let details = RestartDetails::from_values(&[Value::from("/tmp/nvim.sock"), Value::from(1)]);
|
||||
|
||||
assert_eq!(details, None);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ mod tests {
|
|||
use super::*;
|
||||
use crate::{
|
||||
bridge::{
|
||||
create_tokio_nvim_command,
|
||||
OpenMode, create_tokio_nvim_command,
|
||||
session::{NeovimInstance, NeovimSession},
|
||||
},
|
||||
cmd_line::CmdLineSettings,
|
||||
|
|
@ -369,7 +369,7 @@ mod tests {
|
|||
settings.set::<CmdLineSettings>(&CmdLineSettings::default());
|
||||
|
||||
let cmdline_settings = settings.get::<CmdLineSettings>();
|
||||
let command = create_tokio_nvim_command(&cmdline_settings, true, None);
|
||||
let command = create_tokio_nvim_command(&cmdline_settings, true, None, OpenMode::Startup);
|
||||
let instance = NeovimInstance::Embedded(command);
|
||||
let NeovimSession { neovim: nvim, .. } = NeovimSession::new(instance, NeovimHandler())
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::{
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
use {
|
||||
crate::bridge::{send_or_queue_file_drop, set_active_route_handler},
|
||||
crate::bridge::{OpenArgs, send_or_queue_file_drop, set_active_route_handler},
|
||||
crate::utils::resolve_relative_path,
|
||||
std::path::Path,
|
||||
};
|
||||
|
|
@ -260,14 +260,31 @@ impl Application {
|
|||
event_loop: &ActiveEventLoop,
|
||||
new_window: bool,
|
||||
cwd: Option<&Path>,
|
||||
args: OpenArgs,
|
||||
) {
|
||||
if new_window {
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, cwd);
|
||||
self.mark_should_render_all();
|
||||
if !new_window {
|
||||
self.activate_focused_route();
|
||||
self.send_file_drops(args);
|
||||
return;
|
||||
}
|
||||
|
||||
self.activate_focused_route();
|
||||
if self.settings.get::<CmdLineSettings>().server.is_some() {
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, cwd, None);
|
||||
self.mark_should_render_all();
|
||||
self.send_file_drops(args);
|
||||
return;
|
||||
}
|
||||
|
||||
let open_args = (!args.files_to_open.is_empty()).then_some(args);
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, cwd, open_args);
|
||||
self.mark_should_render_all();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn send_file_drops(&self, args: OpenArgs) {
|
||||
for path in args.files_to_open {
|
||||
send_or_queue_file_drop(path, Some(args.tabs));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_app_config_changed(&mut self, config: AppHotReloadConfigs) {
|
||||
|
|
@ -360,7 +377,7 @@ impl Application {
|
|||
#[cfg(feature = "profiling")]
|
||||
self.aggregate_should_render().plot_tracy();
|
||||
if self.create_window_allowed && self.window_wrapper.has_pending_window_creation() {
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, None);
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, None, None);
|
||||
}
|
||||
event_loop.set_control_flow(ControlFlow::WaitUntil(self.get_event_deadline()));
|
||||
}
|
||||
|
|
@ -671,12 +688,15 @@ impl ApplicationHandler<EventPayload> for Application {
|
|||
UserEvent::OpenFiles { files, cwd, caller_cwd, tabs, new_window } => {
|
||||
let cwd = cwd.as_deref().map(Path::new);
|
||||
let caller_cwd = caller_cwd.as_deref().map(Path::new);
|
||||
self.prepare_open_files(event_loop, new_window, cwd);
|
||||
let open_args = OpenArgs {
|
||||
files_to_open: files
|
||||
.into_iter()
|
||||
.map(|path| resolve_relative_path(&path, caller_cwd))
|
||||
.collect(),
|
||||
tabs,
|
||||
};
|
||||
|
||||
for path in files {
|
||||
let path = resolve_relative_path(&path, caller_cwd);
|
||||
send_or_queue_file_drop(path, Some(tabs));
|
||||
}
|
||||
self.prepare_open_files(event_loop, new_window, cwd, open_args);
|
||||
}
|
||||
UserEvent::NeovimExited => {
|
||||
let route_id = self.route_id_for_target(target);
|
||||
|
|
@ -767,7 +787,7 @@ impl ApplicationHandler<EventPayload> for Application {
|
|||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
UserEvent::CreateWindow => {
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, None);
|
||||
self.window_wrapper.try_create_window(event_loop, &self.proxy, None, None);
|
||||
self.sync_render_states();
|
||||
self.mark_should_render_all();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ use {
|
|||
use crate::{
|
||||
CmdLineSettings,
|
||||
bridge::{
|
||||
NeovimHandler, NeovimRuntime, ParallelCommand, RestartDetails, SerialCommand, send_ui,
|
||||
set_active_route_handler, unregister_route_handler,
|
||||
NeovimHandler, NeovimRuntime, OpenArgs, OpenMode, ParallelCommand, RestartDetails,
|
||||
SerialCommand, send_ui, set_active_route_handler, unregister_route_handler,
|
||||
},
|
||||
clipboard::ClipboardHandle,
|
||||
cmd_line::{GeometryArgs, MouseCursorIcon},
|
||||
|
|
@ -282,6 +282,7 @@ impl WinitWindowWrapper {
|
|||
self.settings.clone(),
|
||||
&config,
|
||||
None,
|
||||
OpenMode::Startup,
|
||||
)
|
||||
.expect("Failed to launch neovim runtime");
|
||||
|
||||
|
|
@ -1390,6 +1391,7 @@ impl WinitWindowWrapper {
|
|||
event_loop: &ActiveEventLoop,
|
||||
proxy: &EventLoopProxy<EventPayload>,
|
||||
cwd: Option<&Path>,
|
||||
args: Option<OpenArgs>,
|
||||
) {
|
||||
let creating_initial_window = self.routes.is_empty();
|
||||
let route_id = if creating_initial_window {
|
||||
|
|
@ -1507,6 +1509,7 @@ impl WinitWindowWrapper {
|
|||
self.settings.clone(),
|
||||
&config,
|
||||
cwd,
|
||||
args.map_or(OpenMode::None, OpenMode::Args),
|
||||
)
|
||||
.expect("Failed to launch neovim runtime");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue