Skip to main content

3.2 - Assign ZSH Aliases

Step 1 - Open your terminal and type:

sudo pacman -S --needed --noconfirm kate && kate ~/.zshrc

Step 2 - Delete everything and paste the following block:

# ~/.zshrc

# --- Zsh Configuration ---

# Source Manjaro Zsh configuration if it exists
# This often sets up prompt, completion, aliases, etc.
if [[ -e /usr/share/zsh/manjaro-zsh-config ]]; then
source /usr/share/zsh/manjaro-zsh-config
fi

# --- Environment Variables & Path ---

# Export NVM directory
export NVM_DIR="$HOME/.nvm"

# Add user bin directories if they exist (prepend to find user scripts first)
# typeset -U path # Ensure path array exists if using typeset method
# [ -d "$HOME/.local/bin" ] && path=("$HOME/.local/bin" $path)
# [ -d "$HOME/bin" ] && path=("$HOME/bin" $path)
# Simpler export way:
[ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
[ -d "$HOME/bin" ] && export PATH="$HOME/bin:$PATH"

# Source NVM script and completion if they exist
# Sourced after PATH mods, before functions/aliases using Node/npm.
# Note: Sourcing bash_completion into Zsh isn't ideal but is NVM's default.
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

# -------------------------------------------------------------------------
# --------------------- Shell Functions -----------------------------------
# -------------------------------------------------------------------------

# Helper function for editor selection
_xget_editor() {
local editor_cmd=""
if [[ -n "$VISUAL" ]] && (( $+commands[$VISUAL] )); then
editor_cmd="$VISUAL"
elif [[ -n "$EDITOR" ]] && (( $+commands[$EDITOR] )); then
editor_cmd="$EDITOR"
elif (( $+commands[subl] )); then
editor_cmd="subl"
elif (( $+commands[kate] )); then
editor_cmd="kate"
elif (( $+commands[micro] )); then # Added micro as a common modern editor
editor_cmd="micro"
elif (( $+commands[nano] )); then
editor_cmd="nano"
elif (( $+commands[vim] )); then
editor_cmd="vim"
elif (( $+commands[vi] )); then
editor_cmd="vi"
fi

if [[ -z "$editor_cmd" ]]; then
return 1 # Indicate no editor found
fi
echo "$editor_cmd"
return 0
}

# xlock: Makes a file immutable
# Usage: xlock <filename>
xlock() {
if (( ! $# )); then
echo "xlock: Usage: xlock <filename>" >&2
return 1
fi
if [ ! -e "$1" ]; then
echo "xlock: Error: File '$1' not found." >&2
return 1
fi
# Optional: Check if already locked
# local attributes; attributes=$(lsattr -d -- "$1" 2>/dev/null)
# if [[ "$attributes" == *"----i"* ]]; then
# echo "xlock: File '$1' is already locked." # To stdout or >&2 as preferred
# return 0
# fi
echo "Attempting to lock '$1' (make immutable)..."
if sudo chattr +i "$1"; then
echo "xlock: Successfully locked '$1'."
return 0
else
echo "xlock: Error: Failed to lock '$1'." >&2
return 1
fi
}

# xunlock: Makes a file mutable
# Usage: xunlock <filename>
xunlock() {
if (( ! $# )); then
echo "xunlock: Usage: xunlock <filename>" >&2
return 1
fi
if [ ! -e "$1" ]; then
echo "xunlock: Error: File '$1' not found." >&2
return 1
fi
# Optional: Check if already unlocked
# local attributes; attributes=$(lsattr -d -- "$1" 2>/dev/null)
# if [[ "$attributes" != *"----i"* ]]; then # Check if immutable flag is NOT set
# echo "xunlock: File '$1' is already unlocked." # To stdout or >&2 as preferred
# return 0
# fi
echo "Attempting to unlock '$1' (make mutable)..."
if sudo chattr -i "$1"; then
echo "xunlock: Successfully unlocked '$1'."
return 0
else
echo "xunlock: Error: Failed to unlock '$1'." >&2
return 1
fi
}

# xwget: Downloads/mirrors a website
# Usage: xwget <URL>
xwget() {
if (( ! $# )); then
echo "xwget: Usage: xwget <URL>" >&2
return 1
fi

local url="$1"
local site_name
local output_base_dir="$HOME/Downloads/MirroredSites"
local output_dir

# Extract site name from URL
site_name=$(echo "$url" | sed -E 's#^([a-zA-Z.+-]+:)?(//)?([^/?#]+).*#\3#' | sed 's/[^a-zA-Z0-9._-]/_/g')

if [ -z "$site_name" ]; then
site_name="unknown_site_$(date +%s)"
echo "xwget: Warning: Could not extract site name from URL, using fallback '$site_name'." >&2
fi

output_dir="$output_base_dir/$site_name"

if ! mkdir -p "$output_dir"; then
echo "xwget: Error: Failed to create output directory '$output_dir'." >&2
return 1
fi

echo "Mirroring '$url' to '$output_dir'..."

if wget --mirror --convert-links --adjust-extension --page-requisites \
--no-parent --wait=1 --random-wait --limit-rate=200k \
--user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" \
-P "$output_dir" "$url"; then
echo "xwget: Download completed successfully for '$url'."
return 0
else
echo "xwget: Error: wget failed for '$url'. Check connection, URL, or wget output." >&2
return 1
fi
}

# xserve: Serves static files, installs 'serve' if needed
# Usage: xserve [directory_to_serve] [port]
xserve() {
local serve_dir="${1:-.}" # Default to current directory if no argument
local port="${2:-3000}" # Default to port 3000

if ! (( $+commands[serve] )); then
echo "xserve: 'serve' command not found."
if ! (( $+commands[npm] )); then
echo "xserve: Error: 'npm' command not found. Cannot install 'serve'. Please install Node.js/npm." >&2
return 1
fi
echo "xserve: Attempting global install of 'serve' via npm..."
echo "xserve: Note: Requires NVM sourced & Node active for 'npm install -g' without sudo, or sudo privileges."
if ! npm install -g "serve"; then # Consider sudo if user environment expects it: sudo npm install -g "serve"
echo "xserve: Error: Failed to install 'serve'. Check Node/NVM setup or try with sudo." >&2
return 1
fi
echo "xserve: 'serve' installed successfully."
fi

local actual_serve_dir="$serve_dir"
if [ "$serve_dir" = "." ]; then # Only do auto-detection if no specific dir was given
if [ -d "./build" ]; then
actual_serve_dir="./build"
echo "xserve: Found './build' directory, serving from there."
elif [ -d "./dist" ]; then
actual_serve_dir="./dist"
echo "xserve: Found './dist' directory, serving from there."
else
echo "xserve: Serving current directory ('.')."
fi
fi

echo "xserve: Starting server for directory '$actual_serve_dir' on http://localhost:$port ..."
serve -s "$actual_serve_dir" -l "$port" || {
echo "xserve: Error: 'serve' command failed. Check port $port or 'serve' package." >&2
return 1
}
return 0
}

# xedit-hosts: Edits /etc/hosts using sudoedit
xedit-hosts() {
local editor_to_use
editor_to_use=$(_xget_editor)
if [[ $? -ne 0 ]] || [[ -z "$editor_to_use" ]]; then
echo "xedit-hosts: Error: No suitable editor found (checked \$VISUAL, \$EDITOR, subl, kate, micro, nano, vim, vi)." >&2
return 1
fi

echo "xedit-hosts: Attempting to edit /etc/hosts with $editor_to_use (via sudoedit)..."
EDITOR="$editor_to_use" sudoedit /etc/hosts || {
echo "xedit-hosts: Error: sudoedit failed for /etc/hosts." >&2
return 1
}
return 0
}

# xedit-ba: Edits ~/.bashrc
xedit-ba() {
local target_file="$HOME/.bashrc"
local editor_to_use
editor_to_use=$(_xget_editor)
if [[ $? -ne 0 ]] || [[ -z "$editor_to_use" ]]; then
echo "xedit-ba: Error: No suitable editor found to edit $target_file." >&2
return 1
fi

echo "xedit-ba: Opening '$target_file' with '$editor_to_use'..."
"$editor_to_use" "$target_file" || {
echo "xedit-ba: Error: Editor '$editor_to_use' failed to open '$target_file'." >&2
return 1
}
return 0
}

# xedit-zsh: Edits ~/.zshrc
xedit-zsh() {
local target_file="$HOME/.zshrc"
local editor_to_use
editor_to_use=$(_xget_editor)
if [[ $? -ne 0 ]] || [[ -z "$editor_to_use" ]]; then
echo "xedit-zsh: Error: No suitable editor found to edit $target_file." >&2
return 1
fi

echo "xedit-zsh: Opening '$target_file' with '$editor_to_use'..."
"$editor_to_use" "$target_file" || {
echo "xedit-zsh: Error: Editor '$editor_to_use' failed to open '$target_file'." >&2
return 1
}
return 0
}

# xedit: Edits given file(s) using sudoedit if they seem to require root, otherwise direct.
# Usage: xedit <filename> [additional files...]
xedit() {
if (( ! $# )); then
echo "xedit: Usage: xedit <filename> [additional files...]" >&2
return 1
fi

local editor_to_use
editor_to_use=$(_xget_editor)
if [[ $? -ne 0 ]] || [[ -z "$editor_to_use" ]]; then
echo "xedit: Error: No suitable editor found (checked \$VISUAL, \$EDITOR, subl, kate, micro, nano, vim, vi)." >&2
return 1
fi

# Simple check: if any file is in /etc or we can't write to it, use sudoedit
# This is a heuristic. A more robust check might involve checking actual parent directory permissions.
local use_sudoedit=0
for file in "$@"; do
if [[ "$file" == /etc/* ]] || { [[ -e "$file" ]] && [[ ! -w "$file" ]]; } || { [[ ! -e "$file" ]] && [[ "$file" == */* ]] && [[ ! -w "$(dirname "$file")" ]]; } then
use_sudoedit=1
break
fi
done

if (( use_sudoedit )); then
echo "xedit: Attempting to edit file(s) with $editor_to_use (via sudoedit due to path or permissions)..."
EDITOR="$editor_to_use" sudoedit "$@" || {
echo "xedit: Error: sudoedit failed for the specified file(s). Check permissions or editor config." >&2
return 1
}
else
echo "xedit: Opening file(s) with $editor_to_use..."
"$editor_to_use" "$@" || {
echo "xedit: Error: Editor '$editor_to_use' failed to open the specified file(s)." >&2
return 1
}
fi
return 0
}


# xpy-venv-activate: Creates and/or activates a Python virtual environment
xpy-venv-activate() {
local venv_dir="venv" # Default venv directory name
local activate_script="$venv_dir/bin/activate"
local log_file="venv-creation.log"

if ! (( $+commands[python3] )); then
echo "xpy-venv-activate: Error: python3 command not found. Please install Python 3." >&2
return 1
fi

if [ -d "$venv_dir" ]; then
echo "xpy-venv-activate: '$venv_dir' directory exists."
if [ -f "$activate_script" ]; then
echo "xpy-venv-activate: Attempting to activate existing venv..."
if source "$activate_script"; then
echo "xpy-venv-activate: Existing venv activated successfully."
return 0
else
echo "xpy-venv-activate: ERROR: Failed to activate existing venv at '$activate_script'." >&2
return 1
fi
else
echo "xpy-venv-activate: ERROR: '$venv_dir' exists but activate script missing: '$activate_script'." >&2
echo "Delete '$venv_dir' and try again, or check its integrity." >&2
return 1
fi
else
echo "xpy-venv-activate: '$venv_dir' directory does not exist."
echo "xpy-venv-activate: Attempting to create venv with python3 (logs to '$log_file')..."
# The Zsh construct `>(tee ...)` sends stderr to both the log file and the terminal's stderr.
if python3 -m venv "$venv_dir" 2> >(tee "$log_file" >&2); then
echo "xpy-venv-activate: venv created successfully."
if [ -f "$activate_script" ]; then
echo "xpy-venv-activate: Attempting to activate newly created venv..."
if source "$activate_script"; then
echo "xpy-venv-activate: New venv activated successfully."
return 0
else
echo "xpy-venv-activate: ERROR: Failed to activate new venv at '$activate_script'." >&2
echo "Check '$log_file' for potential venv creation errors." >&2
return 1
fi
else
echo "xpy-venv-activate: ERROR: venv created but activate script missing: '$activate_script'." >&2
echo "Check '$log_file' for creation errors." >&2
return 1
fi
else
echo "xpy-venv-activate: ERROR: Failed to create venv using 'python3 -m venv'." >&2
echo "See '$log_file' for detailed errors." >&2
return 1
fi
fi
}

# Package Management (yay/pacman) helper
_xrun_yay() {
if ! (( $+commands[yay] )); then
echo "yay command not found. Please install yay." >&2
return 1
fi
# Pass yay command options as first arg, rest are packages
yay "$@"
}

xinstall() {
_xrun_yay -S --needed "$@"
}

xreinstall() {
_xrun_yay -S "$@"
}

xremove() {
_xrun_yay -Rns "$@"
}

# xclean: Comprehensive system clean function
xclean() {
echo "Starting comprehensive system clean..."
local hr_sep="----------------------------------------" # Define a horizontal rule string

echo $hr_sep; echo "Cleaning pacman cache (keeping last 1 version)..."
{ sudo paccache -rk1 && echo "Successfully kept last 1 version from pacman cache." || echo "paccache -rk1 failed or no cache to clean." >&2; }

echo $hr_sep; echo "Cleaning pacman cache (uninstalled packages) and unused sync dbs..."
{ sudo pacman -Scc --noconfirm && echo "Successfully cleaned pacman cache and unused sync dbs." || echo "pacman -Scc failed." >&2; }

if (( $+commands[yay] )); then
echo $hr_sep; echo "Cleaning unneeded yay dependencies..."
{ yay -Yc --noconfirm && echo "Successfully cleaned unneeded yay dependencies." || echo "yay -Yc failed." >&2; }

echo $hr_sep; echo "Cleaning yay build cache..."
{ yay -Sc --noconfirm && echo "Successfully cleaned yay build cache." || echo "yay -Sc failed." >&2; }
else
echo $hr_sep; echo "yay not found, skipping yay cache cleaning." >&2
fi

local pamac_build_dir="/var/tmp/pamac-build-$USER/"
echo $hr_sep; echo "Checking pamac build directory: $pamac_build_dir..."
if [ -d "$pamac_build_dir" ]; then
echo "Attempting to clean pamac build dir: $pamac_build_dir"
# Using :? ensures the variable is set, preventing accidental 'rm -rf /*'
{ sudo rm -rf "${pamac_build_dir:?}"/* && echo "Cleaned pamac build files for user $USER." || echo "Failed to clean pamac build dir contents (permissions?)." >&2; }
# Consider removing the directory itself if empty: sudo rmdir "$pamac_build_dir" 2>/dev/null
else
echo "Pamac build directory for user $USER not found, skipping."
fi

echo $hr_sep; echo "System cleaning finished."
return 0
}

# xdelete-docker: Destructive Docker cleanup function
xdelete-docker() {
if ! (( $+commands[docker] )); then
echo "xdelete-docker: Docker command not found." >&2
return 1
fi

echo "WARNING: This will stop all containers, remove all containers, images, volumes, and prune the Docker system."
echo "This operation is highly destructive and irreversible."

local confirm
# Zsh specific read prompt for a single character
read -k 1 -r "confirm?Are you absolutely sure you want to continue? (y/N): "
echo # Newline after read

if [[ "$confirm" =~ ^[Yy]$ ]]; then
echo "Proceeding with Docker cleanup..."
local hr_sep="----------------------------------------"

echo $hr_sep; echo "Stopping all running containers..."
{ docker ps -aq | grep -q . && docker stop $(docker ps -aq) || echo "No running containers to stop."; }

echo $hr_sep; echo "Removing all containers..."
{ docker ps -aq | grep -q . && docker rm $(docker ps -aq) || echo "No containers to remove."; }

echo $hr_sep; echo "Pruning Docker system (networks, dangling images, build cache)..."
{ docker system prune -af && echo "System pruned." || echo "Docker system prune failed." >&2; }

echo $hr_sep; echo "Removing all Docker images..."
{ docker images -q | grep -q . && docker rmi -f $(docker images -q) || echo "No images to remove."; }

echo $hr_sep; echo "Pruning unused Docker volumes..."
{ docker volume prune -f && echo "Unused volumes pruned." || echo "Docker volume prune failed." >&2; }

# Attempt to remove any remaining volumes (usually named volumes not automatically pruned if recently used by a removed container)
echo $hr_sep; echo "Attempting to remove remaining Docker volumes..."
{ docker volume ls -q | grep -q . && docker volume rm $(docker volume ls -q) || echo "No remaining volumes to remove."; }

echo $hr_sep
echo "Docker cleanup process finished."
echo "Current Docker disk usage:"
docker system df
else
echo "Docker cleanup cancelled."
fi
return 0
}

# xnpm-doc: Docusaurus project management function
xnpm-doc() {
local hr_sep="----------------------------------------"
if ! (( $+commands[npm] )); then
echo "xnpm-doc: Error: npm command not found. Please install Node.js and npm." >&2
return 1
fi

echo "xnpm-doc: Ensuring npm is latest..."
{ npm install -g npm@latest || { echo "xnpm-doc: Failed to update npm globally." >&2; return 1; } }
echo $hr_sep

echo "xnpm-doc: Installing/updating Docusaurus dependencies for the project..."
{ npm i @docusaurus/core@latest @docusaurus/preset-classic@latest @docusaurus/module-type-aliases@latest @docusaurus/types@latest || { echo "xnpm-doc: Failed to install/update Docusaurus dependencies." >&2; return 1; } }
echo $hr_sep

echo "xnpm-doc: Upgrading project packages (respecting package.json constraints)..."
{ npm upgrade || { echo "xnpm-doc: Failed npm upgrade." >&2; return 1; } } # Consider 'npm-check-updates -u && npm install' for more aggressive updates
echo $hr_sep

echo "xnpm-doc: Building Docusaurus site..."
{ npm run build || { echo "xnpm-doc: Failed Docusaurus build." >&2; return 1; } }
echo $hr_sep

echo "xnpm-doc: Docusaurus build complete. You can now serve it."
echo "xnpm-doc: To serve, you might typically run: npm run serve"
return 0
}

# xupdate: Comprehensive system update function
xupdate() {
local hr_sep="----------------------------------------"
echo "Starting full system update..."

echo $hr_sep; echo "Updating main system packages (yay)..."
if (( $+commands[yay] )); then
{ yay -Syyu --devel --timeupdate --needed --noconfirm && echo "Main system update successful." || echo "Main system update failed (yay error)." >&2; }
else
echo "yay command not found. Skipping main system update." >&2
fi

echo $hr_sep; echo "Starting kernel update process using yay (double check)..."
echo "This script will attempt to update the latest stable kernel and the latest LTS kernel."

# 1. Update Latest Stable Kernel and its Headers
echo $hr_sep; echo "Checking for Latest Stable Kernel and Headers (packages: linux, linux-headers)..."
if (( $+commands[yay] )); then
if yay -S --needed --noconfirm linux linux-headers; then # Ensures these specific packages are targeted
echo "Latest Stable Kernel and Headers (linux, linux-headers) check/update complete."
else
echo "Latest Stable Kernel and Headers (linux, linux-headers) check/update failed." >&2
fi
else
echo "yay not found, skipping kernel update." >&2
fi

echo $hr_sep

# 2. Update Latest LTS Kernel and its Headers
# Manjaro uses a meta-package 'linux-lts' which points to the current recommended LTS kernel.
# This meta-package should automatically handle the installation of the correct LTS kernel and its headers.
echo "Checking for Latest LTS Kernel and its Headers (meta-package: linux-lts)..."
if (( $+commands[yay] )); then
if yay -S --needed --noconfirm linux-lts; then # Ensures this meta-package is targeted
echo "Latest LTS Kernel (meta-package: linux-lts) and its associated Headers check/update complete."
echo "Note: 'linux-lts' is a meta-package. The actual kernel version installed (e.g., linux66, linux69)"
echo "and its headers depend on Manjaro's current LTS recommendation."
else
echo "Latest LTS Kernel (meta-package: linux-lts) check/update failed." >&2
fi
else
echo "yay not found, skipping LTS kernel update." >&2 # ADDED: yay check for this block too
fi


echo $hr_sep; echo "Checking for Flatpak updates..."
if (( $+commands[flatpak] )); then
{ flatpak update --noninteractive --assumeyes && echo "Flatpak update successful." || echo "Flatpak update failed or no updates." >&2; }
else
echo "Flatpak not found, skipping Flatpak updates." >&2
fi

echo $hr_sep; echo "Updating Astral development tools (Ruff & uv)..."
if (( $+commands[pacman] )); then
if sudo pacman -S --needed --noconfirm curl; then
echo "Attempting to install/update Ruff..."
{ curl -LsSf https://astral.sh/ruff/install.sh | sh && echo "Ruff update check completed." || echo "Ruff installation script failed." >&2; }
echo "Attempting to install/update uv..."
{ curl -LsSf https://astral.sh/uv/install.sh | sh && echo "uv update check completed." || echo "uv installation script failed." >&2; }
else
echo "Could not install 'curl', skipping Astral tools update." >&2
fi
else
echo "pacman not found, skipping Astral tools update." >&2
fi

# NVM specific block (Hybrid: Official Installer + Interactive Subshell for Node ops)
echo $hr_sep; echo "Updating NVM, Node.js (LTS default), and npm..."

export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" # Ensure NVM_DIR is set

echo "Step 1: Attempting to install/update NVM using the official NVM installer script..."
# Ensure NVM_DIR exists for the installer log, though installer script might handle this.
mkdir -p "$NVM_DIR"
if curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash; then
echo "NVM installer script executed. Your .zshrc should now be configured by NVM."
echo "Sourcing NVM directly for immediate use in this script if possible..."
# Attempt to source NVM immediately after install for the subshell
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
else
echo "Failed to download or execute NVM installer script. Node.js updates might fail." >&2
fi

echo ""
echo "Step 2: Attempting Node.js/npm updates in a new interactive Zsh subshell..."
echo "This assumes your .zshrc (now updated by NVM installer) correctly sources NVM."
echo "NVM_DIR for subshell operations: $NVM_DIR"

local nvm_node_commands="
export NVM_DIR=\"${NVM_DIR}\";
echo \"Subshell: NVM_DIR is \$NVM_DIR\";

echo 'Subshell: Attempting to explicitly source nvm.sh...';
if [ -s \"\$NVM_DIR/nvm.sh\" ]; then
echo 'Subshell: Found \$NVM_DIR/nvm.sh, sourcing it.';
# shellcheck source=/dev/null
\. \"\$NVM_DIR/nvm.sh\";
elif [ -s \"/usr/share/nvm/nvm.sh\" ]; then # Fallback for some system-wide NVM installs
echo 'Subshell: Found /usr/share/nvm/nvm.sh, sourcing it.';
# shellcheck source=/dev/null
\. \"/usr/share/nvm/nvm.sh\";
else
echo 'Subshell: nvm.sh not found in primary locations for explicit sourcing.';
fi

# Check if nvm command is available as a function
if typeset -f nvm >/dev/null 2>&1; then
echo 'Subshell: NVM is available as a function. Version: ' \$(nvm --version);

echo 'Subshell: Installing/Updating latest stable Node.js (node)...';
nvm install node || { echo 'Subshell: Failed to install/update latest Node.js (node).' >&2; exit 1; };

echo 'Subshell: Installing/Updating latest LTS Node.js...';
nvm install --lts || { echo 'Subshell: Failed to install/update LTS Node.js.' >&2; exit 1; };

echo 'Subshell: Setting LTS (lts/*) as default Node.js version for new shells...';
nvm alias default 'lts/*' || { echo 'Subshell: Failed to set LTS as default.' >&2; exit 1; };

echo 'Subshell: Switching to default (LTS) Node.js for current operations...';
nvm use default || { echo 'Subshell: Failed to switch to default (LTS) Node.js.' >&2; exit 1; };

echo 'Subshell: Installing latest npm for the current (LTS) Node.js version...';
nvm install-latest-npm || { echo 'Subshell: Failed to install latest npm.' >&2; exit 1; };

echo 'Subshell: NVM, Node.js, and npm update tasks processed successfully.';
if type node >/dev/null 2>&1 && type npm >/dev/null 2>&1; then
echo \"Subshell: Active Node version: \$(node -v), npm: \$(npm -v)\";
else
echo \"Subshell: Node or npm command not found after updates.\" >&2;
fi
exit 0; # Success
else
echo 'Subshell: NVM command is not available as a function even after explicit sourcing.' >&2;
echo 'Subshell: This indicates a persistent issue with NVM activation in this subshell type.' >&2;
echo 'Subshell: NVM version check (nvm --version) output if command exists but not as function:'
command nvm --version 2>/dev/null || echo 'Subshell: nvm command truly not found.'
exit 1; # Failure
fi
"

if zsh -i -c "$nvm_node_commands"; then
echo "Node.js/npm update process via subshell completed successfully."
# Re-source NVM in the current shell as the subshell doesn't affect the parent
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
else
echo "Node.js/npm update process via subshell failed or encountered errors." >&2
echo "NVM itself should be updated. Node.js updates might require a new terminal session." >&2
fi

echo $hr_sep; echo "Updating ClamAV definitions..."
if (( $+commands[freshclam] )); then
{ sudo freshclam && echo "ClamAV definitions updated." || echo "freshclam failed." >&2; }
else
echo "ClamAV (freshclam) not found, skipping." >&2
fi

echo $hr_sep; echo "Full system update process finished."
return 0
}

# -------------------------------------------------------------------------
# ----------------------- Zsh Aliases -------------------------------------
# -------------------------------------------------------------------------

# -- Utility --
alias xhr='printf "%*s\n" "${COLUMNS:-$(tput cols)}" "" | tr " " "-"'
alias xclear='tput reset'

# -- History Cleaning --
# Using >| (clobber) ensures overwrite even if NOCLOBBER is set.
alias xclean-zsh='echo "Clearing Zsh history file ($HISTFILE)..."; command >| "$HISTFILE" && fc -R "$HISTFILE" && echo "Zsh history file truncated and re-read. Current session history cleared." >&2'

# -- System Cleaning --
# 'xclean' is now a function defined above.

# -- Docker Management --
# 'xdelete-docker' is now a function defined above.
alias xenable-docker='sudo systemctl enable --now docker.socket docker.service && echo "Docker enabled and started."'
alias xstop-docker-autostart='sudo systemctl disable docker.socket docker.service && echo "Docker auto-start disabled."'
alias xstop-docker='sudo systemctl stop docker.socket docker.service && echo "Docker stopped."'

# -- System Fixes & Maintenance --
alias xfixaudio='echo "Attempting PulseAudio fix (kills, clears config, reinstalls, starts)..."; { pulseaudio -k &>/dev/null; rm -rf ~/.config/pulse/* ~/.cache/pulse/*; sudo pacman -S --noconfirm --needed pulseaudio pulseaudio-alsa; pulseaudio --start } && echo "PulseAudio fix attempt completed. If you use PipeWire, this might not be relevant or could cause issues." || echo "PulseAudio fix attempt failed." >&2' # ADDED: PipeWire warning
alias xfixkeys='echo "Refreshing pacman keys and keyrings..."; { sudo pacman-key --init && sudo pacman-key --populate archlinux manjaro && sudo pacman-key --refresh-keys && sudo pacman -Sy --noconfirm archlinux-keyring manjaro-keyring } && echo "Pacman keys refreshed and keyrings updated successfully." || echo "Key refresh/update failed." >&2'
alias xfixpoedit='echo "Clearing system and user fontconfig caches..."; { sudo rm -rf /var/cache/fontconfig/*; rm -rf ~/.cache/fontconfig/*; echo "Rebuilding fontconfig caches (system and user)..."; sudo fc-cache -fsv && fc-cache -fsv } && echo "Fontconfig caches cleared and rebuilt successfully." || echo "Fontconfig cache rebuild failed." >&2'
alias xfixsearch='if (( $+commands[balooctl6] )); then echo "Using balooctl6 (KDE 6)..."; balooctl6 enable; balooctl6 check; balooctl6 status; elif (( $+commands[balooctl] )); then echo "Using balooctl (KDE 5)..."; balooctl enable; balooctl check; balooctl status; else echo "Baloo control command (balooctl6 or balooctl) not found." >&2; fi'

# -- System Information --
alias xinfo='echo "--- Fastfetch ---"; { (( $+commands[fastfetch] )) && fastfetch || echo "fastfetch not found." >&2 }; xhr; echo "--- Inxi ---"; { (( $+commands[inxi] )) && inxi -FGx || echo "inxi not found." >&2 }; xhr; echo "--- Display Info (X11) ---"; if (( $+commands[xdpyinfo] )); then xdpyinfo | grep -B2 resolution; else echo "xdpyinfo not found (may be Wayland or xdpyinfo not installed)." >&2; fi'

# -- Package Management (yay/pacman) --
alias xpacman-unlock='sudo rm -f /var/lib/pacman/db.lck && echo "Pacman lock file (/var/lib/pacman/db.lck) removed."'
alias xtunemirrors='echo "Tuning Manjaro mirrors and updating system..."; { sudo pacman-mirrors --fasttrack && (( $+commands[yay] )) && yay -Syyu --noconfirm } || echo "Mirror tuning or subsequent system update failed." >&2'

# -- Development & Servers --
alias xlampp='if [ -x /opt/lampp/manager-linux-x64.run ]; then sudo /opt/lampp/manager-linux-x64.run; else echo "XAMPP manager not found or not executable at /opt/lampp/manager-linux-x64.run" >&2; return 1; fi'
# 'xnpm-doc' is now a function defined above.
alias xnpm-update='echo "Checking for npm package updates using ncu, then installing and auditing..."; { if (( $+commands[ncu] )); then ncu -u; else echo "npm-check-updates (ncu) not found. To install: npm install -g npm-check-updates" >&2; fi } && npm install && npm audit fix --force' # --force for audit fix is convenient but can be aggressive.
alias xserver='if (( $+commands[python3] )); then python3 -m http.server 8080; else echo "python3 not found, cannot start server." >&2; fi'
alias xstart-allm='if [ -x "$HOME/AnythingLLMDesktop/start" ]; then "$HOME/AnythingLLMDesktop/start"; else echo "AnythingLLM start script not found or not executable at $HOME/AnythingLLMDesktop/start." >&2; return 1; fi'

# -- System & Application Updates --
# 'xupdate' is now a function defined above.
alias xupdate-allm='echo "Updating AnythingLLM (using curl|sh method)..."; curl -fsSL https://cdn.anythingllm.com/latest/installer.sh | sh'
alias xupdate-ollama='echo "Updating Ollama (using curl|sh method)..."; curl -fsSL https://ollama.ai/install.sh | sh'
alias xupdate-vdh='echo "Updating VDHCoApp (using curl|sh method)..."; curl -sSLf https://github.com/aclap-dev/vdhcoapp/releases/latest/download/install.sh | bash'
# Combined alias for all external updates
alias xupdate-externals='echo "Updating external applications (Ollama, AnythingLLM, VDHCoApp)..."; xupdate-ollama && xhr && xupdate-allm && xhr && xupdate-vdh && echo "External application updates finished." || echo "One or more external updates failed." >&2'
# Main update alias to call the function and then other specific updates
alias xupdate-all='xupdate && xhr && xupdate-externals'

# -------------------------------------------------------------------------
# ------------- Final Initialization (Prompt, etc) ------------------------
# -------------------------------------------------------------------------

# Initialize Starship Prompt - Should be very last.
# Ensure starship binary is in PATH.
if (( $+commands[starship] )); then
eval "$(starship init zsh)"
else
# Optional: Fallback prompt if starship is missing
# autoload -U promptinit; promptinit
# prompt adam1
print -u2 "Warning: starship command not found. Starship prompt disabled."
fi

Step 3 - Apply the changes to the (.zshrc) file:

source ~/.zshrc

3.2.3 - Update The ZSH History File

The commands history file is found at: ~/.zhistory. Open this file then paste the following inside it:

exa --tree --list
ffmpeg -i input.mp4 -filter:a loudnorm output.mp4
marp input.md -o output.pdf --allow-local-files
npm install --save @easyops-cn/docusaurus-search-local
pdftoppm -png out.pdf out
xclean
xclear
xnpm-doc
xupdate