123 lines
3.3 KiB
Rust
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(),
|
|
};
|
|
}
|