project-manager/src/session.rs

117 lines
3.2 KiB
Rust

use skim::prelude::*;
use std::{collections::BTreeMap, io::Cursor};
use tmux_interface::{
commands::tmux::StdIO, AttachSession, HasSession, NewSession, SwitchClient, Tmux,
};
pub fn add_project(
projects: &mut BTreeMap<String, String>,
project_name: Option<&String>,
) -> Option<String> {
let project_path = std::env::current_dir().expect("Current directory is not available.");
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 = 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)
}
fn project_by_path(projects: &BTreeMap<String, String>, project_path: &String) -> 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_path: &String) {
match project_by_path(&projects, &project_path) {
Some(name) => projects.remove(&name),
None => None,
};
}
pub fn find_projects(
projects: &BTreeMap<String, String>,
project_name: Option<&String>,
old_session_path: &String,
) -> 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),
},
}
}
pub fn focus_project(projects: &BTreeMap<String, String>, project_name: Option<String>) {
let session_name = match project_name {
Some(name) => name,
None => "base".to_string(),
};
let has_session = Tmux::with_command(HasSession::new().target_session(&session_name))
.stderr(Some(StdIO::Null))
.status()
.unwrap()
.success();
match has_session {
false => {
let base_directory = "~".to_string();
Tmux::with_command(
NewSession::new()
.session_name(&session_name)
.start_directory(projects.get(&session_name).unwrap_or(&base_directory))
.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(),
};
}