project-manager/src/session.rs

123 lines
3.3 KiB
Rust

use skim::prelude::*;
use std::{collections::BTreeMap, io::Cursor, path::PathBuf};
use tmux_interface::{
commands::tmux::StdIO, AttachSession, HasSession, NewSession, SwitchClient, Tmux,
};
pub fn add_project(
projects: &mut BTreeMap<String, String>,
project_name: Option<&String>,
project_path: PathBuf,
) -> Option<String> {
let project_path_string = project_path
.clone()
.into_os_string()
.into_string()
.expect("Current directory is not UTF-8 encoded.");
let project_name_string: String = clean_project_name(&match project_name {
Some(name) => name.to_string(),
None => match project_path.file_name() {
Some(name) => name
.to_str()
.expect("Current directory name cannot be stringified.")
.to_string(),
None => "unnamed".to_string(),
},
});
projects.insert(project_name_string.clone(), project_path_string);
Some(project_name_string)
}
pub fn project_by_path(projects: &BTreeMap<String, String>, project_path: &str) -> Option<String> {
projects
.iter()
.filter(|(_k, v)| v == &project_path)
.last()
.map(|(k, _v)| k.clone())
}
pub fn delete_project(projects: &mut BTreeMap<String, String>, project_name: Option<&String>) {
match project_name {
Some(name) => projects.remove(name),
None => None,
};
}
pub fn find_projects(
projects: &BTreeMap<String, String>,
project_name: Option<&String>,
old_session_path: &str,
) -> Option<String> {
let project_names = projects.clone().into_keys().collect::<Vec<_>>().join("\n");
let options = SkimOptionsBuilder::default()
.height(Some("100%"))
.multi(false)
.query(project_name.map(|string| string.as_str()))
.select1(true)
.build()
.unwrap();
let items = SkimItemReader::default().of_bufread(Cursor::new(project_names));
let result = Skim::run_with(&options, Some(items)).expect("No skim result.");
match result.is_abort {
true => project_by_path(&projects, &old_session_path),
false => match result.selected_items.first() {
Some(name) => Some(name.output().to_string()),
None => project_by_path(&projects, &old_session_path),
},
}
}
fn path_by_project(
projects: &BTreeMap<String, String>,
project_name: Option<String>,
) -> Option<&String> {
projects.get(&project_name?)
}
pub fn clean_project_name(project_name: &String) -> String {
project_name.replace(".", "").replace(":", "")
}
pub fn focus_project(projects: &BTreeMap<String, String>, project_name: Option<&String>) {
let base_name = String::from("base");
let session_name = project_name.unwrap_or(&base_name);
let has_session = Tmux::with_command(HasSession::new().target_session(session_name))
.stderr(Some(StdIO::Null))
.status()
.unwrap()
.success();
match has_session {
false => Tmux::with_command(
NewSession::new()
.session_name(session_name)
.start_directory(
path_by_project(projects, project_name.cloned()).unwrap_or(&"~".to_string()),
)
.detached(),
)
.status()
.unwrap()
.success(),
true => true,
};
match std::env::var("TMUX") {
Ok(_) => Tmux::with_command(SwitchClient::new().target_session(session_name))
.status()
.unwrap()
.success(),
Err(_) => Tmux::with_command(AttachSession::new().target_session(session_name))
.status()
.unwrap()
.success(),
};
}