diff --git a/.gitignore b/.gitignore index b85fe63..18fb33f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,12 +3,21 @@ .DS_Store *test.* package-lock.json -config/starship/starship-default.toml # Folders -node_modules -.codacy +node_modules/ +.codacy/ # AI .github/instructions/codacy.instructions.md .claude/ +plan.md +CLAUDE.md +GEMINI.md +doc/ + +# Added by ggshield +.cache_ggshield + +# Temp +.hasrc diff --git a/bin/boiler-bash.sh b/bin/boiler-bash.sh new file mode 100755 index 0000000..9fb36c2 --- /dev/null +++ b/bin/boiler-bash.sh @@ -0,0 +1,397 @@ +#!/usr/bin/env bash +# +# boilerplate.sh — Bash template: subcommands, short+long options with +# bundling (-vF), glued values (-fconfig, --file=config), +# logging, and per-command --help. +# +# Usage: +# ./boilerplate.sh [global options] [command options] [args] +# +# Examples: +# ./boilerplate.sh -vf config.txt add widget # bundled: -v + -f config.txt +# ./boilerplate.sh -vfconfig.txt add widget # same, value glued to -f +# ./boilerplate.sh add -F widget gadget +# ./boilerplate.sh add --help +# ./boilerplate.sh help add +# +# Compatibility: Bash 3.2+ (macOS default), Linux, WSL. +# No getopts (short-only), no getopt (GNU-only, broken on macOS). +# +# Architecture: +# 1. _normalize_args expands bundled/glued short options into canonical +# "-x" / "-x value" tokens (this is the same job getopts does internally). +# 2. A plain while/case loop then parses the canonical tokens. +# Each parsing stage (global, per-command) declares its own option spec. + +# ------------------------------------------------------------------------------ +# Safety settings +# ------------------------------------------------------------------------------ +# -e : exit immediately if any command fails +# -u : treat unset variables as an error (catches typos in variable names) +# -o pipefail : a pipeline fails if ANY command in it fails, not just the last +set -euo pipefail + +# ------------------------------------------------------------------------------ +# Script metadata +# ------------------------------------------------------------------------------ +readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")" +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly VERSION="0.3.0" + +# ------------------------------------------------------------------------------ +# Defaults (overridden by flags) +# ------------------------------------------------------------------------------ +VERBOSE=0 # -v / --verbose → 1, and DEBUG logs become visible +CONFIG_FILE="" # -f / --file +LOG_LEVEL="INFO" # minimum level printed: DEBUG < INFO < WARN < ERROR + +# ============================================================================== +# LOGGING +# ============================================================================== + +# Map a level name to a number so levels can be compared. +# (A case statement instead of an associative array keeps Bash 3.2 compat.) +_log_level_num() { + case "$1" in + DEBUG) echo 0 ;; + INFO) echo 1 ;; + WARN) echo 2 ;; + ERROR) echo 3 ;; + *) echo 1 ;; + esac +} + +# Core logger. Everything goes to stderr so stdout stays clean for real +# output — this lets you pipe your script's results without log noise. +_log() { + local level="$1"; shift + local msg="$*" + + local want have + want="$(_log_level_num "$level")" + have="$(_log_level_num "$LOG_LEVEL")" + [ "$want" -lt "$have" ] && return 0 + + # Color only when stderr is a terminal (not when redirected to a file) + local color="" reset="" + if [ -t 2 ]; then + reset="\033[0m" + case "$level" in + DEBUG) color="\033[0;36m" ;; # cyan + INFO) color="\033[0;32m" ;; # green + WARN) color="\033[0;33m" ;; # yellow + ERROR) color="\033[0;31m" ;; # red + esac + fi + + printf "%b[%s] %-5s%b %s\n" \ + "$color" "$(date '+%Y-%m-%d %H:%M:%S')" "$level" "$reset" "$msg" >&2 +} + +log_debug() { _log DEBUG "$@"; } +log_info() { _log INFO "$@"; } +log_warn() { _log WARN "$@"; } +log_error() { _log ERROR "$@"; } + +# Log an error and exit. Optional second arg sets the exit code. +die() { + log_error "$1" + exit "${2:-1}" +} + +# ============================================================================== +# CLEANUP +# ============================================================================== + +# Runs on ANY exit — success, failure, or Ctrl+C. +cleanup() { + local exit_code=$? + log_debug "Cleanup running (exit code: ${exit_code})" + # rm -f "$TMP_FILE" 2>/dev/null || true +} +trap cleanup EXIT + +# ============================================================================== +# OPTION NORMALIZER +# ============================================================================== +# Expands bundled short options into canonical one-flag-per-token form so the +# parse loops stay dead simple. This is exactly the preprocessing getopts does +# internally — we just do it ourselves so long options can coexist. +# +# -vF → -v -F +# -vf conf.txt → -v -f conf.txt +# -vfconf.txt → -v -f conf.txt (value glued to the last flag) +# --file=x → passed through untouched (the parse loop splits '=') +# -- a b → passed through untouched (end-of-options marker) +# +# Arguments: +# $1 option spec, getopts-style: letters, ':' after any flag that takes a +# value. Example: "f:vhV" = -f takes a value; -v -h -V are booleans. +# $2 mode: +# "stop" → stop normalizing at the first positional token (used for +# the GLOBAL stage, where the first positional is the +# command and its args belong to a DIFFERENT spec) +# "mixed" → normalize the whole line (used inside commands, where +# options and positionals may be freely interleaved) +# $@ the arguments to normalize +# +# Output: sets the global array NORMALIZED_ARGS. (Bash 3.2 has no namerefs, +# so a well-known global is the portable way to "return" an array.) +_normalize_args() { + local spec="$1" mode="$2" + shift 2 + NORMALIZED_ARGS=() + + while [ $# -gt 0 ]; do + case "$1" in + --) + # End-of-options: keep the marker and everything after it verbatim + NORMALIZED_ARGS+=("$@") + break + ;; + --*) + # Long option: pass through; the parse loop handles --opt=value + NORMALIZED_ARGS+=("$1"); shift + ;; + -?*) + # One or more short flags in a single token. Peel one char at a time. + local bundle="${1#-}"; shift + while [ -n "$bundle" ]; do + local flag="${bundle:0:1}" + bundle="${bundle:1}" + case "$spec" in + *"${flag}:"*) + # This flag takes a value. + if [ -n "$bundle" ]; then + # Rest of the token IS the value: -fconf.txt + NORMALIZED_ARGS+=("-${flag}" "$bundle") + bundle="" + else + # Value must be the next token: -f conf.txt + # Emit the flag; the parse loop consumes (and validates) it. + NORMALIZED_ARGS+=("-${flag}") + fi + ;; + *"${flag}"*) + # Boolean flag — emit and continue peeling the bundle + NORMALIZED_ARGS+=("-${flag}") + ;; + *) + # Unknown flag. Emit it anyway; the parse loop owns error + # reporting so all "unknown option" messages look identical. + NORMALIZED_ARGS+=("-${flag}") + ;; + esac + done + ;; + *) + # Positional token (includes a bare '-', the stdin convention) + if [ "$mode" = "stop" ]; then + # Global stage: this is the command — its args are not ours to touch + NORMALIZED_ARGS+=("$@") + break + fi + NORMALIZED_ARGS+=("$1"); shift + ;; + esac + done +} + +# ============================================================================== +# HELP / USAGE +# ============================================================================== + +usage() { + cat < [command options] [args] + +Global options: + -f, --file Path to config file (also: --file=, -f) + -v, --verbose Verbose output (show DEBUG logs) + -h, --help Show this help + -V, --version Show version + +Short flags may be bundled: -vf config.txt + +Commands: + help [command] Show help (optionally for a specific command) + add Add an item + version Show version + +Run '${SCRIPT_NAME} --help' for command-specific options. +EOF +} + +# ============================================================================== +# COMMANDS +# ============================================================================== +# Conventions: +# cmd_ — the command itself; normalizes + parses its OWN options +# cmd__help — that command's help text, reachable two ways: +# ./script --help +# ./script help + +# --- help --------------------------------------------------------------------- + +cmd_help() { + # 'help' with an argument shows that command's help; bare 'help' shows global. + if [ $# -ge 1 ]; then + case "$1" in + add) cmd_add_help ;; + version) echo "Usage: ${SCRIPT_NAME} version — prints the version." ;; + help) echo "Very meta. Usage: ${SCRIPT_NAME} help [command]" ;; + *) die "No help available: unknown command '$1'" ;; + esac + else + usage + fi +} + +# --- version ------------------------------------------------------------------ + +cmd_version() { + echo "${SCRIPT_NAME} v${VERSION}" +} + +# --- add ---------------------------------------------------------------------- + +cmd_add_help() { + cat < [...] + +Add one or more items. + +Options: + -F, --force Overwrite if the item already exists + -h, --help Show this help + +Short flags may be bundled: -Fh + +Examples: + ${SCRIPT_NAME} add widget + ${SCRIPT_NAME} add -F widget gadget +EOF +} + +cmd_add() { + # Expand any bundles against THIS command's spec ("Fh": both boolean), + # then reset the positional parameters to the canonical form. + _normalize_args "Fh" "mixed" "$@" + set -- ${NORMALIZED_ARGS[@]+"${NORMALIZED_ARGS[@]}"} + + local force=0 + local items=() + + # Options and positional args can be freely mixed (add widget -F works). + while [ $# -gt 0 ]; do + case "$1" in + -F|--force) force=1; shift ;; + -h|--help) cmd_add_help; exit 0 ;; + --) shift; items+=("$@"); break ;; # everything after -- is positional + -*) die "Unknown option for 'add': $1 (see '${SCRIPT_NAME} add --help')" ;; + *) items+=("$1"); shift ;; + esac + done + + # NOTE: ${items[@]+"${items[@]}"} instead of "${items[@]}". + # Under 'set -u', Bash 3.2 treats an EMPTY array as unset and errors out. + # This expansion idiom means: "expand the array only if it has elements." + if [ "${#items[@]}" -eq 0 ]; then + die "add requires at least one item. See '${SCRIPT_NAME} add --help'" + fi + + log_debug "cmd_add: force=${force}, items=${#items[@]}" + + if [ -n "$CONFIG_FILE" ]; then + log_debug "Using config file: ${CONFIG_FILE}" + [ -f "$CONFIG_FILE" ] || die "Config file not found: ${CONFIG_FILE}" + fi + + local item + for item in ${items[@]+"${items[@]}"}; do + # --- actual work goes here --- + if [ "$force" -eq 1 ]; then + log_info "Added (forced): ${item}" + else + log_info "Added: ${item}" + fi + done +} + +# ============================================================================== +# GLOBAL ARGUMENT PARSING + DISPATCH +# ============================================================================== + +main() { + # --- 1. Normalize, then parse GLOBAL options --- + # Spec "f:vhV": -f takes a value; -v, -h, -V are booleans. + # Mode "stop": don't touch anything from the command onward — the command + # normalizes its own args against its own spec. + _normalize_args "f:vhV" "stop" "$@" + set -- ${NORMALIZED_ARGS[@]+"${NORMALIZED_ARGS[@]}"} + + while [ $# -gt 0 ]; do + case "$1" in + -f|--file) + # Value in the NEXT argument: --file config.txt / -f config.txt + [ $# -ge 2 ] || die "Option $1 requires a value." + CONFIG_FILE="$2" + shift 2 + ;; + --file=*) + # Value glued on with '=': --file=config.txt + # ${1#*=} strips everything up to and including the first '=' + CONFIG_FILE="${1#*=}" + shift + ;; + -v|--verbose) + VERBOSE=1 + LOG_LEVEL="DEBUG" + shift + ;; + -h|--help) + usage; exit 0 + ;; + -V|--version) + cmd_version; exit 0 + ;; + --) + # Explicit end-of-options marker + shift; break + ;; + -*) + die "Unknown global option: $1. Run '${SCRIPT_NAME} help' for usage." + ;; + *) + # First non-option token = the command. Stop parsing globals here. + break + ;; + esac + done + + log_debug "Verbose mode on (VERBOSE=${VERBOSE})" + log_debug "Args after global parsing: $*" + + # --- 2. Require a command --- + if [ $# -eq 0 ]; then + log_error "No command given." + usage + exit 1 + fi + + local command="$1"; shift # $@ now belongs to the command + + # --- 3. Dispatch --- + case "$command" in + help) cmd_help "$@" ;; + add) cmd_add "$@" ;; + version) cmd_version "$@" ;; + *) die "Unknown command: '${command}'. Run '${SCRIPT_NAME} help' for usage." ;; + esac +} + +main "$@" \ No newline at end of file diff --git a/bin/boiler-python.py b/bin/boiler-python.py new file mode 100755 index 0000000..bc744aa --- /dev/null +++ b/bin/boiler-python.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +"""Boilerplate for a small automation CLI with subcommands. + +Usage: + ./cli.py --help + ./cli.py greet Pavel --upper + ./cli.py sync ./src ./dest --exclude .git --exclude node_modules --dry-run + ./cli.py clean ~/tmp --older-than 30 -vv +""" + +from __future__ import annotations + +import argparse +import logging +import sys +from pathlib import Path + +__version__ = "0.1.0" + +log = logging.getLogger("cli") + + +# -------------------------------------------------------------------------- +# Command handlers +# Each one receives the parsed args namespace and returns an exit code. +# -------------------------------------------------------------------------- + +def cmd_greet(args: argparse.Namespace) -> int: + message = f"Hello, {args.name}!" + if args.upper: + message = message.upper() + for _ in range(args.repeat): + print(message) + return 0 + + +def cmd_sync(args: argparse.Namespace) -> int: + log.debug("source=%s dest=%s exclude=%s", args.source, args.dest, args.exclude) + + if not args.source.exists(): + log.error("Source does not exist: %s", args.source) + return 1 + + if args.dry_run: + log.info("[dry-run] would sync %s -> %s", args.source, args.dest) + return 0 + + log.info("Syncing %s -> %s", args.source, args.dest) + # ... real work here ... + return 0 + + +def cmd_clean(args: argparse.Namespace) -> int: + log.info("Cleaning %s (older than %d days)", args.target, args.older_than) + if args.dry_run: + log.info("[dry-run] nothing was deleted") + return 0 + + +# -------------------------------------------------------------------------- +# Parser construction +# -------------------------------------------------------------------------- + +def build_parser() -> argparse.ArgumentParser: + # Flags every command shares. add_help=False keeps it from fighting with + # the real -h on each subparser. + # default=SUPPRESS is load-bearing: without it the subparser writes its own + # defaults over anything parsed before the subcommand name. + common = argparse.ArgumentParser(add_help=False) + common.add_argument( + "-v", "--verbose", + action="count", + default=argparse.SUPPRESS, + help="increase verbosity (-v info, -vv debug)", + ) + common.add_argument( + "-q", "--quiet", + action="store_true", + default=argparse.SUPPRESS, + help="suppress all but errors", + ) + common.add_argument( + "-n", "--dry-run", + action="store_true", + default=argparse.SUPPRESS, + help="show what would happen without doing it", + ) + + parser = argparse.ArgumentParser( + prog="cli", + description="Small automation helper.", + parents=[common], + ) + parser.add_argument( + "--version", + action="version", + version=f"%(prog)s {__version__}", + ) + + sub = parser.add_subparsers( + dest="command", + metavar="COMMAND", + required=True, + ) + + # --- greet --- + p_greet = sub.add_parser( + "greet", + parents=[common], + help="print a greeting", + ) + p_greet.add_argument("name", help="who to greet") + p_greet.add_argument( + "-u", "--upper", + action="store_true", + help="shout it", + ) + p_greet.add_argument( + "-r", "--repeat", + type=int, + default=1, + metavar="N", + help="print N times (default: %(default)s)", + ) + p_greet.set_defaults(func=cmd_greet) + + # --- sync --- + p_sync = sub.add_parser( + "sync", + parents=[common], + help="copy one tree to another", + ) + p_sync.add_argument("source", type=Path) + p_sync.add_argument("dest", type=Path) + p_sync.add_argument( + "-e", "--exclude", + action="append", + default=[], + metavar="PATTERN", + help="skip paths matching PATTERN (repeatable)", + ) + p_sync.add_argument( + "--mode", + choices=("mirror", "additive"), + default="additive", + help="sync strategy (default: %(default)s)", + ) + p_sync.set_defaults(func=cmd_sync) + + # --- clean --- + p_clean = sub.add_parser( + "clean", + parents=[common], + help="remove stale files", + ) + p_clean.add_argument("target", type=Path) + p_clean.add_argument( + "--older-than", + type=int, + default=30, + metavar="DAYS", + help="age threshold in days (default: %(default)s)", + ) + p_clean.set_defaults(func=cmd_clean) + + return parser + + +def setup_logging(verbose: int, quiet: bool) -> None: + if quiet: + level = logging.ERROR + elif verbose >= 2: + level = logging.DEBUG + elif verbose == 1: + level = logging.INFO + else: + level = logging.WARNING + + logging.basicConfig( + level=level, + format="%(levelname)s: %(message)s", + stream=sys.stderr, + ) + + +# Because the shared flags use SUPPRESS, an unused flag is simply absent from +# the namespace. Fill in the real defaults here instead. +GLOBAL_DEFAULTS = {"verbose": 0, "quiet": False, "dry_run": False} + + +def main(argv: list[str] | None = None) -> int: + parser = build_parser() + args = parser.parse_args(argv) + + for key, value in GLOBAL_DEFAULTS.items(): + if not hasattr(args, key): + setattr(args, key, value) + + setup_logging(args.verbose, args.quiet) + + try: + return args.func(args) + except KeyboardInterrupt: + log.error("Interrupted") + return 130 + except Exception as exc: # noqa: BLE001 + log.error("%s", exc) + log.debug("Traceback:", exc_info=True) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/bin/checkDirtyRepos.sh b/bin/checkDirtyRepos.sh new file mode 100755 index 0000000..a2baecc --- /dev/null +++ b/bin/checkDirtyRepos.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# +# checkDirtyRepos.sh +# +# Scans a two-level-deep github.com/org/repo directory for repos with +# uncommitted changes or unpushed commits, and prints a bordered box +# summary — but only when there's something to report. Silent on a +# clean run. +# +# Self-contained: does NOT rely on the calling shell's variables +# (colors are defined below). Run it directly as an executable — +# it is not meant to be sourced. +# +# To run on every interactive shell, add this line to .zshrc: +# /path/to/check-repos.sh +# +# Compatible with bash 3.2+ (macOS system default) — no bash 4-only +# features (no `mapfile`, no associative arrays). + +shopt -s nullglob + +GITHUB_ROOT="${1:-/Users/psanchez/Documents/github.com}" +RED=$'\033[0;31m' # dirty / uncommitted changes +YELLOW=$'\033[0;33m' # unpushed commits +CYAN=$'\033[0;36m' # no upstream branch set +NC=$'\033[0m' + +# Phase 1 — data producer. Emits one plain (no color codes) line per +# issue found: " : ". +_scan_repos_raw() { + local root="$1" + [[ -d "$root" ]] || return + + for org_dir in "$root"/*/; do + for repo_dir in "${org_dir}"*/; do + [[ -d "${repo_dir}.git" ]] || continue + + ( + cd "$repo_dir" || exit + local org_name repo_name repo_label + org_name=$(basename "$org_dir") + repo_name=$(basename "$repo_dir") + repo_label="${org_name}/${repo_name}" + + local dirty_count + dirty_count=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ') + + local unpushed upstream_exit + unpushed=$(git log '@{u}..HEAD' --oneline 2>/dev/null) + upstream_exit=$? + + if [[ "$dirty_count" -gt 0 ]]; then + echo "* ${repo_label}: ${dirty_count} uncommitted change(s)" + fi + + if [[ $upstream_exit -eq 0 && -n "$unpushed" ]]; then + local ahead_count + ahead_count=$(echo "$unpushed" | wc -l | tr -d ' ') + echo "^ ${repo_label}: ${ahead_count} unpushed commit(s)" + elif [[ $upstream_exit -ne 0 ]]; then + echo "! ${repo_label}: no upstream branch set" + fi + ) + done + done +} + +# Phase 2 — presentation. Runs the scan, and only if something was +# found, draws it inside a bordered box sized to the longest line. +check_dirty_repos() { + local root="${1:-$GITHUB_ROOT}" + + local findings=() + while IFS= read -r line; do + [[ -n "$line" ]] && findings+=("$line") + done < <(_scan_repos_raw "$root") + + [[ ${#findings[@]} -eq 0 ]] && return + + local title=" Repos with unsaved work " + + local max_len=${#title} + local line + for line in "${findings[@]}"; do + (( ${#line} > max_len )) && max_len=${#line} + done + + local border="" + local i + for (( i = 0; i < max_len + 2; i++ )); do + border+="─" + done + + # Blank line up top for separation from whatever printed before this + # (previous command's output, shell prompt, etc.) + echo "" + + printf "┌%s┐\n" "$border" + printf "│ %-*s │\n" "$max_len" "$title" + printf "├%s┤\n" "$border" + for line in "${findings[@]}"; do + # Pad the PLAIN (uncolored) line to max_len first — padding must + # be computed on the visible text only. Only after padding is + # fixed do we wrap it in a color code, since escape sequences + # have zero visible width but nonzero byte length, and would + # throw off %-*s if included before padding. + local padded_line color + padded_line=$(printf "%-*s" "$max_len" "$line") + + case "${line:0:1}" in + "*") color="$RED" ;; # dirty / uncommitted changes + "^") color="$YELLOW" ;; # unpushed commits + "!") color="$CYAN" ;; # no upstream branch set + *) color="$NC" ;; + esac + + printf "│ %s%s%s │\n" "$color" "$padded_line" "$NC" + done + printf "└%s┘\n" "$border" +} + +check_dirty_repos "$GITHUB_ROOT" diff --git a/bin/dashboard.py b/bin/dashboard.py new file mode 100755 index 0000000..e32f32b --- /dev/null +++ b/bin/dashboard.py @@ -0,0 +1,664 @@ +#!/usr/bin/env python3 +""" +System Dashboard +A dark-themed desktop GUI showing CPU, RAM, Disk, Network, and Power Profile. +Requirements: pip install psutil --break-system-packages +""" + +import tkinter as tk +from tkinter import font +import psutil +import subprocess +import threading +import time +from collections import deque + +# ── Themes ──────────────────────────────────────────────────────────────────── + +THEMES = { + "dark": { + "BG": "#0e1117", + "CARD_BG": "#1a1f2e", + "BORDER": "#2a2f3e", + "TEXT": "#e2e8f0", + "MUTED": "#64748b", + }, + "light": { + "BG": "#f1f5f9", + "CARD_BG": "#ffffff", + "BORDER": "#cbd5e1", + "TEXT": "#0f172a", + "MUTED": "#94a3b8", + }, +} + +# ── Accent colors (shared across themes) ───────────────────────────────────── +ACCENT_BLUE = "#3b82f6" +ACCENT_GREEN = "#22c55e" +ACCENT_RED = "#ef4444" +ACCENT_AMBER = "#f59e0b" +ACCENT_PURP = "#a855f7" + +REFRESH_MS = 1000 +NET_HISTORY = 60 + +# ── Helpers ─────────────────────────────────────────────────────────────────── + +def bytes_to_human(n): + for unit in ("B", "KB", "MB", "GB", "TB"): + if n < 1024: + return f"{n:.1f} {unit}" + n /= 1024 + return f"{n:.1f} PB" + +def get_power_profile(): + try: + return subprocess.check_output( + ["powerprofilesctl", "get"], stderr=subprocess.DEVNULL + ).decode().strip() + except Exception: + try: + return subprocess.check_output( + ["cat", "/sys/firmware/acpi/platform_profile"], + stderr=subprocess.DEVNULL + ).decode().strip() + except Exception: + return "unavailable" + +def profile_color(profile): + p = profile.lower() + if "performance" in p: + return ACCENT_RED + if "power" in p or "saver" in p or "low" in p: + return ACCENT_GREEN + return ACCENT_AMBER + +# ── Card widget ─────────────────────────────────────────────────────────────── + +class Card(tk.Frame): + def __init__(self, parent, title, accent=ACCENT_BLUE, theme=None, **kwargs): + t = theme or {} + super().__init__(parent, bg=t.get("CARD_BG", "#1a1f2e"), + highlightbackground=t.get("BORDER", "#2a2f3e"), + highlightthickness=1, **kwargs) + self.accent = accent + self._theme = t + self._accent_bar = tk.Frame(self, bg=accent, height=3) + self._accent_bar.pack(fill="x") + self._title_lbl = tk.Label( + self, text=title, + bg=t.get("CARD_BG", "#1a1f2e"), + fg=t.get("MUTED", "#64748b"), + font=("SF Pro Display", 10, "bold") + ) + self._title_lbl.pack(anchor="w", padx=14, pady=(8, 0)) + + def apply_theme(self, t): + self._theme = t + self.config(bg=t["CARD_BG"], highlightbackground=t["BORDER"]) + self._title_lbl.config(bg=t["CARD_BG"], fg=t["MUTED"]) + # Recursively update all child frames/labels that aren't accent-colored + self._retheme_children(self, t) + + def _retheme_children(self, widget, t): + for child in widget.winfo_children(): + cls = child.winfo_class() + if cls == "Frame": + # Don't recolor the accent bar + if child is not self._accent_bar: + child.config(bg=t["CARD_BG"]) + self._retheme_children(child, t) + elif cls == "Label": + fg = child.cget("fg") + # Preserve accent-colored labels (stats, values) + if fg not in (t["TEXT"], t["MUTED"], THEMES["dark"]["TEXT"], + THEMES["dark"]["MUTED"], THEMES["light"]["TEXT"], + THEMES["light"]["MUTED"]): + child.config(bg=t["CARD_BG"]) + else: + child.config(bg=t["CARD_BG"]) + elif cls == "Canvas": + child.config(bg=t["CARD_BG"]) + +# ── Progress bar ────────────────────────────────────────────────────────────── + +class ProgressBar(tk.Canvas): + def __init__(self, parent, color=ACCENT_BLUE, height=6, theme=None, **kwargs): + t = theme or {} + super().__init__(parent, height=height, + bg=t.get("CARD_BG", "#1a1f2e"), + highlightthickness=0, **kwargs) + self.color = color + self._border_color = t.get("BORDER", "#2a2f3e") + self.bind("", self._on_resize) + self._pct = 0 + + def _on_resize(self, e): + self.set(self._pct) + + def set(self, pct): + self._pct = max(0, min(100, pct)) + self.delete("all") + w = self.winfo_width() + h = self.winfo_height() + if w < 2: + return + self.create_rectangle(0, 0, w, h, fill=self._border_color, outline="") + fill_w = int(w * self._pct / 100) + if fill_w > 0: + self.create_rectangle(0, 0, fill_w, h, fill=self.color, outline="") + + def apply_theme(self, t): + self._border_color = t["BORDER"] + self.config(bg=t["CARD_BG"]) + self.set(self._pct) + +# ── Settings Window ─────────────────────────────────────────────────────────── + +class SettingsWindow(tk.Toplevel): + def __init__(self, parent): + super().__init__(parent) + self.parent = parent + self.title("Settings") + self.resizable(False, False) + self.configure(bg=parent.theme["BG"]) + + # Keep on top, center over parent + self.transient(parent) + self.grab_set() + self.geometry("300x200") + self._center() + self._build() + + def _center(self): + self.update_idletasks() + px = self.parent.winfo_x() + self.parent.winfo_width() // 2 - 150 + py = self.parent.winfo_y() + self.parent.winfo_height() // 2 - 100 + self.geometry(f"+{px}+{py}") + + def _build(self): + t = self.parent.theme + pad = {"padx": 20, "pady": 10} + + tk.Label(self, text="SETTINGS", bg=t["BG"], fg=t["MUTED"], + font=("SF Pro Display", 10, "bold")).pack(anchor="w", padx=20, pady=(16, 4)) + + # Divider + tk.Frame(self, bg=t["BORDER"], height=1).pack(fill="x", padx=20) + + # Theme toggle + row1 = tk.Frame(self, bg=t["BG"]) + row1.pack(fill="x", **pad) + tk.Label(row1, text="Theme", bg=t["BG"], fg=t["TEXT"], + font=("SF Pro Display", 11)).pack(side="left") + + self._theme_var = tk.StringVar(value=self.parent.current_theme) + theme_btn = tk.Button( + row1, textvariable=self._theme_var, + bg=ACCENT_BLUE, fg="#ffffff", + font=("SF Pro Display", 10), + relief="flat", padx=12, pady=4, + cursor="hand2", + command=self._toggle_theme + ) + theme_btn.pack(side="right") + + # Graph toggle + row2 = tk.Frame(self, bg=t["BG"]) + row2.pack(fill="x", **pad) + tk.Label(row2, text="Network Graph", bg=t["BG"], fg=t["TEXT"], + font=("SF Pro Display", 11)).pack(side="left") + + self._graph_var = tk.StringVar(value="on" if self.parent.show_graph else "off") + graph_btn = tk.Button( + row2, textvariable=self._graph_var, + bg=ACCENT_GREEN if self.parent.show_graph else ACCENT_RED, + fg="#ffffff", + font=("SF Pro Display", 10), + relief="flat", padx=12, pady=4, + cursor="hand2", + command=self._toggle_graph + ) + self._graph_btn = graph_btn + graph_btn.pack(side="right") + + # Close button + tk.Button( + self, text="Close", + bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 10), + relief="flat", padx=12, pady=4, + cursor="hand2", + command=self.destroy + ).pack(side="bottom", pady=16) + + def _toggle_theme(self): + new = "light" if self.parent.current_theme == "dark" else "dark" + self.parent.apply_theme(new) + self._theme_var.set(new) + # Update settings window bg to match + t = self.parent.theme + self.configure(bg=t["BG"]) + for w in self.winfo_children(): + self._recolor(w, t) + + def _recolor(self, widget, t): + cls = widget.winfo_class() + if cls in ("Frame",): + try: widget.config(bg=t["BG"]) + except: pass + elif cls == "Label": + try: widget.config(bg=t["BG"]) + except: pass + for child in widget.winfo_children(): + self._recolor(child, t) + + def _toggle_graph(self): + self.parent.toggle_graph() + is_on = self.parent.show_graph + self._graph_var.set("on" if is_on else "off") + self._graph_btn.config(bg=ACCENT_GREEN if is_on else ACCENT_RED) + +# ── Main App ────────────────────────────────────────────────────────────────── + +class Dashboard(tk.Tk): + def __init__(self): + super().__init__() + self.title("System Dashboard") + self.resizable(True, True) + self.geometry("820x620") + self.minsize(700, 520) + + # App state + self.current_theme = "dark" + self.theme = THEMES["dark"] + self.show_graph = True + self.configure(bg=self.theme["BG"]) + + # Stat state + self._net_prev = psutil.net_io_counters() + self._disk_prev = psutil.disk_io_counters() + self._prev_time = time.time() + self._net_recv_hist = deque([0] * NET_HISTORY, maxlen=NET_HISTORY) + self._net_sent_hist = deque([0] * NET_HISTORY, maxlen=NET_HISTORY) + + # Track all progress bars and cards for theme updates + self._progress_bars = [] + self._cards = [] + + self._build_ui() + self._schedule_update() + + # ── Theme ───────────────────────────────────────────────────────────────── + + def apply_theme(self, name): + self.current_theme = name + self.theme = THEMES[name] + t = self.theme + self.configure(bg=t["BG"]) + self._hdr.config(bg=t["BG"]) + self._clock_lbl.config(bg=t["BG"], fg=t["MUTED"]) + self._title_lbl.config(bg=t["BG"], fg=t["TEXT"]) + self._gear_btn.config(bg=t["BG"], fg=t["MUTED"], activebackground=t["BG"]) + self._grid.config(bg=t["BG"]) + for card in self._cards: + card.apply_theme(t) + for pb in self._progress_bars: + pb.apply_theme(t) + + # ── Graph toggle ────────────────────────────────────────────────────────── + + def toggle_graph(self): + self.show_graph = not self.show_graph + if self.show_graph: + self._spark.pack(fill="x", pady=(10, 0)) + else: + self._spark.pack_forget() + + # ── UI Construction ─────────────────────────────────────────────────────── + + def _build_ui(self): + t = self.theme + + # Header + self._hdr = tk.Frame(self, bg=t["BG"]) + self._hdr.pack(fill="x", padx=20, pady=(16, 8)) + self._title_lbl = tk.Label( + self._hdr, text="⬡ SYSTEM DASHBOARD", + bg=t["BG"], fg=t["TEXT"], + font=("SF Pro Display", 14, "bold") + ) + self._title_lbl.pack(side="left") + + self._gear_btn = tk.Button( + self._hdr, text="⚙", + bg=t["BG"], fg=t["MUTED"], + font=("SF Pro Display", 16), + relief="flat", cursor="hand2", + activebackground=t["BG"], + command=self._open_settings + ) + self._gear_btn.pack(side="right") + + self._clock_lbl = tk.Label( + self._hdr, text="", + bg=t["BG"], fg=t["MUTED"], + font=("SF Pro Display", 10) + ) + self._clock_lbl.pack(side="right", padx=(0, 8)) + + # Grid + self._grid = tk.Frame(self, bg=t["BG"]) + self._grid.pack(fill="both", expand=True, padx=20, pady=(0, 20)) + self._grid.columnconfigure(0, weight=1) + self._grid.columnconfigure(1, weight=1) + + self._cpu_card = self._build_cpu_card(self._grid) + self._cpu_card.grid(row=0, column=0, sticky="nsew", padx=(0, 8), pady=(0, 8)) + + self._ram_card = self._build_ram_card(self._grid) + self._ram_card.grid(row=0, column=1, sticky="nsew", padx=(8, 0), pady=(0, 8)) + + self._disk_card = self._build_disk_card(self._grid) + self._disk_card.grid(row=1, column=0, sticky="nsew", padx=(0, 8), pady=(0, 8)) + + self._power_card = self._build_power_card(self._grid) + self._power_card.grid(row=1, column=1, sticky="nsew", padx=(8, 0), pady=(0, 8)) + + self._grid.rowconfigure(2, weight=1) + self._net_card = self._build_net_card(self._grid) + self._net_card.grid(row=2, column=0, columnspan=2, sticky="nsew") + + def _open_settings(self): + SettingsWindow(self) + + # ── CPU Card ────────────────────────────────────────────────────────────── + + def _build_cpu_card(self, parent): + t = self.theme + card = Card(parent, "CPU", accent=ACCENT_BLUE, theme=t) + self._cards.append(card) + body = tk.Frame(card, bg=t["CARD_BG"]) + body.pack(fill="both", expand=True, padx=14, pady=10) + + top = tk.Frame(body, bg=t["CARD_BG"]) + top.pack(fill="x") + self._cpu_pct_lbl = tk.Label(top, text="0%", bg=t["CARD_BG"], fg=t["TEXT"], + font=("SF Pro Display", 28, "bold")) + self._cpu_pct_lbl.pack(side="left") + self._cpu_freq_lbl = tk.Label(top, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 10)) + self._cpu_freq_lbl.pack(side="right", anchor="s", pady=6) + + self._cpu_bar = ProgressBar(body, color=ACCENT_BLUE, theme=t) + self._cpu_bar.pack(fill="x", pady=(6, 8)) + self._progress_bars.append(self._cpu_bar) + + cores = tk.Frame(body, bg=t["CARD_BG"]) + cores.pack(fill="x") + count = psutil.cpu_count(logical=True) + physical = psutil.cpu_count(logical=False) + tk.Label(cores, text=f"{physical} cores / {count} threads", + bg=t["CARD_BG"], fg=t["MUTED"], font=("SF Pro Display", 9)).pack(side="left") + self._cpu_temp_lbl = tk.Label(cores, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)) + self._cpu_temp_lbl.pack(side="right") + return card + + # ── RAM Card ────────────────────────────────────────────────────────────── + + def _build_ram_card(self, parent): + t = self.theme + card = Card(parent, "MEMORY", accent=ACCENT_PURP, theme=t) + self._cards.append(card) + body = tk.Frame(card, bg=t["CARD_BG"]) + body.pack(fill="both", expand=True, padx=14, pady=10) + + top = tk.Frame(body, bg=t["CARD_BG"]) + top.pack(fill="x") + self._ram_pct_lbl = tk.Label(top, text="0%", bg=t["CARD_BG"], fg=t["TEXT"], + font=("SF Pro Display", 28, "bold")) + self._ram_pct_lbl.pack(side="left") + self._ram_used_lbl = tk.Label(top, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 10)) + self._ram_used_lbl.pack(side="right", anchor="s", pady=6) + + self._ram_bar = ProgressBar(body, color=ACCENT_PURP, theme=t) + self._ram_bar.pack(fill="x", pady=(6, 8)) + self._progress_bars.append(self._ram_bar) + + self._ram_detail_lbl = tk.Label(body, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)) + self._ram_detail_lbl.pack(anchor="w") + return card + + # ── Disk Card ───────────────────────────────────────────────────────────── + + def _build_disk_card(self, parent): + t = self.theme + card = Card(parent, "STORAGE", accent=ACCENT_AMBER, theme=t) + self._cards.append(card) + body = tk.Frame(card, bg=t["CARD_BG"]) + body.pack(fill="both", expand=True, padx=14, pady=10) + + top = tk.Frame(body, bg=t["CARD_BG"]) + top.pack(fill="x") + self._disk_pct_lbl = tk.Label(top, text="0%", bg=t["CARD_BG"], fg=t["TEXT"], + font=("SF Pro Display", 28, "bold")) + self._disk_pct_lbl.pack(side="left") + self._disk_size_lbl = tk.Label(top, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 10)) + self._disk_size_lbl.pack(side="right", anchor="s", pady=6) + + self._disk_bar = ProgressBar(body, color=ACCENT_AMBER, theme=t) + self._disk_bar.pack(fill="x", pady=(6, 8)) + self._progress_bars.append(self._disk_bar) + + io = tk.Frame(body, bg=t["CARD_BG"]) + io.pack(fill="x") + self._disk_read_lbl = tk.Label(io, text="↓ --", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)) + self._disk_read_lbl.pack(side="left") + self._disk_write_lbl = tk.Label(io, text="↑ --", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)) + self._disk_write_lbl.pack(side="right") + return card + + # ── Power Card ──────────────────────────────────────────────────────────── + + def _build_power_card(self, parent): + t = self.theme + card = Card(parent, "POWER PROFILE", accent=ACCENT_GREEN, theme=t) + self._cards.append(card) + body = tk.Frame(card, bg=t["CARD_BG"]) + body.pack(fill="both", expand=True, padx=14, pady=10) + + self._power_lbl = tk.Label(body, text="—", bg=t["CARD_BG"], fg=ACCENT_GREEN, + font=("SF Pro Display", 22, "bold")) + self._power_lbl.pack(anchor="w", pady=(4, 0)) + self._power_dot = tk.Label(body, text="● active", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)) + self._power_dot.pack(anchor="w", pady=(4, 0)) + return card + + # ── Network Card ────────────────────────────────────────────────────────── + + def _build_net_card(self, parent): + t = self.theme + card = Card(parent, "NETWORK", accent=ACCENT_GREEN, theme=t) + self._cards.append(card) + body = tk.Frame(card, bg=t["CARD_BG"]) + body.pack(fill="both", expand=True, padx=14, pady=10) + + stats = tk.Frame(body, bg=t["CARD_BG"]) + stats.pack(fill="x") + + dl = tk.Frame(stats, bg=t["CARD_BG"]) + dl.pack(side="left", padx=(0, 30)) + tk.Label(dl, text="↓ DOWNLOAD", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)).pack(anchor="w") + self._net_dl_lbl = tk.Label(dl, text="0 B/s", bg=t["CARD_BG"], fg=ACCENT_GREEN, + font=("SF Pro Display", 20, "bold")) + self._net_dl_lbl.pack(anchor="w") + + ul = tk.Frame(stats, bg=t["CARD_BG"]) + ul.pack(side="left") + tk.Label(ul, text="↑ UPLOAD", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9)).pack(anchor="w") + self._net_ul_lbl = tk.Label(ul, text="0 B/s", bg=t["CARD_BG"], fg=ACCENT_BLUE, + font=("SF Pro Display", 20, "bold")) + self._net_ul_lbl.pack(anchor="w") + + totals = tk.Frame(stats, bg=t["CARD_BG"]) + totals.pack(side="right") + self._net_total_lbl = tk.Label(totals, text="", bg=t["CARD_BG"], fg=t["MUTED"], + font=("SF Pro Display", 9), justify="right") + self._net_total_lbl.pack(anchor="e") + + self._spark = tk.Canvas(body, bg=t["CARD_BG"], highlightthickness=0, height=60) + self._spark.pack(fill="x", pady=(10, 0)) + self._spark.bind("", lambda e: self._draw_sparkline()) + + return card + + # ── Sparkline ───────────────────────────────────────────────────────────── + + def _draw_sparkline(self): + c = self._spark + c.delete("all") + w = c.winfo_width() + h = c.winfo_height() + if w < 2 or h < 2: + return + + def draw_line(history, color): + mx = max(max(history), 1) + pts = [] + for i, v in enumerate(history): + x = int(i * w / (NET_HISTORY - 1)) + y = h - int(v / mx * h) + pts.append((x, y)) + if len(pts) > 1: + flat = [coord for pt in pts for coord in pt] + c.create_line(*flat, fill=color, width=1, smooth=True) + + draw_line(self._net_recv_hist, ACCENT_GREEN) + draw_line(self._net_sent_hist, ACCENT_BLUE) + + # ── Data Collection ─────────────────────────────────────────────────────── + + def _collect(self): + now = time.time() + elapsed = max(now - self._prev_time, 0.001) + self._prev_time = now + + cpu_pct = psutil.cpu_percent() + try: + freq = psutil.cpu_freq() + freq_str = f"{freq.current:.0f} MHz" + except Exception: + freq_str = "" + try: + temps = psutil.sensors_temperatures() + temp_val = None + for key in ("coretemp", "k10temp", "cpu_thermal", "acpitz"): + if key in temps and temps[key]: + temp_val = temps[key][0].current + break + temp_str = f"{temp_val:.0f}°C" if temp_val else "" + except Exception: + temp_str = "" + + ram = psutil.virtual_memory() + + disk = psutil.disk_usage("/") + try: + disk_io = psutil.disk_io_counters() + read_rate = (disk_io.read_bytes - self._disk_prev.read_bytes) / elapsed + write_rate = (disk_io.write_bytes - self._disk_prev.write_bytes) / elapsed + self._disk_prev = disk_io + except Exception: + read_rate = write_rate = 0 + + net = psutil.net_io_counters() + recv_rate = (net.bytes_recv - self._net_prev.bytes_recv) / elapsed + sent_rate = (net.bytes_sent - self._net_prev.bytes_sent) / elapsed + self._net_prev = net + self._net_recv_hist.append(recv_rate) + self._net_sent_hist.append(sent_rate) + + profile = get_power_profile() + + return { + "cpu_pct": cpu_pct, "freq": freq_str, "temp": temp_str, + "ram_pct": ram.percent, + "ram_used": bytes_to_human(ram.used), + "ram_total": bytes_to_human(ram.total), + "ram_avail": bytes_to_human(ram.available), + "disk_pct": disk.percent, + "disk_used": bytes_to_human(disk.used), + "disk_total": bytes_to_human(disk.total), + "disk_read": bytes_to_human(read_rate) + "/s", + "disk_write": bytes_to_human(write_rate) + "/s", + "net_recv": bytes_to_human(recv_rate) + "/s", + "net_sent": bytes_to_human(sent_rate) + "/s", + "net_total_recv": bytes_to_human(net.bytes_recv), + "net_total_sent": bytes_to_human(net.bytes_sent), + "profile": profile, + } + + # ── UI Update ───────────────────────────────────────────────────────────── + + def _update_ui(self, d): + t = self.theme + self._clock_lbl.config(text=time.strftime("%H:%M:%S")) + + pct = d["cpu_pct"] + color = ACCENT_RED if pct > 80 else ACCENT_AMBER if pct > 50 else ACCENT_BLUE + self._cpu_pct_lbl.config(text=f"{pct:.0f}%", fg=color) + self._cpu_freq_lbl.config(text=d["freq"]) + self._cpu_bar.color = color + self._cpu_bar.set(pct) + self._cpu_temp_lbl.config(text=d["temp"]) + + rpct = d["ram_pct"] + rcolor = ACCENT_RED if rpct > 85 else ACCENT_AMBER if rpct > 65 else ACCENT_PURP + self._ram_pct_lbl.config(text=f"{rpct:.0f}%", fg=rcolor) + self._ram_used_lbl.config(text=f"{d['ram_used']} / {d['ram_total']}") + self._ram_bar.color = rcolor + self._ram_bar.set(rpct) + self._ram_detail_lbl.config(text=f"Available: {d['ram_avail']}") + + dpct = d["disk_pct"] + dcolor = ACCENT_RED if dpct > 90 else ACCENT_AMBER if dpct > 70 else ACCENT_AMBER + self._disk_pct_lbl.config(text=f"{dpct:.0f}%", fg=dcolor) + self._disk_size_lbl.config(text=f"{d['disk_used']} / {d['disk_total']}") + self._disk_bar.color = dcolor + self._disk_bar.set(dpct) + self._disk_read_lbl.config(text=f"↓ {d['disk_read']}") + self._disk_write_lbl.config(text=f"↑ {d['disk_write']}") + + pc = profile_color(d["profile"]) + self._power_lbl.config(text=d["profile"].replace("-", " ").title(), fg=pc) + self._power_dot.config(fg=pc) + + self._net_dl_lbl.config(text=d["net_recv"]) + self._net_ul_lbl.config(text=d["net_sent"]) + self._net_total_lbl.config( + text=f"Total ↓ {d['net_total_recv']} ↑ {d['net_total_sent']}" + ) + if self.show_graph: + self._draw_sparkline() + + def _schedule_update(self): + def _worker(): + data = self._collect() + self.after(0, lambda: self._update_ui(data)) + self.after(REFRESH_MS, self._schedule_update) + threading.Thread(target=_worker, daemon=True).start() + +# ── Entry point ─────────────────────────────────────────────────────────────── + +if __name__ == "__main__": + app = Dashboard() + app.mainloop() \ No newline at end of file diff --git a/bin/overseerr_to_collection.py b/bin/overseerr_to_collection.py new file mode 100755 index 0000000..e22dadc --- /dev/null +++ b/bin/overseerr_to_collection.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +The use case of this script is the following: + Put all requested movies from overseerr in a collection in plex. + +Requirements (python3 -m pip install [requirement]): + requests + +Setup: + 1. Fill the variables below. + 2. Run the script in a terminal/shell with the "-h" flag to learn more about the parameters. + python3 overseerr_to_collection.py -h + or + python overseerr_to_collection.py -h + 3. Run this script at an interval to keep the collection updated. + Decide for yourself what the interval is (e.g. every 12h or every 2 days). + +Examples: + --LibraryName "Movies" --CollectionName "Requested Movies" + + Create a collection called "Requested Movies" in the library called + "Movies" with all requested movies in it (that are in that library). +""" + +from os import getenv +from typing import TYPE_CHECKING, List + +if TYPE_CHECKING: + from requests import Session + +# ===== FILL THESE VARIABLES ===== +plex_base_url = "http://192.168.20.2:32400" +plex_api_token = "edsPxGfaBhTFpejV-ai" +overseerr_base_url = "http://192.168.20.21:5055" +overseerr_api_token = ( + "MTczODQ3NjQyNzIxMDZhYmYyZjMxLWJlNTgtNGEzMy05MjZmLTEyNWIxZmI3NTUxNA==" +) +# ================================ + +# Environmental Variables +plex_base_url = getenv("plex_base_url", plex_base_url) +plex_api_token = getenv("plex_api_token", plex_api_token) +overseerr_base_url = getenv("overseerr_base_url", overseerr_base_url) +overseerr_api_token = getenv("overseerr_api_token", overseerr_api_token) +p_base_url = plex_base_url.rstrip("/") +o_base_url = overseerr_base_url.rstrip("/") + "/api/v1" + + +def overseerr_to_collection( + plex_ssn: "Session", + overseerr_ssn: "Session", + library_name: str, + collection_name: str = "Overseerr Requests", +) -> List[int]: + """Put all requested movies from overseerr in a collection in plex. + + Args: + plex_ssn (Session): The plex requests session to fetch with. + + overseerr_ssn (Session): The overseerr requests session to fetch with. + + library_name (str): Movie library to put the collection in. + + collection_name (str, optional): Name of the collection. + Defaults to "Overseerr Requests". + + Raises: + ValueError: Library not found. + + Returns: + List[int]: List of media rating keys that are in the collection. + """ + result_json = [] + + # Find plex library + sections = ( + plex_ssn.get(f"{p_base_url}/library/sections") + .json()["MediaContainer"] + .get("Directory", []) + ) + + for lib in sections: + if lib["title"] == library_name: + break + else: + raise ValueError("Library not found") + + # Note down plex rating key of every requested and downloaded + # movie in overseerr + + offset = 0 + while 1: + requests: List[dict] = ( + overseerr_ssn.get( + f"{o_base_url}/request", + params={"filter": "available", "take": 50, "skip": offset}, + ) + .json() + .get("results", []) + ) + + if not requests: + break + + for request in requests: + if request["type"] != "movie": + continue + + if request["media"]["ratingKey4k"]: + result_json.append(request["media"]["ratingKey4k"]) + + elif request["media"]["ratingKey"]: + result_json.append(request["media"]["ratingKey"]) + + offset += 50 + + # Delete collection if it exists + collections = ( + plex_ssn.get(f"{p_base_url}/library/sections/{lib['key']}/collections") + .json()["MediaContainer"] + .get("Metadata", []) + ) + + for collection in collections: + if collection == collection_name: + plex_ssn.delete( + f"{p_base_url}/library/collections/{collection['ratingKey']}" + ).json() + break + + # Create collection + machine_id = plex_ssn.get(f"{p_base_url}/").json()["MediaContainer"][ + "machineIdentifier" + ] + + plex_ssn.post( + f"{p_base_url}/library/collections", + params={ + "title": collection_name, + "smart": "0", + "sectionId": lib["key"], + "uri": f"server://{machine_id}/com.plexapp.plugins.library/library/metadata/{','.join(result_json)}", + }, + ) + + return [int(e) for e in result_json] + + +if __name__ == "__main__": + from argparse import ArgumentParser + + from requests import Session + + # Setup vars + plex_ssn = Session() + plex_ssn.headers.update({"Accept": "application/json"}) + plex_ssn.params.update({"X-Plex-Token": plex_api_token}) + overseerr_ssn = Session() + overseerr_ssn.headers.update({"X-Api-Key": overseerr_api_token}) + + # Setup vars + plex_ssn = Session() + plex_ssn.headers.update({"Accept": "application/json"}) + plex_ssn.params.update({"X-Plex-Token": plex_api_token}) # type: ignore + overseerr_ssn = Session() + overseerr_ssn.headers.update({"X-Api-Key": overseerr_api_token}) + + # Setup arg parsing + # autopep8: off + parser = ArgumentParser( + description="Put all requested movies from overseerr in a collection in plex." + ) + parser.add_argument( + "-l", + "--LibraryName", + type=str, + required=True, + help="Name of target movie library", + ) + parser.add_argument( + "-c", + "--CollectionName", + type=str, + default="Overseerr Requests", + help="Name of collection that movies will be put in", + ) + # autopep8: on + + args = parser.parse_args() + + try: + overseerr_to_collection( + plex_ssn, overseerr_ssn, args.LibraryName, args.CollectionName + ) + + except ValueError as e: + parser.error(e.args[0]) diff --git a/bin/welcome.sh b/bin/welcome.sh index 8f8162f..393295d 100755 --- a/bin/welcome.sh +++ b/bin/welcome.sh @@ -1,5 +1,4 @@ #!/bin/bash -clear USER=$(whoami) figlet -f fraktur -S -w 90 ${USER} \ No newline at end of file diff --git a/config/bash/.bashrc b/config/bash/.bashrc index b198b32..f334753 100644 --- a/config/bash/.bashrc +++ b/config/bash/.bashrc @@ -89,7 +89,7 @@ fi #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' # some more ls aliases -alias ll='ls -alF' +alias ll='ls -alFhr' alias la='ls -A' alias l='ls -CF' @@ -97,12 +97,24 @@ alias l='ls -CF' # sleep 10; alert alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if ! shopt -oq posix; then + if [ -f /usr/share/bash-completion/bash_completion ]; then + . /usr/share/bash-completion/bash_completion + elif [ -f /etc/bash_completion ]; then + . /etc/bash_completion + fi +fi + + # Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. -if [ -f ~/.aliases ]; then - . ~/.aliases +if [ -f ~/.config/dotfiles/config/zsh/.aliases ]; then + . ~/.config/dotfiles/config/zsh/.aliases fi # Functions definitions. @@ -111,16 +123,24 @@ if [ -f $HOME/.functions ]; then . $HOME/.functions fi -# enable programmable completion features (you don't need to enable -# this, if it's already enabled in /etc/bash.bashrc and /etc/profile -# sources /etc/bash.bashrc). -if ! shopt -oq posix; then - if [ -f /usr/share/bash-completion/bash_completion ]; then - . /usr/share/bash-completion/bash_completion - elif [ -f /etc/bash_completion ]; then - . /etc/bash_completion - fi -fi +# my basic alias and functions to get a system up and running +alias c="clear" +alias df='df -h' +alias pi="apt-mark showmanual" +alias fresh='source ~/.bashrc && echo refreshed' +alias tm="tmux attach -t main || tmux new -s main" +alias ta='tmux attach -t' +alias td='tmux detach' +alias tl='tmux ls' +alias tk='tmux kill-session -t' + +detach() { + if [ -n "$TMUX" ]; then + tmux detach + else + echo "Not in a tmux session _ nothing to detach from." + fi +} # Intro message shown on terminal source welcome.sh diff --git a/config/bat/config b/config/bat/config new file mode 100644 index 0000000..ca48415 --- /dev/null +++ b/config/bat/config @@ -0,0 +1,5 @@ +--theme="knuckles" +--style="numbers,changes,header,grid" +--wrap=auto +--italic-text=always +--paging=auto \ No newline at end of file diff --git a/config/bat/themes/knuckles.tmTheme b/config/bat/themes/knuckles.tmTheme new file mode 100644 index 0000000..cb199c0 --- /dev/null +++ b/config/bat/themes/knuckles.tmTheme @@ -0,0 +1,235 @@ + + + + + + nameKnuckles + settings + + + settings + + background#240809 + foreground#ceb5b4 + caret#ff7a7c + lineHighlight#330e10 + selection#4b1d1e + selectionForeground#ceb5b4 + invisibles#5f3c3b + gutter#240809 + gutterForeground#946b6a + findHighlight#ff8384 + findHighlightForeground#240809 + + + + nameComment + scopecomment, comment.line, comment.block, punctuation.definition.comment + settings + + foreground#946b6a + fontStyleitalic + + + + nameString + scopestring, string.quoted, string.quoted.double, string.quoted.single, string.unquoted, punctuation.definition.string + settings + + foreground#da4a52 + + + + nameEscape + scopeconstant.character.escape, string.regexp + settings + + foreground#ffdfde + + + + nameNumber + scopeconstant.numeric, constant.language, constant + settings + + foreground#bd9d9c + + + + nameConstant + scopeconstant.other, support.constant, variable.language + settings + + foreground#bd9d9c + + + + nameKeyword + scopekeyword, keyword.control, storage, storage.type, storage.modifier + settings + + foreground#f6646a + + + + nameOperator + scopekeyword.operator, punctuation.separator, punctuation.terminator + settings + + foreground#ffdfde + + + + nameFunction + scopeentity.name.function, support.function, meta.function, meta.function-call + settings + + foreground#a48685 + + + + nameType + scopeentity.name.type, entity.name.class, support.type, support.class, entity.other.inherited-class + settings + + foreground#ff8384 + + + + nameVariable + scopevariable, variable.other, variable.parameter, entity.name.tag + settings + + foreground#ffc3c1 + + + + nameProperty + scopevariable.other.member, meta.object-literal.key, support.type.property-name + settings + + foreground#ffc3c1 + + + + nameAttribute + scopeentity.other.attribute-name, meta.attribute + settings + + foreground#ff8384 + + + + nameTag delimiter + scopepunctuation.definition.tag + settings + + foreground#c0303e + + + + nameNamespace + scopeentity.name.namespace, entity.name.module, meta.namespace + settings + + foreground#ff8384 + + + + nameDecorator + scopemeta.decorator, entity.name.decorator, meta.annotation + settings + + foreground#bd9d9c + + + + nameHeading + scopemarkup.heading, entity.name.section + settings + + foreground#a48685 + fontStylebold + + + + namePunctuation + scopepunctuation, meta.brace, punctuation.section + settings + + foreground#ceb5b4 + + + + nameInvalid + scopeinvalid, invalid.illegal + settings + + foreground#ffc3c1 + + + + nameDeprecated + scopeinvalid.deprecated + settings + + foreground#c0303e + + + + nameDiff inserted + scopemarkup.inserted, markup.inserted.diff + settings + foreground#da4a52 + + + nameDiff deleted + scopemarkup.deleted, markup.deleted.diff + settings + foreground#ffc3c1 + + + nameDiff changed + scopemarkup.changed, markup.changed.diff + settings + foreground#bd9d9c + + + nameDiff header + scopemeta.diff.header, meta.diff.range + settings + foreground#ffdfde + + + nameMarkup link + scopemarkup.underline.link, string.other.link + settings + foreground#a48685 + + + nameMarkup bold + scopemarkup.bold + settings + foreground#ff8384 + + + nameMarkup italic + scopemarkup.italic + settings + foreground#f6646a + + + nameMarkup raw + scopemarkup.raw, markup.raw.inline + settings + foreground#da4a52 + + + uuid888a6e19-80c7-4741-a84d-c9580952155a + colorSpaceNamesRGB + semanticClass + theme.dark.knuckles + + \ No newline at end of file diff --git a/config/espanso/match/aclu.yml b/config/espanso/match/aclu.yml index bbef8ea..3fc5906 100644 --- a/config/espanso/match/aclu.yml +++ b/config/espanso/match/aclu.yml @@ -4,30 +4,38 @@ name: ACLU package_author: Pavel Sanchez parent: base matches: - - trigger: aff - replace: affiliate - propagate_case: true - word: true - - - trigger: ";date" - replace: "{{mydate}}" - vars: - - name: mydate - type: date - params: - format: "%Y%m%d" - locale: "en-US" - - trigger: ";logo" image_path: "$CONFIG/images/aclu-sig-logo.png" - trigger: ";sup" + label: "Default Suppressions" replace: "Suppressions:\nCAN Default Suppression\n" + - trigger: ";sup" + label: "Today's Suppressions" + replace: "Suppressions:\nCAN Default Suppression\n{{clipboard}}" + vars: + - name: "clipboard" + type: "clipboard" + - trigger: ";sig" label: "Basic signature" replace: "Thanks,\nPavel" + - trigger: ";sig" + label: "Zendesk signature" + replace: | + Thanks, + Pavel + + Pavel Sanchez + Pronouns: He, him, his + Associate Director, Affiliates Digital Campaigns + American Civil Liberties Union + 125 Broad St., New York, NY 10004 + 212.284.7371 | psanchez@aclu.org + www.aclu.org + - trigger: ";sig" label: "Full signature" replace: | @@ -55,20 +63,26 @@ matches: type: choice params: values: - - label: "ACLU Blue" - id: "#0055aa" - - label: "ACLU Red" - id: "#ef404e" - - label: "ACLU Light Azure" - id: "#a3dbe3" - - label: "ACLU Light Green" - id: "#a7d7b5" - - label: "ACLU Light Orange" - id: "#fcaa17" - - label: "ACLU Light Pink" - id: "#fabeaf" - - label: "ACLU Light Yellow" - id: "#ffe06a" + - label: "01. Primary Blue" + id: "#146cd2" + - label: "02. Primary Red" + id: "#d9192b" + - label: "03. Primary Yellow" + id: "#fdc221" + - label: "04. Primary Green" + id: "#499764" + - label: "05. Primary Orange" + id: "#ff7d00" + - label: "06. Primary Purple" + id: "#862dcb" + - label: "07. Primary Pink" + id: "#db2a7d" + - label: "08. Off White" + id: "#f7f9fd" + - label: "09. Grey" + id: "#696968" + - label: "10. Black" + id: "#090c0f" - trigger: ";issues" replace: "\nCapital Punishment\nCivil Liberties\nCriminal Law Reform\nDisability Rights\nFree Speech\nHIV and AIDS\nHuman Rights\nImmigrants' Rights\nJuvenile Justice\nLGBT Rights\nMass Incarceration\nNational Security\nNon-Issue Campaign\nPrisoners' Rights\nPrivacy & Technology\nRacial Justice\nReligious Liberty\nReproductive Freedom\nVoting Rights\nWomen's Rights" @@ -85,5 +99,17 @@ matches: - trigger: ";uaf" replace: "Hello [NAME],\n\nYou can sign up to gain access to Springboard by submitting this webform: https://dbsupport.aclu.org/hc/en-us/requests/new?ticket_form_id=985388.\n\nThanks,\nPavel" + - regex: ";greet\\((?P.*)\\)" + replace: "Hi {{name}}!" + + - trigger: ";seed" + replace: "seedlist-nat@aclu.org" + + - trigger: ";ea" + replace: "the email has been adjusted." + + - trigger: ";upd" + replace: "this has been updated!" + # For a complete introduction, visit the official docs at: https://espanso.org/docs/ \ No newline at end of file diff --git a/config/espanso/match/ats.yml b/config/espanso/match/ats.yml deleted file mode 100644 index 70cceb4..0000000 --- a/config/espanso/match/ats.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Espanso Match File - -name: ATS -package_author: Pavel Sanchez -parent: base -matches: - - trigger: ";atsip" - replace: "35.227.136.104" - - - trigger: ";atsstaged" - replace: "https://atsstaged.wpengine.com/wp-admin" - - - trigger: ";atsp" - replace: "275b06b4" - -# For a complete introduction, visit the official docs at: https://espanso.org/docs/ \ No newline at end of file diff --git a/config/espanso/match/autocorrect.yml b/config/espanso/match/autocorrect.yml index 28873d3..7853017 100644 --- a/config/espanso/match/autocorrect.yml +++ b/config/espanso/match/autocorrect.yml @@ -4,6 +4,11 @@ name: autocorrect package_author: Pavel Sanchez parent: base matches: + - trigger: aff + replace: affiliate + propagate_case: true + word: true + - trigger: emial replace: email propagate_case: true diff --git a/config/espanso/match/base.yml b/config/espanso/match/base.yml index 254fe99..acd1261 100644 --- a/config/espanso/match/base.yml +++ b/config/espanso/match/base.yml @@ -1,7 +1,16 @@ # Espanso Match File - +name: base +package_author: Pavel Sanchez matches: -# Outputs a Choice list of Emails + - triggers: [";fn"] + replace: "Pavel" + + - triggers: [";ln"] + replace: "Sanchez" + + - triggers: [";fln"] + replace: "Pavel Sanchez" + - triggers: [";email", ";eml"] replace: "{{output}}" vars: @@ -10,18 +19,16 @@ matches: params: values: - label: "Personal" - id: "hello@psanchez.me" + id: "accounts@psanchez.me" - label: "Work" id: "psanchez@aclu.org" - label: "CAN Support" id: "cansupport@aclu.org" - label: "CAN Test" id: "cantest@aclu.org" - - label: "ACLU Test" + - label: "Gmail Test" id: "aclucan.test@gmail.com" - label: "Litmus" - id: "cantest@litmusemail.com" - - - - + id: "pavel@litmusemail.com" + - label: "Seedlist" + id: "seedlist-nat@aclu.org" diff --git a/config/espanso/match/emails.yml b/config/espanso/match/emails.yml new file mode 100644 index 0000000..5e5c8c7 --- /dev/null +++ b/config/espanso/match/emails.yml @@ -0,0 +1,24 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json + +# Espanso Match File +# name: emails +# package_author: Pavel Sanchez +# parent: base + +matches: + - trigger: ";can102" + label: "CAN 102 Email" + replace: | + Thank you for meeting with me today. Below are the slide deck and other tools covered today. + + 1. CAN 102 deck (https://aclunational.sharepoint.com/:p:/s/DigitalCampaigns/EVNJuJnBtOpLmqrS-iuVo_cBzNQLZlV4rgzPY2AyxGmFhw?rtime=cBUEgi6J20g) + 2. User Access Form (https://dbsupport.aclu.org/hc/en-us/requests/new?ticket_form_id=985388) + 3. Request forms (https://hub.aclu.org/Interact/Pages/Section/ContentListing.aspx?subsection=5185) + 4. Asana Calendar form (https://form.asana.com/?k=Iyp8UjhWUH889-MfyhEm5g&d=25535823564359) + 5. Asana Calendar (https://app.asana.com/0/1200170098126627/calendar) + 6. Grades (https://docs.google.com/spreadsheets/d/1cZrJYqni0I5z5bt5-lQc6zTre6h4REATFz5rj2eGIis/edit#gid=119869387) + 7. Digital Campaigns Documentation (https://app.getguru.com/card/i64qeaoT/Digital-Campaigns) + a. Email Style Guide (https://app.getguru.com/card/TXzebxxc/Email-Style-Guide-Table-of-Contents) + + +# For a complete introduction, visit the official docs at: https://espanso.org/docs/ \ No newline at end of file diff --git a/config/espanso/match/utils.yml b/config/espanso/match/utils.yml index b3b9fd1..9cb6eae 100644 --- a/config/espanso/match/utils.yml +++ b/config/espanso/match/utils.yml @@ -1,10 +1,12 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json + # Espanso Match File +# name: utils +# package_author: Pavel Sanchez +# parent: base -name: utils -package_author: Pavel Sanchez -parent: base matches: - - trigger: ";html-link" + - trigger: ";link" replace: "$|$" vars: - name: "clipboard" @@ -19,6 +21,16 @@ matches: params: cmd: "curl 'https://api.ipify.org'" + # Outputs public IP address + - trigger: ";loip" + replace: "{{output}}" + vars: + - name: output + type: shell + params: + cmd: "ifconfig | grep 'broadcast' | awk '{ print $2 }'" + # debug: true + # Outputs SSH Pub Key - trigger: ";ssh" replace: "{{output}}" @@ -26,7 +38,16 @@ matches: - name: output type: shell params: - cmd: "cat ~/.ssh/macbook.pub" + cmd: "cat ~/.ssh/config" + + - trigger: ";date" + replace: "{{mydate}}" + vars: + - name: mydate + type: date + params: + format: "%Y%m%d" + locale: "en-US" # Outputs Current Time - trigger: ";time" @@ -87,12 +108,15 @@ matches: - trigger: ';-' replace: '-$|$-' -# Outputs the month and year (e.g. January 2020) - - trigger: ";figlet" - replace: "echo {{text}} | figlet -f fraktur -w 90 -c" +# Outputs the current weather for your location + - trigger: ";test" + replace: "{{output}}" vars: - - name: text - type: echo + - name: output + type: shell + params: + cmd: "loIP" + shell: bash + # debug: true # For a complete introduction, visit the official docs at: https://espanso.org/docs/ - diff --git a/config/ghostty/config.ghostty b/config/ghostty/config.ghostty new file mode 100644 index 0000000..c416f1a --- /dev/null +++ b/config/ghostty/config.ghostty @@ -0,0 +1,74 @@ +# Ghostty Configuration +# Pavel Sanchez +# https://github.com/PaleBluDot/dotfiles +# Last updated: 2026-08-27 + +theme = Starburst +working-directory = home +auto-update = check +copy-on-select = true +font-size = 14 +shell-integration = zsh +scrollback-limit = 10000000 + +# keyboard and mouse +clipboard-trim-trailing-spaces = true +clipboard-paste-protection = true +cursor-style = block +cursor-style-blink = false +adjust-cursor-thickness = 2 +mouse-hide-while-typing = true +mouse-shift-capture = true + +# screen +fullscreen = true +quick-terminal-size = 600px +window-padding-x = 10 +window-padding-y = 10 +window-decoration = true +window-inherit-working-directory = true +window-save-state = always +background-opacity = 0.92 +background-blur-radius = 30 +unfocused-split-opacity = 0.5 +unfocused-split-fill = #151515 + +# fonts +font-family = "Monaspace Neon NF" +font-family-bold = "Monaspace Radon NF" +font-feature = calt +font-feature = liga +font-feature = ss01 +font-feature = ss02 +font-feature = ss03 +font-feature = ss04 +font-feature = ss05 +font-feature = ss06 +font-feature = ss07 +font-feature = ss08 + +# macOS only +macos-titlebar-style = tabs +macos-option-as-alt = true + +# custom shaders +custom-shader = ~/.config/ghostty/shaders/smear_cursor_blocks.glsl +# custom-shader = ~/.config/ghostty/shaders/in-game-crt-cursor.glsl +# custom-shader = ~/.config/ghostty/shaders/starfield.glsl +# custom-shader = ~/.config/ghostty/shaders/inside-the-matrix.glsl +# custom-shader = ~/.config/ghostty/shaders/galaxy.glsl + + +# keybindings +keybind = cmd+shift+enter=toggle_split_zoom +keybind = cmd+d=new_split:right + +keybind = cmd+shift+d=new_split:down +keybind = cmd+alt+left=goto_split:left +keybind = cmd+alt+right=goto_split:right +keybind = cmd+alt+up=goto_split:up +keybind = cmd+alt+down=goto_split:down +keybind = cmd+alt+h=goto_split:left +keybind = cmd+alt+j=goto_split:down +keybind = cmd+alt+k=goto_split:up +keybind = cmd+alt+l=goto_split:right diff --git a/config/ghostty/themes/Demo b/config/ghostty/themes/Demo new file mode 100644 index 0000000..1f11d14 --- /dev/null +++ b/config/ghostty/themes/Demo @@ -0,0 +1,27 @@ +# Ghostty Theme: Demo +# Pavel Sanchez +# https://github.com/PaleBluDot/dotfiles +# Last updated: 2026-08-27 + +background = #330014 +foreground = #e8e8e8 +cursor-color = #9e9e9e +cursor-text = #330014 +selection-background = #e3a6a6 +selection-foreground = #330014 +palette = 0=#000000 +palette = 1=#d9004c +palette = 2=#ff4d82 +palette = 3=#f3032a +palette = 4=#ad3649 +palette = 5=#f8bac5 +palette = 6=#c4536a +palette = 7=#b31446 +palette = 8=#eb83c5 +palette = 9=#d9004c +palette = 10=#ff004c +palette = 11=#d9004c +palette = 12=#f15932 +palette = 13=#8c1f4b +palette = 14=#d94141 +palette = 15=#ff6666 \ No newline at end of file diff --git a/config/ghostty/themes/Knuckles b/config/ghostty/themes/Knuckles new file mode 100644 index 0000000..803f8ae --- /dev/null +++ b/config/ghostty/themes/Knuckles @@ -0,0 +1,27 @@ +# Ghostty Theme: Knuckles +# Pavel Sanchez +# https://github.com/PaleBluDot/dotfiles +# Last updated: 2026-08-27 + +background = #400716 +foreground = #bdbdbd +cursor-color = #9e9e9e +cursor-text = #400716 +selection-background = #e3a6a6 +selection-foreground = #400716 +palette = 0=#000000 +palette = 1=#000000 +palette = 2=#ff4d82 +palette = 3=#f10d0d +palette = 4=#5e5f56 +palette = 5=#848579 +palette = 6=#b0b1a2 +palette = 7=#833449 +palette = 8=#eb83c5 +palette = 9=#d9004c +palette = 10=#ff004c +palette = 11=#e78043 +palette = 12=#f15932 +palette = 13=#8c7bed +palette = 14=#d94141 +palette = 15=#ff6666 diff --git a/config/ghostty/themes/Starburst b/config/ghostty/themes/Starburst new file mode 100644 index 0000000..edc82fa --- /dev/null +++ b/config/ghostty/themes/Starburst @@ -0,0 +1,27 @@ +# Ghostty Theme: Starburst +# Pavel Sanchez +# https://github.com/PaleBluDot/dotfiles +# Last updated: 2026-08-27 + +background = #151515 +foreground = #f8f8f2 +cursor-color = #FF6183 +cursor-text = #FFFFFF +selection-background = #E2E40F +selection-foreground = #151515 +palette = 0=#21222c +palette = 1=#ff5555 +palette = 2=#50fa7b +palette = 3=#f1fa8c +palette = 4=#bd93f9 +palette = 5=#ff79c6 +palette = 6=#8be9fd +palette = 7=#f8f8f2 +palette = 8=#6272A4 +palette = 9=#ff6e6e +palette = 10=#69ff94 +palette = 11=#ffffa5 +palette = 12=#d6acff +palette = 13=#ff92df +palette = 14=#a4ffff +palette = 15=#ffffff \ No newline at end of file diff --git a/config/ghostty/themes/term-color-generator b/config/ghostty/themes/term-color-generator new file mode 100644 index 0000000..5969dd5 --- /dev/null +++ b/config/ghostty/themes/term-color-generator @@ -0,0 +1,272 @@ +# Terminal Color Generator +# Generated by term-color-generator + +background = #240809 +foreground = #ceb5b4 +cursor-color = #ff7a7c +cursor-text = #240809 +selection-background = #4b1d1e +selection-foreground = #ceb5b4 + +palette = 0=#4c2b2a +palette = 1=#ffc3c1 +palette = 2=#da4a52 +palette = 3=#ff8384 +palette = 4=#a48685 +palette = 5=#f6646a +palette = 6=#ffdfde +palette = 7=#ceb5b4 +palette = 8=#946b6a +palette = 9=#ffe4e3 +palette = 10=#f86a6e +palette = 11=#ffb4b2 +palette = 12=#c0a2a1 +palette = 13=#ff9494 +palette = 14=#f9dbda +palette = 15=#efd5d4 + +# Harmonized 256-color cube. Lightness of each index is preserved, +# only hue and chroma lean toward the nearest of your 16 slots. +palette = 16=#000000 +palette = 17=#2d0433 +palette = 18=#420b4a +palette = 19=#571460 +palette = 20=#6b1d77 +palette = 21=#80268d +palette = 22=#654700 +palette = 23=#55552f +palette = 24=#624d75 +palette = 25=#744e82 +palette = 26=#854f92 +palette = 27=#9652a4 +palette = 28=#8f6704 +palette = 29=#82713a +palette = 30=#7a794a +palette = 31=#84709f +palette = 32=#9570aa +palette = 33=#a771b9 +palette = 34=#b88715 +palette = 35=#ae8e42 +palette = 36=#a69556 +palette = 37=#9e9d64 +palette = 38=#a792ca +palette = 39=#b892d4 +palette = 40=#e1a623 +palette = 41=#d9ac49 +palette = 42=#d2b25e +palette = 43=#cab971 +palette = 44=#c2c17e +palette = 45=#c9b5f5 +palette = 46=#ffca66 +palette = 47=#ffcc63 +palette = 48=#fdd068 +palette = 49=#f5d67c +palette = 50=#eedd8d +palette = 51=#e6e59a +palette = 52=#5f0009 +palette = 53=#69003c +palette = 54=#68224d +palette = 55=#752761 +palette = 56=#842e76 +palette = 57=#95358c +palette = 58=#76522e +palette = 59=#645d5d +palette = 60=#755971 +palette = 61=#855980 +palette = 62=#955990 +palette = 63=#a55ba2 +palette = 64=#986f33 +palette = 65=#8c7855 +palette = 66=#808163 +palette = 67=#90799b +palette = 68=#a178a7 +palette = 69=#b179b7 +palette = 70=#be8d39 +palette = 71=#b49458 +palette = 72=#ac9b6a +palette = 73=#a3a378 +palette = 74=#af9ac6 +palette = 75=#c099d1 +palette = 76=#e6ab40 +palette = 77=#deb15c +palette = 78=#d7b76f +palette = 79=#cebd81 +palette = 80=#c6c58f +palette = 81=#cfbbf1 +palette = 82=#ffcf7e +palette = 83=#ffd17e +palette = 84=#ffd47b +palette = 85=#f9da89 +palette = 86=#f1e19a +palette = 87=#e9e8a7 +palette = 88=#860012 +palette = 89=#8d0042 +palette = 90=#950057 +palette = 91=#a0006d +palette = 92=#99397a +palette = 93=#a83f8e +palette = 94=#895b41 +palette = 95=#836160 +palette = 96=#8a6172 +palette = 97=#966181 +palette = 98=#a46292 +palette = 99=#b363a3 +palette = 100=#a47749 +palette = 101=#987f67 +palette = 102=#8c8585 +palette = 103=#9e8199 +palette = 104=#ad80a7 +palette = 105=#bd80b6 +palette = 106=#c7934e +palette = 107=#bd9a69 +palette = 108=#b4a07c +palette = 109=#a8a88f +palette = 110=#b8a1c3 +palette = 111=#c99fcf +palette = 112=#ecb054 +palette = 113=#e4b66c +palette = 114=#dcbb7e +palette = 115=#d3c291 +palette = 116=#caca9f +palette = 117=#d5c1ee +palette = 118=#ffd594 +palette = 119=#ffd795 +palette = 120=#ffd995 +palette = 121=#fddd97 +palette = 122=#f5e4a8 +palette = 123=#ececb4 +palette = 124=#ac0b1d +palette = 125=#b00e48 +palette = 126=#b60d5e +palette = 127=#bf0e73 +palette = 128=#c91288 +palette = 129=#be4b94 +palette = 130=#c04e22 +palette = 131=#9f6968 +palette = 132=#a46a77 +palette = 133=#ad6b86 +palette = 134=#b96b96 +palette = 135=#c66da7 +palette = 136=#b67f5b +palette = 137=#ae8575 +palette = 138=#ac8988 +palette = 139=#b38999 +palette = 140=#bf88a9 +palette = 141=#cd88b8 +palette = 142=#d39b63 +palette = 143=#c9a17b +palette = 144=#c1a68e +palette = 145=#b4adad +palette = 146=#c7a9c1 +palette = 147=#d6a7cf +palette = 148=#f5b769 +palette = 149=#ecbc80 +palette = 150=#e5c191 +palette = 151=#dcc8a4 +palette = 152=#cfd0b6 +palette = 153=#dfc9eb +palette = 154=#ffdcae +palette = 155=#ffdeb0 +palette = 156=#ffe0b2 +palette = 157=#ffe4b3 +palette = 158=#fbeab9 +palette = 159=#f1f2c6 +palette = 160=#ce252d +palette = 161=#d12751 +palette = 162=#d62765 +palette = 163=#dc2779 +palette = 164=#e5298d +palette = 165=#ef2ca2 +palette = 166=#dd5637 +palette = 167=#dd595c +palette = 168=#df5a73 +palette = 169=#e55a8a +palette = 170=#e7609e +palette = 171=#f260b2 +palette = 172=#e67945 +palette = 173=#e37d66 +palette = 174=#e47f7f +palette = 175=#cc919e +palette = 176=#d691ad +palette = 177=#e291bc +palette = 178=#e4a375 +palette = 179=#dca98a +palette = 180=#d7ad9c +palette = 181=#d5b0b0 +palette = 182=#dcb0c1 +palette = 183=#efabd2 +palette = 184=#ffc082 +palette = 185=#f9c492 +palette = 186=#f2c9a3 +palette = 187=#e9ceb6 +palette = 188=#dcd5d5 +palette = 189=#eed1e9 +palette = 190=#ffe6ca +palette = 191=#ffe8cd +palette = 192=#ffead0 +palette = 193=#ffecd4 +palette = 194=#fff1d6 +palette = 195=#f7f8dd +palette = 196=#f0393d +palette = 197=#f23b5a +palette = 198=#f53b6e +palette = 199=#fb3c81 +palette = 200=#ff4395 +palette = 201=#ff55a7 +palette = 202=#fc6049 +palette = 203=#fc6266 +palette = 204=#fe647a +palette = 205=#ff6790 +palette = 206=#ff6fa4 +palette = 207=#ff7ab5 +palette = 208=#ff835b +palette = 209=#ff8573 +palette = 210=#ff8787 +palette = 211=#ff8a9e +palette = 212=#ff8fb2 +palette = 213=#ff97c2 +palette = 214=#ffaa7d +palette = 215=#fbad8e +palette = 216=#f9b09f +palette = 217=#f8b3b2 +palette = 218=#fdb4c4 +palette = 219=#ffb8d4 +palette = 220=#ffcfab +palette = 221=#ffd0b1 +palette = 222=#ffd2b8 +palette = 223=#fed5c4 +palette = 224=#fad9d8 +palette = 225=#ffdbe9 +palette = 226=#fff2e6 +palette = 227=#fff3e9 +palette = 228=#fff5ec +palette = 229=#fff8f1 +palette = 230=#fffbf7 +palette = 231=#ffffff +palette = 232=#0b0707 +palette = 233=#151111 +palette = 234=#201b1a +palette = 235=#2a2524 +palette = 236=#342f2e +palette = 237=#3e3938 +palette = 238=#484242 +palette = 239=#524c4c +palette = 240=#5d5656 +palette = 241=#676060 +palette = 242=#716a6a +palette = 243=#7b7474 +palette = 244=#857e7e +palette = 245=#8f8888 +palette = 246=#999292 +palette = 247=#a39c9c +palette = 248=#ada6a6 +palette = 249=#b7b0b0 +palette = 250=#c1baba +palette = 251=#cbc4c4 +palette = 252=#d5cece +palette = 253=#dfd8d8 +palette = 254=#e9e2e2 +palette = 255=#f4ecec + +# Save as ~/.config/ghostty/themes/knuckles +# then add theme = knuckles to ~/.config/ghostty/config diff --git a/config/git/.gitconfig.bak b/config/git/.gitconfig.bak deleted file mode 100644 index 8672898..0000000 --- a/config/git/.gitconfig.bak +++ /dev/null @@ -1,21 +0,0 @@ -[user] - name = Pavel Sanchez - email = 23495830+PaleBluDot@users.noreply.github.com - signingkey = F60BB56DBC017F59 -[init] - defaultBranch = main -[filter "lfs"] - clean = git-lfs clean -- %f - smudge = git-lfs smudge -- %f - process = git-lfs filter-process - required = true -[gpg] - format = openpgp -[credential "https://github.com"] - helper = - helper = !/usr/bin/gh auth git-credential -[credential "https://gist.github.com"] - helper = - helper = !/usr/bin/gh auth git-credential -[commit] - gpgsign = true diff --git a/config/npm/.npmrc b/config/npm/.npmrc index 5fb5453..16a5c1d 100644 --- a/config/npm/.npmrc +++ b/config/npm/.npmrc @@ -1,4 +1,3 @@ -prefix=${HOME}/.config/npm init-author-name=Pavel Sanchez init-author-url=https://github.com/PaleBluDot init-license=MIT diff --git a/config/nvim/.gitignore b/config/nvim/.gitignore new file mode 100644 index 0000000..cc5457a --- /dev/null +++ b/config/nvim/.gitignore @@ -0,0 +1,8 @@ +tt.* +.tests +doc/tags +debug +.repro +foo.* +*.log +data diff --git a/config/nvim/.neoconf.json b/config/nvim/.neoconf.json new file mode 100644 index 0000000..7c48087 --- /dev/null +++ b/config/nvim/.neoconf.json @@ -0,0 +1,15 @@ +{ + "neodev": { + "library": { + "enabled": true, + "plugins": true + } + }, + "neoconf": { + "plugins": { + "lua_ls": { + "enabled": true + } + } + } +} diff --git a/config/nvim/LICENSE b/config/nvim/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/config/nvim/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/config/nvim/README.md b/config/nvim/README.md new file mode 100644 index 0000000..185280b --- /dev/null +++ b/config/nvim/README.md @@ -0,0 +1,4 @@ +# 💤 LazyVim + +A starter template for [LazyVim](https://github.com/LazyVim/LazyVim). +Refer to the [documentation](https://lazyvim.github.io/installation) to get started. diff --git a/config/nvim/init.lua b/config/nvim/init.lua new file mode 100644 index 0000000..2514f9e --- /dev/null +++ b/config/nvim/init.lua @@ -0,0 +1,2 @@ +-- bootstrap lazy.nvim, LazyVim and your plugins +require("config.lazy") diff --git a/config/nvim/lazy-lock.json b/config/nvim/lazy-lock.json new file mode 100644 index 0000000..ecd3749 --- /dev/null +++ b/config/nvim/lazy-lock.json @@ -0,0 +1,57 @@ +{ + "LazyVim": { "branch": "main", "commit": "c10948c50b18fae7f256433afdef09e432410480" }, + "SchemaStore.nvim": { "branch": "main", "commit": "2940d5e12f8797620cd47dca984d46119e1fa4b8" }, + "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" }, + "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, + "catppuccin": { "branch": "main", "commit": "edefef779ab08ce1a4a404713e3012b0d202bd35" }, + "chezmoi.nvim": { "branch": "main", "commit": "4167bbec76f693f481a5243f1be521ff0ccf1a6d" }, + "chezmoi.vim": { "branch": "main", "commit": "7a498ea65f658993237fb0469001bdf71f68cf94" }, + "claudecode.nvim": { "branch": "main", "commit": "2390c6e45c4789072c293ac69de051d169668b29" }, + "conform.nvim": { "branch": "master", "commit": "016802de402556da54c36bd7359b441266b01cdd" }, + "dial.nvim": { "branch": "master", "commit": "f2634758455cfa52a8acea6f142dcd6271a1bf57" }, + "dressing.nvim": { "branch": "master", "commit": "2d7c2db2507fa3c4956142ee607431ddb2828639" }, + "flash.nvim": { "branch": "main", "commit": "5f0f270fdc7c5b0c21d903ee85b9cb06f2ac636a" }, + "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, + "gh.nvim": { "branch": "main", "commit": "6f367b2ab8f9d4a0a23df2b703a3f91137618387" }, + "gitsigns.nvim": { "branch": "main", "commit": "5be654f2232c10ddcad19c1607a67b6b4b78fc29" }, + "grug-far.nvim": { "branch": "main", "commit": "11595bf747edc270bce2069d1020502ad4ae56cf" }, + "lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" }, + "lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" }, + "litee.nvim": { "branch": "main", "commit": "4efaf373322d9e71eaff31164abb393417cc6f6a" }, + "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" }, + "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "40276c4df7e6bdce6801d6c035c6227f9115a855" }, + "mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" }, + "mini.ai": { "branch": "main", "commit": "25248c6aa002391936a6200f12d1466015987133" }, + "mini.icons": { "branch": "main", "commit": "98faae31e9be1cc054ae63485e58ceb185efcad0" }, + "mini.pairs": { "branch": "main", "commit": "b1c5a726921b7a8c9321e9a7a208aa0571de5810" }, + "neo-tree.nvim": { "branch": "main", "commit": "3352e998cb8343a4b8d82eca50c74aa17bc61f5e" }, + "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, + "nui.nvim": { "branch": "main", "commit": "10fc361835c856ba4233ef5ea135b919bf3dce97" }, + "nvim-lint": { "branch": "master", "commit": "3d55c8f67c6ae5c15e1042571e107c7a3d5c5f4e" }, + "nvim-lspconfig": { "branch": "master", "commit": "16286347bdba1333c7d124d9de9fe6630731b2b2" }, + "nvim-treesitter": { "branch": "main", "commit": "857651fce37eba032ebe28f3a206283cdc65c45a" }, + "nvim-treesitter-context": { "branch": "master", "commit": "f3061339b8eaf9fda873600bc425b8d2d8502533" }, + "nvim-treesitter-textobjects": { "branch": "main", "commit": "898ee307df58f854d11cd7edd06472574d48014e" }, + "nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" }, + "octo.nvim": { "branch": "master", "commit": "af2411604b51cb4a0f3e2de50b1b7cacc2581c48" }, + "overseer.nvim": { "branch": "master", "commit": "a93d9f6d6defdac4bcd6d2c8ba988650e42e0a0e" }, + "persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" }, + "plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" }, + "project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" }, + "render-markdown.nvim": { "branch": "main", "commit": "4663eb3ecd538bd5062628fb6d95bbe6bdca78f6" }, + "snacks.nvim": { "branch": "main", "commit": "882c996cf28183f4d63640de0b4c02ec886d01f2" }, + "telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" }, + "telescope.nvim": { "branch": "master", "commit": "40aedd8a68c78a656a10a8d62d80c54af59420fb" }, + "todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" }, + "tokyonight.nvim": { "branch": "main", "commit": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6" }, + "trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" }, + "ts-comments.nvim": { "branch": "main", "commit": "a59d6092213447450191122c9346f309161504cb" }, + "venv-selector.nvim": { "branch": "main", "commit": "cc4bb3975de8835291f9bb45889e96c6b2795fc4" }, + "vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" }, + "vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" }, + "vim-dadbod-ui": { "branch": "master", "commit": "afd07819d8efcefc3317205b855ad4e3513b0011" }, + "vim-startuptime": { "branch": "master", "commit": "5f33e50f1e2e2a80370c9094e4c303ea54cd2aea" }, + "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }, + "yanky.nvim": { "branch": "main", "commit": "dd6689fdda85f66cab7d9b1a1664625f3be0920d" } +} diff --git a/config/nvim/lazyvim.json b/config/nvim/lazyvim.json new file mode 100644 index 0000000..23da36e --- /dev/null +++ b/config/nvim/lazyvim.json @@ -0,0 +1,39 @@ +{ + "extras": [ + "lazyvim.plugins.extras.ai.claudecode", + "lazyvim.plugins.extras.coding.yanky", + "lazyvim.plugins.extras.editor.dial", + "lazyvim.plugins.extras.editor.neo-tree", + "lazyvim.plugins.extras.editor.overseer", + "lazyvim.plugins.extras.editor.telescope", + "lazyvim.plugins.extras.formatting.prettier", + "lazyvim.plugins.extras.lang.docker", + "lazyvim.plugins.extras.lang.git", + "lazyvim.plugins.extras.lang.go", + "lazyvim.plugins.extras.lang.json", + "lazyvim.plugins.extras.lang.markdown", + "lazyvim.plugins.extras.lang.php", + "lazyvim.plugins.extras.lang.python", + "lazyvim.plugins.extras.lang.sql", + "lazyvim.plugins.extras.lang.toml", + "lazyvim.plugins.extras.lang.typescript", + "lazyvim.plugins.extras.lang.typescript.tsgo", + "lazyvim.plugins.extras.lang.typescript.vtsls", + "lazyvim.plugins.extras.lang.vue", + "lazyvim.plugins.extras.lang.yaml", + "lazyvim.plugins.extras.linting.eslint", + "lazyvim.plugins.extras.ui.treesitter-context", + "lazyvim.plugins.extras.util.chezmoi", + "lazyvim.plugins.extras.util.dot", + "lazyvim.plugins.extras.util.gh", + "lazyvim.plugins.extras.util.gitui", + "lazyvim.plugins.extras.util.octo", + "lazyvim.plugins.extras.util.project", + "lazyvim.plugins.extras.util.startuptime" + ], + "install_version": 8, + "news": { + "NEWS.md": "11866" + }, + "version": 8 +} \ No newline at end of file diff --git a/config/nvim/lua/config/autocmds.lua b/config/nvim/lua/config/autocmds.lua new file mode 100644 index 0000000..4221e75 --- /dev/null +++ b/config/nvim/lua/config/autocmds.lua @@ -0,0 +1,8 @@ +-- Autocmds are automatically loaded on the VeryLazy event +-- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua +-- +-- Add any additional autocmds here +-- with `vim.api.nvim_create_autocmd` +-- +-- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults) +-- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell") diff --git a/config/nvim/lua/config/keymaps.lua b/config/nvim/lua/config/keymaps.lua new file mode 100644 index 0000000..2c134f7 --- /dev/null +++ b/config/nvim/lua/config/keymaps.lua @@ -0,0 +1,3 @@ +-- Keymaps are automatically loaded on the VeryLazy event +-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua +-- Add any additional keymaps here diff --git a/config/nvim/lua/config/lazy.lua b/config/nvim/lua/config/lazy.lua new file mode 100644 index 0000000..d73bfa1 --- /dev/null +++ b/config/nvim/lua/config/lazy.lua @@ -0,0 +1,53 @@ +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +require("lazy").setup({ + spec = { + -- add LazyVim and import its plugins + { "LazyVim/LazyVim", import = "lazyvim.plugins" }, + -- import/override with your plugins + { import = "plugins" }, + }, + defaults = { + -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup. + -- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default. + lazy = false, + -- It's recommended to leave version=false for now, since a lot the plugin that support versioning, + -- have outdated releases, which may break your Neovim install. + version = false, -- always use the latest git commit + -- version = "*", -- try installing the latest stable version for plugins that support semver + }, + install = { colorscheme = { "tokyonight", "habamax" } }, + checker = { + enabled = true, -- check for plugin updates periodically + notify = false, -- notify on update + }, -- automatically check for plugin updates + performance = { + rtp = { + -- disable some rtp plugins + disabled_plugins = { + "gzip", + -- "matchit", + -- "matchparen", + -- "netrwPlugin", + "tarPlugin", + "tohtml", + "tutor", + "zipPlugin", + }, + }, + }, +}) diff --git a/config/nvim/lua/config/options.lua b/config/nvim/lua/config/options.lua new file mode 100644 index 0000000..3ea1454 --- /dev/null +++ b/config/nvim/lua/config/options.lua @@ -0,0 +1,3 @@ +-- Options are automatically loaded before lazy.nvim startup +-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua +-- Add any additional options here diff --git a/config/nvim/lua/plugins/example.lua b/config/nvim/lua/plugins/example.lua new file mode 100644 index 0000000..17f53d6 --- /dev/null +++ b/config/nvim/lua/plugins/example.lua @@ -0,0 +1,197 @@ +-- since this is just an example spec, don't actually load anything here and return an empty spec +-- stylua: ignore +if true then return {} end + +-- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim +-- +-- In your plugin files, you can: +-- * add extra plugins +-- * disable/enabled LazyVim plugins +-- * override the configuration of LazyVim plugins +return { + -- add gruvbox + { "ellisonleao/gruvbox.nvim" }, + + -- Configure LazyVim to load gruvbox + { + "LazyVim/LazyVim", + opts = { + colorscheme = "gruvbox", + }, + }, + + -- change trouble config + { + "folke/trouble.nvim", + -- opts will be merged with the parent spec + opts = { use_diagnostic_signs = true }, + }, + + -- disable trouble + { "folke/trouble.nvim", enabled = false }, + + -- override nvim-cmp and add cmp-emoji + { + "hrsh7th/nvim-cmp", + dependencies = { "hrsh7th/cmp-emoji" }, + ---@param opts cmp.ConfigSchema + opts = function(_, opts) + table.insert(opts.sources, { name = "emoji" }) + end, + }, + + -- change some telescope options and a keymap to browse plugin files + { + "nvim-telescope/telescope.nvim", + keys = { + -- add a keymap to browse plugin files + -- stylua: ignore + { + "fp", + function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end, + desc = "Find Plugin File", + }, + }, + -- change some options + opts = { + defaults = { + layout_strategy = "horizontal", + layout_config = { prompt_position = "top" }, + sorting_strategy = "ascending", + winblend = 0, + }, + }, + }, + + -- add pyright to lspconfig + { + "neovim/nvim-lspconfig", + ---@class PluginLspOpts + opts = { + ---@type lspconfig.options + servers = { + -- pyright will be automatically installed with mason and loaded with lspconfig + pyright = {}, + }, + }, + }, + + -- add tsserver and setup with typescript.nvim instead of lspconfig + { + "neovim/nvim-lspconfig", + dependencies = { + "jose-elias-alvarez/typescript.nvim", + init = function() + require("lazyvim.util").lsp.on_attach(function(_, buffer) + -- stylua: ignore + vim.keymap.set( "n", "co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" }) + vim.keymap.set("n", "cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer }) + end) + end, + }, + ---@class PluginLspOpts + opts = { + ---@type lspconfig.options + servers = { + -- tsserver will be automatically installed with mason and loaded with lspconfig + tsserver = {}, + }, + -- you can do any additional lsp server setup here + -- return true if you don't want this server to be setup with lspconfig + ---@type table + setup = { + -- example to setup with typescript.nvim + tsserver = function(_, opts) + require("typescript").setup({ server = opts }) + return true + end, + -- Specify * to use this function as a fallback for any server + -- ["*"] = function(server, opts) end, + }, + }, + }, + + -- for typescript, LazyVim also includes extra specs to properly setup lspconfig, + -- treesitter, mason and typescript.nvim. So instead of the above, you can use: + { import = "lazyvim.plugins.extras.lang.typescript" }, + + -- add more treesitter parsers + { + "nvim-treesitter/nvim-treesitter", + opts = { + ensure_installed = { + "bash", + "html", + "javascript", + "json", + "lua", + "markdown", + "markdown_inline", + "python", + "query", + "regex", + "tsx", + "typescript", + "vim", + "yaml", + }, + }, + }, + + -- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above + -- would overwrite `ensure_installed` with the new value. + -- If you'd rather extend the default config, use the code below instead: + { + "nvim-treesitter/nvim-treesitter", + opts = function(_, opts) + -- add tsx and treesitter + vim.list_extend(opts.ensure_installed, { + "tsx", + "typescript", + }) + end, + }, + + -- the opts function can also be used to change the default opts: + { + "nvim-lualine/lualine.nvim", + event = "VeryLazy", + opts = function(_, opts) + table.insert(opts.sections.lualine_x, { + function() + return "😄" + end, + }) + end, + }, + + -- or you can return new options to override all the defaults + { + "nvim-lualine/lualine.nvim", + event = "VeryLazy", + opts = function() + return { + --[[add your custom lualine config here]] + } + end, + }, + + -- use mini.starter instead of alpha + { import = "lazyvim.plugins.extras.ui.mini-starter" }, + + -- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc + { import = "lazyvim.plugins.extras.lang.json" }, + + -- add any tools you want to have installed below + { + "williamboman/mason.nvim", + opts = { + ensure_installed = { + "stylua", + "shellcheck", + "shfmt", + "flake8", + }, + }, + }, +} diff --git a/config/nvim/stylua.toml b/config/nvim/stylua.toml new file mode 100644 index 0000000..5d6c50d --- /dev/null +++ b/config/nvim/stylua.toml @@ -0,0 +1,3 @@ +indent_type = "Spaces" +indent_width = 2 +column_width = 120 \ No newline at end of file diff --git a/config/ssh/config b/config/ssh/config index ec6e8ab..7cf2bee 100644 --- a/config/ssh/config +++ b/config/ssh/config @@ -1,18 +1,86 @@ -Host * - IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" - -Host pfsense - HostName 10.0.17.1 - User pbd - -Host pve - HostName 10.0.20.4 - User pbd - -Host helix - HostName 10.0.20.2 - User pbd - -Host blazar - HostName 10.0.20.3 - User pbd +Host * + IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" + IdentitiesOnly yes + IdentityFile ~/.ssh/macbook.pub + SetEnv TERM=xterm-256color + +# Network +Host pfsense + HostName 10.0.17.1 + User pbd + +# Servers +Host helix + HostName 192.168.20.2 + User pbd + +Host blazar + HostName 192.168.20.3 + User pbd + +Host atlas + HostName 10.0.20.3 + User pbd + +# Devices +Host s23u + HostName 10.0.10.14 + User u0_a312 + Port 8022 + +Host uconsole + HostName 10.0.10.15 + User pavel + +Host hackberry + HostName 10.0.20.25 + User pbd + + +# VMs +Host svr-ubuntu + HostName 10.0.20.100 + User pbd + +Host svr-arch + HostName 10.0.20.101 + User pbd + +Host svr-debian + HostName 10.0.20.102 + User pbd + +Host svr-kali + HostName 10.0.20.103 + User pbd + +Host svr-omarchy + HostName 10.0.20.104 + User pale + +# Containers +Host postgres + HostName 10.0.20.20 + User root + +Host npm + HostName 10.0.20.10 + User root + +Host ghrunner + HostName 10.0.20.204 + User ghrunner + +Host rustdesk + HostName 10.0.20.205 + User root + +Host wakapi + HostName 10.0.20.206 + User root + + +# Tailnet +Host tn-bluetrix + HostName 100.64.233.14 + User pbd diff --git a/config/starship/starship-custom.toml b/config/starship/custom.toml similarity index 100% rename from config/starship/starship-custom.toml rename to config/starship/custom.toml diff --git a/config/starship/default.toml b/config/starship/default.toml new file mode 100644 index 0000000..fd0b726 --- /dev/null +++ b/config/starship/default.toml @@ -0,0 +1,1091 @@ +# Starship default configuration — all modules with their default values +# Reference: https://starship.rs/config/ +# Use this as a base to build your own prompt. +# Uncomment and modify any section to override a default. + +"$schema" = 'https://starship.rs/config-schema.json' + +# ─── PROMPT (top-level) ──────────────────────────────────────────────────────── +format = """ +$username\ +$hostname\ +$localip\ +$shlvl\ +$singularity\ +$kubernetes\ +$directory\ +$vcsh\ +$fossil_branch\ +$fossil_metrics\ +$git_branch\ +$git_commit\ +$git_state\ +$git_metrics\ +$git_status\ +$hg_branch\ +$hg_state\ +$pijul_channel\ +$docker_context\ +$package\ +$c\ +$cmake\ +$cobol\ +$daml\ +$dart\ +$deno\ +$dotnet\ +$elixir\ +$elm\ +$erlang\ +$fennel\ +$fortran\ +$gleam\ +$golang\ +$guix_shell\ +$haskell\ +$haxe\ +$helm\ +$java\ +$julia\ +$kotlin\ +$gradle\ +$lua\ +$nim\ +$nodejs\ +$ocaml\ +$opa\ +$perl\ +$php\ +$pulumi\ +$purescript\ +$python\ +$quarto\ +$raku\ +$rlang\ +$red\ +$ruby\ +$rust\ +$scala\ +$solidity\ +$swift\ +$terraform\ +$typst\ +$vlang\ +$vagrant\ +$zig\ +$buf\ +$nix_shell\ +$conda\ +$meson\ +$spack\ +$memory_usage\ +$aws\ +$gcloud\ +$openstack\ +$azure\ +$nats\ +$direnv\ +$env_var\ +$mise\ +$crystal\ +$custom\ +$sudo\ +$cmd_duration\ +$line_break\ +$jobs\ +$battery\ +$time\ +$status\ +$os\ +$container\ +$netns\ +$shell\ +$character\ +""" + +right_format = '' +scan_timeout = 30 +command_timeout = 500 +add_newline = true +palette = '' +follow_symlinks = true + +# ─── AWS ─────────────────────────────────────────────────────────────────────── +[aws] +format = 'on [$symbol($profile )(\($region\) )(\[$duration\] )]($style)' +symbol = '☁️ ' +style = 'bold yellow' +expiration_symbol = 'X' +disabled = false +force_display = false +region_aliases = {} +profile_aliases = {} + +# ─── AZURE ───────────────────────────────────────────────────────────────────── +[azure] +format = 'on [$symbol($subscription)]($style) ' +symbol = '󰠅 ' +style = 'blue bold' +disabled = true +subscription_aliases = {} + +# ─── BATTERY ─────────────────────────────────────────────────────────────────── +[battery] +format = '[$symbol$percentage]($style) ' +full_symbol = '󰁹 ' +charging_symbol = '󰂄 ' +discharging_symbol = '󰂃 ' +unknown_symbol = '󰁽 ' +empty_symbol = '󰂎 ' +disabled = false + +# ─── BUF ─────────────────────────────────────────────────────────────────────── +[buf] +format = 'with [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🐃 ' +style = 'bold blue' +detect_extensions = [] +detect_files = ['buf.yaml', 'buf.gen.yaml', 'buf.work.yaml'] +detect_folders = [] +disabled = false + +# ─── BUN ─────────────────────────────────────────────────────────────────────── +[bun] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🥟 ' +style = 'bold red' +detect_extensions = [] +detect_files = ['bun.lock', 'bun.lockb', 'bunfig.toml'] +detect_folders = [] +disabled = false + +# ─── C ───────────────────────────────────────────────────────────────────────── +[c] +format = 'via [$symbol($version(-$name) )]($style)' +version_format = 'v${raw}' +symbol = 'C ' +style = 'bold 149' +detect_extensions = ['c', 'h'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── C++ ─────────────────────────────────────────────────────────────────────── +[cpp] +format = 'via [$symbol($version(-$name) )]($style)' +version_format = 'v${raw}' +symbol = 'C++ ' +style = 'bold 149' +detect_extensions = ['cpp', 'cc', 'cxx', 'c++', 'hpp', 'hh', 'hxx', 'h++', 'tcc'] +detect_files = [] +detect_folders = [] +disabled = true + +# ─── CHARACTER ───────────────────────────────────────────────────────────────── +[character] +format = '$symbol ' +success_symbol = '[❯](bold green)' +error_symbol = '[❯](bold red)' +vimcmd_symbol = '[❮](bold green)' +vimcmd_replace_one_symbol = '[❮](bold purple)' +vimcmd_replace_symbol = '[❮](bold purple)' +vimcmd_visual_symbol = '[❮](bold yellow)' +disabled = false + +# ─── CMAKE ───────────────────────────────────────────────────────────────────── +[cmake] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '△ ' +style = 'bold blue' +detect_extensions = [] +detect_files = ['CMakeLists.txt', 'CMakeCache.txt'] +detect_folders = [] +disabled = false + +# ─── CMD DURATION ────────────────────────────────────────────────────────────── +[cmd_duration] +format = 'took [$duration]($style) ' +style = 'bold yellow' +min_time = 2000 +show_milliseconds = false +disabled = false +show_notifications = false +min_time_to_notify = 45000 + +# ─── COBOL ───────────────────────────────────────────────────────────────────── +[cobol] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⚙️ ' +style = 'bold blue' +detect_extensions = ['cbl', 'cob', 'CBL', 'COB'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── CONDA ───────────────────────────────────────────────────────────────────── +[conda] +format = 'via [$symbol$environment]($style) ' +symbol = '🅒 ' +style = 'bold green' +truncation_length = 1 +ignore_base = true +detect_env_vars = ['!PIXI_ENVIRONMENT_NAME'] +disabled = false + +# ─── CONTAINER ───────────────────────────────────────────────────────────────── +[container] +format = '[$symbol \[$name\]]($style) ' +symbol = '⬢' +style = 'bold red dimmed' +disabled = false + +# ─── CRYSTAL ─────────────────────────────────────────────────────────────────── +[crystal] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🔮 ' +style = 'bold red' +detect_extensions = ['cr'] +detect_files = ['shard.yml'] +detect_folders = [] +disabled = false + +# ─── DAML ────────────────────────────────────────────────────────────────────── +[daml] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = 'Λ ' +style = 'bold cyan' +detect_extensions = [] +detect_files = ['daml.yaml'] +detect_folders = [] +disabled = false + +# ─── DART ────────────────────────────────────────────────────────────────────── +[dart] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🎯 ' +style = 'bold blue' +detect_extensions = ['dart'] +detect_files = ['pubspec.yaml', 'pubspec.yml', 'pubspec.lock'] +detect_folders = ['.dart_tool'] +disabled = false + +# ─── DENO ────────────────────────────────────────────────────────────────────── +[deno] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🦕 ' +style = 'green bold' +detect_extensions = [] +detect_files = ['deno.json', 'deno.jsonc', 'deno.lock', 'mod.ts', 'mod.js', 'deps.ts', 'deps.js'] +detect_folders = [] +disabled = false + +# ─── DIRECTORY ───────────────────────────────────────────────────────────────── +[directory] +format = '[$path]($style)[$read_only]($read_only_style) ' +style = 'bold cyan' +truncation_length = 3 +truncate_to_repo = true +truncation_symbol = '' +home_symbol = '~' +read_only = '🔒' +read_only_style = 'red' +use_os_path_sep = true +use_logical_path = true +fish_style_pwd_dir_length = 0 +disabled = false + +# ─── DIRENV ──────────────────────────────────────────────────────────────────── +[direnv] +format = '[$symbol$loaded/$allowed]($style) ' +symbol = 'direnv ' +style = 'bold orange' +detect_files = ['.envrc'] +detect_env_vars = ['DIRENV_FILE'] +allowed_msg = 'allowed' +not_allowed_msg = 'not allowed' +denied_msg = 'denied' +loaded_msg = 'loaded' +unloaded_msg = 'not loaded' +disabled = true + +# ─── DOCKER CONTEXT ──────────────────────────────────────────────────────────── +[docker_context] +format = 'via [$symbol$context]($style) ' +symbol = '🐳 ' +style = 'blue bold' +only_with_files = true +detect_extensions = [] +detect_files = ['compose.yml', 'compose.yaml', 'docker-compose.yml', 'docker-compose.yaml', 'Dockerfile'] +detect_folders = [] +disabled = false + +# ─── DOTNET ──────────────────────────────────────────────────────────────────── +[dotnet] +format = 'via [$symbol($version )(🎯 $tfm )]($style)' +version_format = 'v${raw}' +symbol = '.NET ' +style = 'bold blue' +heuristic = true +detect_extensions = ['csproj', 'fsproj', 'xproj'] +detect_files = ['global.json', 'project.json', 'Directory.Build.props', 'Directory.Build.targets', 'Packages.props'] +detect_folders = [] +disabled = false + +# ─── ELIXIR ──────────────────────────────────────────────────────────────────── +[elixir] +format = 'via [$symbol($version \(OTP $otp_version\) )]($style)' +version_format = 'v${raw}' +symbol = '💧 ' +style = 'bold purple' +detect_extensions = [] +detect_files = ['mix.exs'] +detect_folders = [] +disabled = false + +# ─── ELM ─────────────────────────────────────────────────────────────────────── +[elm] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🌳 ' +style = 'cyan bold' +detect_extensions = ['elm'] +detect_files = ['elm.json', 'elm-package.json', '.elm-version'] +detect_folders = ['elm-stuff'] +disabled = false + +# ─── ENV_VAR ─────────────────────────────────────────────────────────────────── +[env_var] +format = 'with [$env_value]($style) ' +symbol = '' +disabled = false + +# ─── ERLANG ──────────────────────────────────────────────────────────────────── +[erlang] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = ' ' +style = 'bold red' +detect_extensions = [] +detect_files = ['rebar.config', 'erlang.mk'] +detect_folders = [] +disabled = false + +# ─── FENNEL ──────────────────────────────────────────────────────────────────── +[fennel] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🧅 ' +style = 'bold green' +detect_extensions = ['fnl'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── FILL ────────────────────────────────────────────────────────────────────── +[fill] +symbol = '.' +style = 'bold black' +disabled = false + +# ─── FORTRAN ─────────────────────────────────────────────────────────────────── +[fortran] +format = 'via [$symbol($version )]($style)' +version_format = '${raw}' +symbol = ' ' +style = 'bold purple' +detect_extensions = ['f', 'F', 'for', 'FOR', 'ftn', 'FTN', 'f77', 'F77', 'f90', 'F90', 'f95', 'F95', 'f03', 'F03', 'f08', 'F08', 'f18', 'F18'] +detect_files = ['fpm.toml'] +detect_folders = [] +disabled = false + +# ─── FOSSIL BRANCH ───────────────────────────────────────────────────────────── +[fossil_branch] +format = 'on [$symbol$branch]($style) ' +symbol = ' ' +style = 'bold purple' +truncation_length = 9223372036854775807 +truncation_symbol = '…' +disabled = true + +# ─── FOSSIL METRICS ──────────────────────────────────────────────────────────── +[fossil_metrics] +format = '([+$added]($added_style) )([-$deleted]($deleted_style) )' +added_style = 'bold green' +deleted_style = 'bold red' +only_nonzero_diffs = true +disabled = true + +# ─── GCLOUD ──────────────────────────────────────────────────────────────────── +[gcloud] +format = 'on [$symbol$account(@$domain)(\($region\))]($style) ' +symbol = '☁️ ' +style = 'bold blue' +region_aliases = {} +project_aliases = {} +detect_env_vars = [] +disabled = false + +# ─── GIT BRANCH ──────────────────────────────────────────────────────────────── +[git_branch] +format = 'on [$symbol$branch(:$remote_branch)]($style) ' +symbol = ' ' +style = 'bold purple' +truncation_length = 9223372036854775807 +truncation_symbol = '…' +always_show_remote = false +only_attached = false +ignore_branches = [] +ignore_bare_repo = false +disabled = false + +# ─── GIT COMMIT ──────────────────────────────────────────────────────────────── +[git_commit] +format = '[\($hash$tag\)]($style) ' +style = 'bold green' +commit_hash_length = 7 +only_detached = true +tag_disabled = true +tag_max_candidates = 0 +tag_symbol = ' 🏷 ' +disabled = false + +# ─── GIT STATE ───────────────────────────────────────────────────────────────── +[git_state] +format = '\([$state( $progress_current/$progress_total)]($style)\) ' +style = 'bold yellow' +rebase = 'REBASING' +merge = 'MERGING' +revert = 'REVERTING' +cherry_pick = 'CHERRY-PICKING' +bisect = 'BISECTING' +am = 'AM' +am_or_rebase = 'AM/REBASE' +disabled = false + +# ─── GIT METRICS ─────────────────────────────────────────────────────────────── +[git_metrics] +format = '([+$added]($added_style) )([-$deleted]($deleted_style) )' +added_style = 'bold green' +deleted_style = 'bold red' +only_nonzero_diffs = true +ignore_submodules = false +disabled = true + +# ─── GIT STATUS ──────────────────────────────────────────────────────────────── +[git_status] +format = '([\[$all_status$ahead_behind\]]($style) )' +style = 'bold red' +conflicted = '=' +ahead = '⇡' +behind = '⇣' +diverged = '⇕' +up_to_date = '' +untracked = '?' +stashed = '\$' +modified = '!' +staged = '+' +renamed = '»' +deleted = '✘' +typechanged = '' +ignore_submodules = false +disabled = false +use_git_executable = false + +# ─── GLEAM ───────────────────────────────────────────────────────────────────── +[gleam] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⭐ ' +style = 'bold #FFAFF3' +detect_extensions = ['gleam'] +detect_files = ['gleam.toml'] +disabled = false + +# ─── GOLANG ──────────────────────────────────────────────────────────────────── +[golang] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🐹 ' +style = 'bold cyan' +detect_extensions = ['go'] +detect_files = ['go.mod', 'go.sum', 'go.work', 'glide.yaml', 'Gopkg.yml', 'Gopkg.lock', '.go-version'] +detect_folders = ['Godeps'] +not_capable_style = 'bold red' +disabled = false + +# ─── GRADLE ──────────────────────────────────────────────────────────────────── +[gradle] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🅶 ' +style = 'bold bright-cyan' +detect_extensions = ['gradle', 'gradle.kts'] +detect_files = [] +detect_folders = ['gradle'] +recursive = false +disabled = false + +# ─── GUIX SHELL ──────────────────────────────────────────────────────────────── +[guix_shell] +format = 'via [$symbol]($style) ' +symbol = '🐃 ' +style = 'yellow bold' +disabled = false + +# ─── HASKELL ─────────────────────────────────────────────────────────────────── +[haskell] +format = 'via [$symbol($version )]($style)' +symbol = 'λ ' +style = 'bold purple' +detect_extensions = ['hs', 'cabal', 'hs-boot'] +detect_files = ['stack.yaml', 'cabal.project'] +detect_folders = [] +disabled = false + +# ─── HAXE ────────────────────────────────────────────────────────────────────── +[haxe] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⌘ ' +style = 'bold fg:202' +detect_extensions = ['hx', 'hxml'] +detect_files = ['project.xml', 'Project.xml', 'application.xml', 'haxelib.json', 'hxformat.json', '.haxerc'] +detect_folders = ['.haxelib', 'haxe_libraries'] +disabled = false + +# ─── HELM ────────────────────────────────────────────────────────────────────── +[helm] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⎈ ' +style = 'bold white' +detect_extensions = [] +detect_files = ['helmfile.yaml', 'Chart.yaml'] +detect_folders = [] +disabled = false + +# ─── HOSTNAME ────────────────────────────────────────────────────────────────── +[hostname] +format = '[$ssh_symbol$hostname]($style) in ' +style = 'bold dimmed green' +ssh_only = true +ssh_symbol = '🌐 ' +trim_at = '.' +detect_env_vars = [] +aliases = {} +disabled = false + +# ─── JAVA ────────────────────────────────────────────────────────────────────── +[java] +format = 'via [${symbol}(${version} )]($style)' +version_format = 'v${raw}' +symbol = '☕ ' +style = 'red dimmed' +detect_extensions = ['java', 'class', 'gradle', 'jar', 'cljs', 'cljc'] +detect_files = ['pom.xml', 'build.gradle.kts', 'build.sbt', '.java-version', 'deps.edn', 'project.clj', 'build.boot', '.sdkmanrc'] +detect_folders = [] +disabled = false + +# ─── JOBS ────────────────────────────────────────────────────────────────────── +[jobs] +format = '[$symbol$number]($style) ' +symbol = '✦' +style = 'bold blue' +symbol_threshold = 1 +number_threshold = 2 +disabled = false + +# ─── JULIA ───────────────────────────────────────────────────────────────────── +[julia] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = 'ஃ ' +style = 'bold purple' +detect_extensions = ['jl'] +detect_files = ['Project.toml', 'Manifest.toml'] +detect_folders = [] +disabled = false + +# ─── KOTLIN ──────────────────────────────────────────────────────────────────── +[kotlin] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🅺 ' +style = 'bold blue' +detect_extensions = ['kt', 'kts'] +detect_files = [] +detect_folders = [] +kotlin_binary = 'kotlin' +disabled = false + +# ─── KUBERNETES ──────────────────────────────────────────────────────────────── +[kubernetes] +format = '[$symbol$context( \($namespace\))]($style) in ' +symbol = '☸ ' +style = 'cyan bold' +detect_extensions = [] +detect_files = [] +detect_folders = [] +detect_env_vars = [] +disabled = true + +# ─── LINE BREAK ──────────────────────────────────────────────────────────────── +[line_break] +disabled = false + +# ─── LOCAL IP ────────────────────────────────────────────────────────────────── +[localip] +disabled = true + +# ─── LUA ─────────────────────────────────────────────────────────────────────── +[lua] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🌙 ' +style = 'bold blue' +detect_extensions = ['lua'] +detect_files = ['.lua-version', 'lua.cfg'] +detect_folders = [] +disabled = false + +# ─── MEMORY USAGE ────────────────────────────────────────────────────────────── +[memory_usage] +format = '$symbol[$ram_pct]($style) ' +symbol = '🧠 ' +style = 'white dimmed' +threshold = 75 +disabled = true + +# ─── MESON ───────────────────────────────────────────────────────────────────── +[meson] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⬢ ' +style = 'blue bold' +detect_extensions = [] +detect_files = ['meson.build', 'meson_options.txt'] +detect_folders = [] +disabled = false + +# ─── NATS ────────────────────────────────────────────────────────────────────── +[nats] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '✉️ ' +style = 'bold purple' +detect_extensions = [] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── NIM ─────────────────────────────────────────────────────────────────────── +[nim] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '👑 ' +style = 'yellow bold' +detect_extensions = ['nim', 'nims'] +detect_files = ['nim.cfg'] +detect_folders = [] +disabled = false + +# ─── NODEJS ──────────────────────────────────────────────────────────────────── +[nodejs] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = ' ' +style = 'bold green' +detect_extensions = ['js', 'mjs', 'cjs', 'ts', 'mts', 'cts'] +detect_files = ['package.json', '.node-version', '.nvmrc'] +detect_folders = ['node_modules'] +disabled = false + +# ─── OCAML ───────────────────────────────────────────────────────────────────── +[ocaml] +format = 'via [$symbol($version )(\($switch_name\) )]($style)' +version_format = 'v${raw}' +symbol = '🐫 ' +style = 'bold yellow' +detect_extensions = ['opam', 'ml', 'mli', 'mll', 'mly'] +detect_files = ['dune', 'dune-project', 'jbuild', '.merlin'] +detect_folders = ['_opam', 'opam-nix'] +disabled = false + +# ─── OPA ─────────────────────────────────────────────────────────────────────── +[opa] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🪖 ' +style = 'bold blue' +detect_extensions = ['rego'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── OPENSTACK ───────────────────────────────────────────────────────────────── +[openstack] +format = 'on [$symbol$cloud]($style) ' +symbol = '☁️ ' +style = 'bold yellow' +disabled = false + +# ─── OS ──────────────────────────────────────────────────────────────────────── +[os] +format = '[$symbol]($style)' +style = 'bold white' +disabled = true + +[os.symbols] +Alpaquita = '🔔 ' +Alpine = '🏔 ' +AlmaLinux = '💠 ' +Amazon = '🙂 ' +Android = '🤖 ' +Arch = '🎗 ' +Artix = '🎗 ' +CentOS = '💠 ' +Debian = '🌀 ' +DragonFly = '🐉 ' +Emscripten = '🔗 ' +EndeavourOS = '🚀 ' +Fedora = '🎩 ' +FreeBSD = '😈 ' +Garuda = '🦅 ' +Gentoo = '🗜 ' +HardenedBSD = '🛡 ' +Illumos = '🐦 ' +Kali = '🐉 ' +Linux = '🐧 ' +Macos = '🍎 ' +Manjaro = '🥭 ' +Mariner = '🌊 ' +MidnightBSD = '🌘 ' +Mint = '🌿 ' +NetBSD = '🚩 ' +NixOS = '❄ ' +OpenBSD = '🐡 ' +OpenCloudOS = '☁ ' +openEuler = '🦉 ' +openSUSE = '🦎 ' +OracleLinux = '🦴 ' +Pop = '🍭 ' +Raspbian = '🍓 ' +Redhat = '🎩 ' +RedHatEnterprise = '🎩 ' +RockyLinux = '💠 ' +Redox = '🧪 ' +Solus = '⛵ ' +SUSE = '🦎 ' +Ubuntu = '🎯 ' +Ultramarine = '🔷 ' +Unknown = '❓ ' +Void = ' ' +Windows = '🪟 ' + +# ─── PACKAGE ─────────────────────────────────────────────────────────────────── +[package] +format = 'is [$symbol$version]($style) ' +symbol = '📦 ' +version_format = 'v${raw}' +style = '208 bold' +display_private = false +detect_extensions = [] +detect_files = ['package.json', 'pyproject.toml', 'Cargo.toml'] +detect_folders = [] +disabled = false + +# ─── PERL ────────────────────────────────────────────────────────────────────── +[perl] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🐪 ' +style = 'bold blue' +detect_extensions = ['pl', 'pm', 't'] +detect_files = ['Makefile.PL', 'Build.PL', 'cpanfile', 'cpanfile.snapshot'] +detect_folders = [] +disabled = false + +# ─── PHP ─────────────────────────────────────────────────────────────────────── +[php] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🐘 ' +style = 'bold purple' +detect_extensions = ['php'] +detect_files = ['composer.json', '.php-version'] +detect_folders = [] +disabled = false + +# ─── PIJUL CHANNEL ───────────────────────────────────────────────────────────── +[pijul_channel] +format = 'on [$symbol$channel]($style) ' +symbol = '🪶 ' +style = 'bold purple' +truncation_length = 2147483647 +truncation_symbol = '…' +disabled = true + +# ─── PULUMI ──────────────────────────────────────────────────────────────────── +[pulumi] +format = 'via [$symbol$stack]($style) ' +symbol = '🛡️ ' +style = 'bold 5' +search_upwards = true +disabled = false + +# ─── PURESCRIPT ──────────────────────────────────────────────────────────────── +[purescript] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '<=> ' +style = 'bold white' +detect_extensions = ['purs'] +detect_files = ['spago.dhall', 'spago.yaml'] +detect_folders = [] +disabled = false + +# ─── PYTHON ──────────────────────────────────────────────────────────────────── +[python] +format = 'via [${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)' +version_format = 'v${raw}' +symbol = '🐍 ' +style = 'yellow bold' +pyenv_version_name = false +pyenv_prefix = 'pyenv ' +python_binary = ['python3', 'python', 'python2'] +detect_extensions = ['py'] +detect_files = ['.python-version', 'Pipfile', '__pycache__', 'pyproject.toml', 'requirements.txt', 'setup.py', 'tox.ini'] +detect_folders = [] +disabled = false + +# ─── QUARTO ──────────────────────────────────────────────────────────────────── +[quarto] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⚙️ ' +style = 'bold blue' +detect_extensions = ['qmd'] +detect_files = ['_quarto.yml', '_quarto.yaml', 'quarto.yml', 'quarto.yaml'] +detect_folders = [] +disabled = false + +# ─── RAKU ────────────────────────────────────────────────────────────────────── +[raku] +format = 'via [$symbol($version-$vm_version )]($style)' +version_format = 'v${raw}' +symbol = '🦋 ' +style = 'bold 149' +detect_extensions = ['raku', 'rakumod'] +detect_files = ['META6.json'] +detect_folders = [] +disabled = false + +# ─── RED ─────────────────────────────────────────────────────────────────────── +[red] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🔴 ' +style = 'bold red' +detect_extensions = ['red', 'reds'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── RLANG ───────────────────────────────────────────────────────────────────── +[rlang] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '📊 ' +style = 'blue bold' +detect_extensions = ['R', 'Rmd', 'Rsx', 'Rproj'] +detect_files = ['.Rprofile', '.Renviron'] +detect_folders = ['.Rproj.user'] +disabled = false + +# ─── RUBY ────────────────────────────────────────────────────────────────────── +[ruby] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '💎 ' +style = 'bold red' +detect_extensions = ['rb'] +detect_files = ['Gemfile', '.ruby-version', '.rbenv-version'] +detect_folders = [] +disabled = false + +# ─── RUST ────────────────────────────────────────────────────────────────────── +[rust] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🦀 ' +style = 'bold red' +detect_extensions = ['rs'] +detect_files = ['Cargo.toml', 'Cargo.lock'] +detect_folders = [] +disabled = false + +# ─── SCALA ───────────────────────────────────────────────────────────────────── +[scala] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🆂 ' +style = 'bold red' +detect_extensions = ['scala'] +detect_files = ['.scalaenv', '.sbtenv', 'build.sbt'] +detect_folders = ['.metals', '.bloop'] +disabled = false + +# ─── SHELL ───────────────────────────────────────────────────────────────────── +[shell] +format = '[$symbol]($style) ' +symbol = 'shell' +style = 'cyan bold' +disabled = false + +# ─── SHLVL ───────────────────────────────────────────────────────────────────── +[shlvl] +format = '[$symbol($level )]($style)' +symbol = '↕️ ' +style = 'bold blue' +threshold = 2 +disabled = true + +# ─── SINGULARITY ─────────────────────────────────────────────────────────────── +[singularity] +format = '[$symbol\[$env\]]($style) ' +symbol = '' +style = 'blue bold dimmed' +disabled = false + +# ─── SOLIDITY ────────────────────────────────────────────────────────────────── +[solidity] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🔗 ' +style = 'bold blue' +detect_extensions = ['sol'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── SPACK ───────────────────────────────────────────────────────────────────── +[spack] +format = 'via [$symbol$environment]($style) ' +symbol = '🅢 ' +style = 'bold blue' +disabled = false + +# ─── STATUS ──────────────────────────────────────────────────────────────────── +[status] +format = '[\[$symbol$common_meaning$signal_name$maybe_int\]]($style) ' +symbol = '✖' +success_symbol = '✓' +not_executable_symbol = '🚫' +not_found_symbol = '🔍' +sigint_symbol = '⚡' +signal_symbol = '⚡' +style = 'bold red' +map_symbol = false +pipestatus = false +pipestatus_separator = '|' +pipestatus_format = '\[$pipestatus\] => [$symbol$common_meaning$signal_name$maybe_int]($style)' +disabled = true + +# ─── SUDO ────────────────────────────────────────────────────────────────────── +[sudo] +format = '[$symbol]($style)' +symbol = '🧙 ' +style = 'bold blue' +show_sync_icon = false +disabled = true + +# ─── SWIFT ───────────────────────────────────────────────────────────────────── +[swift] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '🐦 ' +style = 'bold 202' +detect_extensions = ['swift'] +detect_files = ['Package.swift'] +detect_folders = [] +disabled = false + +# ─── TERRAFORM ───────────────────────────────────────────────────────────────── +[terraform] +format = 'via [$symbol$workspace]($style) ' +version_format = 'v${raw}' +symbol = '💠 ' +style = 'bold 105' +detect_extensions = ['tf', 'tfplan', 'tfstate'] +detect_files = [] +detect_folders = ['.terraform'] +disabled = false + +# ─── TIME ────────────────────────────────────────────────────────────────────── +[time] +format = '🕙[\[$time\]]($style) ' +time_format = 'T%T' +style = 'bold yellow' +use_12hr = false +utc_enabled = false +disabled = true + +# ─── TYPST ───────────────────────────────────────────────────────────────────── +[typst] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '📜 ' +style = 'bold #0093A7' +detect_extensions = ['typ'] +detect_files = [] +detect_folders = [] +disabled = false + +# ─── USERNAME ────────────────────────────────────────────────────────────────── +[username] +format = '[$user]($style)in ' +style_user = 'white bold' +style_root = 'red bold' +show_always = false +disabled = false + +# ─── VAGRANT ─────────────────────────────────────────────────────────────────── +[vagrant] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⍱ ' +style = 'cyan bold' +detect_extensions = [] +detect_files = ['Vagrantfile'] +detect_folders = [] +disabled = false + +# ─── VLANG ───────────────────────────────────────────────────────────────────── +[vlang] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = 'V ' +style = 'bold blue' +detect_extensions = ['v'] +detect_files = ['v.mod', 'vpkg.json', '.vpkg-lock.json'] +detect_folders = [] +disabled = false + +# ─── ZIG ─────────────────────────────────────────────────────────────────────── +[zig] +format = 'via [$symbol($version )]($style)' +version_format = 'v${raw}' +symbol = '⚡ ' +style = 'bold yellow' +detect_extensions = ['zig'] +detect_files = ['build.zig', 'build.zig.zon'] +detect_folders = [] +disabled = false diff --git a/config/starship/demo.toml b/config/starship/demo.toml new file mode 100644 index 0000000..a75d57e --- /dev/null +++ b/config/starship/demo.toml @@ -0,0 +1,202 @@ +"$schema" = 'https://starship.rs/config-schema.json' + +palette = 'custom' + +format = """ +[](base00)\ +$os\ +[](fg:base00 bg:base0d)\ +$username\ +[](fg:base0d bg:base08)\ +$directory\ +[](fg:base08 bg:base0b)\ +$git_branch\ +$git_status\ +[](fg:base0b bg:base03)\ +$cmake\ +$dart\ +$deno\ +$dotnet\ +$golang\ +$kotlin\ +$lua\ +$nodejs\ +$nix_shell\ +$php\ +$python\ +$rust\ +$ruby\ +[](fg:base03 bg:base0a)\ +$aws\ +$azure\ +$gcloud\ +[](fg:base03 bg:base02)\ +$docker_context\ +[](fg:base02 bg:base0c)\ +$time\ +[ ](fg:base0c)\ +$package\ +""" + +# Disable the blank line at the start of the prompt +# add_newline = false + +[os] +style = "bg:base00 fg:base0c" +format = "[ $symbol $path ]($style)" +disabled = false + +[os.symbols] +Arch = "󰣇" +Debian = "" +FreeBSD = "" +Linux = "" +Macos = "" +Windows = "" + +[username] +show_always = true +style_user = "bg:base0d fg:base00" +style_root = "bg:base09" +format = '[ $user ]($style)' +disabled = false + +[directory] +style = "bold bg:base08 fg:base00" +home_symbol = "" +format = "[ 󰉋 $path ]($style)" +truncation_length = 3 +truncation_symbol = "…/" + +[git_branch] +symbol = "󰊢" +style = "bold bg:base0b fg:base00" +format = '[ $symbol $branch ]($style)' + +[git_status] +style = "bold bg:base0b fg:base00" +format = '[$all_status$ahead_behind ]($style)' + + +# Languages +[cmake] +symbol = "△" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[dart] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[deno] +symbol = "🦕" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[dotnet] +symbol = "󰪮" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[golang] +symbol = "󰟓" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[kotlin] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[lua] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[nix_shell] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol $state ]($style)' + +[nodejs] +symbol = "󰎙" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[php] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[python] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[ruby] +symbol = "" +style = "bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +[rust] +symbol = "" +style = " bold bg:base03 fg:base00" +format = '[ $symbol ($version) ]($style)' + +# Cloud Services +[aws] +symbol = " " +style = "bold bg:base0a fg:base00" +format = '[ $symbol$profile ]($style)' +disabled = false + +[azure] +symbol = "󰠅 " +style = "bold bg:base0a fg:base00" +format = '[ $symbol($subscription) ]($style)' +disabled = false + +[gcloud] +symbol = "󱇶 " +style = "bold bg:base0a fg:base00" +format = '[ $symbol$account(@$domain)(\($region\)) ]($style)' +disabled = false + +# Container +[docker_context] +symbol = "󰡨" +style = "bold bg:base02 fg:base00" +format = '[ $symbol $context ]($style)' + +[package] +symbol = "󰏗" +style = "bold bg:base0c fg:base00" +format = '[ $symbol $version ]($style)' + +# Time +[time] +disabled = false +time_format = "%R" +style = "bold bg:base0c fg:base00" +format = '[ $time ]($style)' + + +# Color Scheme +[palettes.custom] +base00 = '#240809' # Background — was "os" +base01 = '#412423' # Surface +base02 = '#5c3e3d' # Selection — was "docker" +base03 = '#946b6a' # Muted — was "language" +base04 = '#bfa2a1' # Dim text +base05 = '#ceb5b4' # Foreground +base06 = '#d9bebd' # Bright text +base07 = '#efd5d4' # Brightest +base08 = '#ffc3c1' # Red — was "directory" +base09 = '#ffa5a3' # Orange — was "root" +base0a = '#ff8384' # Yellow +base0b = '#da4a52' # Green — was "git" +base0c = '#ffdfde' # Cyan — was "time" +base0d = '#a48685' # Blue — was "username" +base0e = '#f6646a' # Magenta +base0f = '#d6807e' # Rust \ No newline at end of file diff --git a/config/starship/knuckles.toml b/config/starship/knuckles.toml new file mode 100644 index 0000000..85666cc --- /dev/null +++ b/config/starship/knuckles.toml @@ -0,0 +1,170 @@ +"$schema" = 'https://starship.rs/config-schema.json' + +# color scheme +# yellow #ffdfde +# blue #a48685 +# red #c0303e +# organge #da4a52 +# pink #c0303e +# purple #c0303e +# green #a48685 +# aqua #a48685 +# teal #a48685 + +format = """ +[](#ffdfde)\ +$os\ +[](fg:#ffdfde bg:#a48685)\ +$username\ +[](fg:#a48685 bg:#c0303e)\ +$directory\ +[](fg:#c0303e bg:#c0303e)\ +$git_branch\ +$git_status\ +[](fg:#c0303e bg:#a48685)\ +$c\ +$elixir\ +$elm\ +$golang\ +$gradle\ +$haskell\ +$java\ +$julia\ +$nodejs\ +$nim\ +$rust\ +$scala\ +[](fg:#a48685 bg:#a48685)\ +$docker_context\ +[](fg:#a48685 bg:#a48685)\ +$time\ +[ ](fg:#a48685)\ +""" + +# Disable the blank line at the start of the prompt +# add_newline = false + +# An alternative to the username module which displays a symbol that +# represents the current operating system +[os] +style = "bg:#ffdfde fg:#240809" +format = "[ $symbol $path ]($style)" +disabled = false # Disabled by default + +[os.symbols] +Arch = "󰣇" +Debian = "" +FreeBSD = "" +Linux = "" +Macos = "" +Windows = "" + +# You can also replace your username with a neat symbol like or disable this +# and use the os module below +[username] +show_always = true +# symbol = "" +style_user = "bg:#a48685" +style_root = "bg:#da4a52" +format = '[ $user ]($style)' +disabled = false + +[directory] +style = "bold bg:#c0303e" +home_symbol = "" +format = "[ 󰉋 $path ]($style)" +truncation_length = 3 +truncation_symbol = "…/" + +# Here is how you can shorten some long paths by text replacement +# similar to mapped_locations in Oh My Posh: +# [directory.substitutions] +# "Documents" = "󰈙" +# "Downloads" = "" +# "Music" = "" +# "Pictures" = "" +# "aclu-emails" = "󱃜" + +[git_branch] +symbol = "󰊢" +style = "bold bg:#c0303e" +format = '[ $symbol $branch ]($style)' + +[git_status] +style = "bold bg:#c0303e" +format = '[$all_status$ahead_behind ]($style)' + +[c] +symbol = "" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[cpp] +symbol = "" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[elixir] +symbol = "" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[elm] +symbol = "" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[golang] +symbol = "󰟓" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[gradle] +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[haskell] +symbol = " " +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[java] +symbol = " " +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[julia] +symbol = " " +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[nodejs] +symbol = "󰎙" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[nim] +symbol = "󰆥" +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[rust] +symbol = "" +style = " bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[scala] +symbol = " " +style = "bold bg:#a48685" +format = '[ $symbol ($version) ]($style)' + +[docker_context] +symbol = "󰡨" +style = "bold bg:#a48685" +format = '[ $symbol $context ]($style)' + +[time] +disabled = false +time_format = "%R" +style = "bold bg:#a48685" +format = '[  $time ]($style)' diff --git a/config/starship/starship.toml b/config/starship/starship.toml index 026188c..95d6130 100644 --- a/config/starship/starship.toml +++ b/config/starship/starship.toml @@ -1,15 +1,27 @@ "$schema" = 'https://starship.rs/config-schema.json' +# color scheme +# yellow #cef542 +# blue #0a63c9 +# red #d40f51 +# organge #db490b +# pink #c91e7a +# purple #9a348e +# green #417e37 +# aqua #06969a +# teal #33658a + format = """ -[](#9A348E)\ +[](#cef542)\ $os\ +[](fg:#cef542 bg:#0a63c9)\ $username\ -[](bg:#d40f51 fg:#9A348E)\ +[](fg:#0a63c9 bg:#c91e7a)\ $directory\ -[](fg:#d40f51 bg:#417E37)\ +[](fg:#c91e7a bg:#9a348e)\ $git_branch\ $git_status\ -[](fg:#417E37 bg:#cef542)\ +[](fg:#9a348e bg:#417e37)\ $c\ $elixir\ $elm\ @@ -22,125 +34,137 @@ $nodejs\ $nim\ $rust\ $scala\ -[](fg:#cef542 bg:#06969A)\ +[](fg:#417e37 bg:#06969a)\ $docker_context\ -[](fg:#06969A bg:#33658A)\ +[](fg:#06969a bg:#33658a)\ $time\ -[ ](fg:#33658A)\ +[ ](fg:#33658a)\ """ # Disable the blank line at the start of the prompt # add_newline = false +# An alternative to the username module which displays a symbol that +# represents the current operating system +[os] +style = "bg:#cef542 fg:#151515" +format = "[ $symbol $path ]($style)" +disabled = false # Disabled by default + +[os.symbols] +Arch = "󰣇" +Debian = "" +FreeBSD = "" +Linux = "" +Macos = "" +Windows = "" + # You can also replace your username with a neat symbol like or disable this # and use the os module below [username] show_always = true -style_user = "bg:#9A348E" -style_root = "bg:#9A348E" -format = '[$user ]($style)' +# symbol = "" +style_user = "bg:#0a63c9" +style_root = "bg:#db490b" +format = '[ $user ]($style)' disabled = false -# An alternative to the username module which displays a symbol that -# represents the current operating system -[os] -style = "bg:#9A348E" -disabled = true # Disabled by default - [directory] -style = "bg:#d40f51" -format = "[ $path ]($style)" +style = "bold bg:#c91e7a" +home_symbol = "" +format = "[ 󰉋 $path ]($style)" truncation_length = 3 truncation_symbol = "…/" # Here is how you can shorten some long paths by text replacement # similar to mapped_locations in Oh My Posh: -[directory.substitutions] -"Documents" = "󰈙 " -"Downloads" = " " -"Music" = " " -"Pictures" = " " +# [directory.substitutions] +# "Documents" = "󰈙" +# "Downloads" = "" +# "Music" = "" +# "Pictures" = "" +# "aclu-emails" = "󱃜" + +[git_branch] +symbol = "󰊢" +style = "bold bg:#9a348e" +format = '[ $symbol $branch ]($style)' + +[git_status] +style = "bold bg:#9a348e" +format = '[$all_status$ahead_behind ]($style)' [c] -symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +symbol = "" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [cpp] -symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +symbol = "" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' -[docker_context] -symbol = " " -style = "bg:#06969A" -format = '[ $symbol $context ]($style)' - [elixir] -symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +symbol = "" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [elm] -symbol = " " -style = "bg:#cef542 fg:#1a1a1a" -format = '[ $symbol ($version) ]($style)' - -[git_branch] symbol = "" -style = "bg:#417E37" -format = '[ $symbol $branch ]($style)' - -[git_status] -style = "bg:#417E37" -format = '[$all_status$ahead_behind ]($style)' +style = "bold bg:#417e37" +format = '[ $symbol ($version) ]($style)' [golang] -symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +symbol = "󰟓" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [gradle] -style = "bg:#cef542 fg:#1a1a1a" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [haskell] symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [java] symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [julia] symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [nodejs] -symbol = "" -style = "bg:#cef542 fg:#1a1a1a" +symbol = "󰎙" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [nim] -symbol = "󰆥 " -style = "bg:#cef542 fg:#1a1a1a" +symbol = "󰆥" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [rust] -symbol = "" -style = "bg:#cef542 fg:#1a1a1a" +symbol = "" +style = " bold bg:#417e37" format = '[ $symbol ($version) ]($style)' [scala] symbol = " " -style = "bg:#cef542 fg:#1a1a1a" +style = "bold bg:#417e37" format = '[ $symbol ($version) ]($style)' +[docker_context] +symbol = "󰡨" +style = "bold bg:#06969a" +format = '[ $symbol $context ]($style)' + [time] disabled = false -time_format = "%R" # Hour:Minute Format -style = "bg:#33658A" -format = '[ ♥ $time ]($style)' +time_format = "%R" +style = "bold bg:#33658a" +format = '[  $time ]($style)' diff --git a/config/symlinks.yml b/config/symlinks.yml index a50561e..9c6cbf3 100644 --- a/config/symlinks.yml +++ b/config/symlinks.yml @@ -105,6 +105,11 @@ warp: symlinks: starburst.yml: ~/.warp/starburst.yml +wezterm: + enabled: true + symlinks: + wezterm.lua: ~/.config/wezterm/wezterm.lua + zsh: enabled: true symlinks: diff --git a/config/tmux/theme.conf b/config/tmux/theme.conf new file mode 100644 index 0000000..c6835d2 --- /dev/null +++ b/config/tmux/theme.conf @@ -0,0 +1,9 @@ +# ── Theme colors ───────────────────────────────────────────────────────────── +# Change these values to re-theme the whole tmux setup. +# This file is sourced from tmux.conf — don't source it directly. + +set -g @tmux_color_bg "#1a1b26" +set -g @tmux_color_fg "#c0caf5" +set -g @tmux_color_accent "#d6f511" +set -g @tmux_color_muted "#565f89" +set -g @tmux_color_active "#9ece6a" \ No newline at end of file diff --git a/config/tmux/tmux.conf b/config/tmux/tmux.conf new file mode 100644 index 0000000..0e6cdd2 --- /dev/null +++ b/config/tmux/tmux.conf @@ -0,0 +1,88 @@ +# ── Prefix key ────────────────────────────────── +# Default is Ctrl+b — many people remap to Ctrl+a +# Uncomment to change: +# unbind C-b +# set -g prefix C-a +# bind C-a send-prefix + +# ── Theme ──────────────────────────────────────── +source-file ~/.config/dotfiles/config/tmux/theme.conf + +# ── General behavior ──────────────────────────── +set -g history-limit 10000 +set -g mouse on +set -sg escape-time 0 +set -g base-index 1 +setw -g pane-base-index 1 +set -g renumber-windows on + + +# ── macOS clipboard integration ───────────────── +set -g set-clipboard on +bind -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy" +bind -T copy-mode-vi Enter send -X copy-pipe-and-cancel "pbcopy" + + +# ── Pane splitting ────────────────────────────── +bind | split-window -h -c "#{pane_current_path}" +bind - split-window -v -c "#{pane_current_path}" +unbind '"' +unbind % + + +# ── Pane navigation (vim-style) ───────────────── +bind h select-pane -L +bind j select-pane -D +bind k select-pane -U +bind l select-pane -R + + +# ── Pane resizing ─────────────────────────────── +bind -r H resize-pane -L 5 +bind -r J resize-pane -D 5 +bind -r K resize-pane -U 5 +bind -r L resize-pane -R 5 + + +# ── Window Navigation ─────────────────────────── +bind -n M-1 select-window -t 1 +bind -n M-2 select-window -t 2 +bind -n M-3 select-window -t 3 +bind -n M-4 select-window -t 4 +bind -n M-5 select-window -t 5 +bind -n M-6 select-window -t 6 +bind -n M-7 select-window -t 7 +bind -n M-8 select-window -t 8 +bind -n M-9 select-window -t 9 + + +# ── Reload config ─────────────────────────────── +bind r source-file ~/.config/tmux/tmux.conf + +# ── New window/pane in current directory ──────── +bind c new-window -c "#{pane_current_path}" + +# ── Status bar styling ────────────────────────── +set -g status-position top +set -g status-left-length 30 + +# ── True color support ────────────────────────── +set -g default-terminal "tmux-256color" +set -ag terminal-overrides ",xterm-256color:RGB" + +# ── Apply theme colors ────────────────────────── +set -g status-style "bg=#{@tmux_color_bg},fg=#{@tmux_color_fg}" + +setw -g window-status-current-style "bg=#{@tmux_color_accent},fg=#{@tmux_color_bg},bold" +setw -g window-status-current-format " #I:#W " + +setw -g window-status-style "bg=#{@tmux_color_bg},fg=#{@tmux_color_muted}" +setw -g window-status-format "#I" + +set -g pane-border-style "fg=#{@tmux_color_muted}" +set -g pane-active-border-style "fg=#{@tmux_color_accent}" + +set -g status-left "#[fg=#{@tmux_color_fg},bold] #S #[bg=#{@tmux_color_bg}] " +set -g status-right "#[fg=#{@tmux_color_active}]%Y-%m-%d #[fg=#{@tmux_color_active}]%H:%M " + +set -g message-style "bg=#{@tmux_color_accent},fg=#{@tmux_color_bg}" \ No newline at end of file diff --git a/config/wezterm/wezterm.lua b/config/wezterm/wezterm.lua new file mode 100644 index 0000000..809009a --- /dev/null +++ b/config/wezterm/wezterm.lua @@ -0,0 +1,22 @@ +-- Pull in the wezterm API +local wezterm = require 'wezterm' + +-- This will hold the configuration. +local config = wezterm.config_builder() + +-- This is where you actually apply your config choices. +config.enable_tab_bar = false +-- config.use_fancy_tab_bar = false +config.window_background_opacity = 0.9 + +-- For example, changing the initial geometry for new windows: +config.initial_cols = 120 +config.initial_rows = 50 + +-- or, changing the font size and color scheme. +config.font_size = 16 +config.font = wezterm.font 'FiraCode NF' +-- config.color_scheme = 'Batman' + +-- Finally, return the configuration to wezterm: +return config \ No newline at end of file diff --git a/config/yazi/keymap.toml b/config/yazi/keymap.toml new file mode 100644 index 0000000..757fd9a --- /dev/null +++ b/config/yazi/keymap.toml @@ -0,0 +1,389 @@ +# A TOML linter such as Tombi can use this schema to validate your config. +# If you encounter any problems, please file an issue at https://github.com/yazi-rs/schemas. + +#:schema https://yazi-rs.github.io/schemas/keymap.json + +[mgr] + +keymap = [ + { on = "", run = "escape", desc = "Exit visual mode, clear selection, or cancel search" }, + { on = "", run = "escape", desc = "Exit visual mode, clear selection, or cancel search" }, + { on = "q", run = "quit", desc = "Quit the process" }, + { on = "Q", run = "quit --no-cwd-file", desc = "Quit without outputting cwd-file" }, + { on = "", run = "close", desc = "Close the current tab, or quit if it's last" }, + { on = "", run = "suspend", desc = "Suspend the process" }, + + # Hop around + { on = "k", run = "arrow prev", desc = "Previous file" }, + { on = "j", run = "arrow next", desc = "Next file" }, + { on = "", run = "arrow prev", desc = "Previous file" }, + { on = "", run = "arrow next", desc = "Next file" }, + + { on = [ "g", "g" ], run = "arrow top", desc = "Go to top" }, + { on = "G", run = "arrow bot", desc = "Go to bottom" }, + { on = "", run = "arrow top", desc = "Go to top" }, + { on = "", run = "arrow bot", desc = "Go to bottom" }, + + { on = "", run = "arrow -50%", desc = "Move cursor up half page" }, + { on = "", run = "arrow 50%", desc = "Move cursor down half page" }, + { on = "", run = "arrow -100%", desc = "Move cursor up one page" }, + { on = "", run = "arrow 100%", desc = "Move cursor down one page" }, + + { on = "", run = "arrow -50%", desc = "Move cursor up half page" }, + { on = "", run = "arrow 50%", desc = "Move cursor down half page" }, + { on = "", run = "arrow -100%", desc = "Move cursor up one page" }, + { on = "", run = "arrow 100%", desc = "Move cursor down one page" }, + + # Navigation + { on = "h", run = "leave", desc = "Back to the parent directory" }, + { on = "l", run = "enter", desc = "Enter the child directory" }, + + { on = "", run = "leave", desc = "Back to the parent directory" }, + { on = "", run = "enter", desc = "Enter the child directory" }, + + { on = "H", run = "back", desc = "Back to previous directory" }, + { on = "L", run = "forward", desc = "Forward to next directory" }, + + # Toggle + { on = "", run = [ "toggle", "arrow 1" ], desc = "Toggle the current selection state" }, + { on = "", run = "toggle_all --state=on", desc = "Select all files" }, + { on = "", run = "toggle_all", desc = "Invert selection of all files" }, + + # Visual mode + { on = "v", run = "visual_mode", desc = "Enter visual mode (selection mode)" }, + { on = "V", run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" }, + + # Seeking + { on = "K", run = "seek -5", desc = "Seek up 5 units in the preview" }, + { on = "J", run = "seek 5", desc = "Seek down 5 units in the preview" }, + + # Spotting + { on = "", run = "spot", desc = "Spot hovered file" }, + + # Operation + { on = "o", run = "open", desc = "Open selected files" }, + { on = "O", run = "open --interactive", desc = "Open selected files interactively" }, + { on = "", run = "open", desc = "Open selected files" }, + { on = "", run = "open --interactive", desc = "Open selected files interactively" }, + { on = "y", run = "yank", desc = "Yank selected files (copy)" }, + { on = "x", run = "yank --cut", desc = "Yank selected files (cut)" }, + { on = "p", run = "paste", desc = "Paste yanked files" }, + { on = "P", run = "paste --force", desc = "Paste yanked files (overwrite if the destination exists)" }, + { on = "-", run = "link", desc = "Symlink the absolute path of yanked files" }, + { on = "_", run = "link --relative", desc = "Symlink the relative path of yanked files" }, + { on = "", run = "hardlink", desc = "Hardlink yanked files" }, + { on = "Y", run = "unyank", desc = "Cancel the yank status" }, + { on = "X", run = "unyank", desc = "Cancel the yank status" }, + { on = "d", run = "remove", desc = "Trash selected files" }, + { on = "D", run = "remove --permanently", desc = "Permanently delete selected files" }, + { on = "a", run = "create", desc = "Create a file (ends with / for directories)" }, + { on = "A", run = "bulk_create", desc = "Bulk create files" }, + { on = "r", run = "rename --cursor=before_ext", desc = "Rename selected file(s)" }, + { on = ";", run = "shell --interactive", desc = "Run a shell command" }, + { on = ":", run = "shell --block --interactive", desc = "Run a shell command (block until finishes)" }, + { on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" }, + { on = "s", run = "search --via=fd", desc = "Search files by name via fd" }, + { on = "S", run = "search --via=rg", desc = "Search files by content via ripgrep" }, + { on = "", run = "escape --search", desc = "Cancel the ongoing search" }, + { on = "z", run = "plugin fzf", desc = "Jump to a file/directory via fzf" }, + { on = "Z", run = "plugin zoxide", desc = "Jump to a directory via zoxide" }, + + # Linemode + { on = [ "m", "s" ], run = "linemode size", desc = "Linemode: size" }, + { on = [ "m", "p" ], run = "linemode permissions", desc = "Linemode: permissions" }, + { on = [ "m", "b" ], run = "linemode btime", desc = "Linemode: btime" }, + { on = [ "m", "m" ], run = "linemode mtime", desc = "Linemode: mtime" }, + { on = [ "m", "o" ], run = "linemode owner", desc = "Linemode: owner" }, + { on = [ "m", "n" ], run = "linemode none", desc = "Linemode: none" }, + + # Copy + { on = [ "c", "c" ], run = "copy path", desc = "Copy file path" }, + { on = [ "c", "C" ], run = "copy url", desc = "Copy file URL" }, + { on = [ "c", "d" ], run = "copy dirpath", desc = "Copy directory path" }, + { on = [ "c", "D" ], run = "copy dirurl", desc = "Copy directory URL" }, + { on = [ "c", "f" ], run = "copy filename", desc = "Copy filename" }, + { on = [ "c", "n" ], run = "copy name_without_ext", desc = "Copy filename without extension" }, + + # Filter + { on = "f", run = "filter --smart", desc = "Filter files" }, + + # Find + { on = "/", run = "find --smart", desc = "Find next file" }, + { on = "?", run = "find --previous --smart", desc = "Find previous file" }, + { on = "n", run = "find_arrow", desc = "Next found" }, + { on = "N", run = "find_arrow --previous", desc = "Previous found" }, + + # Sorting + { on = [ ",", "m" ], run = [ "sort mtime --reverse=no", "linemode mtime" ], desc = "Sort by modified time" }, + { on = [ ",", "M" ], run = [ "sort mtime --reverse=yes", "linemode mtime" ], desc = "Sort by modified time (reverse)" }, + { on = [ ",", "b" ], run = [ "sort btime --reverse=no", "linemode btime" ], desc = "Sort by birth time" }, + { on = [ ",", "B" ], run = [ "sort btime --reverse=yes", "linemode btime" ], desc = "Sort by birth time (reverse)" }, + { on = [ ",", "e" ], run = "sort extension --reverse=no", desc = "Sort by extension" }, + { on = [ ",", "E" ], run = "sort extension --reverse=yes", desc = "Sort by extension (reverse)" }, + { on = [ ",", "a" ], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" }, + { on = [ ",", "A" ], run = "sort alphabetical --reverse=yes", desc = "Sort alphabetically (reverse)" }, + { on = [ ",", "n" ], run = "sort natural --reverse=no", desc = "Sort naturally" }, + { on = [ ",", "N" ], run = "sort natural --reverse=yes", desc = "Sort naturally (reverse)" }, + { on = [ ",", "s" ], run = [ "sort size --reverse=no", "linemode size" ], desc = "Sort by size" }, + { on = [ ",", "S" ], run = [ "sort size --reverse=yes", "linemode size" ], desc = "Sort by size (reverse)" }, + { on = [ ",", "r" ], run = "sort random --reverse=no", desc = "Sort randomly" }, + + # Goto + { on = [ "g", "h" ], run = "cd ~", desc = "Go home" }, + { on = [ "g", "c" ], run = "cd ~/.config", desc = "Go to ~/.config" }, + { on = [ "g", "d" ], run = "cd ~/Downloads", desc = "Go to ~/Downloads" }, + { on = [ "g", "t" ], run = "plugin trash", desc = "Go to trash bin" }, + { on = [ "g", "" ], run = "cd --interactive", desc = "Jump interactively" }, + { on = [ "g", "f" ], run = "follow", desc = "Follow hovered symlink" }, + + # Tabs + { on = [ "t", "t" ], run = "tab_create --current", desc = "Create a new tab in CWD" }, + { on = [ "t", "r" ], run = "tab_rename --interactive", desc = "Rename current tab" }, + + { on = "1", run = "tab_switch 0", desc = "Switch to first tab" }, + { on = "2", run = "tab_switch 1", desc = "Switch to second tab" }, + { on = "3", run = "tab_switch 2", desc = "Switch to third tab" }, + { on = "4", run = "tab_switch 3", desc = "Switch to fourth tab" }, + { on = "5", run = "tab_switch 4", desc = "Switch to fifth tab" }, + { on = "6", run = "tab_switch 5", desc = "Switch to sixth tab" }, + { on = "7", run = "tab_switch 6", desc = "Switch to seventh tab" }, + { on = "8", run = "tab_switch 7", desc = "Switch to eighth tab" }, + { on = "9", run = "tab_switch 8", desc = "Switch to ninth tab" }, + + { on = "[", run = "tab_switch -1 --relative", desc = "Switch to previous tab" }, + { on = "]", run = "tab_switch 1 --relative", desc = "Switch to next tab" }, + + { on = "{", run = "tab_swap -1", desc = "Swap current tab with previous tab" }, + { on = "}", run = "tab_swap 1", desc = "Swap current tab with next tab" }, + + # Tasks + { on = "w", run = "tasks:show", desc = "Show task manager" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[tasks] + +keymap = [ + { on = "", run = "close", desc = "Close task manager" }, + { on = "", run = "close", desc = "Close task manager" }, + { on = "", run = "close", desc = "Close task manager" }, + { on = "w", run = "close", desc = "Close task manager" }, + + { on = "k", run = "arrow prev", desc = "Previous task" }, + { on = "j", run = "arrow next", desc = "Next task" }, + + { on = "", run = "arrow prev", desc = "Previous task" }, + { on = "", run = "arrow next", desc = "Next task" }, + + { on = "", run = "inspect", desc = "Inspect the task" }, + { on = "x", run = "cancel", desc = "Cancel the task" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[spot] + +keymap = [ + { on = "", run = "close", desc = "Close the spot" }, + { on = "", run = "close", desc = "Close the spot" }, + { on = "", run = "close", desc = "Close the spot" }, + { on = "", run = "close", desc = "Close the spot" }, + + { on = "k", run = "arrow prev", desc = "Previous line" }, + { on = "j", run = "arrow next", desc = "Next line" }, + { on = "h", run = "swipe prev", desc = "Swipe to previous file" }, + { on = "l", run = "swipe next", desc = "Swipe to next file" }, + + { on = "", run = "arrow prev", desc = "Previous line" }, + { on = "", run = "arrow next", desc = "Next line" }, + { on = "", run = "swipe prev", desc = "Swipe to previous file" }, + { on = "", run = "swipe next", desc = "Swipe to next file" }, + + # Copy + { on = [ "c", "c" ], run = "copy cell", desc = "Copy selected cell" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[pick] + +keymap = [ + { on = "", run = "close", desc = "Cancel pick" }, + { on = "", run = "close", desc = "Cancel pick" }, + { on = "", run = "close", desc = "Cancel pick" }, + { on = "", run = "close --submit", desc = "Submit the pick" }, + + { on = "k", run = "arrow prev", desc = "Previous option" }, + { on = "j", run = "arrow next", desc = "Next option" }, + + { on = "", run = "arrow prev", desc = "Previous option" }, + { on = "", run = "arrow next", desc = "Next option" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[input] + +keymap = [ + { on = "", run = "close", desc = "Cancel input" }, + { on = "", run = "close --submit", desc = "Submit input" }, + { on = "", run = "escape", desc = "Back to normal mode, or cancel input" }, + { on = "", run = "escape", desc = "Back to normal mode, or cancel input" }, + + # Mode + { on = "i", run = "insert", desc = "Enter insert mode" }, + { on = "I", run = [ "move first-char", "insert" ], desc = "Move to the BOL, and enter insert mode" }, + { on = "a", run = "insert --append", desc = "Enter append mode" }, + { on = "A", run = [ "move eol", "insert --append" ], desc = "Move to the EOL, and enter append mode" }, + { on = "v", run = "visual", desc = "Enter visual mode" }, + { on = "r", run = "replace", desc = "Replace a single character" }, + + # Selection + { on = "V", run = [ "move bol", "visual", "move eol" ], desc = "Select from BOL to EOL" }, + { on = "", run = [ "move eol", "visual", "move bol" ], desc = "Select from EOL to BOL" }, + { on = "", run = [ "move bol", "visual", "move eol" ], desc = "Select from BOL to EOL" }, + + # Character-wise movement + { on = "h", run = "move -1", desc = "Move back a character" }, + { on = "l", run = "move 1", desc = "Move forward a character" }, + { on = "", run = "move -1", desc = "Move back a character" }, + { on = "", run = "move 1", desc = "Move forward a character" }, + { on = "", run = "move -1", desc = "Move back a character" }, + { on = "", run = "move 1", desc = "Move forward a character" }, + + # Word-wise movement + { on = "b", run = "backward", desc = "Move back to the start of the current or previous word" }, + { on = "B", run = "backward wide", desc = "Move back to the start of the current or previous WORD" }, + { on = "w", run = "forward", desc = "Move forward to the start of the next word" }, + { on = "W", run = "forward wide", desc = "Move forward to the start of the next WORD" }, + { on = "e", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" }, + { on = "E", run = "forward wide --end-of-word", desc = "Move forward to the end of the current or next WORD" }, + { on = "", run = "backward lean", desc = "Move back to the start of the current or previous word" }, + { on = "", run = "forward lean --end-of-word", desc = "Move forward to the end of the current or next word" }, + { on = "", run = "backward lean", desc = "Move back to the start of the current or previous word" }, + { on = "", run = "forward lean --end-of-word", desc = "Move forward to the end of the current or next word" }, + + # Line-wise movement + { on = "0", run = "move bol", desc = "Move to the BOL" }, + { on = "$", run = "move eol", desc = "Move to the EOL" }, + { on = "_", run = "move first-char", desc = "Move to the first non-whitespace character" }, + { on = "^", run = "move first-char", desc = "Move to the first non-whitespace character" }, + { on = "", run = "move bol", desc = "Move to the BOL" }, + { on = "", run = "move eol", desc = "Move to the EOL" }, + { on = "", run = "move bol", desc = "Move to the BOL" }, + { on = "", run = "move eol", desc = "Move to the EOL" }, + + # Delete + { on = "", run = "backspace", desc = "Delete the character before the cursor" }, + { on = "", run = "backspace --under", desc = "Delete the character under the cursor" }, + { on = "", run = "backspace", desc = "Delete the character before the cursor" }, + { on = "", run = "backspace --under", desc = "Delete the character under the cursor" }, + + # Kill + { on = "", run = "kill bol", desc = "Kill backwards to the BOL" }, + { on = "", run = "kill eol", desc = "Kill forwards to the EOL" }, + { on = "", run = "kill backward", desc = "Kill backwards to the start of the current word" }, + { on = "", run = "kill forward", desc = "Kill forwards to the end of the current word" }, + { on = "", run = "kill backward", desc = "Kill backwards to the start of the current word" }, + { on = "", run = "kill forward", desc = "Kill forwards to the end of the current word" }, + + # Cut/Yank/Paste + { on = "d", run = "delete --cut", desc = "Cut selected characters" }, + { on = "D", run = [ "delete --cut", "move eol" ], desc = "Cut until EOL" }, + { on = "c", run = "delete --cut --insert", desc = "Cut selected characters, and enter insert mode" }, + { on = "C", run = [ "delete --cut --insert", "move eol" ], desc = "Cut until EOL, and enter insert mode" }, + { on = "s", run = [ "delete --cut --insert", "move 1" ], desc = "Cut current character, and enter insert mode" }, + { on = "S", run = [ "move bol", "delete --cut --insert", "move eol" ], desc = "Cut from BOL until EOL, and enter insert mode" }, + { on = "x", run = [ "delete --cut", "move 1 --in-operating" ], desc = "Cut current character" }, + { on = "y", run = "yank", desc = "Copy selected characters" }, + { on = "p", run = "paste", desc = "Paste copied characters after the cursor" }, + { on = "P", run = "paste --before", desc = "Paste copied characters before the cursor" }, + + # Undo/Redo/Casefy + { on = "u", run = [ "undo", "casefy lower" ], desc = "Undo, or lowercase if in visual mode" }, + { on = "U", run = "casefy upper", desc = "Uppercase" }, + { on = "", run = "redo", desc = "Redo the last operation" }, + + # History + { on = "k", run = "recall -1", desc = "Recall previous input" }, + { on = "j", run = "recall 1", desc = "Recall next input" }, + { on = "", run = "recall -1", desc = "Recall previous input" }, + { on = "", run = "recall 1", desc = "Recall next input" }, + { on = "", run = "recall -1", desc = "Recall previous input" }, + { on = "", run = "recall 1", desc = "Recall next input" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[confirm] + +keymap = [ + { on = "", run = "close", desc = "Cancel the confirm" }, + { on = "", run = "close", desc = "Cancel the confirm" }, + { on = "", run = "close", desc = "Cancel the confirm" }, + { on = "", run = "close --submit", desc = "Submit the confirm" }, + + { on = "n", run = "close", desc = "Cancel the confirm" }, + { on = "y", run = "close --submit", desc = "Submit the confirm" }, + + { on = "k", run = "arrow prev", desc = "Previous line" }, + { on = "j", run = "arrow next", desc = "Next line" }, + + { on = "", run = "arrow prev", desc = "Previous line" }, + { on = "", run = "arrow next", desc = "Next line" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[cmp] + +keymap = [ + { on = "", run = "close", desc = "Cancel completion" }, + { on = "", run = "close --submit", desc = "Submit the completion" }, + { on = "", run = [ "close --submit", "input:close --submit" ], desc = "Complete and submit the input" }, + + { on = "", run = "arrow prev", desc = "Previous item" }, + { on = "", run = "arrow next", desc = "Next item" }, + + { on = "", run = "arrow prev", desc = "Previous item" }, + { on = "", run = "arrow next", desc = "Next item" }, + + { on = "", run = "arrow prev", desc = "Previous item" }, + { on = "", run = "arrow next", desc = "Next item" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[help] + +keymap = [ + { on = "", run = "escape", desc = "Enter normal mode, or hide help menu" }, + { on = "", run = "escape", desc = "Enter normal mode, or hide help menu" }, + { on = "", run = "close", desc = "Close help menu" }, + { on = "", run = "close --submit", desc = "Close help menu and run selected action(s)" }, + + # Navigation + { on = "k", run = "arrow prev", desc = "Previous line" }, + { on = "j", run = "arrow next", desc = "Next line" }, + + { on = "", run = "arrow prev", desc = "Previous line" }, + { on = "", run = "arrow next", desc = "Next line" }, + + { on = "", run = "arrow prev", desc = "Previous line" }, + { on = "", run = "arrow next", desc = "Next line" }, +] \ No newline at end of file diff --git a/config/yazi/theme.toml b/config/yazi/theme.toml new file mode 100644 index 0000000..f675bf6 --- /dev/null +++ b/config/yazi/theme.toml @@ -0,0 +1,1006 @@ +# If the user's terminal is in dark mode, Yazi will load `theme-dark.toml` on startup; otherwise, `theme-light.toml`. +# You can override any parts of them that are not related to the dark/light mode in your own `theme.toml`. + +# If you want to dynamically override their content based on dark/light mode, you can specify two different flavors +# for dark and light modes under `[flavor]`, and do so in those flavors instead. + +#:schema https://yazi-rs.github.io/schemas/theme.json +# vim:fileencoding=utf-8:foldmethod=marker + +# : Flavor {{{ + +[flavor] +dark = "" +light = "" + +# : }}} + + +# : App {{{ + +[app] +overall = {} + +# : }}} + + +# : Manager {{{ + +[mgr] +cwd = { fg = "cyan" } + +# Find +find_keyword = { fg = "yellow", bold = true, italic = true, underline = true } +find_position = { fg = "magenta", bg = "reset", bold = true, italic = true } + +# Symlink +symlink_target = { italic = true } + +# Marker +marker_copied = { fg = "lightgreen", bg = "lightgreen" } +marker_cut = { fg = "lightred", bg = "lightred" } +marker_marked = { fg = "lightcyan", bg = "lightcyan" } +marker_selected = { fg = "lightyellow", bg = "lightyellow" } +marker_symbol = "│" + +# Count +count_copied = { fg = "white", bg = "green" } +count_cut = { fg = "white", bg = "red" } +count_selected = { fg = "black", bg = "yellow" } + +# Border +border_symbol = "│" +border_style = { fg = "gray" } + +# Highlighting +syntect_theme = "" + +# : }}} + + +# : Tabs {{{ + +[tabs] +active = { bg = "blue", bold = true } +inactive = { fg = "blue", bg = "gray" } + +# Separator +sep_inner = { open = "", close = "" } +sep_outer = { open = "", close = "" } + +# : }}} + + +# : Mode {{{ + +[mode] +normal_main = { bg = "blue", bold = true } +normal_alt = { fg = "blue", bg = "gray" } + +# Select mode +select_main = { bg = "red", bold = true } +select_alt = { fg = "red", bg = "gray" } + +# Unset mode +unset_main = { bg = "red", bold = true } +unset_alt = { fg = "red", bg = "gray" } + +# : }}} + + +# : Indicator of hovered file {{{ + +[indicator] +parent = { reversed = true } +current = { reversed = true } +preview = { underline = true } +padding = { open = "", close = "" } + +# : }}} + + +# : Status bar {{{ + +[status] +overall = {} +sep_left = { open = "", close = "" } +sep_right = { open = "", close = "" } + +# Permissions +perm_sep = { fg = "darkgray" } +perm_type = { fg = "green" } +perm_read = { fg = "yellow" } +perm_write = { fg = "red" } +perm_exec = { fg = "cyan" } + +# Progress +progress_label = { bold = true } +progress_normal = { fg = "green", bg = "black" } +progress_error = { fg = "yellow", bg = "red" } + +# : }}} + + +# : Which {{{ + +[which] +border = { fg = "blue" } +cols = 3 +mask = {} +cand = { fg = "lightcyan" } +rest = { fg = "darkgray" } +desc = { fg = "lightmagenta" } +separator = "  " +separator_style = { fg = "darkgray" } + +# : }}} + + +# : Confirmation {{{ + +[confirm] +border = { fg = "blue" } +title = { fg = "blue" } +body = {} +list = {} +btn_yes = { reversed = true } +btn_no = {} +btn_labels = [ " [Y]es ", " (N)o " ] + +# : }}} + + +# : Spotter {{{ + +[spot] +border = { fg = "blue" } +title = { fg = "blue" } + +# Table +tbl_col = { fg = "blue" } +tbl_cell = { fg = "yellow", reversed = true } + +# : }}} + + +# : Notification {{{ + +[notify] +title_info = { fg = "green" } +title_warn = { fg = "yellow" } +title_error = { fg = "red" } + +# Icons +icon_info = "" +icon_warn = "" +icon_error = "" + +# : }}} + + +# : Picker {{{ + +[pick] +border = { fg = "blue" } +active = { fg = "magenta", bold = true } +inactive = {} + +# : }}} + + +# : Input {{{ + +[input] +border = { fg = "blue" } +title = {} +value = {} +selected = { reversed = true } + +# : }}} + + +# : Completion {{{ + +[cmp] +border = { fg = "blue" } +active = { reversed = true } +inactive = {} + +# Icons +icon_file = "" +icon_folder = "" +icon_command = "" + +# : }}} + + +# : Task manager {{{ + +[tasks] +border = { fg = "blue" } +title = {} +hovered = { fg = "magenta", bold = true } + +# : }}} + + +# : Help menu {{{ + +[help] +border = { fg = "blue" } +chord = { fg = "cyan" } +action = {} +hovered = { reversed = true, bold = true } + +# : }}} + + +# : File-specific styles {{{ + +[filetype] +rules = [ + # Image + { mime = "**/image/*", fg = "yellow" }, + # Media + { mime = "**/{audio,video}/*", fg = "magenta" }, + # Archive + { mime = "**/application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "red" }, + # Document + { mime = "**/application/{pdf,doc,rtf}", fg = "cyan" }, + # Virtual file system + { mime = "vfs/{absent,stale}", fg = "gray" }, + # Special file + { url = "*", is = "orphan", bg = "red" }, + { url = "*", is = "exec" , fg = "green" }, + # Dummy file + { url = "*", is = "dummy", bg = "red" }, + { url = "*/", is = "dummy", bg = "red" }, + # Fallback + { url = "*/", fg = "blue" } +] + +# : }}} + + +# : Icons {{{ + +[icon] +globs = [] +dirs = [ + { name = ".config", text = "", fg = "#ff9800" }, + { name = ".git", text = "", fg = "#00bcd4" }, + { name = ".github", text = "", fg = "#03a9f4" }, + { name = ".npm", text = "", fg = "#03a9f4" }, + { name = "Desktop", text = "", fg = "#00bcd4" }, + { name = "Development", text = "", fg = "#00bcd4" }, + { name = "Documents", text = "", fg = "#00bcd4" }, + { name = "Downloads", text = "", fg = "#00bcd4" }, + { name = "Library", text = "", fg = "#00bcd4" }, + { name = "Movies", text = "", fg = "#00bcd4" }, + { name = "Music", text = "", fg = "#00bcd4" }, + { name = "Pictures", text = "", fg = "#00bcd4" }, + { name = "Public", text = "", fg = "#00bcd4" }, + { name = "Videos", text = "", fg = "#00bcd4" }, +] +files = [ + { name = ".babelrc", text = "", fg = "#cbcb41" }, + { name = ".bash_profile", text = "", fg = "#89e051" }, + { name = ".bashrc", text = "", fg = "#89e051" }, + { name = ".clang-format", text = "", fg = "#6d8086" }, + { name = ".clang-tidy", text = "", fg = "#6d8086" }, + { name = ".codespellrc", text = "󰓆", fg = "#35da60" }, + { name = ".condarc", text = "", fg = "#43b02a" }, + { name = ".dockerignore", text = "󰡨", fg = "#458ee6" }, + { name = ".ds_store", text = "", fg = "#41535b" }, + { name = ".editorconfig", text = "", fg = "#fff2f2" }, + { name = ".env", text = "", fg = "#faf743" }, + { name = ".eslintignore", text = "", fg = "#4b32c3" }, + { name = ".eslintrc", text = "", fg = "#4b32c3" }, + { name = ".git-blame-ignore-revs", text = "", fg = "#f54d27" }, + { name = ".gitattributes", text = "", fg = "#f54d27" }, + { name = ".gitconfig", text = "", fg = "#f54d27" }, + { name = ".gitignore", text = "", fg = "#f54d27" }, + { name = ".gitlab-ci.yml", text = "", fg = "#e24329" }, + { name = ".gitmodules", text = "", fg = "#f54d27" }, + { name = ".gtkrc-2.0", text = "", fg = "#ffffff" }, + { name = ".gvimrc", text = "", fg = "#019833" }, + { name = ".justfile", text = "", fg = "#6d8086" }, + { name = ".luacheckrc", text = "", fg = "#00a2ff" }, + { name = ".luaurc", text = "", fg = "#00a2ff" }, + { name = ".mailmap", text = "󰊢", fg = "#f54d27" }, + { name = ".nanorc", text = "", fg = "#440077" }, + { name = ".npmignore", text = "", fg = "#e8274b" }, + { name = ".npmrc", text = "", fg = "#e8274b" }, + { name = ".nuxtrc", text = "󱄆", fg = "#00c58e" }, + { name = ".nvmrc", text = "", fg = "#5fa04e" }, + { name = ".pnpmfile.cjs", text = "", fg = "#f9ad02" }, + { name = ".pre-commit-config.yaml", text = "󰛢", fg = "#f8b424" }, + { name = ".prettierignore", text = "", fg = "#4285f4" }, + { name = ".prettierrc", text = "", fg = "#4285f4" }, + { name = ".prettierrc.cjs", text = "", fg = "#4285f4" }, + { name = ".prettierrc.js", text = "", fg = "#4285f4" }, + { name = ".prettierrc.json", text = "", fg = "#4285f4" }, + { name = ".prettierrc.json5", text = "", fg = "#4285f4" }, + { name = ".prettierrc.mjs", text = "", fg = "#4285f4" }, + { name = ".prettierrc.toml", text = "", fg = "#4285f4" }, + { name = ".prettierrc.yaml", text = "", fg = "#4285f4" }, + { name = ".prettierrc.yml", text = "", fg = "#4285f4" }, + { name = ".pylintrc", text = "", fg = "#6d8086" }, + { name = ".settings.json", text = "", fg = "#854cc7" }, + { name = ".SRCINFO", text = "󰣇", fg = "#0f94d2" }, + { name = ".vimrc", text = "", fg = "#019833" }, + { name = ".Xauthority", text = "", fg = "#e54d18" }, + { name = ".xinitrc", text = "", fg = "#e54d18" }, + { name = ".Xresources", text = "", fg = "#e54d18" }, + { name = ".xsession", text = "", fg = "#e54d18" }, + { name = ".zprofile", text = "", fg = "#89e051" }, + { name = ".zshenv", text = "", fg = "#89e051" }, + { name = ".zshrc", text = "", fg = "#89e051" }, + { name = "_gvimrc", text = "", fg = "#019833" }, + { name = "_vimrc", text = "", fg = "#019833" }, + { name = "AUTHORS", text = "", fg = "#a172ff" }, + { name = "AUTHORS.txt", text = "", fg = "#a172ff" }, + { name = "brewfile", text = "", fg = "#701516" }, + { name = "bspwmrc", text = "", fg = "#2f2f2f" }, + { name = "build", text = "", fg = "#89e051" }, + { name = "build.gradle", text = "", fg = "#005f87" }, + { name = "build.zig.zon", text = "", fg = "#f69a1b" }, + { name = "bun.lock", text = "", fg = "#eadcd1" }, + { name = "bun.lockb", text = "", fg = "#eadcd1" }, + { name = "cantorrc", text = "", fg = "#1c99f3" }, + { name = "checkhealth", text = "󰓙", fg = "#75b4fb" }, + { name = "cmakelists.txt", text = "", fg = "#dce3eb" }, + { name = "code_of_conduct", text = "", fg = "#e41662" }, + { name = "code_of_conduct.md", text = "", fg = "#e41662" }, + { name = "commit_editmsg", text = "", fg = "#f54d27" }, + { name = "commitlint.config.js", text = "󰜘", fg = "#2b9689" }, + { name = "commitlint.config.ts", text = "󰜘", fg = "#2b9689" }, + { name = "compose.yaml", text = "󰡨", fg = "#458ee6" }, + { name = "compose.yml", text = "󰡨", fg = "#458ee6" }, + { name = "config", text = "", fg = "#6d8086" }, + { name = "containerfile", text = "󰡨", fg = "#458ee6" }, + { name = "copying", text = "", fg = "#cbcb41" }, + { name = "copying.lesser", text = "", fg = "#cbcb41" }, + { name = "Directory.Build.props", text = "", fg = "#00a2ff" }, + { name = "Directory.Build.targets", text = "", fg = "#00a2ff" }, + { name = "Directory.Packages.props", text = "", fg = "#00a2ff" }, + { name = "docker-compose.yaml", text = "󰡨", fg = "#458ee6" }, + { name = "docker-compose.yml", text = "󰡨", fg = "#458ee6" }, + { name = "dockerfile", text = "󰡨", fg = "#458ee6" }, + { name = "eslint.config.cjs", text = "", fg = "#4b32c3" }, + { name = "eslint.config.js", text = "", fg = "#4b32c3" }, + { name = "eslint.config.mjs", text = "", fg = "#4b32c3" }, + { name = "eslint.config.ts", text = "", fg = "#4b32c3" }, + { name = "ext_typoscript_setup.txt", text = "", fg = "#ff8700" }, + { name = "favicon.ico", text = "", fg = "#cbcb41" }, + { name = "fp-info-cache", text = "", fg = "#ffffff" }, + { name = "fp-lib-table", text = "", fg = "#ffffff" }, + { name = "FreeCAD.conf", text = "", fg = "#cb333b" }, + { name = "Gemfile", text = "", fg = "#701516" }, + { name = "gnumakefile", text = "", fg = "#6d8086" }, + { name = "go.mod", text = "", fg = "#00add8" }, + { name = "go.sum", text = "", fg = "#00add8" }, + { name = "go.work", text = "", fg = "#00add8" }, + { name = "gradle-wrapper.properties", text = "", fg = "#005f87" }, + { name = "gradle.properties", text = "", fg = "#005f87" }, + { name = "gradlew", text = "", fg = "#005f87" }, + { name = "groovy", text = "", fg = "#4a687c" }, + { name = "gruntfile.babel.js", text = "", fg = "#e37933" }, + { name = "gruntfile.coffee", text = "", fg = "#e37933" }, + { name = "gruntfile.js", text = "", fg = "#e37933" }, + { name = "gruntfile.ts", text = "", fg = "#e37933" }, + { name = "gtkrc", text = "", fg = "#ffffff" }, + { name = "gulpfile.babel.js", text = "", fg = "#cc3e44" }, + { name = "gulpfile.coffee", text = "", fg = "#cc3e44" }, + { name = "gulpfile.js", text = "", fg = "#cc3e44" }, + { name = "gulpfile.ts", text = "", fg = "#cc3e44" }, + { name = "hypridle.conf", text = "", fg = "#00aaae" }, + { name = "hyprland.conf", text = "", fg = "#00aaae" }, + { name = "hyprlandd.conf", text = "", fg = "#00aaae" }, + { name = "hyprlock.conf", text = "", fg = "#00aaae" }, + { name = "hyprpaper.conf", text = "", fg = "#00aaae" }, + { name = "hyprsunset.conf", text = "", fg = "#00aaae" }, + { name = "i18n.config.js", text = "󰗊", fg = "#7986cb" }, + { name = "i18n.config.ts", text = "󰗊", fg = "#7986cb" }, + { name = "i3blocks.conf", text = "", fg = "#e8ebee" }, + { name = "i3status.conf", text = "", fg = "#e8ebee" }, + { name = "index.theme", text = "", fg = "#2db96f" }, + { name = "ionic.config.json", text = "", fg = "#4f8ff7" }, + { name = "Jenkinsfile", text = "", fg = "#d33833" }, + { name = "justfile", text = "", fg = "#6d8086" }, + { name = "kalgebrarc", text = "", fg = "#1c99f3" }, + { name = "kdeglobals", text = "", fg = "#1c99f3" }, + { name = "kdenlive-layoutsrc", text = "", fg = "#83b8f2" }, + { name = "kdenliverc", text = "", fg = "#83b8f2" }, + { name = "kritadisplayrc", text = "", fg = "#f245fb" }, + { name = "kritarc", text = "", fg = "#f245fb" }, + { name = "license", text = "", fg = "#d0bf41" }, + { name = "license.md", text = "", fg = "#d0bf41" }, + { name = "lxde-rc.xml", text = "", fg = "#909090" }, + { name = "lxqt.conf", text = "", fg = "#0192d3" }, + { name = "makefile", text = "", fg = "#6d8086" }, + { name = "mix.lock", text = "", fg = "#a074c4" }, + { name = "mpv.conf", text = "", fg = "#3b1342" }, + { name = "next.config.cjs", text = "", fg = "#ffffff" }, + { name = "next.config.js", text = "", fg = "#ffffff" }, + { name = "next.config.ts", text = "", fg = "#ffffff" }, + { name = "node_modules", text = "", fg = "#e8274b" }, + { name = "nuxt.config.cjs", text = "󱄆", fg = "#00c58e" }, + { name = "nuxt.config.js", text = "󱄆", fg = "#00c58e" }, + { name = "nuxt.config.mjs", text = "󱄆", fg = "#00c58e" }, + { name = "nuxt.config.ts", text = "󱄆", fg = "#00c58e" }, + { name = "package-lock.json", text = "", fg = "#7a0d21" }, + { name = "package.json", text = "", fg = "#e8274b" }, + { name = "PKGBUILD", text = "", fg = "#0f94d2" }, + { name = "platformio.ini", text = "", fg = "#f6822b" }, + { name = "playwright.config.cjs", text = "", fg = "#2fad33" }, + { name = "playwright.config.cts", text = "", fg = "#2fad33" }, + { name = "playwright.config.js", text = "", fg = "#2fad33" }, + { name = "playwright.config.mjs", text = "", fg = "#2fad33" }, + { name = "playwright.config.mts", text = "", fg = "#2fad33" }, + { name = "playwright.config.ts", text = "", fg = "#2fad33" }, + { name = "pnpm-lock.yaml", text = "", fg = "#f9ad02" }, + { name = "pnpm-workspace.yaml", text = "", fg = "#f9ad02" }, + { name = "pom.xml", text = "", fg = "#7a0d21" }, + { name = "prettier.config.cjs", text = "", fg = "#4285f4" }, + { name = "prettier.config.js", text = "", fg = "#4285f4" }, + { name = "prettier.config.mjs", text = "", fg = "#4285f4" }, + { name = "prettier.config.ts", text = "", fg = "#4285f4" }, + { name = "prisma.config.mts", text = "", fg = "#5a67d8" }, + { name = "prisma.config.ts", text = "", fg = "#5a67d8" }, + { name = "procfile", text = "", fg = "#a074c4" }, + { name = "PrusaSlicer.ini", text = "", fg = "#ec6b23" }, + { name = "PrusaSlicerGcodeViewer.ini", text = "", fg = "#ec6b23" }, + { name = "py.typed", text = "", fg = "#ffbc03" }, + { name = "QtProject.conf", text = "", fg = "#40cd52" }, + { name = "rakefile", text = "", fg = "#701516" }, + { name = "readme", text = "󰂺", fg = "#ededed" }, + { name = "readme.md", text = "󰂺", fg = "#ededed" }, + { name = "rmd", text = "", fg = "#519aba" }, + { name = "robots.txt", text = "󰚩", fg = "#5d7096" }, + { name = "security", text = "󰒃", fg = "#bec4c9" }, + { name = "security.md", text = "󰒃", fg = "#bec4c9" }, + { name = "settings.gradle", text = "", fg = "#005f87" }, + { name = "svelte.config.js", text = "", fg = "#ff3e00" }, + { name = "sxhkdrc", text = "", fg = "#2f2f2f" }, + { name = "sym-lib-table", text = "", fg = "#ffffff" }, + { name = "tailwind.config.js", text = "󱏿", fg = "#20c2e3" }, + { name = "tailwind.config.mjs", text = "󱏿", fg = "#20c2e3" }, + { name = "tailwind.config.ts", text = "󱏿", fg = "#20c2e3" }, + { name = "tmux.conf", text = "", fg = "#14ba19" }, + { name = "tmux.conf.local", text = "", fg = "#14ba19" }, + { name = "tsconfig.json", text = "", fg = "#519aba" }, + { name = "unlicense", text = "", fg = "#d0bf41" }, + { name = "vagrantfile", text = "", fg = "#1563ff" }, + { name = "vercel.json", text = "", fg = "#ffffff" }, + { name = "vite.config.cjs", text = "", fg = "#ffa800" }, + { name = "vite.config.cts", text = "", fg = "#ffa800" }, + { name = "vite.config.js", text = "", fg = "#ffa800" }, + { name = "vite.config.mjs", text = "", fg = "#ffa800" }, + { name = "vite.config.mts", text = "", fg = "#ffa800" }, + { name = "vite.config.ts", text = "", fg = "#ffa800" }, + { name = "vitest.config.cjs", text = "", fg = "#739b1b" }, + { name = "vitest.config.cts", text = "", fg = "#739b1b" }, + { name = "vitest.config.js", text = "", fg = "#739b1b" }, + { name = "vitest.config.mjs", text = "", fg = "#739b1b" }, + { name = "vitest.config.mts", text = "", fg = "#739b1b" }, + { name = "vitest.config.ts", text = "", fg = "#739b1b" }, + { name = "vlcrc", text = "󰕼", fg = "#ee7a00" }, + { name = "webpack", text = "󰜫", fg = "#519aba" }, + { name = "weston.ini", text = "", fg = "#ffbb01" }, + { name = "workspace", text = "", fg = "#89e051" }, + { name = "wrangler.jsonc", text = "", fg = "#f48120" }, + { name = "wrangler.toml", text = "", fg = "#f48120" }, + { name = "xdph.conf", text = "", fg = "#00aaae" }, + { name = "xmobarrc", text = "", fg = "#fd4d5d" }, + { name = "xmobarrc.hs", text = "", fg = "#fd4d5d" }, + { name = "xmonad.hs", text = "", fg = "#fd4d5d" }, + { name = "xorg.conf", text = "", fg = "#e54d18" }, + { name = "xsettingsd.conf", text = "", fg = "#e54d18" }, +] +exts = [ + { name = "3gp", text = "", fg = "#fd971f" }, + { name = "3mf", text = "󰆧", fg = "#888888" }, + { name = "7z", text = "", fg = "#eca517" }, + { name = "a", text = "", fg = "#dcddd6" }, + { name = "aac", text = "", fg = "#00afff" }, + { name = "ada", text = "", fg = "#599eff" }, + { name = "adb", text = "", fg = "#599eff" }, + { name = "ads", text = "", fg = "#a074c4" }, + { name = "ai", text = "", fg = "#cbcb41" }, + { name = "aif", text = "", fg = "#00afff" }, + { name = "aiff", text = "", fg = "#00afff" }, + { name = "android", text = "", fg = "#34a853" }, + { name = "ape", text = "", fg = "#00afff" }, + { name = "apk", text = "", fg = "#34a853" }, + { name = "apl", text = "", fg = "#24a148" }, + { name = "app", text = "", fg = "#9f0500" }, + { name = "applescript", text = "", fg = "#6d8085" }, + { name = "asc", text = "󰦝", fg = "#576d7f" }, + { name = "asm", text = "", fg = "#0091bd" }, + { name = "ass", text = "󰨖", fg = "#ffb713" }, + { name = "astro", text = "", fg = "#e23f67" }, + { name = "avif", text = "", fg = "#a074c4" }, + { name = "awk", text = "", fg = "#4d5a5e" }, + { name = "azcli", text = "", fg = "#0078d4" }, + { name = "bak", text = "󰁯", fg = "#6d8086" }, + { name = "bash", text = "", fg = "#89e051" }, + { name = "bat", text = "", fg = "#c1f12e" }, + { name = "bazel", text = "", fg = "#89e051" }, + { name = "bib", text = "󱉟", fg = "#cbcb41" }, + { name = "bicep", text = "", fg = "#519aba" }, + { name = "bicepparam", text = "", fg = "#9f74b3" }, + { name = "bin", text = "", fg = "#9f0500" }, + { name = "blade.php", text = "", fg = "#f05340" }, + { name = "blend", text = "󰂫", fg = "#ea7600" }, + { name = "blp", text = "󰺾", fg = "#5796e2" }, + { name = "bmp", text = "", fg = "#a074c4" }, + { name = "bqn", text = "", fg = "#24a148" }, + { name = "brep", text = "󰻫", fg = "#839463" }, + { name = "bz", text = "", fg = "#eca517" }, + { name = "bz2", text = "", fg = "#eca517" }, + { name = "bz3", text = "", fg = "#eca517" }, + { name = "bzl", text = "", fg = "#89e051" }, + { name = "c", text = "", fg = "#599eff" }, + { name = "c++", text = "", fg = "#f34b7d" }, + { name = "cache", text = "", fg = "#ffffff" }, + { name = "cast", text = "", fg = "#fd971f" }, + { name = "cbl", text = "", fg = "#005ca5" }, + { name = "cc", text = "", fg = "#f34b7d" }, + { name = "ccm", text = "", fg = "#f34b7d" }, + { name = "cfc", text = "", fg = "#01a4ba" }, + { name = "cfg", text = "", fg = "#6d8086" }, + { name = "cfm", text = "", fg = "#01a4ba" }, + { name = "cjs", text = "", fg = "#cbcb41" }, + { name = "clj", text = "", fg = "#8dc149" }, + { name = "cljc", text = "", fg = "#8dc149" }, + { name = "cljd", text = "", fg = "#519aba" }, + { name = "cljs", text = "", fg = "#519aba" }, + { name = "cmake", text = "", fg = "#dce3eb" }, + { name = "cob", text = "", fg = "#005ca5" }, + { name = "cobol", text = "", fg = "#005ca5" }, + { name = "coffee", text = "", fg = "#cbcb41" }, + { name = "conda", text = "", fg = "#43b02a" }, + { name = "conf", text = "", fg = "#6d8086" }, + { name = "config.ru", text = "", fg = "#701516" }, + { name = "cow", text = "󰆚", fg = "#965824" }, + { name = "cp", text = "", fg = "#519aba" }, + { name = "cpp", text = "", fg = "#519aba" }, + { name = "cppm", text = "", fg = "#519aba" }, + { name = "cpy", text = "", fg = "#005ca5" }, + { name = "cr", text = "", fg = "#c8c8c8" }, + { name = "crdownload", text = "", fg = "#44cda8" }, + { name = "cs", text = "󰌛", fg = "#596706" }, + { name = "csh", text = "", fg = "#4d5a5e" }, + { name = "cshtml", text = "󱦗", fg = "#512bd4" }, + { name = "cson", text = "", fg = "#cbcb41" }, + { name = "csproj", text = "󰪮", fg = "#512bd4" }, + { name = "css", text = "", fg = "#663399" }, + { name = "csv", text = "", fg = "#89e051" }, + { name = "cts", text = "", fg = "#519aba" }, + { name = "cu", text = "", fg = "#89e051" }, + { name = "cue", text = "󰲹", fg = "#ed95ae" }, + { name = "cuh", text = "", fg = "#a074c4" }, + { name = "cxx", text = "", fg = "#519aba" }, + { name = "cxxm", text = "", fg = "#519aba" }, + { name = "d", text = "", fg = "#b03931" }, + { name = "d.ts", text = "", fg = "#d59855" }, + { name = "dart", text = "", fg = "#03589c" }, + { name = "db", text = "", fg = "#dad8d8" }, + { name = "dconf", text = "", fg = "#ffffff" }, + { name = "desktop", text = "", fg = "#563d7c" }, + { name = "diff", text = "", fg = "#41535b" }, + { name = "dll", text = "", fg = "#4d2c0b" }, + { name = "doc", text = "󰈬", fg = "#185abd" }, + { name = "Dockerfile", text = "󰡨", fg = "#458ee6" }, + { name = "dockerignore", text = "󰡨", fg = "#458ee6" }, + { name = "docx", text = "󰈬", fg = "#185abd" }, + { name = "dot", text = "󱁉", fg = "#30638e" }, + { name = "download", text = "", fg = "#44cda8" }, + { name = "drl", text = "", fg = "#ffafaf" }, + { name = "dropbox", text = "", fg = "#0061fe" }, + { name = "dump", text = "", fg = "#dad8d8" }, + { name = "dwg", text = "󰻫", fg = "#839463" }, + { name = "dxf", text = "󰻫", fg = "#839463" }, + { name = "ebook", text = "", fg = "#eab16d" }, + { name = "ebuild", text = "", fg = "#4c416e" }, + { name = "edn", text = "", fg = "#519aba" }, + { name = "eex", text = "", fg = "#a074c4" }, + { name = "ejs", text = "", fg = "#cbcb41" }, + { name = "el", text = "", fg = "#8172be" }, + { name = "elc", text = "", fg = "#8172be" }, + { name = "elf", text = "", fg = "#9f0500" }, + { name = "elm", text = "", fg = "#519aba" }, + { name = "eln", text = "", fg = "#8172be" }, + { name = "env", text = "", fg = "#faf743" }, + { name = "eot", text = "", fg = "#ececec" }, + { name = "epp", text = "", fg = "#ffa61a" }, + { name = "epub", text = "", fg = "#eab16d" }, + { name = "erb", text = "", fg = "#701516" }, + { name = "erl", text = "", fg = "#b83998" }, + { name = "ex", text = "", fg = "#a074c4" }, + { name = "exe", text = "", fg = "#9f0500" }, + { name = "exs", text = "", fg = "#a074c4" }, + { name = "f#", text = "", fg = "#519aba" }, + { name = "f3d", text = "󰻫", fg = "#839463" }, + { name = "f90", text = "󱈚", fg = "#734f96" }, + { name = "fbx", text = "󰆧", fg = "#888888" }, + { name = "fcbak", text = "", fg = "#cb333b" }, + { name = "fcmacro", text = "", fg = "#cb333b" }, + { name = "fcmat", text = "", fg = "#cb333b" }, + { name = "fcparam", text = "", fg = "#cb333b" }, + { name = "fcscript", text = "", fg = "#cb333b" }, + { name = "fcstd", text = "", fg = "#cb333b" }, + { name = "fcstd1", text = "", fg = "#cb333b" }, + { name = "fctb", text = "", fg = "#cb333b" }, + { name = "fctl", text = "", fg = "#cb333b" }, + { name = "fdmdownload", text = "", fg = "#44cda8" }, + { name = "feature", text = "", fg = "#00a818" }, + { name = "fish", text = "", fg = "#4d5a5e" }, + { name = "flac", text = "", fg = "#0075aa" }, + { name = "flc", text = "", fg = "#ececec" }, + { name = "flf", text = "", fg = "#ececec" }, + { name = "fnl", text = "", fg = "#fff3d7" }, + { name = "fodg", text = "", fg = "#fffb57" }, + { name = "fodp", text = "", fg = "#fe9c45" }, + { name = "fods", text = "", fg = "#78fc4e" }, + { name = "fodt", text = "", fg = "#2dcbfd" }, + { name = "frag", text = "", fg = "#5586a6" }, + { name = "fs", text = "", fg = "#519aba" }, + { name = "fsi", text = "", fg = "#519aba" }, + { name = "fsscript", text = "", fg = "#519aba" }, + { name = "fsx", text = "", fg = "#519aba" }, + { name = "gcode", text = "󰐫", fg = "#1471ad" }, + { name = "gd", text = "", fg = "#6d8086" }, + { name = "gemspec", text = "", fg = "#701516" }, + { name = "geom", text = "", fg = "#5586a6" }, + { name = "gif", text = "", fg = "#a074c4" }, + { name = "git", text = "", fg = "#f14c28" }, + { name = "glb", text = "", fg = "#ffb13b" }, + { name = "gleam", text = "", fg = "#ffaff3" }, + { name = "glsl", text = "", fg = "#5586a6" }, + { name = "gnumakefile", text = "", fg = "#6d8086" }, + { name = "go", text = "", fg = "#00add8" }, + { name = "godot", text = "", fg = "#6d8086" }, + { name = "gpr", text = "", fg = "#6d8086" }, + { name = "gql", text = "", fg = "#e535ab" }, + { name = "gradle", text = "", fg = "#005f87" }, + { name = "graphql", text = "", fg = "#e535ab" }, + { name = "gresource", text = "", fg = "#ffffff" }, + { name = "gv", text = "󱁉", fg = "#30638e" }, + { name = "gz", text = "", fg = "#eca517" }, + { name = "h", text = "", fg = "#a074c4" }, + { name = "haml", text = "", fg = "#eaeae1" }, + { name = "hbs", text = "", fg = "#f0772b" }, + { name = "heex", text = "", fg = "#a074c4" }, + { name = "hex", text = "", fg = "#2e63ff" }, + { name = "hh", text = "", fg = "#a074c4" }, + { name = "hpp", text = "", fg = "#a074c4" }, + { name = "hrl", text = "", fg = "#b83998" }, + { name = "hs", text = "", fg = "#a074c4" }, + { name = "htm", text = "", fg = "#e34c26" }, + { name = "html", text = "", fg = "#e44d26" }, + { name = "http", text = "", fg = "#008ec7" }, + { name = "huff", text = "󰡘", fg = "#4242c7" }, + { name = "hurl", text = "", fg = "#ff0288" }, + { name = "hx", text = "", fg = "#ea8220" }, + { name = "hxx", text = "", fg = "#a074c4" }, + { name = "ical", text = "", fg = "#2b2e83" }, + { name = "icalendar", text = "", fg = "#2b2e83" }, + { name = "ico", text = "", fg = "#cbcb41" }, + { name = "ics", text = "", fg = "#2b2e83" }, + { name = "ifb", text = "", fg = "#2b2e83" }, + { name = "ifc", text = "󰻫", fg = "#839463" }, + { name = "ige", text = "󰻫", fg = "#839463" }, + { name = "iges", text = "󰻫", fg = "#839463" }, + { name = "igs", text = "󰻫", fg = "#839463" }, + { name = "image", text = "", fg = "#d0bec8" }, + { name = "img", text = "", fg = "#d0bec8" }, + { name = "import", text = "", fg = "#ececec" }, + { name = "info", text = "", fg = "#ffffcd" }, + { name = "ini", text = "", fg = "#6d8086" }, + { name = "ino", text = "", fg = "#56b6c2" }, + { name = "ipynb", text = "", fg = "#f57d01" }, + { name = "iso", text = "", fg = "#d0bec8" }, + { name = "ixx", text = "", fg = "#519aba" }, + { name = "jar", text = "", fg = "#ffaf67" }, + { name = "java", text = "", fg = "#cc3e44" }, + { name = "jl", text = "", fg = "#a270ba" }, + { name = "jpeg", text = "", fg = "#a074c4" }, + { name = "jpg", text = "", fg = "#a074c4" }, + { name = "js", text = "", fg = "#cbcb41" }, + { name = "json", text = "", fg = "#cbcb41" }, + { name = "json5", text = "", fg = "#cbcb41" }, + { name = "jsonc", text = "", fg = "#cbcb41" }, + { name = "jsx", text = "", fg = "#20c2e3" }, + { name = "jwmrc", text = "", fg = "#0078cd" }, + { name = "jxl", text = "", fg = "#a074c4" }, + { name = "kbx", text = "󰯄", fg = "#737672" }, + { name = "kdb", text = "", fg = "#529b34" }, + { name = "kdbx", text = "", fg = "#529b34" }, + { name = "kdenlive", text = "", fg = "#83b8f2" }, + { name = "kdenlivetitle", text = "", fg = "#83b8f2" }, + { name = "kicad_dru", text = "", fg = "#ffffff" }, + { name = "kicad_mod", text = "", fg = "#ffffff" }, + { name = "kicad_pcb", text = "", fg = "#ffffff" }, + { name = "kicad_prl", text = "", fg = "#ffffff" }, + { name = "kicad_pro", text = "", fg = "#ffffff" }, + { name = "kicad_sch", text = "", fg = "#ffffff" }, + { name = "kicad_sym", text = "", fg = "#ffffff" }, + { name = "kicad_wks", text = "", fg = "#ffffff" }, + { name = "ko", text = "", fg = "#dcddd6" }, + { name = "kpp", text = "", fg = "#f245fb" }, + { name = "kra", text = "", fg = "#f245fb" }, + { name = "krz", text = "", fg = "#f245fb" }, + { name = "ksh", text = "", fg = "#4d5a5e" }, + { name = "kt", text = "", fg = "#7f52ff" }, + { name = "kts", text = "", fg = "#7f52ff" }, + { name = "lck", text = "", fg = "#bbbbbb" }, + { name = "leex", text = "", fg = "#a074c4" }, + { name = "less", text = "", fg = "#563d7c" }, + { name = "lff", text = "", fg = "#ececec" }, + { name = "lhs", text = "", fg = "#a074c4" }, + { name = "lib", text = "", fg = "#4d2c0b" }, + { name = "license", text = "", fg = "#cbcb41" }, + { name = "liquid", text = "", fg = "#95bf47" }, + { name = "lock", text = "", fg = "#bbbbbb" }, + { name = "log", text = "󰌱", fg = "#dddddd" }, + { name = "lrc", text = "󰨖", fg = "#ffb713" }, + { name = "lua", text = "", fg = "#51a0cf" }, + { name = "luac", text = "", fg = "#51a0cf" }, + { name = "luau", text = "", fg = "#00a2ff" }, + { name = "m", text = "", fg = "#599eff" }, + { name = "m3u", text = "󰲹", fg = "#ed95ae" }, + { name = "m3u8", text = "󰲹", fg = "#ed95ae" }, + { name = "m4a", text = "", fg = "#00afff" }, + { name = "m4v", text = "", fg = "#fd971f" }, + { name = "magnet", text = "", fg = "#a51b16" }, + { name = "makefile", text = "", fg = "#6d8086" }, + { name = "markdown", text = "", fg = "#dddddd" }, + { name = "material", text = "", fg = "#b83998" }, + { name = "md", text = "", fg = "#dddddd" }, + { name = "md5", text = "󰕥", fg = "#8c86af" }, + { name = "mdx", text = "", fg = "#519aba" }, + { name = "mint", text = "󰌪", fg = "#87c095" }, + { name = "mjs", text = "", fg = "#f1e05a" }, + { name = "mk", text = "", fg = "#6d8086" }, + { name = "mkv", text = "", fg = "#fd971f" }, + { name = "ml", text = "", fg = "#e37933" }, + { name = "mli", text = "", fg = "#e37933" }, + { name = "mm", text = "", fg = "#519aba" }, + { name = "mo", text = "", fg = "#9772fb" }, + { name = "mobi", text = "", fg = "#eab16d" }, + { name = "mojo", text = "", fg = "#ff4c1f" }, + { name = "mov", text = "", fg = "#fd971f" }, + { name = "mp3", text = "", fg = "#00afff" }, + { name = "mp4", text = "", fg = "#fd971f" }, + { name = "mpp", text = "", fg = "#519aba" }, + { name = "msf", text = "", fg = "#137be1" }, + { name = "mts", text = "", fg = "#519aba" }, + { name = "mustache", text = "", fg = "#e37933" }, + { name = "nfo", text = "", fg = "#ffffcd" }, + { name = "nim", text = "", fg = "#f3d400" }, + { name = "nix", text = "", fg = "#7ebae4" }, + { name = "norg", text = "", fg = "#4878be" }, + { name = "nswag", text = "", fg = "#85ea2d" }, + { name = "nu", text = "", fg = "#3aa675" }, + { name = "o", text = "", fg = "#9f0500" }, + { name = "obj", text = "󰆧", fg = "#888888" }, + { name = "odf", text = "", fg = "#ff5a96" }, + { name = "odg", text = "", fg = "#fffb57" }, + { name = "odin", text = "󰟢", fg = "#3882d2" }, + { name = "odp", text = "", fg = "#fe9c45" }, + { name = "ods", text = "", fg = "#78fc4e" }, + { name = "odt", text = "", fg = "#2dcbfd" }, + { name = "oga", text = "", fg = "#0075aa" }, + { name = "ogg", text = "", fg = "#0075aa" }, + { name = "ogv", text = "", fg = "#fd971f" }, + { name = "ogx", text = "", fg = "#fd971f" }, + { name = "opus", text = "", fg = "#0075aa" }, + { name = "org", text = "", fg = "#77aa99" }, + { name = "otf", text = "", fg = "#ececec" }, + { name = "out", text = "", fg = "#9f0500" }, + { name = "part", text = "", fg = "#44cda8" }, + { name = "patch", text = "", fg = "#41535b" }, + { name = "pck", text = "", fg = "#6d8086" }, + { name = "pcm", text = "", fg = "#0075aa" }, + { name = "pdf", text = "", fg = "#b30b00" }, + { name = "php", text = "", fg = "#a074c4" }, + { name = "pl", text = "", fg = "#519aba" }, + { name = "pls", text = "󰲹", fg = "#ed95ae" }, + { name = "ply", text = "󰆧", fg = "#888888" }, + { name = "pm", text = "", fg = "#519aba" }, + { name = "png", text = "", fg = "#a074c4" }, + { name = "po", text = "", fg = "#2596be" }, + { name = "pot", text = "", fg = "#2596be" }, + { name = "pp", text = "", fg = "#ffa61a" }, + { name = "ppt", text = "󰈧", fg = "#cb4a32" }, + { name = "pptx", text = "󰈧", fg = "#cb4a32" }, + { name = "prisma", text = "", fg = "#5a67d8" }, + { name = "pro", text = "", fg = "#e4b854" }, + { name = "ps1", text = "󰨊", fg = "#4273ca" }, + { name = "psb", text = "", fg = "#519aba" }, + { name = "psd", text = "", fg = "#519aba" }, + { name = "psd1", text = "󰨊", fg = "#6975c4" }, + { name = "psm1", text = "󰨊", fg = "#6975c4" }, + { name = "pub", text = "󰷖", fg = "#e3c58e" }, + { name = "pxd", text = "", fg = "#5aa7e4" }, + { name = "pxi", text = "", fg = "#5aa7e4" }, + { name = "py", text = "", fg = "#ffbc03" }, + { name = "pyc", text = "", fg = "#ffe291" }, + { name = "pyd", text = "", fg = "#ffe291" }, + { name = "pyi", text = "", fg = "#ffbc03" }, + { name = "pyo", text = "", fg = "#ffe291" }, + { name = "pyw", text = "", fg = "#5aa7e4" }, + { name = "pyx", text = "", fg = "#5aa7e4" }, + { name = "qm", text = "", fg = "#2596be" }, + { name = "qml", text = "", fg = "#40cd52" }, + { name = "qrc", text = "", fg = "#40cd52" }, + { name = "qss", text = "", fg = "#40cd52" }, + { name = "query", text = "", fg = "#90a850" }, + { name = "R", text = "󰟔", fg = "#2266ba" }, + { name = "r", text = "󰟔", fg = "#2266ba" }, + { name = "rake", text = "", fg = "#701516" }, + { name = "rar", text = "", fg = "#eca517" }, + { name = "rasi", text = "", fg = "#cbcb41" }, + { name = "razor", text = "󱦘", fg = "#512bd4" }, + { name = "rb", text = "", fg = "#701516" }, + { name = "res", text = "", fg = "#cc3e44" }, + { name = "resi", text = "", fg = "#f55385" }, + { name = "rlib", text = "", fg = "#dea584" }, + { name = "rmd", text = "", fg = "#519aba" }, + { name = "rproj", text = "󰗆", fg = "#358a5b" }, + { name = "rs", text = "", fg = "#dea584" }, + { name = "rss", text = "", fg = "#fb9d3b" }, + { name = "s", text = "", fg = "#0071c5" }, + { name = "sass", text = "", fg = "#f55385" }, + { name = "sbt", text = "", fg = "#cc3e44" }, + { name = "sc", text = "", fg = "#cc3e44" }, + { name = "scad", text = "", fg = "#f9d72c" }, + { name = "scala", text = "", fg = "#cc3e44" }, + { name = "scm", text = "󰘧", fg = "#eeeeee" }, + { name = "scss", text = "", fg = "#f55385" }, + { name = "sh", text = "", fg = "#4d5a5e" }, + { name = "sha1", text = "󰕥", fg = "#8c86af" }, + { name = "sha224", text = "󰕥", fg = "#8c86af" }, + { name = "sha256", text = "󰕥", fg = "#8c86af" }, + { name = "sha384", text = "󰕥", fg = "#8c86af" }, + { name = "sha512", text = "󰕥", fg = "#8c86af" }, + { name = "sig", text = "󰘧", fg = "#e37933" }, + { name = "signature", text = "󰘧", fg = "#e37933" }, + { name = "skp", text = "󰻫", fg = "#839463" }, + { name = "sldasm", text = "󰻫", fg = "#839463" }, + { name = "sldprt", text = "󰻫", fg = "#839463" }, + { name = "slim", text = "", fg = "#e34c26" }, + { name = "sln", text = "", fg = "#854cc7" }, + { name = "slnx", text = "", fg = "#854cc7" }, + { name = "slvs", text = "󰻫", fg = "#839463" }, + { name = "sml", text = "󰘧", fg = "#e37933" }, + { name = "so", text = "", fg = "#dcddd6" }, + { name = "sol", text = "", fg = "#519aba" }, + { name = "spec.js", text = "", fg = "#cbcb41" }, + { name = "spec.jsx", text = "", fg = "#20c2e3" }, + { name = "spec.ts", text = "", fg = "#519aba" }, + { name = "spec.tsx", text = "", fg = "#1354bf" }, + { name = "spx", text = "", fg = "#0075aa" }, + { name = "sql", text = "", fg = "#dad8d8" }, + { name = "sqlite", text = "", fg = "#dad8d8" }, + { name = "sqlite3", text = "", fg = "#dad8d8" }, + { name = "srt", text = "󰨖", fg = "#ffb713" }, + { name = "ssa", text = "󰨖", fg = "#ffb713" }, + { name = "ste", text = "󰻫", fg = "#839463" }, + { name = "step", text = "󰻫", fg = "#839463" }, + { name = "stl", text = "󰆧", fg = "#888888" }, + { name = "stories.js", text = "", fg = "#ff4785" }, + { name = "stories.jsx", text = "", fg = "#ff4785" }, + { name = "stories.mjs", text = "", fg = "#ff4785" }, + { name = "stories.svelte", text = "", fg = "#ff4785" }, + { name = "stories.ts", text = "", fg = "#ff4785" }, + { name = "stories.tsx", text = "", fg = "#ff4785" }, + { name = "stories.vue", text = "", fg = "#ff4785" }, + { name = "stp", text = "󰻫", fg = "#839463" }, + { name = "strings", text = "", fg = "#2596be" }, + { name = "styl", text = "", fg = "#8dc149" }, + { name = "sub", text = "󰨖", fg = "#ffb713" }, + { name = "sublime", text = "", fg = "#e37933" }, + { name = "suo", text = "", fg = "#854cc7" }, + { name = "sv", text = "󰍛", fg = "#019833" }, + { name = "svelte", text = "", fg = "#ff3e00" }, + { name = "svg", text = "󰜡", fg = "#ffb13b" }, + { name = "svgz", text = "󰜡", fg = "#ffb13b" }, + { name = "svh", text = "󰍛", fg = "#019833" }, + { name = "swift", text = "", fg = "#e37933" }, + { name = "t", text = "", fg = "#519aba" }, + { name = "tbc", text = "󰛓", fg = "#1e5cb3" }, + { name = "tcl", text = "󰛓", fg = "#1e5cb3" }, + { name = "templ", text = "", fg = "#dbbd30" }, + { name = "terminal", text = "", fg = "#31b53e" }, + { name = "test.js", text = "", fg = "#cbcb41" }, + { name = "test.jsx", text = "", fg = "#20c2e3" }, + { name = "test.ts", text = "", fg = "#519aba" }, + { name = "test.tsx", text = "", fg = "#1354bf" }, + { name = "tex", text = "", fg = "#3d6117" }, + { name = "tf", text = "", fg = "#5f43e9" }, + { name = "tfvars", text = "", fg = "#5f43e9" }, + { name = "tgz", text = "", fg = "#eca517" }, + { name = "tmpl", text = "", fg = "#dbbd30" }, + { name = "tmux", text = "", fg = "#14ba19" }, + { name = "toml", text = "", fg = "#9c4221" }, + { name = "torrent", text = "", fg = "#44cda8" }, + { name = "tres", text = "", fg = "#6d8086" }, + { name = "ts", text = "", fg = "#519aba" }, + { name = "tscn", text = "", fg = "#6d8086" }, + { name = "tsconfig", text = "", fg = "#ff8700" }, + { name = "tsx", text = "", fg = "#1354bf" }, + { name = "ttf", text = "", fg = "#ececec" }, + { name = "twig", text = "", fg = "#8dc149" }, + { name = "txt", text = "󰈙", fg = "#89e051" }, + { name = "txz", text = "", fg = "#eca517" }, + { name = "typ", text = "", fg = "#0dbcc0" }, + { name = "typoscript", text = "", fg = "#ff8700" }, + { name = "ui", text = "", fg = "#015bf0" }, + { name = "v", text = "󰍛", fg = "#019833" }, + { name = "vala", text = "", fg = "#7b3db9" }, + { name = "vert", text = "", fg = "#5586a6" }, + { name = "vh", text = "󰍛", fg = "#019833" }, + { name = "vhd", text = "󰍛", fg = "#019833" }, + { name = "vhdl", text = "󰍛", fg = "#019833" }, + { name = "vi", text = "", fg = "#fec60a" }, + { name = "vim", text = "", fg = "#019833" }, + { name = "vsh", text = "", fg = "#5d87bf" }, + { name = "vsix", text = "", fg = "#854cc7" }, + { name = "vue", text = "", fg = "#8dc149" }, + { name = "wasm", text = "", fg = "#5c4cdb" }, + { name = "wav", text = "", fg = "#00afff" }, + { name = "webm", text = "", fg = "#fd971f" }, + { name = "webmanifest", text = "", fg = "#f1e05a" }, + { name = "webp", text = "", fg = "#a074c4" }, + { name = "webpack", text = "󰜫", fg = "#519aba" }, + { name = "wma", text = "", fg = "#00afff" }, + { name = "wmv", text = "", fg = "#fd971f" }, + { name = "woff", text = "", fg = "#ececec" }, + { name = "woff2", text = "", fg = "#ececec" }, + { name = "wrl", text = "󰆧", fg = "#888888" }, + { name = "wrz", text = "󰆧", fg = "#888888" }, + { name = "wv", text = "", fg = "#00afff" }, + { name = "wvc", text = "", fg = "#00afff" }, + { name = "x", text = "", fg = "#599eff" }, + { name = "xaml", text = "󰙳", fg = "#512bd4" }, + { name = "xcf", text = "", fg = "#635b46" }, + { name = "xcplayground", text = "", fg = "#e37933" }, + { name = "xcstrings", text = "", fg = "#2596be" }, + { name = "xls", text = "󰈛", fg = "#207245" }, + { name = "xlsx", text = "󰈛", fg = "#207245" }, + { name = "xm", text = "", fg = "#519aba" }, + { name = "xml", text = "󰗀", fg = "#e37933" }, + { name = "xpi", text = "", fg = "#ff1b01" }, + { name = "xslt", text = "󰗀", fg = "#33a9dc" }, + { name = "xul", text = "", fg = "#e37933" }, + { name = "xz", text = "", fg = "#eca517" }, + { name = "yaml", text = "", fg = "#6d8086" }, + { name = "yml", text = "", fg = "#6d8086" }, + { name = "zig", text = "", fg = "#f69a1b" }, + { name = "zip", text = "", fg = "#eca517" }, + { name = "zsh", text = "", fg = "#89e051" }, + { name = "zst", text = "", fg = "#eca517" }, + { name = "🔥", text = "", fg = "#ff4c1f" }, +] +conds = [ + # Special files + { if = "orphan", text = "", fg = "#ffffff" }, + { if = "link", text = "", fg = "#9e9e9e" }, + { if = "block", text = "", fg = "#cddc39" }, + { if = "char", text = "", fg = "#cddc39" }, + { if = "fifo", text = "", fg = "#cddc39" }, + { if = "sock", text = "", fg = "#cddc39" }, + { if = "sticky", text = "", fg = "#cddc39" }, + { if = "dummy", text = "", fg = "#f44336" }, + + # Fallback + { if = "dir & hovered", text = "", fg = "#03a9f4" }, + { if = "dir", text = "", fg = "#03a9f4" }, + { if = "exec", text = "", fg = "#8bc34a" }, + { if = "!dir", text = "", fg = "#ffffff" }, +] + +# : }}} \ No newline at end of file diff --git a/config/yazi/yazi.toml b/config/yazi/yazi.toml new file mode 100644 index 0000000..f7d56cf --- /dev/null +++ b/config/yazi/yazi.toml @@ -0,0 +1,296 @@ +# A TOML linter such as Tombi can use this schema to validate your config. +# If you encounter any problems, please file an issue at https://github.com/yazi-rs/schemas. + +#:schema https://yazi-rs.github.io/schemas/yazi.json + +[mgr] +ratio = [1, 2, 4] +sort_by = "natural" +sort_sensitive = false +sort_reverse = false +sort_dir_first = true +sort_translit = false +sort_fallback = "alphabetical" +linemode = "none" +show_hidden = true +show_symlink = true +scrolloff = 5 +mouse_events = ["click", "scroll", "drag"] + +[preview] +wrap = "yes" +tab_size = 2 +max_width = 600 +max_height = 900 +cache_dir = "" +image_delay = 30 +image_filter = "triangle" +image_quality = 75 +ueberzug_scale = 1 +ueberzug_offset = [0, 0, 0, 0] + +[opener] +edit = [ + { run = "nvim %s", desc = "$EDITOR", for = "unix", block = true }, + { run = "code %s", desc = "code", for = "windows", orphan = true }, + { run = "code -w %s", desc = "code (block)", for = "windows", block = true }, +] + +play = [ + { run = "xdg-open %s1", desc = "Play", for = "linux", orphan = true }, + { run = "open %s", desc = "Play", for = "macos" }, + { run = 'start "" %s1', desc = "Play", for = "windows", orphan = true }, + { run = "termux-open %s1", desc = "Play", for = "android" }, + { run = "mediainfo %s1; echo 'Press enter to exit'; read _", block = true, desc = "Show media info", for = "unix" }, + { run = "mediainfo %s1 & pause", block = true, desc = "Show media info", for = "windows" }, +] + +open = [ + { run = "xdg-open %s1", desc = "Open", for = "linux" }, + { run = "open %s", desc = "Open", for = "macos" }, + { run = 'start "" %s1', desc = "Open", for = "windows", orphan = true }, + { run = "termux-open %s1", desc = "Open", for = "android" }, +] + +reveal = [ + { run = "xdg-open %d1", desc = "Reveal", for = "linux" }, + { run = "open -R %s1", desc = "Reveal", for = "macos" }, + { run = "explorer /select,%s1", desc = "Reveal", for = "windows", orphan = true }, + { run = "termux-open %d1", desc = "Reveal", for = "android" }, + { run = "clear; exiftool %s1; echo 'Press enter to exit'; read _", desc = "Show EXIF", for = "unix", block = true }, +] + +extract = [{ run = "ya pub extract --list %s", desc = "Extract here" }] + +download = [ + { run = "ya emit download --open %S", desc = "Download and open" }, + { run = "ya emit download %S", desc = "Download" }, +] + +trash = [ + { run = "ya pub trash-restore --list %S", desc = "Restore selected files" }, + { run = "ya pub trash-empty --list %S", desc = "Empty trash bin" }, +] + +[open] +rules = [ + # Folder + { mime = "folder/*", use = [ + "edit", + "open", + "reveal", + ] }, + # Text + { mime = "text/*", use = [ + "edit", + "reveal", + ] }, + # Image + { mime = "image/*", use = [ + "open", + "reveal", + ] }, + # Media + { mime = "{audio,video}/*", use = [ + "play", + "reveal", + ] }, + # Code + { mime = "application/{json,ndjson,javascript,wine-extension-ini}", use = [ + "edit", + "reveal", + ] }, + # Archive + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", use = [ + "extract", + "reveal", + ] }, + # Empty file + { mime = "inode/empty", use = [ + "edit", + "reveal", + ] }, + # Virtual file system + { mime = "vfs/{absent,stale}", use = "download" }, + # Trash + { mime = "trash/**", use = [ + "open", + "trash", + ] }, + # Fallback + { url = "*", use = [ + "open", + "reveal", + ] }, +] + +[tasks] +file_workers = 3 +plugin_workers = 5 +fetch_workers = 5 +preload_workers = 2 +process_workers = 5 +bizarre_retry = 3 +image_alloc = 536870912 # 512MB +image_bound = [10000, 10000] +suppress_preload = false + +[plugin] +fetchers = [ + # MIME-type + { url = "*/", run = "mime.dir", prio = "high", group = "mime" }, + { url = "local://*", run = "mime.local", prio = "high", group = "mime" }, + { url = "trash://*", run = "mime.trash", prio = "high", group = "mime" }, + { url = "remote://*", run = "mime.remote", prio = "high", group = "mime" }, +] + +spotters = [ + # Multi-file + { mime = "multi/*", run = "multi" }, + # Folder + { mime = "folder/*", run = "folder" }, + # Code + { mime = "text/*", run = "code" }, + { mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" }, + # Image + { mime = "image/{avif,hei?,jxl}", run = "magick" }, + { mime = "image/svg+xml", run = "svg" }, + { mime = "image/*", run = "image" }, + # Video + { mime = "video/*", run = "video" }, + # Virtual file system + { mime = "vfs/*", run = "vfs" }, + # Trash + { mime = "trash/**", run = "trash" }, + # Error + { mime = "null/*", run = "null" }, + # Fallback + { url = "*", run = "file" }, + { url = "*/", run = "file" }, +] + +preloaders = [ + # Image + { mime = "image/{avif,hei?,jxl}", run = "magick" }, + { mime = "image/svg+xml", run = "svg" }, + { mime = "image/*", run = "image" }, + # Video + { mime = "video/*", run = "video" }, + # PDF + { mime = "application/pdf", run = "pdf" }, + # Font + { mime = "font/*", run = "font" }, + { mime = "application/ms-opentype", run = "font" }, + # Trash + { mime = "trash/**", run = "trash" }, +] + +previewers = [ + { mime = "folder/*", run = "folder" }, + # Code + { mime = "text/*", run = "code" }, + { mime = "application/{mbox,javascript,wine-extension-ini}", run = "code" }, + # JSON + { mime = "application/{json,ndjson}", run = "json" }, + # Image + { mime = "image/{avif,hei?,jxl}", run = "magick" }, + { mime = "image/svg+xml", run = "svg" }, + { mime = "image/*", run = "image" }, + # Video + { mime = "video/*", run = "video" }, + # PDF + { mime = "application/pdf", run = "pdf" }, + # Archive + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", run = "archive" }, + { mime = "application/{debian*-package,redhat-package-manager,rpm,android.package-archive}", run = "archive" }, + { url = "*.{AppImage,appimage}", run = "archive" }, + # Virtual Disk / Disk Image + { mime = "application/{iso9660-image,qemu-disk,ms-wim,apple-diskimage}", run = "archive" }, + { mime = "application/virtualbox-{vhd,vhdx}", run = "archive" }, + { url = "*.{img,fat,ext,ext2,ext3,ext4,squashfs,ntfs,hfs,hfsx}", run = "archive" }, + # Font + { mime = "font/*", run = "font" }, + { mime = "application/ms-opentype", run = "font" }, + # Empty file + { mime = "inode/empty", run = "empty" }, + # Virtual file system + { mime = "vfs/*", run = "vfs" }, + # Trash + { mime = "trash/**", run = "trash" }, + # Error + { mime = "null/*", run = "null" }, + # Fallback + { url = "*", run = "file" }, +] + +[input] +cursor_blink = false + +# cd +cd_title = "Change directory:" +cd_origin = "top-center" +cd_offset = [0, 2, 50, 3] + +# create +create_title = ["Create:", "Create (dir):"] +create_origin = "top-center" +create_offset = [0, 2, 50, 3] + +# rename +rename_title = "Rename:" +rename_origin = "hovered" +rename_offset = [0, 1, 50, 3] + +# filter +filter_title = "Filter:" +filter_origin = "top-center" +filter_offset = [0, 2, 50, 3] + +# find +find_title = ["Find next:", "Find previous:"] +find_origin = "top-center" +find_offset = [0, 2, 50, 3] + +# search +search_title = "Search via {n}:" +search_origin = "top-center" +search_offset = [0, 2, 50, 3] + +# shell +shell_title = ["Shell:", "Shell (block):"] +shell_origin = "top-center" +shell_offset = [0, 2, 50, 3] + +[confirm] +# trash +trash_title = "Trash {n} selected file{s}?" +trash_origin = "center" +trash_offset = [0, 0, 70, 20] + +# delete +delete_title = "Permanently delete {n} selected file{s}?" +delete_origin = "center" +delete_offset = [0, 0, 70, 20] + +# overwrite +overwrite_title = "Overwrite file?" +overwrite_body = "Will overwrite the following file:" +overwrite_origin = "center" +overwrite_offset = [0, 0, 50, 15] + +# quit +quit_title = "Quit?" +quit_body = "There are unfinished tasks, quit anyway?\n(Open task manager with default key 'w')" +quit_origin = "center" +quit_offset = [0, 0, 50, 15] + +[pick] +open_title = "Open with:" +open_origin = "hovered" +open_offset = [0, 1, 50, 7] + +[which] +sort_by = "none" +sort_sensitive = false +sort_reverse = false +sort_translit = false diff --git a/config/zsh/.aliases b/config/zsh/.aliases index 544820d..3aeea8f 100644 --- a/config/zsh/.aliases +++ b/config/zsh/.aliases @@ -1,7 +1,6 @@ # !------------------------------------ # @@@ LINUX # !------------------------------------ -# Force terminal to recognize changes to .zshrc if [[ -n "$ZSH_VERSION" ]] then alias refresh="source ~/.zshrc" @@ -9,128 +8,83 @@ else alias refresh="source ~/.bashrc" fi -alias fresh="refresh" -alias aliasUpdate="fresh 2>&1 && c" - -# Clear terminal +# Base alias c="clear" +alias fenv="source ~/.zshenv" +alias fresh="clear && refresh" +alias aliasUpdate="fresh 2>&1 && c" -alias ls='eza --icons --group-directories-last' - -alias ll="ls -lha" - -# Ask before removing files -alias rm="rm -i" +# LS replacements +alias ls="eza --icons --group-directories-last" +alias ll="ls -l" +alias la="ls -lah" +alias lt="ls --tree" # Update and Upgrade -alias uu='sudo apt update && sudo apt upgrade -y' - -# Create a user -alias adduser='sudo adduser $1' - -# Remove a user -alias deluser='sudo deluser --remove-home $1' - -# Create a group -alias addgroup='sudo usermod -aG $1 $2' +alias update="sudo apt update && sudo apt upgrade -y" -# Remove a group -alias delgroup='sudo usermod -G $1 $2' +# Users and groups +alias adduser="sudo adduser" +alias deluser="sudo deluser --remove-home" +alias addgroup="sudo usermod -aG" +alias delgroup="sudo usermod -G" -# Search history. Example usage: `histg git` to recent commands that use git -alias histg="history | grep" - -# Remove Package -alias rmdpkg='sudo apt-get --purge remove $1' - -# Make all files in ~/scripts executable -alias xbin='chmod +x ~/bin/*' - -# Copy SSH Key to remote server -alias sshcopy="ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 $1" - -# Short for calling goBuster -alias gd="gobuster -w ~/.config/gobuster.txt" - -# Rename ~/.bash_aliases to ~/.aliases -alias alre="sed -i 's/~\/.bash_aliases/~\/.aliases/g' ~/.bashrc" +# Permissions +alias xbin="chmod +x ~/bin/*" +alias rm="rm -i" -# wget without history -alias wget='wget --no-hsts' +# +alias histg="history | fzf" +alias wget="wget --no-hsts" +alias rmdpkg="sudo apt-get --purge remove" +# SHH +alias sshcopy="ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22" # !------------------------------------ # @@@ CHANGE DIRECTORIES # !------------------------------------ -# PaleBluDot alias dotfiles="cd $DOTFILES" -alias home="cd ~/" alias github="cd $GITHUB_DIR" -alias cspell-dictionaries="cd ~/Github/PaleBluDot/cspell-dictionaries" -alias lint-config="cd ~/Github/PaleBluDot/lint-config" -alias psd="cd ~/Github/PaleBluDot/website" -alias aclu-emails="cd ~/Github/PaleBluDot/aclu-emails" -alias playground="cd /Users/psanchez/Library/CloudStorage/OneDrive-Personal/Dev/demos/jsExplorer" - -# taste-ink -alias tasteink="cd ~/Github/taste-ink/tasteink.studio" - -# american-technion-society -alias ats="cd ~/Github/American-Technion-Society/purple" -alias publications="cd ~/Github/American-Technion-Society/publications" - -# aclu-national -alias builder="cd ~/Github/ACLU-National/email-builder" - - alias sshd="cd /etc/ssh" -alias findAlias="alias | grep \"$1\"" - # !------------------------------------ # @@@ FILE EDITS # !------------------------------------ -# Edit aliases alias edit="$EDITOR ~/.config/dotfiles/config/zsh/.aliases" - alias base="$EDITOR ~/Library/CloudStorage/OneDrive-Personal/Documents/Espanso/match/base.yml" +alias alre="sed -i "s/~\/.bash_aliases/~\/.aliases/g" ~/.bashrc" +alias netcfg="sudo $EDITOR /etc/netplan/50-cloud-init.yaml" +alias cloudcfg="sudo $EDITOR /etc/cloud/cloud.cfg" -# Configure Static IP -alias netcfg='sudo nano /etc/netplan/50-cloud-init.yaml' - -# Configure Hostname -alias cloudcfg='sudo nano /etc/cloud/cloud.cfg' - -# See Groups -alias group='cat /etc/group' - +alias group="cat /etc/group" +alias findAlias="alias | fzf" # !------------------------------------ # @@@ Manipulations # !------------------------------------ -alias comlist='cat test.html | tr "\n" "," > comma-list.txt' - - +alias comlist="cat test.html | tr "\n" "," > comma-list.txt" +alias gd="gobuster -w ~/.config/gobuster.txt" # !------------------------------------ # @@@ GIT # !------------------------------------ alias gs="git status" -alias s="git status -s" -alias gbs="git status -bs" -alias clone="git clone" -alias gnit="git init" +alias gss="git status -s" +alias gsb="git status -bs" +alias gc="git clone" +alias gi="git init" alias gcm="git commit -m" -alias amend="git commit --amend --no-edit" +alias gam="git commit --amend --no-edit" alias ga="git add" alias gaa="git add ." -alias push="git push" -alias pushup="git push -u origin main" -alias pull="git pull" -alias nb="git checkout -b" -alias switch="git switch" +alias gp="git push" +alias gpu="git push -u origin main" +alias gpl="git pull" +alias gco="git checkout -b" +alias gsw="git switch" alias save="gaa && gcm \"chore: save point\"" alias incom="gaa && gcm \"initial commit\"" alias cached="git rm -r --cached" @@ -142,31 +96,39 @@ alias cached="git rm -r --cached" alias toi="npm init --scope=@taste-ink --init-author-email=pavel@tasteink.me -y" alias npmi="npm init" alias npmiy="npm init -y" -alias build="npm run build" -alias dev="npm run dev" -alias start="npm run start" -alias commit="npm run commit" +alias npmb="npm run build" +alias npmd="npm run dev" +alias npms="npm run start" +alias npmc="npm run commit" alias clean-node="rm -rf ./node_modules && rm -rf package-lock.json" +# !------------------------------------ +# @@@ TMUX +# !------------------------------------ +alias tm="tmux attach -t main || tmux new -s main" +alias tn="tmux new -s" +alias ta="tmux attach -t" +alias td="tmux detach" +alias tl="tmux ls" +alias tk="tmux kill-session -t" +alias tka="tmux kill-server" +alias trn="tmux rename-session -t" +alias ts="tmux switch-client -t" + # !------------------------------------ # @@@ NETWORKING # !------------------------------------ -# Get your current IP alias myip="curl http://ipecho.net/plain; echo" -# alias localip="ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'" +# alias localip="ip -4 addr show eth0 | grep -oP "(?<=inet\s)\d+(\.\d+){3}"" alias ping="ping -c 3" # !------------------------------------ # @@@ OS SPECIFIC # !------------------------------------ -# Open VSCode Insiders alias code="code-insiders" - -# Use teach user data -alias teach="code-insiders --extensions-dir ~/code_profiles/teach/exts --user-data-dir ~/code_profiles/teach/data" - +alias teach="code --extensions-dir ~/code_profiles/teach/exts --user-data-dir ~/code_profiles/teach/data" alias brew-installs="brew list > .config/brew.txt" diff --git a/config/zsh/.functions b/config/zsh/.functions index 8fcb835..df13bf3 100644 --- a/config/zsh/.functions +++ b/config/zsh/.functions @@ -152,6 +152,91 @@ function checkGit() { fi } +# Walks github.com/org/reponame two levels deep, cd's into each repo, +# and reports both uncommitted changes (via your existing checkGit) +# and commits that are ahead of the pushed upstream branch. +# +# Usage: +# checkAllRepos # scans ~/github.com by default +# checkAllRepos ~/some/path # scans a different root +function checkAllRepos() { + local root="${1:-/Users/psanchez/Documents/github.com}" + + if [[ ! -d "$root" ]]; then + echo "Directory not found: $root" + return 1 + fi + + # org/repo = two levels of directories. + # (/N) qualifier: / = dirs only, N = don't error if nothing matches. + for org_dir in "$root"/*(/N); do + for repo_dir in "$org_dir"/*(/N); do + [[ -d "$repo_dir/.git" ]] || continue + + local repo_label="${org_dir:t}/${repo_dir:t}" + + # checkGit reads git status in the current directory, so + # subshell + cd keeps us from having to cd back afterward. + ( + cd "$repo_dir" || exit + echo "${repo_label}:" + checkGit + + # Commits made locally but never pushed to upstream. + local unpushed + unpushed=$(git log '@{u}..HEAD' --oneline 2>/dev/null) + local upstream_exit=$? + + if [[ $upstream_exit -ne 0 ]]; then + echo " ⚠️ ${LIGHTRED}No upstream branch set${NC}" + elif [[ -n "$unpushed" ]]; then + local count=$(echo "$unpushed" | wc -l | tr -d ' ') + echo " ⬆️ ${LIGHTRED}$count unpushed commit(s)${NC}" + fi + ) + done + done +} + +# Same repo-walk as checkAllRepos, but silent unless a repo has +# uncommitted changes or unpushed commits. Designed to be captured +# and conditionally printed from .zshrc, not called directly. +function checkAllReposQuiet() { + local root="${1:-/Users/psanchez/Documents/github.com}" + [[ -d "$root" ]] || return + + for org_dir in "$root"/*(/N); do + for repo_dir in "$org_dir"/*(/N); do + [[ -d "$repo_dir/.git" ]] || continue + + ( + cd "$repo_dir" || exit + + local repo_label="${org_dir:t}/${repo_dir:t}" + + local dirty_count + dirty_count=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ') + + local unpushed + unpushed=$(git log '@{u}..HEAD' --oneline 2>/dev/null) + local upstream_exit=$? + + if [[ "$dirty_count" -gt 0 ]]; then + echo " 🔴 ${LIGHTRED}${repo_label}: ${dirty_count} uncommitted change(s)${NC}" + fi + + if [[ $upstream_exit -eq 0 && -n "$unpushed" ]]; then + local ahead_count + ahead_count=$(echo "$unpushed" | wc -l | tr -d ' ') + echo " ⬆️ ${LIGHTRED}${repo_label}: ${ahead_count} unpushed commit(s)${NC}" + elif [[ $upstream_exit -ne 0 ]]; then + echo " ⚠️ ${LIGHTRED}${repo_label}: no upstream branch set${NC}" + fi + ) + done + done +} + # Checks if HTTP Status is 200 # if not, then it outputs errors message. function getHTTPCode() { @@ -296,4 +381,22 @@ ghs() { # Example: setenv GH_TOKEN abc123 setenv() { export $1=$2 -} \ No newline at end of file +} + + +exit() { + if [ -n "$TMUX" ]; then + tmux detach + else + builtin exit + fi +} + + +detach() { + if [ -n "$TMUX" ]; then + tmux detach + else + echo "Not in a tmux session — nothing to detach from." + fi +} diff --git a/config/zsh/.zshenv b/config/zsh/.zshenv index 6b2eeeb..7f42975 100644 --- a/config/zsh/.zshenv +++ b/config/zsh/.zshenv @@ -2,16 +2,24 @@ # Use nano over SSH, VS Code locally # ----------------------- if [[ -n $SSH_CONNECTION ]]; then - export EDITOR='nano' + export EDITOR='nvim' + export VISUAL='nvim' else - export EDITOR='code' + export EDITOR='code-insiders' + export VISUAL='code-insiders' fi # CORE DIRECTORIES # Paths needed before .zshrc loads # ----------------------- -export ZSH="$HOME/.config/oh-my-zsh" +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_DATA_HOME="$HOME/.local/share" +export XDG_STATE_HOME="$HOME/.local/state" +export XDG_CACHE_HOME="$HOME/.cache" + +export ZSH="$HOME/.config/zsh/oh-my-zsh" export DOTFILES="$HOME/.config/dotfiles" +export STARSHIP_CONFIG="$HOME/.config/starship/starship.toml" # LANGUAGE RUNTIMES # Go and NVM directories @@ -22,7 +30,8 @@ export NVM_DIR="$HOME/.config/nvm" # COMPLETION CACHE # ----------------------- -export ZSH_COMPDUMP="$ZSH/cache/.zcompdump-$HOST" +# export ZSH_COMPDUMP="$ZSH/cache/.zcompdump-$HOST" +export ZSH_COMPDUMP="" # HISTORY SUPPRESSION # Disable history for noisy tools @@ -33,3 +42,5 @@ export NODE_REPL_HISTORY="" # PATH # ----------------------- export PATH="$HOME/bin:$HOME/.config/npm/bin:$GOPATH/bin:$GOROOT/bin:$PATH" + + diff --git a/config/zsh/.zshrc b/config/zsh/.zshrc index 97d4f92..11b3571 100644 --- a/config/zsh/.zshrc +++ b/config/zsh/.zshrc @@ -1,14 +1,7 @@ -# POWERLEVEL10K INSTANT PROMPT -# Uncomment to revert to p10k -# ----------------------- -# if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then -# source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" -# fi - # OH-MY-ZSH CONFIGURATION + # Theme, update settings, and plugins # ----------------------- -# ZSH_THEME="powerlevel10k/powerlevel10k" # uncomment to revert to p10k ZSH_THEME="" HIST_STAMPS="yyyy-mm-dd" @@ -22,30 +15,30 @@ NVM_LAZY_LOAD=true DISABLE_COMPFIX=true plugins=( - 1password + # 1password brew #colored-man-pages #composer #copypath - dotenv + # dotenv gh - git-auto-fetch + # git-auto-fetch #gulp macos npm nvm #postgres - #python + # python #rsync ssh #systemadmin #systemd - tailscale - tldr + # tailscalex + # tldr #tmux #ubuntu #ufw - urltools + # urltools #vscode #wp-cli zsh-autosuggestions @@ -55,7 +48,7 @@ plugins=( # COMPLETIONS # fpath must be set before oh-my-zsh loads so compinit picks it up # ----------------------- -fpath+=${ZSH_CUSTOM:-${ZSH:-~/.oh-my-zsh}/custom}/plugins/zsh-completions/src +fpath+=${ZSH_CUSTOM:-${ZSH:-~/.config/zsh/oh-my-zsh}/custom}/plugins/zsh-completions/src source $ZSH/oh-my-zsh.sh @@ -73,11 +66,12 @@ export WAKATIME_HOME="$HOME/.config/wakatime" export SEMGREP_SETTINGS_FILE="$HOME/.config/semgrep/settings.yml" export TEALDEER_CONFIG_DIR="$HOME/.config/tldr" -# SHELL TOOLS -# thefuck is lazy-loaded — only initializes on first use -# ----------------------- + +eval "$(starship init zsh)" eval "$(zoxide init zsh)" -POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true +eval "$(op completion zsh)"; compdef _op op +eval $(thefuck --alias) + thefuck() { unfunction thefuck @@ -85,11 +79,24 @@ thefuck() { thefuck "$@" } +function y() { + local tmp cwd; tmp="$(mktemp -t "yazi-cwd.XXXXXX")" + command yazi "$@" --cwd-file="$tmp" + IFS= read -r -d '' cwd < "$tmp" + [ "$cwd" != "$PWD" ] && [ -d "$cwd" ] && builtin cd -- "$cwd" || builtin true + command rm -f -- "$tmp" +} + # LOCAL CONFIG # Aliases, functions, theme, welcome message # ----------------------- [[ ! -f $DOTFILES/config/zsh/.aliases ]] || source $DOTFILES/config/zsh/.aliases [[ ! -f $DOTFILES/config/zsh/.functions ]] || source $DOTFILES/config/zsh/.functions -# [[ ! -f $DOTFILES/config/zsh/.p10k.zsh ]] || source $DOTFILES/config/zsh/.p10k.zsh # uncomment to revert to p10k -eval "$(starship init zsh)" -[[ ! -x "$(command -v welcome.sh)" ]] || source welcome.sh && fastfetch --pipe false + + +# Welcome screen +[[ ! -x "$(command -v welcome.sh)" ]] || source welcome.sh && +echo +fastfetch --pipe false +echo +checkDirtyRepos.sh diff --git a/dotfiles.sh b/dotfiles.sh old mode 100644 new mode 100755 index a329819..f1e51c5 --- a/dotfiles.sh +++ b/dotfiles.sh @@ -1,575 +1,127 @@ -#!/bin/bash - -# Check if bc command is available -if ! command -v bc &> /dev/null; then - echo "'bc' command not found. Attempting to install..." - # Install bc (adjust as needed based on your package manager) - sudo apt-get update > /dev/null - sudo apt-get install -y bc > /dev/null - echo "Installation completed successfully." - echo - - # Check again - if ! command -v bc &> /dev/null; then - echo "Error: Unable to install 'bc'. Please install bc manually and run the script again." - exit 1 - fi -fi - -# Record start time -start_time=$(date +%s.%N) - -###################### -##@ BANNER -###################### -clear -echo - -cat << "EOF" - .. s . .. .x+=:. - dF :8 oec : @88> x .d88" z` ^% -'88bu. u. .88 @88888 %8P 5888R . 8888 u888888> ''888E` 888R :888'8888. x88: `)8b. - 888E 888E 888R I888> 8888 8888R 888E 888R d888 '88%" 8888N=*8888 - 888E 888E 888R I888> 8888 8888P 888E 888R 8888.+" %8" R88 - 888E 888F u8888cJ888 .8888Lu= *888> 888E 888R 8888L @8Wou 9% -.888N..888 "*888*P" ^%888* 4888 888& .888B . '8888c. .+ .888888P` - `"888*"" 'Y" 'Y" '888 R888" ^*888% "88888% ` ^"F - "" 88R "" "% "YP' - 88> - 48 - '8 -EOF - -echo -sleep 1 - -###################### -##@ VARIABLES -###################### - -# Export dotfiles directory as an environment variable -export DOTFILES=$HOME/.config/dotfiles - -###################### -##@ MACOS -###################### - -# Function to install packages for macOS -install_macos() { - local macos_dir="config/os-only/macos/" - local install_packages=true - - # Check if Brewfile exists - if [ ! -f "$macos_dir/Brewfile" ]; then - echo "Error: Brewfile not found in $macos_dir" - exit 1 - fi - - # Check if -d flag is present - if [[ $* == *"-d"* ]]; then - echo "Packages to be installed for macOS:" - cat "$macos_dir/Brewfile" - install_packages=false - fi - - if [ "$install_packages" == true ]; then - # Update Homebrew - brew update > /dev/null - - # Install packages for macOS - echo "Installing packages for macOS..." - while IFS= read -r line; do - if [[ $line == brew* ]]; then - package=$(echo "$line" | awk -F'"' '{print $2}') - brew install "$package" > /dev/null 2>&1 - - # Wait for the version information to become available - while true; do - installed_version=$(brew list --versions "$package" 2>/dev/null || echo "Not Installed") - [ "$installed_version" != "Not Installed" ] && break - done - - if [ "$installed_version" != "Not Installed" ]; then - echo "$package: Installed (Version: $installed_version)" - else - echo "$package: Installing..." - fi - fi - done < "$macos_dir/Brewfile" - fi -} - -# Function to uninstall packages for macOS -uninstall_macos() { - local macos_dir="config/os-only/macos/" - local uninstall_packages=true - - # Check if Brewfile exists - if [ ! -f "$macos_dir/Brewfile" ]; then - echo "Error: Brewfile not found in $macos_dir" - exit 1 - fi - - # Check if -d flag is present - if [[ $* == *"-d"* ]]; then - echo "Packages to be uninstalled for macOS:" - cat "$macos_dir/Brewfile" - uninstall_packages=false - fi - - if [ "$uninstall_packages" == true ]; then - # Update Homebrew - brew update > /dev/null - - # Uninstall packages for macOS - echo "Uninstalling packages for macOS..." - while IFS= read -r line; do - if [[ $line == brew* ]]; then - package=$(echo "$line" | awk -F'"' '{print $2}') - brew uninstall "$package" > /dev/null 2>&1 - - # Wait for the version information to become unavailable - while true; do - installed_version=$(brew list --versions "$package" 2>/dev/null || echo "Not Installed") - [ "$installed_version" == "Not Installed" ] && break - sleep 1 - done - - if [ "$installed_version" == "Not Installed" ]; then - echo "$package: Uninstalled" - else - echo "$package: Uninstalling..." - fi - fi - done < "$macos_dir/Brewfile" - fi -} - -###################### -##@ LINUX -###################### - -# Function to install packages for Linux -install_linux() { - local linux_dir="config/os-only/linux/" - local install_packages=true - - # Check if required-packages.txt exists - if [ ! -f "$linux_dir/required-packages.txt" ]; then - echo "Error: required-packages.txt not found in $linux_dir" - exit 1 - fi - - # Check if -d flag is present - if [[ $* == *"-d"* ]]; then - echo "Packages to be installed for Linux:" - cat "$linux_dir/required-packages.txt" - install_packages=false - fi - - if [ "$install_packages" == true ]; then - # Update package list - sudo apt-get update > /dev/null - - # Install packages for Linux - echo "Installing packages for Linux..." - while IFS= read -r package; do - sudo apt-get install -y "$package" > /dev/null - sleep 1 - - # Wait for the version information to become available - while true; do - installed_version=$(dpkg-query -W -f='${Version}\n' "$package" 2>/dev/null || echo "Not Installed") - [ "$installed_version" != "Not Installed" ] && break - sleep 1 - done - - if [ "$installed_version" != "Not Installed" ]; then - echo "$package: Installed (Version: $installed_version)" - else - echo "$package: Installing..." - fi - done < "$linux_dir/required-packages.txt" - fi -} - -# Function to uninstall packages for Linux -uninstall_linux() { - local linux_dir="config/os-only/linux/" - - # Check if required-packages.txt exists - if [ ! -f "$linux_dir/required-packages.txt" ]; then - echo "Error: required-packages.txt not found in $linux_dir" - exit 1 - fi - - # Uninstall packages for Linux - echo "Uninstalling packages for Linux..." - while IFS= read -r package; do - if dpkg-query -W -f='${Status}' "$package" 2>/dev/null | grep -q "install ok installed"; then - sudo apt-get remove -y "$package" > /dev/null - echo "$package: Uninstalled" - else - echo "$package: Not Installed" - fi - done < "$linux_dir/required-packages.txt" -} - -###################### -##@ WINDOWS -###################### - -# Function to install packages for Windows -install_windows() { - local windows_dir="config/os-only/windows/" +#!/usr/bin/env zsh + +########################## +##############@ VARIABLES +########################## +readonly LOG_LEVEL_DEBUG=0 +readonly LOG_LEVEL_INFO=1 +readonly LOG_LEVEL_WARN=2 +readonly LOG_LEVEL_ERROR=3 +LOG_LEVEL=$LOG_LEVEL_INFO +DRY_RUN=false + + +########################## +##############@ FUNCTIONS +########################## +_log() { + local level="$1" + local message="$2" + local level_num + local prefix + + local CYAN="\033[0;36m" + local GREEN="\033[0;32m" + local YELLOW="\033[0;33m" + local RED="\033[0;31m" + local RESET="\033[0m" + + + case "$level" in + debug) level_num=$LOG_LEVEL_DEBUG; + prefix="${GREEN}[DEBUG] ${RESET}" ;; + info) level_num=$LOG_LEVEL_INFO; + prefix="${CYAN}[INFO] ${RESET}" ;; + warn) level_num=$LOG_LEVEL_WARN; + prefix="${YELLOW}[WARN] ${RESET}" ;; + error) level_num=$LOG_LEVEL_ERROR; + prefix="${RED}[ERROR] ${RESET}" ;; + *) level_num=$LOG_LEVEL_INFO; + prefix="${CYAN}[INFO] ${RESET}" ;; + esac - # Display packages to be installed - echo "Packages to be installed for Windows:" - if [ -f "$windows_dir/required-packages.txt" ]; then - cat "$windows_dir/required-packages.txt" - # Check if packages are already installed (Update this part based on Windows package manager) - echo -e "\nChecking installed packages and versions: (Update this part based on Windows package manager)" + [[ $level_num -lt $LOG_LEVEL ]] && return - # Wait for 3 seconds - sleep 3 - # Install packages for Windows (Adjust as needed, provide instructions or use the appropriate package manager) - echo "Installing packages for Windows..." - # Example: choco install packageName + if [[ "$level" == "error" ]]; then + echo -e "$prefix $message" >&2 else - echo "Error: required-packages.txt not found in $windows_dir" - exit 1 + echo -e "$prefix $message" fi } -# Function to uninstall packages for Windows -uninstall_windows() { - # Uninstall packages for Windows (adjust as needed) - echo "Uninstalling packages for Windows..." - # Example: choco uninstall packageName -} - -###################### -##@ DOTFILES -###################### - -# Resolve uname to the YAML OS key: darwin | linux | windows -_current_os() { +_detect_os() { case "$(uname)" in - Darwin) echo "darwin" ;; - Linux) echo "linux" ;; - MINGW*|MSYS*|CYGWIN*) echo "windows" ;; - *) echo "unknown" ;; - esac -} - -# Emit tab-separated "tool src dest" lines for all enabled symlinks on the current OS. -# dest is always a full ~/... path. Combines cross-platform (symlinks:) and -# OS-specific (darwin:/linux:/windows:) entries. -_parse_symlinks() { - local symlinks_file="$1" - export OS - OS=$(_current_os) - { - # Cross-platform entries - yq eval 'to_entries[] | select(.value.enabled == true) | . as $e | - .value.symlinks // {} | to_entries[] | - [$e.key, .key, .value] | join("\t")' "$symlinks_file" - # OS-specific entries - yq eval 'to_entries[] | select(.value.enabled == true) | . as $e | - .value[env(OS)] | select(. != null) | to_entries[] | - [$e.key, .key, .value] | join("\t")' "$symlinks_file" - } -} - -# Function to install dotfiles -install_dotfiles() { - local symlinks_file="config/symlinks.yml" - - if [ ! -f "$symlinks_file" ]; then - echo "Error: $symlinks_file not found" - exit 1 - fi - - echo "Creating symlinks (OS: $(_current_os))..." - - while IFS=$'\t' read -r tool src dest; do - local source_path - if [ "$src" = "." ]; then - source_path="${HOME}/.config/dotfiles/config/${tool}" - else - source_path="${HOME}/.config/dotfiles/config/${tool}/${src}" - fi - local target_path="${dest/#\~/$HOME}" - local target_dir - target_dir="$(dirname "$target_path")" - - if [ ! -d "$target_dir" ]; then - mkdir -p "$target_dir" - fi - - if [ -e "$target_path" ] || [ -L "$target_path" ]; then - if [ -L "$target_path" ]; then - echo "Symlink already exists: $target_path" - else - echo "File or directory already exists: $target_path" - fi - else - ln -fs "$source_path" "$target_path" - echo "Symlink created: $target_path -> $source_path" - fi - done < <(_parse_symlinks "$symlinks_file") - - ln -fs "$DOTFILES/bin" "$HOME/bin" - echo "Symlink created: $HOME/bin -> $DOTFILES/bin" - - # Generate cspell.json with resolved $HOME path (not symlinked — relative paths - # break when cspell resolves them from the symlink target, not the symlink location) - local cspell_src="$DOTFILES/config/cspell/cspell.json" - local cspell_dest="$HOME/.config/configstore/cspell.json" - mkdir -p "$(dirname "$cspell_dest")" - sed "s|__HOME__|$HOME|g" "$cspell_src" > "$cspell_dest" - echo "Generated: $cspell_dest" - - echo -e "\nDotfiles installation completed successfully." -} - -# Function to uninstall dotfiles -uninstall_dotfiles() { - local symlinks_file="config/symlinks.yml" - - if [ ! -f "$symlinks_file" ]; then - echo "Error: $symlinks_file not found" - exit 1 - fi - - echo "Removing symlinks (OS: $(_current_os))..." - - while IFS=$'\t' read -r tool src dest; do - local source_path - if [ "$src" = "." ]; then - source_path="${HOME}/.config/dotfiles/config/${tool}" - else - source_path="${HOME}/.config/dotfiles/config/${tool}/${src}" - fi - local target_path="${dest/#\~/$HOME}" - - if [ -L "$target_path" ]; then - rm -f "$target_path" - echo "Symlink removed: $target_path -> $source_path" - elif [ -e "$target_path" ]; then - rm -f "$target_path" - echo "Not a symlink. File deleted: $target_path" - else - echo "Target not found: $target_path" - fi - done < <(_parse_symlinks "$symlinks_file") - - rm -f "$HOME/bin" - echo "Symlink removed: $HOME/bin -> $DOTFILES/bin" - - echo "Dotfiles uninstall completed successfully." -} - - -# Function to update dotfiles -update_dotfiles() { - git pull - - if [ $? -ne 0 ]; then - echo "Error during git pull. Please resolve merge conflicts and try again." - git status - exit 1 - fi - - echo "Dotfiles updated successfully." -} - -###################### -##@ PACKAGES -###################### - -# Function to install packages only -install_packages() { - local os_type="$(uname)" - - case "$os_type" in - Darwin) - CSPELL_DIR="/opt/homebrew/lib" - install_macos - ;; - Linux) - CSPELL_DIR="/usr/lib" - install_linux - ;; - MINGW32*|MSYS*|MINGW64*) - CSPELL_DIR="C:\\Program Files\\nodejs\\" - install_windows - ;; - *) - echo "Unsupported operating system." - exit 1 - ;; - esac -} - -# Function to uninstall packages only -uninstall_packages() { - local os_type="$(uname)" - - case "$os_type" in Darwin) - uninstall_macos + echo "darwin" ;; Linux) - uninstall_linux + if grep -qi "microsoft" /proc/version; then + echo "wsl" + else + echo "linux" + fi ;; - MINGW32*|MSYS*|MINGW64*) - uninstall_windows + MINGW*|MSYS*|CYGWIN*) + echo "windows-native" ;; *) - echo "Unsupported operating system." + _log error "Unsupported OS '$(uname)'" exit 1 ;; esac } +_bootstrap() { + export DOTFILES=$(cd "$(dirname "$0")" && pwd) -###################### -##@ COMMANDS -###################### - -# Function to install dotfiles and/or packages based on options -install() { - local options="$1" - # Ask the user what they want to do - echo "Do you want to (1) install packages or (2) symlink files?" - read -p "Enter pkg or sym: " choice - - # Check if -d flag is present - local install_dotfiles=true - if [[ $options == *"d"* ]]; then - install_dotfiles - fi - - # Check if -p flag is present - local install_packages=true - if [[ $options == *"p"* ]]; then - install_packages - fi - - # If no flag is used, install both dotfiles and packages - if [ -z "$options" ]; then - install_dotfiles - install_packages - fi - - # Process the user's choice - case "$choice" in - pkg) - echo "Installing packages..." - # Call your function or commands to install packages here - ;; - sym) - echo "Symlinking files..." - # Call your function or commands to symlink files here - ;; - *) - echo "Invalid choice" - ;; + if command -v yq &>/dev/null; then + _log debug "yq is installed" + else + _log info "yq is not installed" + _log info "installing yq..." + case "$(_detect_os)" in + darwin) + brew install yq + ;; + linux|wsl) + sudo apt-get install yq + ;; + windows-native) + winget install yq + ;; + esac + fi +} + + +########################## +##################@ FLAGS +########################## +for arg in "$@"; do + case "$arg" in + --dry-run|-n) + DRY_RUN=true ;; + --debug|-d) + LOG_LEVEL=$LOG_LEVEL_DEBUG ;; esac -} - -# Function to uninstall dotfiles and/or packages based on options -uninstall() { - local options="$1" +done - # Check if dotfiles option is selected - if [[ $options == *"d"* ]]; then - uninstall_dotfiles - fi - - # Check if packages option is selected - if [[ $options == *"p"* ]]; then - uninstall_packages - fi -} +[[ "$DRY_RUN" == true ]] && _log info "dry run mode" +[[ "$LOG_LEVEL" == "$LOG_LEVEL_DEBUG" ]] && _log info "debug mode" -# Function to update based on options -update() { - local options="$1" - - # Check if dotfiles option is selected - if [[ $options == *"d"* ]]; then - update_dotfiles - fi - - # Check if packages option is selected - if [[ $options == *"p"* ]]; then - update_packages - fi -} - -# Function to display extensive usage -usage() { - echo "Usage: $0 {command} [options]" - echo - echo "Commands:" - echo " install Install dotfiles and/or packages." - echo " uninstall Uninstall dotfiles and/or packages." - echo " update Update dotfiles and/or packages." - echo " help Display this help message." - echo - echo -e "Options:" - echo " -d Install/uninstall/update dotfiles." - echo " -p Install/uninstall/update packages." - echo " -h Display usage information." - echo - echo -e "Examples:" - echo " $0 install -d -p # Install both dotfiles and packages." - echo " $0 uninstall -d # Uninstall dotfiles." - echo " $0 update -p # Update packages." - echo " $0 help # Display this help message." -} - - -# Check command arguments -if [ "$#" -eq 0 ]; then - # No arguments provided, default to 'install' - install -else - case "$1" in - install) - install "$2" - ;; - uninstall) - uninstall "$2" - ;; - update) - update "$2" - ;; - help) - usage - ;; - *) - usage - exit 1 - ;; - esac -fi -# Record the end time -end_time=$(date +%s.%N) -# Calculate and print the execution time -execution_time=$(echo "$end_time - $start_time" | bc) +########################## +####################@ RUN +########################## +_bootstrap -echo -echo "Script execution time: $execution_time seconds" +_log info "test message" +_log debug "test message" +_log warn "test message" +_log error "test message" -exit 0 +# _log info "dotfiles script loaded successfully" \ No newline at end of file