refactor: moved home config to more logical folder structure
This commit is contained in:
parent
f201190ef1
commit
ecaa2c0dc4
29 changed files with 165 additions and 171 deletions
10
users/modules/de.nix
Normal file
10
users/modules/de.nix
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Default graphical programs and personalisation
|
||||
{
|
||||
imports = [
|
||||
./programs/firefox.nix
|
||||
./programs/font-terminess.nix
|
||||
./programs/kitty.nix
|
||||
./programs/hyprland.nix
|
||||
./programs/waybar.nix
|
||||
];
|
||||
}
|
10
users/modules/programs/bash.nix
Normal file
10
users/modules/programs/bash.nix
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
programs.bash = {
|
||||
enable = true;
|
||||
shellAliases = {
|
||||
rebuild = "sudo nixos-rebuild switch --flake";
|
||||
gs = "git status";
|
||||
ai = "aichat -r %shell% -e";
|
||||
};
|
||||
};
|
||||
}
|
9
users/modules/programs/direnv.nix
Normal file
9
users/modules/programs/direnv.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
# direnv lets us declare a .envrc in each project directory
|
||||
# and updates the shell with the packages specified.
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
}
|
5
users/modules/programs/firefox.nix
Normal file
5
users/modules/programs/firefox.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
programs.firefox = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
11
users/modules/programs/font-terminess.nix
Normal file
11
users/modules/programs/font-terminess.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
fonts = {
|
||||
fontconfig = {
|
||||
enable = true;
|
||||
defaultFonts.emoji = [ "Terminess Nerd Font" ];
|
||||
defaultFonts.monospace = [ "Terminess Nerd Font Mono" ];
|
||||
defaultFonts.sansSerif = [ "Terminess Nerd Font" ];
|
||||
defaultFonts.serif = [ "Terminess Nerd Font" ];
|
||||
};
|
||||
};
|
||||
}
|
7
users/modules/programs/fzf.nix
Normal file
7
users/modules/programs/fzf.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
programs.fzf = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
tmux.enableShellIntegration = true;
|
||||
};
|
||||
}
|
15
users/modules/programs/git.nix
Normal file
15
users/modules/programs/git.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
home.sessionVariables.GIT_CONFIG_GLOBAL = "$HOME/.config/git/config";
|
||||
|
||||
programs.git = {
|
||||
enable = true;
|
||||
userName = "Mohammad Rafiq";
|
||||
userEmail = "mohammadrafiq567@gmail.com";
|
||||
extraConfig = {
|
||||
init.defaultBranch = "prime";
|
||||
push.autoSetupRemote = true;
|
||||
pull.rebase = false;
|
||||
core.editor = "nvim";
|
||||
};
|
||||
};
|
||||
}
|
83
users/modules/programs/hyprland.nix
Normal file
83
users/modules/programs/hyprland.nix
Normal file
|
@ -0,0 +1,83 @@
|
|||
{ config, lib, ... }: {
|
||||
home.sessionVariables.NIXOS_OZONE_WL = "1";
|
||||
wayland.windowManager.hyprland = {
|
||||
enable = true;
|
||||
package = null;
|
||||
portalPackage = null;
|
||||
settings = {
|
||||
env = [
|
||||
"XCURSOR_SIZE,32"
|
||||
|
||||
# Nvidia Settings
|
||||
"LIBVA_DRIVER_NAME,nvidia"
|
||||
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
|
||||
"NVD_BACKEND,direct # needed for running vaapi-driver on later drivers"
|
||||
];
|
||||
|
||||
# Monitors
|
||||
monitor = [
|
||||
"HDMI-A-2, 3840x2160@60, 0x0, 2.5"
|
||||
"DP-4, 1920x1080@60, -1280x0, 1.5"
|
||||
", preferred, auto, 1"
|
||||
];
|
||||
|
||||
# Switching to the current workspace will switch to the previous
|
||||
binds.workspace_back_and_forth = true;
|
||||
cursor.default_monitor = "HDMI-A-2";
|
||||
|
||||
# Windows
|
||||
general = {
|
||||
# Make there be no gaps in between windows or edges
|
||||
border_size = 5;
|
||||
gaps_in = 0;
|
||||
gaps_out = 0;
|
||||
|
||||
resize_on_border = true;
|
||||
};
|
||||
|
||||
# Programs
|
||||
exec-once = [
|
||||
"waybar"
|
||||
];
|
||||
|
||||
# Keybinds
|
||||
"$mainMod" = "SUPER";
|
||||
"$terminal" = "kitty";
|
||||
"$browser" = "firefox";
|
||||
|
||||
bind = [
|
||||
"$mainMod, Q, exec, $terminal"
|
||||
"$mainMod, W, killactive"
|
||||
"$mainMod, E, exec, $browser"
|
||||
"$mainMod, M, exit"
|
||||
|
||||
# HJKL to move between windows
|
||||
"$mainMod, H, cyclenext, visible"
|
||||
"$mainMod, L, cyclenext, visible prev"
|
||||
|
||||
# HJKL to move a window
|
||||
"$mainMod_ALT, H, movewindow, l"
|
||||
"$mainMod_ALT, J, movewindow, d"
|
||||
"$mainMod_ALT, K, movewindow, u"
|
||||
"$mainMod_ALT, L, movewindow, r"
|
||||
|
||||
# HJKL to resize a window
|
||||
"ALT_SHIFT, H, resizeactive, -10% 0"
|
||||
"ALT_SHIFT, J, resizeactive, 0 -10%"
|
||||
"ALT_SHIFT, K, resizeactive, 0 10%"
|
||||
"ALT_SHIFT, L, resizeactive, 10% 0"
|
||||
|
||||
# H and L to move between workspaces on the current monitor including creation
|
||||
"$mainMod_CTRL, H, workspace, r-1"
|
||||
"$mainMod_CTRL, L, workspace, r+1"
|
||||
|
||||
"$mainMod, V, togglefloating"
|
||||
];
|
||||
|
||||
input = {
|
||||
numlock_by_default = true;
|
||||
follow_mouse = 2; # Click on a window to change focus
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
13
users/modules/programs/kitty.nix
Normal file
13
users/modules/programs/kitty.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
programs.kitty = {
|
||||
enable = true;
|
||||
font = {
|
||||
name = "Terminess Nerd Font Mono";
|
||||
size = 16;
|
||||
};
|
||||
keybindings = {
|
||||
"ctrl+equal" = "change_font_size current +2.0";
|
||||
"ctrl+minus" = "change_font_size current -2.0";
|
||||
};
|
||||
};
|
||||
}
|
14
users/modules/programs/nvim.nix
Normal file
14
users/modules/programs/nvim.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
defaultEditor = true;
|
||||
viAlias = true;
|
||||
vimAlias = true;
|
||||
vimdiffAlias = true;
|
||||
extraLuaConfig = ''
|
||||
vim.opt.shiftwidth = 2;
|
||||
vim.opt.number = true;
|
||||
vim.opt.relativenumber = true;
|
||||
'';
|
||||
};
|
||||
}
|
9
users/modules/programs/starship.nix
Normal file
9
users/modules/programs/starship.nix
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
# starship is a customisable prompt for any shell
|
||||
programs.starship = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
}
|
7
users/modules/programs/tealdeer.nix
Normal file
7
users/modules/programs/tealdeer.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
# man page summaries (activate with tldr <command>)
|
||||
programs.tealdeer = {
|
||||
enable = true;
|
||||
enableAutoUpdates = true;
|
||||
};
|
||||
}
|
27
users/modules/programs/tmux.nix
Normal file
27
users/modules/programs/tmux.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{ pkgs, ... }: {
|
||||
# Terminal Multiplexing
|
||||
programs.tmux = {
|
||||
enable = true;
|
||||
plugins = with pkgs.tmuxPlugins; [
|
||||
catppuccin
|
||||
|
||||
# Session Management between Reboots
|
||||
{
|
||||
plugin = resurrect;
|
||||
extraConfig = ''
|
||||
set -g @resurrect-strategy-nvim 'session'
|
||||
'';
|
||||
}
|
||||
{
|
||||
plugin = continuum;
|
||||
extraConfig = ''
|
||||
set -g @continuum-restore 'on'
|
||||
'';
|
||||
}
|
||||
];
|
||||
extraConfig = ''
|
||||
set -g default-terminal "tmux-256color"
|
||||
set -ag terminal-overrides ",xterm-256color:RGB"
|
||||
'';
|
||||
};
|
||||
}
|
12
users/modules/programs/waybar.nix
Normal file
12
users/modules/programs/waybar.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
programs.waybar = {
|
||||
enable = true;
|
||||
settings = {
|
||||
mainBar = {
|
||||
layer = "top";
|
||||
};
|
||||
};
|
||||
style = ''
|
||||
'';
|
||||
};
|
||||
}
|
6
users/modules/programs/yazi.nix
Normal file
6
users/modules/programs/yazi.nix
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
programs.yazi = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
};
|
||||
}
|
5
users/modules/scripts/default.nix
Normal file
5
users/modules/scripts/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
imports = [
|
||||
./git-extract.nix
|
||||
];
|
||||
}
|
12
users/modules/scripts/git-extract.nix
Normal file
12
users/modules/scripts/git-extract.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ pkgs, ... }: {
|
||||
home.packages = [
|
||||
(pkgs.writers.writePython3Bin "git-extract" {
|
||||
|
||||
libraries = with pkgs.python3Packages; [
|
||||
magic
|
||||
chardet
|
||||
];
|
||||
|
||||
} (builtins.readFile ./git-extract.py))
|
||||
];
|
||||
}
|
317
users/modules/scripts/git-extract.py
Normal file
317
users/modules/scripts/git-extract.py
Normal file
|
@ -0,0 +1,317 @@
|
|||
# flake8: noqa: E501
|
||||
import subprocess
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import argparse
|
||||
import magic
|
||||
import chardet
|
||||
import math
|
||||
|
||||
|
||||
def is_ascii(file_path):
|
||||
"""
|
||||
Checks if a file contains only ASCII characters.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
|
||||
Returns:
|
||||
bool: True if the file contains only ASCII characters, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None # Indicate file not found.
|
||||
|
||||
try:
|
||||
with open(file_path, "r", encoding="ascii") as f:
|
||||
f.read() # Attempt to read the entire file as ASCII
|
||||
return True
|
||||
except UnicodeDecodeError:
|
||||
return False
|
||||
|
||||
|
||||
def has_high_entropy(file_path, threshold=0.7):
|
||||
"""
|
||||
Checks if a file has high entropy, which might indicate it's not text.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
threshold (float): Entropy threshold above which it's considered high entropy.
|
||||
|
||||
Returns:
|
||||
bool: True if entropy is above the threshold, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(file_path, "rb") as f: # Important: Read as binary
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return True # Treat as non-text if there is an I/O error
|
||||
|
||||
if not data:
|
||||
return False # empty files considered text
|
||||
|
||||
entropy = calculate_entropy(data)
|
||||
return entropy > threshold
|
||||
|
||||
|
||||
def calculate_entropy(data):
|
||||
"""
|
||||
Calculates the entropy of a byte string.
|
||||
|
||||
Args:
|
||||
data (bytes): The byte string.
|
||||
|
||||
Returns:
|
||||
float: The entropy.
|
||||
"""
|
||||
if not data:
|
||||
return 0.0 # Avoid log(0)
|
||||
|
||||
entropy = 0
|
||||
data_length = len(data)
|
||||
seen_bytes = bytearray(range(256)) # All possible byte values
|
||||
counts = [0] * 256
|
||||
|
||||
for byte in data:
|
||||
counts[byte] += 1
|
||||
|
||||
for byte in seen_bytes:
|
||||
probability = float(counts[byte]) / data_length
|
||||
if probability > 0:
|
||||
entropy -= probability * math.log(probability, 2)
|
||||
|
||||
return entropy
|
||||
|
||||
|
||||
def check_chardet_encoding(file_path, confidence_threshold=0.8):
|
||||
"""
|
||||
Checks the file encoding using chardet library.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
confidence_threshold (float): The minimum confidence level for encoding detection.
|
||||
|
||||
Returns:
|
||||
bool: True if the encoding is detected with high confidence and is a text encoding, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(file_path, "rb") as f: # Important: Read as binary
|
||||
data = f.read()
|
||||
except IOError:
|
||||
return False # If file can't be opened, assume it's not a simple text file.
|
||||
|
||||
if not data:
|
||||
return True # Empty files are usually considered text
|
||||
|
||||
result = chardet.detect(data)
|
||||
encoding = result["encoding"]
|
||||
confidence = result["confidence"]
|
||||
|
||||
if encoding and confidence > confidence_threshold:
|
||||
# Check if it's a recognized text encoding (not binary or None)
|
||||
if encoding != "binary" and encoding is not None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_text_file(file_path, aggressive=False):
|
||||
"""
|
||||
Wrapper function to check if a file is a text file using multiple methods.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file.
|
||||
aggressive (bool, optional): If True, combines all checks for stricter verification.
|
||||
If False, returns True if any check passes. Defaults to False.
|
||||
|
||||
Returns:
|
||||
bool: True if the file is a text file, False otherwise.
|
||||
None: If the file does not exist.
|
||||
"""
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
return None
|
||||
|
||||
# Basic checks
|
||||
ascii_check = is_ascii(file_path)
|
||||
if ascii_check is None:
|
||||
return None # File not found
|
||||
|
||||
if aggressive:
|
||||
# Run all checks and require them all to pass
|
||||
high_entropy_check = not has_high_entropy(
|
||||
file_path
|
||||
) # Invert because we want to know if it DOESN'T have high entropy
|
||||
chardet_check = check_chardet_encoding(file_path)
|
||||
|
||||
return ascii_check and high_entropy_check and chardet_check
|
||||
else:
|
||||
# Run checks and return True if any of them pass
|
||||
high_entropy_check = not has_high_entropy(file_path)
|
||||
chardet_check = check_chardet_encoding(file_path)
|
||||
return ascii_check or high_entropy_check or chardet_check
|
||||
|
||||
|
||||
def get_latest_text_files_to_stdout(remote_repo_url=None, ignored_files=None):
|
||||
"""
|
||||
Checks out the latest commit from a remote Git repository or the current
|
||||
working directory (if no URL is provided) to a temporary folder,
|
||||
and then prints the contents of all files identified as text files to stdout,
|
||||
prepended by their relative paths from the repository root, excluding specified
|
||||
ignored files. Supports "!" to specify includes only.
|
||||
|
||||
Args:
|
||||
remote_repo_url: The URL of the remote Git repository (optional). If None,
|
||||
the current working directory is assumed to be a Git repo.
|
||||
ignored_files: A list of files or directories to ignore (relative to the repo root).
|
||||
If a list contains a value starting with "!", it means "include only".
|
||||
"""
|
||||
|
||||
temp_dir = None
|
||||
if ignored_files is None:
|
||||
ignored_files = []
|
||||
|
||||
# Ensure .git and .gitignore are always ignored (unless include only is specified)
|
||||
include_only = any(item.startswith("!") for item in ignored_files)
|
||||
if not include_only:
|
||||
ignored_files.extend([".git", ".gitignore"])
|
||||
ignored_files = list(set(ignored_files)) # remove duplicates
|
||||
|
||||
# Determine if "include only" is active and extract the include paths
|
||||
include_only = any(item.startswith("!") for item in ignored_files)
|
||||
include_paths = [item[1:] for item in ignored_files if item.startswith("!")]
|
||||
ignore_paths = [item for item in ignored_files if not item.startswith("!")]
|
||||
|
||||
|
||||
try:
|
||||
# Create a temporary directory
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
|
||||
# Clone the repository, but only the latest commit (shallow clone)
|
||||
clone_command = ["git", "clone", "--depth", "1"]
|
||||
if remote_repo_url:
|
||||
clone_command.extend([remote_repo_url, temp_dir])
|
||||
else:
|
||||
# Check if the current directory is a Git repository.
|
||||
try:
|
||||
subprocess.run(
|
||||
["git", "rev-parse", "--is-inside-work-tree"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd=os.getcwd(),
|
||||
) # run in current directory
|
||||
except subprocess.CalledProcessError:
|
||||
raise ValueError(
|
||||
"No Git repository URL provided and current directory is not a Git repository."
|
||||
)
|
||||
clone_command.extend([os.getcwd(), temp_dir]) # clone current dir to temp
|
||||
|
||||
subprocess.run(clone_command, check=True, capture_output=True, text=True)
|
||||
|
||||
# Find all files and filter for text files
|
||||
text_files = []
|
||||
for root, _, files in os.walk(temp_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
relative_path = os.path.relpath(file_path, temp_dir)
|
||||
|
||||
if include_only:
|
||||
# Include only logic
|
||||
include = False
|
||||
for include_path in include_paths:
|
||||
if relative_path.startswith(include_path):
|
||||
include = True
|
||||
break
|
||||
if not include:
|
||||
continue # Skip if not in include paths
|
||||
else:
|
||||
# Ignore logic (standard ignore)
|
||||
ignore = False
|
||||
path_components = relative_path.split(
|
||||
os.sep
|
||||
) # split based on OS-specific path separator
|
||||
current_path = ""
|
||||
for component in path_components:
|
||||
current_path = (
|
||||
os.path.join(current_path, component)
|
||||
if current_path
|
||||
else component
|
||||
) # prevent empty first join
|
||||
if current_path in ignore_paths:
|
||||
ignore = True
|
||||
break
|
||||
if ignore:
|
||||
continue
|
||||
|
||||
if is_text_file(file_path): # Use the is_text_file function
|
||||
text_files.append(file_path)
|
||||
|
||||
# Print the contents of each text file, prepended by its relative path
|
||||
for file_path in text_files:
|
||||
relative_path = os.path.relpath(file_path, temp_dir)
|
||||
print(f"--- {relative_path} ---")
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as f: # Use UTF-8 encoding
|
||||
print(f.read())
|
||||
except UnicodeDecodeError:
|
||||
print(
|
||||
f"Error: Could not decode file {relative_path} using UTF-8. Skipping file contents."
|
||||
) # handle binary or other non-UTF-8 encodings
|
||||
print() # Add a blank line between files
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error executing Git command: {e.stderr}")
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
finally:
|
||||
# Clean up the temporary directory
|
||||
if temp_dir:
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Checkout and print text files from a remote Git repository."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r",
|
||||
"--repo",
|
||||
required=False,
|
||||
help="The URL of the remote Git repository. If not provided, the current directory is used if it's a Git repository.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--ignored-files",
|
||||
nargs="+",
|
||||
default=[],
|
||||
help="Files or directories to ignore (space-separated). Use !<path> to specify include only.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
remote_repository_url = args.repo
|
||||
ignored_files = args.ignored_files
|
||||
|
||||
# Verify the URL only if it's provided
|
||||
if remote_repository_url:
|
||||
if (
|
||||
"github.com" not in remote_repository_url
|
||||
and "gitlab.com" not in remote_repository_url
|
||||
and "bitbucket.org" not in remote_repository_url
|
||||
):
|
||||
print(
|
||||
"Warning: This script is designed for common public repository hosting providers. Ensure the Git URL is correct."
|
||||
)
|
||||
|
||||
get_latest_text_files_to_stdout(remote_repository_url, ignored_files)
|
15
users/modules/sh.nix
Normal file
15
users/modules/sh.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Default shell utilities and programs
|
||||
{
|
||||
imports = [
|
||||
./programs/bash.nix
|
||||
./programs/direnv.nix
|
||||
./programs/fzf.nix
|
||||
./programs/git.nix
|
||||
./programs/nvim.nix
|
||||
./programs/starship.nix
|
||||
./programs/tealdeer.nix
|
||||
./programs/tmux.nix
|
||||
./programs/yazi.nix
|
||||
./scripts
|
||||
];
|
||||
}
|
13
users/modules/utils.nix
Normal file
13
users/modules/utils.nix
Normal file
|
@ -0,0 +1,13 @@
|
|||
{pkgs, ...}: {
|
||||
|
||||
home.packages = with pkgs; [
|
||||
fastfetch # system info
|
||||
wl-clipboard # provides cli copy and paste commands
|
||||
aichat # duh
|
||||
];
|
||||
|
||||
services = {
|
||||
# clipboard history (depends on wl-clipboard)
|
||||
cliphist.enable = true;
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue