Skip to content

Commit

Permalink
Deduplicate session names for repos and bookmarks
Browse files Browse the repository at this point in the history
Improve the deduplication of session names to work for bookmarks as well
as repos. Also make it work when showing the full path in the picker.
The deduplication also changes the name for all duplicate session names
to get similar names for all conflicting session names.

fixes #26
  • Loading branch information
petersimonsson committed Jun 27, 2024
1 parent 3a5b582 commit 4c27d9e
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 215 deletions.
12 changes: 3 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
dirty_paths::DirtyUtf8Path,
execute_command, get_single_selection,
picker::Preview,
repos::{find_repos, RepoContainer},
session::{create_sessions, SessionContainer},
session_exists, set_up_tmux_env, switch_to_session,
tmux::Tmux,
Result, TmsError,
Expand Down Expand Up @@ -246,17 +246,11 @@ fn switch_command(config: Config, tmux: &Tmux) -> Result<()> {

let mut sessions: Vec<String> = sessions.into_iter().map(|s| s.0.to_string()).collect();
if let Some(true) = config.switch_filter_unknown {
let repos = find_repos(
config.search_dirs().change_context(TmsError::ConfigError)?,
config.excluded_dirs,
config.display_full_path,
config.search_submodules,
config.recursive_submodules,
)?;
let configured = create_sessions(&config)?;

sessions = sessions
.into_iter()
.filter(|session| repos.find_repo(session).is_some())
.filter(|session| configured.find_session(session).is_some())
.collect::<Vec<String>>();
}

Expand Down
38 changes: 17 additions & 21 deletions src/configs.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use clap::ValueEnum;
use error_stack::ResultExt;
use serde_derive::{Deserialize, Serialize};
use std::{collections::HashMap, env, fmt::Display, fs::canonicalize, io::Write, path::PathBuf};
use std::{env, fmt::Display, fs::canonicalize, io::Write, path::PathBuf};

use ratatui::style::{Color, Style};

use crate::{dirty_paths::DirtyUtf8Path, keymap::Keymap, Suggestion};
use crate::{keymap::Keymap, Suggestion};

type Result<T> = error_stack::Result<T, ConfigError>;

Expand Down Expand Up @@ -204,29 +204,25 @@ impl Config {
}
}

pub fn bookmark_paths(&self) -> HashMap<String, PathBuf> {
let mut ret = HashMap::new();

pub fn bookmark_paths(&self) -> Vec<PathBuf> {
if let Some(bookmarks) = &self.bookmarks {
for bookmark in bookmarks {
if let Ok(path) = PathBuf::from(bookmark).canonicalize() {
let name = if let Some(true) = self.display_full_path {
Some(path.display().to_string())
bookmarks
.iter()
.filter_map(|b| {
if let Ok(expanded) = shellexpand::full(b) {
if let Ok(path) = PathBuf::from(expanded.to_string()).canonicalize() {
Some(path)
} else {
None
}
} else {
path.file_name()
.expect("should end with a directory")
.to_string()
.ok()
};

if let Some(name) = name {
ret.insert(name, path);
None
}
}
}
})
.collect()
} else {
Vec::new()
}

ret
}
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod error;
pub mod keymap;
pub mod picker;
pub mod repos;
pub mod session;
pub mod tmux;

use error_stack::ResultExt;
Expand Down
93 changes: 8 additions & 85 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
use std::{collections::HashMap, path::PathBuf};

use clap::Parser;
use error_stack::{Report, ResultExt};
use error_stack::Report;

use git2::Repository;
use tms::{
cli::{Cli, SubCommandGiven},
dirty_paths::DirtyUtf8Path,
error::{Result, TmsError},
error::Result,
get_single_selection,
picker::Preview,
repos::find_repos,
repos::RepoContainer,
session_exists, set_up_tmux_env, switch_to_session,
session::{create_sessions, SessionContainer},
tmux::Tmux,
Suggestion,
};
Expand All @@ -35,23 +29,11 @@ fn main() -> Result<()> {
SubCommandGiven::No(config) => config, // continue
};

let bookmarks = config.bookmark_paths();

// Find repositories and present them with the fuzzy finder
let repos = find_repos(
config.search_dirs().change_context(TmsError::ConfigError)?,
config.excluded_dirs,
config.display_full_path,
config.search_submodules,
config.recursive_submodules,
)?;

let mut dirs = repos.list();

dirs.append(&mut bookmarks.keys().map(|b| b.to_string()).collect());
let sessions = create_sessions(&config)?;
let session_strings = sessions.list();

let selected_str = if let Some(str) = get_single_selection(
&dirs,
&session_strings,
Preview::None,
config.picker_colors,
config.shortcuts,
Expand All @@ -62,68 +44,9 @@ fn main() -> Result<()> {
return Ok(());
};

if let Some(found_repo) = repos.find_repo(&selected_str) {
switch_to_repo_session(selected_str, found_repo, &tmux, config.display_full_path)?;
} else {
switch_to_bookmark_session(selected_str, &tmux, bookmarks)?;
}

Ok(())
}

fn switch_to_repo_session(
selected_str: String,
found_repo: &Repository,
tmux: &Tmux,
display_full_path: Option<bool>,
) -> Result<()> {
let path = if found_repo.is_bare() {
found_repo.path().to_string()?
} else {
found_repo
.workdir()
.expect("bare repositories should all have parent directories")
.canonicalize()
.change_context(TmsError::IoError)?
.to_string()?
};
let repo_short_name = (if display_full_path == Some(true) {
std::path::PathBuf::from(&selected_str)
.file_name()
.expect("None of the paths here should terminate in `..`")
.to_string()?
} else {
selected_str
})
.replace('.', "_");

if !session_exists(&repo_short_name, tmux) {
tmux.new_session(Some(&repo_short_name), Some(&path));
set_up_tmux_env(found_repo, &repo_short_name, tmux)?;
if let Some(session) = sessions.find_session(&selected_str) {
session.switch_to(&tmux)?;
}

switch_to_session(&repo_short_name, tmux);

Ok(())
}

fn switch_to_bookmark_session(
selected_str: String,
tmux: &Tmux,
bookmarks: HashMap<String, PathBuf>,
) -> Result<()> {
let path = &bookmarks[&selected_str];
let session_name = path
.file_name()
.expect("Bookmarks should not end in `..`")
.to_string()?
.replace('.', "_");

if !session_exists(&session_name, tmux) {
tmux.new_session(Some(&session_name), path.to_str());
}

switch_to_session(&session_name, tmux);

Ok(())
}
Loading

0 comments on commit 4c27d9e

Please sign in to comment.