From d7332f3cc641d200e6040cfa0ff2fc18de7c1a0c Mon Sep 17 00:00:00 2001 From: Elias Kohout Date: Tue, 7 Apr 2026 18:37:17 +0200 Subject: [PATCH] Integrate scripts into home-manager --- home/default.nix | 1 + home/modules/scripts.nix | 18 +++ scripts/tmpclone | 251 +++++++++++++++++++++++++++++++++++++++ scripts/tmux-sessionizer | 23 ++++ scripts/tmux-setup | 7 ++ 5 files changed, 300 insertions(+) create mode 100644 home/modules/scripts.nix create mode 100644 scripts/tmpclone create mode 100644 scripts/tmux-sessionizer create mode 100644 scripts/tmux-setup diff --git a/home/default.nix b/home/default.nix index 6dfc9ba..ee0e151 100644 --- a/home/default.nix +++ b/home/default.nix @@ -6,6 +6,7 @@ ./modules/editor.nix ./modules/git.nix ./modules/tmux.nix + ./modules/scripts.nix ]; # ============================================ diff --git a/home/modules/scripts.nix b/home/modules/scripts.nix new file mode 100644 index 0000000..796ce43 --- /dev/null +++ b/home/modules/scripts.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +{ + home.file = { + ".local/scripts/tmpclone" = { + source = ../../scripts/tmpclone; + executable = true; + }; + ".local/scripts/tmux-sessionizer" = { + source = ../../scripts/tmux-sessionizer; + executable = true; + }; + ".local/scripts/tmux-setup" = { + source = ../../scripts/tmux-setup; + executable = true; + }; + }; +} diff --git a/scripts/tmpclone b/scripts/tmpclone new file mode 100644 index 0000000..c255a8e --- /dev/null +++ b/scripts/tmpclone @@ -0,0 +1,251 @@ +#!/bin/sh +## +## tmpclone +## +## Clones and manages short-lived git repositories. +## +## Usage examples: +## +## tmpclone > list the tracked repos +## tmplcone -d > deletes all tracked repos +## tmpclone -d target > deletes the target +## tmpclone target > opens the target, try to clone if not exits +## tmpclone -v target > like tmpclone target, but deletes the repo after close +## tmpclone -r target > like tmpcloen target, but if forces a redownload of the target +## tmpclone -n name target > creates a target with the name given, the target may be an url + + +function print_help() +{ + echo ' +tmpclone [-dhrv] [-n NAME] [TARGET] + Clones and manages short lived git repositories. + + -d + If a target is provided this repo will be deleted. Otherwise all repos created by tmpclone will be deleted. + + -h + Print this help page. + + -n NAME + Explicitly define a name for the repo. This only work in combination with a target. + + -r + Recreates the repos before entering it. + + -v + Delete the repo after exit (volatile). + ' +} + + +# ----------------------- +# | Argument parsing | +# ----------------------- + +# Define default flag values +FLAG_D=false +FLAG_N=false +FLAG_N_VALUE="" +FLAG_R=false +FLAG_V=false + +if [ $# -eq 0 ] +then + NO_ARGS=true +else + NO_ARGS=false +fi + +# Parse command-line options +while getopts ":dn:rvh" opt +do + case ${opt} in + h ) + print_help + exit 0 + ;; + d ) + FLAG_D=true + ;; + n ) + FLAG_N=true + FLAG_N_VALUE=$OPTARG + ;; + r ) + FLAG_R=true + ;; + v ) + FLAG_V=true + ;; + \? ) + echo "Invalid option: -$OPTARG" 1>&2 + print_help + exit 1 + ;; + : ) + echo "Option -$OPTARG requires an argument." 1>&2 + print_help + exit 1 + ;; + esac +done + +# Remove the options from the positional parameters +shift $((OPTIND -1)) + +# Check if there are any remaining arguments +if [ $# -eq 0 ] && ! $FLAG_D && ! $NO_ARGS +then + echo "No TARGET was provided." + print_help + exit 1 +fi + +# Get the TARGET +TARGET=false +if [ $# -ne 0 ] +then + TARGET=true + TARGET_VALUE=$1 +fi + + +# ----------------------- +# | Main program | +# ----------------------- + +DATA_ROOT="/var/tmp/tmpclone" +mkdir -p "$DATA_ROOT" + + +function repo_with_name_exists() +{ + ls "$DATA_ROOT/$1" 1> /dev/null 2> /dev/null + return $! +} + +function repo_with_url_exists() +{ + repo_with_name_exists "$(get_name_from_url $1)" + return $! +} + +function get_name_from_url() +{ + echo "$1" | awk 'BEGIN{FS="/"} {print $NF}' +} + +function get_url_from_name() +{ + cd "$DATA_ROOT/$1" && git remote get-url $(git remote | head -n 1) +} + +function recreate_repo_from_name() +{ + local REPO_PATH="$DATA_ROOT/$1" + local URL="$(get_url_from_name $1)" + rm -rf "$REPO_PATH" + git clone "$URL" "$REPO_PATH" +} + +function recreate_repo_from_url() +{ + local REPO_PATH="$DATA_ROOT/$(get_name_from_url $1)" + rm -rf "$REPO_PATH" + git clone "$1" "$REPO_PATH" +} + + +# Display all repos tracked by this script +if [ $NO_ARGS = true ] +then + ls $DATA_ROOT | sed "s/ /\n/g" + exit 0 +fi + +# Convert target to path +TARGET_PATH="" +if [ $TARGET = true ] +then + if repo_with_name_exists $TARGET_VALUE + then + TARGET_PATH="$DATA_ROOT/$TARGET_VALUE" + elif repo_with_url_exists $TARGET_VALUE + then + TARGET_PATH="$DATA_ROOT/$(get_name_from_url $TARGET_VALUE)" + fi +fi + +# Delete repos on -d option call +if [ "$FLAG_D" = true ] +then + if [ $TARGET = false ] + then + rm -rf "$DATA_ROOT" + echo "All repositories deleted." + else + rm -rf "$TARGET_PATH" + echo "Deleted the repo $TARGET_PATH." + fi + exit 0 +fi + +# Use name option to recreate a target with a new name +if [ "$FLAG_N" = true ] +then + TARGET_PATH="$DATA_ROOT/$FLAG_N_VALUE" + + if repo_with_name_exists $TARGET_VALUE + then + git clone "$(get_url_from_name $TARGET_VALUE)" "$TARGET_PATH" + elif repo_with_url_exists $TARGET_VALUE + then + git clone "$TARGET_VALUE" "$TARGET_PATH" + else + echo "Target '$TARGET_VALUE' not found." + exit 1 + fi +fi + +# Check if there exists a repo with the url already. +if [ $FLAG_R = true ] +then + if repo_with_name_exists $TARGET_VALUE + then + recreate_repo_from_name $TARGET_VALUE + elif repo_with_url_exists $TARGET_VALUE + then + recreate_repo_from_url $TARGET_VALUE + else + echo "Target '$TARGET_VALUE' not found." + exit 1 + fi +fi + +# Create if not exists +if [ ! -d "$TARGET_PATH" ] +then + TARGET_PATH="$DATA_ROOT/$(get_name_from_url $TARGET_VALUE)" + git clone "$TARGET_VALUE" "$TARGET_PATH" +fi + +# Define promt prefix +if [ "$FLAG_V" = true ] +then + export PROMPT_PREFIX="%F{244}%F{red}[tmpclone] %F{reset}" +else + export PROMPT_PREFIX="[tmpclone] " +fi + +# Enter the subshell +sh -c "cd \"$TARGET_PATH\"; /bin/zsh" +SHELL_EXIT=$? + +# Volatile +if [ "$FLAG_V" = true ] +then + rm -rf "$TARGET_PATH" +fi + +exit $SHELL_EXIT diff --git a/scripts/tmux-sessionizer b/scripts/tmux-sessionizer new file mode 100644 index 0000000..db8312d --- /dev/null +++ b/scripts/tmux-sessionizer @@ -0,0 +1,23 @@ +#!/usr/bin/env zsh + +selected=$(find ~/projects -maxdepth 1 -mindepth 1 | fzf) +if [[ -z "$selected" ]]; then + exit 0 +fi +selected_name=$(basename $selected | tr ".,: " "____") + +switch_to() { + if [[ -z "$TMUX" ]]; then + tmux attach-session -t $selected_name + else + tmux switch-client -t $selected_name + fi +} + +if tmux has-session -t="$selected_name"; then + switch_to +else + tmux new-session -ds $selected_name -c $selected + tmux send-keys -t $selected_name "tmux-setup" ^M + switch_to +fi diff --git a/scripts/tmux-setup b/scripts/tmux-setup new file mode 100644 index 0000000..d39d5c7 --- /dev/null +++ b/scripts/tmux-setup @@ -0,0 +1,7 @@ +#!/usr/bin/env zsh + +if [[ -x ./.tmux-setup ]]; then + ./.setup-tmux +elif [[ -x $XDG_CONFIG_HOME/.tmux-setup ]]; then + $XDG_CONFIG_HOME/.tmux-setup +fi