diff options
Diffstat (limited to 'pkgs/by-name/ts/tskm/src/interface/open/handle.rs')
-rw-r--r-- | pkgs/by-name/ts/tskm/src/interface/open/handle.rs | 96 |
1 files changed, 70 insertions, 26 deletions
diff --git a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs index 0b565abd..4d7341b2 100644 --- a/pkgs/by-name/ts/tskm/src/interface/open/handle.rs +++ b/pkgs/by-name/ts/tskm/src/interface/open/handle.rs @@ -1,7 +1,13 @@ -use std::process; +use std::{ + fs, + net::{IpAddr, Ipv4Addr}, + path::PathBuf, + process, +}; use anyhow::{bail, Context, Result}; -use log::{error, info}; +use log::{error, info, warn}; +use url::Url; use crate::{cli::OpenCommand, rofi, state::State, task}; @@ -11,7 +17,7 @@ pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { for project in task::Project::all().context("Failed to get all project files")? { if project.is_touched() { info!("Reviewing project: '{}'", project.to_project_display()); - open_in_browser(project, state).with_context(|| { + open_in_browser(project, state, None).with_context(|| { format!( "Failed to open project ('{}') in Firefox", project.to_project_display() @@ -26,23 +32,13 @@ pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { } } } - OpenCommand::Project { project } => { - let project = if let Some(p) = project { - p - } else if let Some(p) = - task::Project::get_current().context("Failed to get currently focused project")? - { - p - } else { - bail!("You need to either supply a project or have a project active!"); - }; - + OpenCommand::Project { project, url } => { project.touch().context("Failed to touch project")?; - open_in_browser(&project, state).with_context(|| { + open_in_browser(&project, state, url).with_context(|| { format!("Failed to open project: {}", project.to_project_display()) })?; } - OpenCommand::Select => { + OpenCommand::Select { url } => { let selected_project: task::Project = task::Project::from_project_string( &rofi::select( task::Project::all() @@ -60,7 +56,7 @@ pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { .touch() .context("Failed to touch project")?; - open_in_browser(&selected_project, state).context("Failed to open project")?; + open_in_browser(&selected_project, state, url).context("Failed to open project")?; } OpenCommand::ListTabs { project } => { let project = if let Some(p) = project { @@ -109,7 +105,11 @@ pub fn handle(command: OpenCommand, state: &mut State) -> Result<()> { Ok(()) } -fn open_in_browser(selected_project: &task::Project, state: &mut State) -> Result<()> { +fn open_in_browser( + selected_project: &task::Project, + state: &mut State, + url: Option<Url>, +) -> Result<()> { let old_project: Option<task::Project> = task::Project::get_current().context("Failed to get currently active project")?; let old_task: Option<task::Task> = @@ -154,14 +154,58 @@ fn open_in_browser(selected_project: &task::Project, state: &mut State) -> Resul tracking_task }; - let status = process::Command::new("firefox") - .args([ - "-P", - selected_project.to_project_display().as_str(), - "about:newtab", - ]) - .status() - .context("Failed to start firefox")?; + let status = { + let mut args = vec!["-P".to_owned(), selected_project.to_project_display()]; + if let Some(url) = url { + args.push(url.to_string()); + } else { + let lock_file = dirs::home_dir() + .expect("Exists") + .join(".mozilla/firefox") + .join(selected_project.to_project_display()) + .join("lock"); + + if lock_file.exists() { + let (ip, pid): (IpAddr, u32) = { + let link = fs::read_link(&lock_file).with_context(|| { + format!("Failed to readlink lock at '{}'", lock_file.display()) + })?; + + let (ip, pid) = link + .to_str() + .expect("Should work") + .split_once(':') + .expect("The split works"); + + ( + ip.parse().expect("Should be a valid ip address"), + pid.parse().expect("Should be a valid pid"), + ) + }; + + if ip != Ipv4Addr::new(127, 0, 0, 2) { + warn!("Your ip is weird.."); + } + + if PathBuf::from("/proc").join(pid.to_string()).exists() { + // Another Firefox instance has already been started for this project + // Add a buffer URL to force Firefox to open it in the already open instance + args.push("about:newtab".to_owned()); + } else { + // This project does not yet have another Firefox instance + // We do not need to add anything to the arguments, Firefox will open a new + // instance. + } + } else { + // There is no lock file and thus no instance already open. + } + }; + + process::Command::new("firefox") + .args(args) + .status() + .context("Failed to start firefox")? + }; if !status.success() { error!("Firefox run exited with error."); |