#!/usr/bin/env python3 """Quick editor for dotfiles directories""" import os import subprocess import sys from pathlib import Path DOTFILES_DIR = Path.home() / "dotfiles" def find_config_dir(base_dir): """Find the actual config directory within a dotfiles package.""" base_path = Path(base_dir) # Common patterns: .config/package, .config/package/package, etc. common_paths = [ base_path / ".config" / base_path.name, # ~/dotfiles/niri/.config/niri base_path / ".config", # ~/dotfiles/niri/.config base_path, # fallback to base ] # Check for .config/package pattern first config_package = base_path / ".config" / base_path.name if config_package.exists() and config_package.is_dir(): return config_package # Check for .config directory config_dir = base_path / ".config" if config_dir.exists() and config_dir.is_dir(): return config_dir # Fallback to base directory return base_path def get_dotfiles_dirs(): """Get list of dotfiles directories with their config paths.""" if not DOTFILES_DIR.exists(): return [] dirs = [] for item in sorted(DOTFILES_DIR.iterdir()): if item.is_dir() and not item.name.startswith("."): config_path = find_config_dir(item) dirs.append((item.name, config_path)) return dirs def main(): dirs_configs = get_dotfiles_dirs() if not dirs_configs: sys.exit(1) # Format with icons/emojis for better visual appeal formatted_dirs = [] name_to_config = {} icons = { "niri": "🪟", "zsh": "🐚", "alacritty": "💻", "kitty": "🐱", "ghostty": "👻", "git": "📦", "fuzzel": "🔍", "nvim": "⚡", "vim": "⚡", "tmux": "📺", "zellij": "📺", "env": "🌍", "fonts": "🔤", "applications": "📱", } for dir_name, config_path in dirs_configs: icon = icons.get(dir_name.lower(), "📁") formatted_dirs.append(f"{icon} {dir_name}") name_to_config[dir_name] = config_path # Present in fuzzel with styling fuzzel_process = subprocess.Popen( [ "fuzzel", "--dmenu", "--prompt", "📝 Edit: ", "--width", "40", "--lines", "15", "--border-width", "2", "--background-color", "#191724ff", "--text-color", "#e0def4ff", "--match-color", "#31748fff", "--selection-color", "#1f1d2eff", "--selection-text-color", "#31748fff", "--selection-match-color", "#31748fff", "--prompt-color", "#f6c177ff", ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, ) stdout, _ = fuzzel_process.communicate(input="\n".join(formatted_dirs)) selected = stdout.strip() if not selected: sys.exit(0) # Remove icon and extract directory name selected_dir = selected.split(" ", 1)[-1] if " " in selected else selected selected_path = name_to_config.get(selected_dir) if not selected_path or not selected_path.is_dir(): sys.exit(1) # Open alacritty with nvim in the actual config directory subprocess.Popen( ["alacritty", f"--working-directory={selected_path}", "-e", "nvim"], start_new_session=True, ) if __name__ == "__main__": main()