diff --git a/README.md b/README.md index ec6b884..ec3a532 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,15 @@ home-manager switch --flake github:Logan-Lin/nix-config#yanlin │ ├── nvim.nix # Neovim configuration with plugins and keymaps │ ├── tmux.nix # Tmux setup with vim-like navigation │ └── zsh.nix # Zsh with Powerlevel10k and modern CLI tools -└── config/ # Configuration files - └── p10k.zsh # Powerlevel10k theme configuration +├── config/ # Configuration files +│ ├── p10k.zsh # Powerlevel10k theme configuration +│ └── projects.nix # Project shortcuts configuration +└── scripts/ # Utility scripts + ├── project-launcher.sh # Universal project launcher + └── templates/ # Tmux session templates + ├── basic.sh # Basic development template + ├── content.sh # Content workflow template + └── research.sh # Research workflow template ``` ## 🛠️ Software Configurations @@ -155,6 +162,32 @@ hm # home-manager shortcut hms # Quick home-manager switch ``` +### 🚀 Project Shortcuts + +**Configuration**: `config/projects.nix` +**Purpose**: Quick access to project workspaces with tmux sessions + +#### Available Projects: +- **`blog`**: Personal blog with code + content workflow +- **`mdshortcut`**: Material Design Shortcut research project (code + paper) +- **`nix-config`**: Nix configuration with basic development workflow + +#### Usage: +```bash +proj # List all available projects +blog # Launch blog project tmux session +mdshortcut # Launch MDShortcut project tmux session +nix-config # Launch nix-config project tmux session +``` + +#### Template Types: +- **Basic**: Single directory (nvim + ai + git + shell) +- **Content**: Code directory + separate content directory +- **Research**: Code directory + separate paper directory + +#### Adding New Projects: +Edit `config/projects.nix` and run `hms` to rebuild configuration. + ### 🌟 Git Visualization **Tool**: gitui diff --git a/config/projects.nix b/config/projects.nix new file mode 100644 index 0000000..50c012e --- /dev/null +++ b/config/projects.nix @@ -0,0 +1,26 @@ +{ + projects = { + blog = { + template = "content"; + name = "blog"; + codePath = "/Users/yanlin/Documents/Projects/personal-blog"; + contentPath = "/Users/yanlin/Documents/Projects/personal-blog/content"; + description = "Personal blog project"; + }; + + mdshortcut = { + template = "research"; + name = "MDShortcut"; + codePath = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-dev"; + paperPath = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-paper"; + description = "Material Design Shortcut research project"; + }; + + nix-config = { + template = "basic"; + name = "nix"; + codePath = "/Users/yanlin/.config/nix"; + description = "Nix configuration"; + }; + }; +} \ No newline at end of file diff --git a/modules/zsh.nix b/modules/zsh.nix index 8725e18..baff3e2 100644 --- a/modules/zsh.nix +++ b/modules/zsh.nix @@ -1,5 +1,9 @@ { pkgs, ... }: +let + projectsConfig = import ../config/projects.nix; + projectLauncher = ../scripts/project-launcher.sh; +in { programs.zsh = { enable = true; @@ -32,7 +36,18 @@ # Nix helpers hm = "home-manager"; hms = "home-manager switch --flake ~/.config/nix#yanlin"; - }; + + # Project shortcuts + proj = "${projectLauncher}"; + } // ( + # Generate project aliases dynamically + builtins.listToAttrs ( + builtins.map (projectName: { + name = projectName; + value = "${projectLauncher} ${projectName}"; + }) (builtins.attrNames projectsConfig.projects) + ) + ); initContent = '' # Load Powerlevel10k theme @@ -95,4 +110,7 @@ # Manage Powerlevel10k configuration home.file.".p10k.zsh".source = ../config/p10k.zsh; + + # Generate projects.json for shell scripts + home.file.".config/nix/config/projects.json".text = builtins.toJSON projectsConfig; } \ No newline at end of file diff --git a/scripts/project-launcher.sh b/scripts/project-launcher.sh new file mode 100755 index 0000000..56b468b --- /dev/null +++ b/scripts/project-launcher.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Universal project launcher - reads project config and launches appropriate template +# Usage: project-launcher.sh PROJECT_NAME + +PROJECT_NAME="$1" +CONFIG_DIR="$(dirname "$0")/../config" +PROJECTS_JSON="$CONFIG_DIR/projects.json" +TEMPLATES_DIR="$(dirname "$0")/templates" + +if [ -z "$PROJECT_NAME" ]; then + echo "Available projects:" + if [ -f "$PROJECTS_JSON" ]; then + jq -r '.projects | keys[]' "$PROJECTS_JSON" 2>/dev/null || echo "No projects configured" + else + echo "No projects configured - run 'home-manager switch' to generate config" + fi + exit 1 +fi + +if [ ! -f "$PROJECTS_JSON" ]; then + echo "Error: Projects configuration not found. Run 'home-manager switch' to generate config." + exit 1 +fi + +# Extract project configuration +PROJECT_CONFIG=$(jq -r ".projects.\"$PROJECT_NAME\"" "$PROJECTS_JSON" 2>/dev/null) +if [ "$PROJECT_CONFIG" = "null" ]; then + echo "Error: Project '$PROJECT_NAME' not found." + echo "Available projects:" + jq -r '.projects | keys[]' "$PROJECTS_JSON" 2>/dev/null + exit 1 +fi + +TEMPLATE=$(echo "$PROJECT_CONFIG" | jq -r '.template') +SESSION_NAME=$(echo "$PROJECT_CONFIG" | jq -r '.name') +CODE_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.codePath') +CONTENT_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.contentPath // empty') +PAPER_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.paperPath // empty') + +# Launch appropriate template +case "$TEMPLATE" in + "basic") + exec "$TEMPLATES_DIR/basic.sh" "$SESSION_NAME" "$CODE_PATH" + ;; + "content") + if [ -z "$CONTENT_PATH" ]; then + echo "Error: Content template requires contentPath" + exit 1 + fi + exec "$TEMPLATES_DIR/content.sh" "$SESSION_NAME" "$CODE_PATH" "$CONTENT_PATH" + ;; + "research") + if [ -z "$PAPER_PATH" ]; then + echo "Error: Research template requires paperPath" + exit 1 + fi + exec "$TEMPLATES_DIR/research.sh" "$SESSION_NAME" "$CODE_PATH" "$PAPER_PATH" + ;; + *) + echo "Error: Unknown template '$TEMPLATE'" + exit 1 + ;; +esac \ No newline at end of file diff --git a/scripts/templates/basic.sh b/scripts/templates/basic.sh new file mode 100755 index 0000000..0372170 --- /dev/null +++ b/scripts/templates/basic.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Basic development template - single directory with nvim, ai, git, shell +# Usage: basic.sh SESSION_NAME CODE_PATH + +SESSION_NAME="$1" +CODE_PATH="$2" + +if [ -z "$SESSION_NAME" ] || [ -z "$CODE_PATH" ]; then + echo "Usage: $0 SESSION_NAME CODE_PATH" + exit 1 +fi + +if tmux has-session -t $SESSION_NAME 2>/dev/null; then + tmux attach-session -t $SESSION_NAME + exit 0 +fi + +tmux new-session -d -s $SESSION_NAME -c "$CODE_PATH" +tmux rename-window -t $SESSION_NAME:1 "nvim" +tmux send-keys -t $SESSION_NAME:1 "nvim" C-m +tmux new-window -t $SESSION_NAME:2 -n "ai" +tmux send-keys -t $SESSION_NAME:2 "claude -r" C-m +tmux split-window -t $SESSION_NAME:2 -h +tmux split-window -t $SESSION_NAME:2.2 -v +tmux select-pane -t $SESSION_NAME:2.1 +tmux new-window -t $SESSION_NAME:3 -n "git" +tmux send-keys -t $SESSION_NAME:3 "gitui" C-m +tmux new-window -t $SESSION_NAME:4 -n "shell" + +tmux select-window -t $SESSION_NAME:1 + +tmux attach-session -t $SESSION_NAME \ No newline at end of file diff --git a/scripts/templates/content.sh b/scripts/templates/content.sh new file mode 100755 index 0000000..d6c1cc0 --- /dev/null +++ b/scripts/templates/content.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Content workflow template - code + separate content directory +# Usage: content.sh SESSION_NAME CODE_PATH CONTENT_PATH + +SESSION_NAME="$1" +CODE_PATH="$2" +CONTENT_PATH="$3" + +if [ -z "$SESSION_NAME" ] || [ -z "$CODE_PATH" ] || [ -z "$CONTENT_PATH" ]; then + echo "Usage: $0 SESSION_NAME CODE_PATH CONTENT_PATH" + exit 1 +fi + +if tmux has-session -t $SESSION_NAME 2>/dev/null; then + tmux attach-session -t $SESSION_NAME + exit 0 +fi + +# Create windows for code +tmux new-session -d -s $SESSION_NAME -c "$CODE_PATH" +tmux rename-window -t $SESSION_NAME:1 "code" +tmux send-keys -t $SESSION_NAME:1 "nvim" C-m +tmux new-window -t $SESSION_NAME:2 -n "code-ai" -c "$CODE_PATH" +tmux send-keys -t $SESSION_NAME:2 "claude -r" C-m +tmux split-window -t $SESSION_NAME:2 -h -c "$CODE_PATH" +tmux split-window -t $SESSION_NAME:2.2 -v -c "$CODE_PATH" +tmux select-pane -t $SESSION_NAME:2.1 +tmux new-window -t $SESSION_NAME:3 -n "git" -c "$CODE_PATH" +tmux send-keys -t $SESSION_NAME:3 "gitui" C-m + +# Create windows for content +tmux new-window -t $SESSION_NAME:4 -n "content-ai" -c "$CONTENT_PATH" +tmux send-keys -t $SESSION_NAME:4 "claude -r" C-m +tmux split-window -t $SESSION_NAME:4 -h -c "$CONTENT_PATH" +tmux split-window -t $SESSION_NAME:4.2 -v -c "$CONTENT_PATH" +tmux select-pane -t $SESSION_NAME:4.1 + +tmux select-window -t $SESSION_NAME:1 + +tmux attach-session -t $SESSION_NAME \ No newline at end of file diff --git a/scripts/templates/research.sh b/scripts/templates/research.sh new file mode 100755 index 0000000..198235e --- /dev/null +++ b/scripts/templates/research.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Research workflow template - code + separate paper directory +# Usage: research.sh SESSION_NAME CODE_PATH PAPER_PATH + +SESSION_NAME="$1" +CODE_PATH="$2" +PAPER_PATH="$3" + +if [ -z "$SESSION_NAME" ] || [ -z "$CODE_PATH" ] || [ -z "$PAPER_PATH" ]; then + echo "Usage: $0 SESSION_NAME CODE_PATH PAPER_PATH" + exit 1 +fi + +if tmux has-session -t $SESSION_NAME 2>/dev/null; then + tmux attach-session -t $SESSION_NAME + exit 0 +fi + +# Create windows for code +tmux new-session -d -s $SESSION_NAME -c "$CODE_PATH" +tmux rename-window -t $SESSION_NAME:1 "code" +tmux send-keys -t $SESSION_NAME:1 "nvim" C-m +tmux new-window -t $SESSION_NAME:2 -n "code-ai" -c "$CODE_PATH" +tmux send-keys -t $SESSION_NAME:2 "claude -r" C-m +tmux split-window -t $SESSION_NAME:2 -h -c "$CODE_PATH" +tmux split-window -t $SESSION_NAME:2.2 -v -c "$CODE_PATH" +tmux select-pane -t $SESSION_NAME:2.1 + +# Create windows for paper +tmux new-window -t $SESSION_NAME:3 -n "paper" -c "$PAPER_PATH" +tmux select-window -t $SESSION_NAME:3 +tmux send-keys -t $SESSION_NAME:3 "nvim" C-m +tmux new-window -t $SESSION_NAME:4 -n "paper-ai" -c "$PAPER_PATH" +tmux send-keys -t $SESSION_NAME:4 "claude -r" C-m +tmux split-window -t $SESSION_NAME:4 -h -c "$PAPER_PATH" +tmux split-window -t $SESSION_NAME:4.2 -v -c "$PAPER_PATH" +tmux select-pane -t $SESSION_NAME:4.1 + +tmux select-window -t $SESSION_NAME:1 + +tmux attach-session -t $SESSION_NAME \ No newline at end of file