Merge remote-tracking branch 'origin/main'

This commit is contained in:
Daniel Flanagan 2023-09-05 15:49:05 -05:00
commit 48996b8391
95 changed files with 1625 additions and 297 deletions

View file

@ -6,12 +6,18 @@
# };
# };
# TODO: copy all by binaries/scripts from dotfiles into ~/.local/bin or
# something?
home.username = "daniel";
home.homeDirectory = lib.mkDefault "/home/daniel/.home";
home.stateVersion = "23.05";
home.packages = [
pkgs.rtx
# TODO: os-specific scripts? macOS versus Linux (arch or nixos? do I need to distinguish at that point?)
(pkgs.buildEnv { name = "my-scripts"; paths = [ ./scripts ]; })
];
programs.password-store = {
@ -34,6 +40,7 @@
settings = {
modal = true;
skin = {
# this is a crappy copy of broot's catppuccin mocha theme
input = "rgb(205, 214, 244) none";
selected_line = "none rgb(88, 91, 112)";
default = "rgb(205, 214, 244) none";
@ -126,7 +133,7 @@
};
verbs = [
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR +{line} {file}"; }
{ invocation = "edit"; shortcut = "e"; execution = "$EDITOR {file}"; }
];
};
};
@ -138,94 +145,12 @@
programs.fish = {
enable = true;
shellInit = ''
# paths
if not set --query NICE_HOME
set --export --universal NICE_HOME $HOME
# if HOME ends with a dir called .home, assume that NICE_HOME is HOME's parent dir
test (basename $HOME) = .home \
&& set --export --universal NICE_HOME (realpath $HOME/..)
end
set --export --universal XDG_CONFIG_HOME $HOME/.config
set --export --universal XDG_CACHE_HOME $HOME/.cache
set --export --universal XDG_DATA_HOME $HOME/.local/share
set --export --universal XDG_STATE_HOME $HOME/.local/state
set --export --universal XDG_DESKTOP_DIR $HOME/desktop
set --export --universal XDG_PUBLICSHARE_DIR $HOME/public
set --export --universal XDG_TEMPLATES_DIR $HOME/templates
set --export --universal XDG_DOCUMENTS_DIR $NICE_HOME/doc
set --export --universal XDG_DOWNLOAD_DIR $NICE_HOME/dl
set --export --universal XDG_MUSIC_DIR $NICE_HOME/music
set --export --universal XDG_PICTURES_DIR $NICE_HOME/img
set --export --universal XDG_VIDEOS_DIR $NICE_HOME/video
set --export --universal XDG_GAMES_DIR $NICE_HOME/games
set --export --universal DOTFILES_PATH $XDG_CONFIG_HOME/lytedev-dotfiles
set --export --universal ENV_PATH $XDG_CONFIG_HOME/lytedev-env
set --export --universal FISH_PATH $XDG_CONFIG_HOME/fish
set --export --universal NOTES_PATH $NICE_HOME/doc/notes
set --export --universal SCROTS_PATH $NICE_HOME/img/scrots
set --export --universal USER_LOGS_PATH $NICE_HOME/doc/logs
for s in $ENV_PATH/*/config.d.fish
source $s (dirname $s)
end
# vars
set --export --universal LS_COLORS 'ow=01;36;40'
set --export --universal EXA_COLORS '*=0'
set --export --universal ERL_AFLAGS "-kernel shell_history enabled -kernel shell_history_file_bytes 1024000"
set --export --universal BROWSER firefox
set --export --universal EDITOR hx
set --export --universal VISUAL hx
# TODO: helix ($EDITOR) as man/pager
set --export --universal PAGER "less"
set --export --universal MANPAGER "less"
set --export --universal SOPS_AGE_KEY_FILE "$XDG_CONFIG_HOME/sops/age/keys.txt"
set --export --universal SKIM_ALT_C_COMMAND "fd --hidden --type directory"
set --export --universal SKIM_CTRL_T_COMMAND "fd --hidden"
# colors
set -U fish_color_normal normal # default color
set -U fish_color_command white # base command being run (>ls< -la)
set -U fish_color_param white # command's parameters
set -U fish_color_end green # command delimiter/separators (; and &)
set -U fish_color_error red # color of errors
set -U fish_color_escape yellow # color of escape codes (\n, \x2d, etc.)
set -U fish_color_operator blue # expansion operators (~, *)
set -U fish_color_quote yellow
set -U fish_color_redirection blue # redirection operators (|, >, etc.)
set -U fish_color_cancel 333 brblack # sigint at prompt (^C)
set -U fish_color_autosuggestion 666 brblack # as-you-type suggestions
set -U fish_color_match blue # matching parens and the like
set -U fish_color_search_match white\x1e\x2d\x2dbackground\x3d333 # selected pager item
set -U fish_color_selection blue # vi mode visual selection (only fg)
set -U fish_color_valid_path yellow # if an argument is a valid path (only -u?)
set -U fish_color_comment 666 brblack # comments like this one!
set -U fish_pager_color_completion white # main color for pager
set -U fish_pager_color_description magenta # color for meta description
set -U fish_pager_color_prefix blue # the string being completed
set -U fish_pager_color_progress white\x1e\x2d\x2dbackground\x3d333 # status indicator at the bottom
# set -U fish_pager_color_secondary \x2d\x2dbackground\x3d181818 # alternating rows
function has_command --wraps=command --description "Exits non-zero if the given command cannot be found"
command --quiet --search $argv[1]
end
'';
# TODO: rtx?
# TODO: homebrew?
# TODO: asdf?
# I load long scripts from files for a better editing experience
shellInit = builtins.readFile ./fish/shellInit.fish;
interactiveShellInit = builtins.readFile ./fish/interactiveShellInit.fish;
loginShellInit = "";
functions = {
# I think these should be loaded from fish files too for better editor experience
d = ''
# --wraps=cd --description "Quickly jump to NICE_HOME (or given relative or absolute path) and list files."
if count $argv > /dev/null
@ -266,163 +191,6 @@
has_command = "command --quiet --search $argv[1]";
};
interactiveShellInit = ''
# prompt
function get_hostname
if test (uname) = Linux || test (uname) = Darwin
has_command hostname && hostname | cut -d. -f1 || cat /etc/hostname
else
# assume bsd
hostname | head -n 1 | cut -d. -f1
end
end
function fish_greeting
_prompt_prefix
printf "%s\n" (date)
end
function preprocess_pwd
test (pwd) = / && echo "/" && return 1
test (pwd) = $NICE_HOME && echo "~" && return 0
pwd \
| cut -c2- \
| gawk '{n=split($0,p,"/");for(i=1;i<=n;i++){if(i==n){printf "/%s",p[i]}else{printf "/%.3s",p[i]}}}'
end
function _maybe_sudo_prefix
if set -q SUDO_USER
set_color -b yellow black
printf " SUDO "
set_color -b normal normal
printf " "
end
end
function _maybe_aws_profile
if set -q AWS_PROFILE && test $AWS_PROFILE = prd
printf " "
set_color -b yellow black
printf " AWS_PROFILE=prd "
set_color -b normal normal
end
end
function _user_and_host
if test $argv[1] -eq 0
set_color -b normal blue
else
set_color -b normal red
end
printf "%s@%s" $USER (get_hostname)
end
function _cur_work_dir
set_color -b normal magenta
printf " %s" (preprocess_pwd)
end
function _last_cmd_duration
set_color -b normal green
set -q CMD_DURATION && printf " %dms" $CMD_DURATION
end
function _maybe_jobs_summary
if jobs -q
set_color -b normal cyan
printf " &%d" (jobs -p | wc -l)
end
end
function _user_prompt
printf "\n"
set_color brblack
if test (id -u) -eq 0
printf '# '
else
printf '$ '
end
set_color -b normal normal
end
function _maybe_git_summary
set_color -b normal yellow
set cur_sha (git rev-parse --short HEAD 2>/dev/null)
if test $status = 0
set num_changes (git status --porcelain | wc -l | string trim)
if test $num_changes = 0
set num_changes ""
else
set num_changes "+$num_changes"
end
printf " %s %s %s" (git branch --show-current) $cur_sha $num_changes
end
end
function _prompt_marker
printf "%b133;A%b" "\x1b\x5d" "\x1b\x5c"
end
function _prompt_continuation_marker
printf "%b133;A;k=s%b" "\x1b\x5d" "\x1b\x5c"
end
function cmd_marker --on-variable _
printf "%b133;C%b" "\x1b\x5d" "\x1b\x5c"
end
function _prompt_prefix
set_color -b normal brblack
printf "# "
end
function fish_prompt
set last_cmd_status $status
_prompt_marker
_prompt_prefix
_maybe_sudo_prefix
_user_and_host $last_cmd_status
_cur_work_dir
_maybe_git_summary
_maybe_aws_profile
_last_cmd_duration
_maybe_jobs_summary
_user_prompt
end
function fish_mode_prompt; end
function fish_right_prompt; end
# key bindings
fish_vi_key_bindings
set --universal fish_cursor_default block
set --universal fish_cursor_insert line
set --universal fish_cursor_block block
fish_vi_cursor
set --universal fish_vi_force_cursor 1
bind --mode insert --sets-mode default jk repaint
bind --mode insert --sets-mode default jK repaint
bind --mode insert --sets-mode default Jk repaint
bind --mode insert --sets-mode default JK repaint
bind --mode insert --sets-mode default jj repaint
bind --mode insert --sets-mode default jJ repaint
bind --mode insert --sets-mode default Jj repaint
bind --mode insert --sets-mode default JJ repaint
bind -M insert \cg skim-cd-widget
bind -M insert \cp up-or-search
bind -M insert \cn down-or-search
bind -M insert \ce end-of-line
bind -M insert \ca beginning-of-line
bind -M insert \cv edit_command_buffer
bind -M default \cv edit_command_buffer
'';
loginShellInit = ''
'';
shellAbbrs = { };
shellAliases = {
l = "br";
@ -480,6 +248,7 @@
};
programs.firefox = {
# TODO: enable dark theme by default
enable = true;
package = (pkgs.firefox.override { extraNativeMessagingHosts = [ pkgs.passff-host ]; });
@ -503,20 +272,17 @@
'';
userChrome = ''
/* Remove close button */
.titlebar-buttonbox-container{ display:none }
#webrtcIndicator {
display: none;
display: none;
}
#main-window[tabsintitlebar="true"]:not([extradragspace="true"]) #TabsToolbar>.toolbar-items {
opacity: 0;
pointer-events: none;
opacity: 0;
pointer-events: none;
}
#main-window:not([tabsintitlebar="true"]) #TabsToolbar {
visibility: collapse !important;
visibility: collapse !important;
}
'';
@ -531,4 +297,5 @@
# enable = true;
# }; # TODO: would be nice to have my sway config declared here instead of symlinked in by dotfiles scripts?
# maybe we can share somehow so things for nix-y systems and non-nix-y systems alike
# am I going to _have_ non-nix systems anymore?
}

View file

@ -1,4 +1,4 @@
{}: {
{
standard = { disks ? [ "/dev/vda" ], ... }: {
# this is my standard partitioning scheme for my machines: an LUKS-encrypted
# btrfs volume

View file

@ -0,0 +1,153 @@
# prompt
function get_hostname
if test (uname) = Linux || test (uname) = Darwin
has_command hostname && hostname | cut -d. -f1 || cat /etc/hostname
else
# assume bsd
hostname | head -n 1 | cut -d. -f1
end
end
function fish_greeting
_prompt_prefix
printf "%s\n" (date)
end
function preprocess_pwd
test (pwd) = / && echo "/" && return 1
test (pwd) = $NICE_HOME && echo "~" && return 0
pwd \
| cut -c2- \
| gawk '{n=split($0,p,"/");for(i=1;i<=n;i++){if(i==n){printf "/%s",p[i]}else{printf "/%.3s",p[i]}}}'
end
function _maybe_sudo_prefix
if set -q SUDO_USER
set_color -b yellow black
printf " SUDO "
set_color -b normal normal
printf " "
end
end
function _maybe_aws_profile
if set -q AWS_PROFILE && test $AWS_PROFILE = prd
printf " "
set_color -b yellow black
printf " AWS_PROFILE=prd "
set_color -b normal normal
end
end
function _user_and_host
if test $argv[1] -eq 0
set_color -b normal blue
else
set_color -b normal red
end
printf "%s@%s" $USER (get_hostname)
end
function _cur_work_dir
set_color -b normal magenta
printf " %s" (preprocess_pwd)
end
function _last_cmd_duration
set_color -b normal green
set -q CMD_DURATION && printf " %dms" $CMD_DURATION
end
function _maybe_jobs_summary
if jobs -q
set_color -b normal cyan
printf " &%d" (jobs -p | wc -l)
end
end
function _user_prompt
printf "\n"
set_color brblack
if test (id -u) -eq 0
printf '# '
else
printf '$ '
end
set_color -b normal normal
end
function _maybe_git_summary
set_color -b normal yellow
set cur_sha (git rev-parse --short HEAD 2>/dev/null)
if test $status = 0
set num_changes (git status --porcelain | wc -l | string trim)
if test $num_changes = 0
set num_changes "✔"
else
set num_changes "+$num_changes"
end
printf " %s %s %s" (git branch --show-current) $cur_sha $num_changes
end
end
function _prompt_marker
printf "%b133;A%b" "\x1b\x5d" "\x1b\x5c"
end
function _prompt_continuation_marker
printf "%b133;A;k=s%b" "\x1b\x5d" "\x1b\x5c"
end
function cmd_marker --on-variable _
printf "%b133;C%b" "\x1b\x5d" "\x1b\x5c"
end
function _prompt_prefix
set_color -b normal brblack
printf "# "
end
function fish_prompt
set last_cmd_status $status
_prompt_marker
_prompt_prefix
_maybe_sudo_prefix
_user_and_host $last_cmd_status
_cur_work_dir
_maybe_git_summary
_maybe_aws_profile
_last_cmd_duration
_maybe_jobs_summary
_user_prompt
end
function fish_mode_prompt; end
function fish_right_prompt; end
# key bindings
fish_vi_key_bindings
set --universal fish_cursor_default block
set --universal fish_cursor_insert line
set --universal fish_cursor_block block
fish_vi_cursor
set --universal fish_vi_force_cursor 1
bind --mode insert --sets-mode default jk repaint
bind --mode insert --sets-mode default jK repaint
bind --mode insert --sets-mode default Jk repaint
bind --mode insert --sets-mode default JK repaint
bind --mode insert --sets-mode default jj repaint
bind --mode insert --sets-mode default jJ repaint
bind --mode insert --sets-mode default Jj repaint
bind --mode insert --sets-mode default JJ repaint
bind -M insert \cg skim-cd-widget
bind -M insert \cp up-or-search
bind -M insert \cn down-or-search
bind -M insert \ce end-of-line
bind -M insert \ca beginning-of-line
bind -M insert \cv edit_command_buffer
bind -M default \cv edit_command_buffer

85
fish/shellInit.fish Normal file
View file

@ -0,0 +1,85 @@
# paths
if not set --query NICE_HOME
set --export --universal NICE_HOME $HOME
# if HOME ends with a dir called .home, assume that NICE_HOME is HOME's parent dir
test (basename $HOME) = .home \
&& set --export --universal NICE_HOME (realpath $HOME/..)
end
set --export --universal XDG_CONFIG_HOME $HOME/.config
set --export --universal XDG_CACHE_HOME $HOME/.cache
set --export --universal XDG_DATA_HOME $HOME/.local/share
set --export --universal XDG_STATE_HOME $HOME/.local/state
set --export --universal XDG_DESKTOP_DIR $HOME/desktop
set --export --universal XDG_PUBLICSHARE_DIR $HOME/public
set --export --universal XDG_TEMPLATES_DIR $HOME/templates
set --export --universal XDG_DOCUMENTS_DIR $NICE_HOME/doc
set --export --universal XDG_DOWNLOAD_DIR $NICE_HOME/dl
set --export --universal XDG_MUSIC_DIR $NICE_HOME/music
set --export --universal XDG_PICTURES_DIR $NICE_HOME/img
set --export --universal XDG_VIDEOS_DIR $NICE_HOME/video
set --export --universal XDG_GAMES_DIR $NICE_HOME/games
set --export --universal DOTFILES_PATH $XDG_CONFIG_HOME/lytedev-dotfiles
set --export --universal ENV_PATH $XDG_CONFIG_HOME/lytedev-env
set --export --universal FISH_PATH $XDG_CONFIG_HOME/fish
set --export --universal NOTES_PATH $NICE_HOME/doc/notes
set --export --universal SCROTS_PATH $NICE_HOME/img/scrots
set --export --universal USER_LOGS_PATH $NICE_HOME/doc/logs
set --export --universal CDPATH $NICE_HOME
for s in $ENV_PATH/*/config.d.fish
source $s (dirname $s)
end
# vars
set --export --universal LS_COLORS 'ow=01;36;40'
set --export --universal EXA_COLORS '*=0'
set --export --universal ERL_AFLAGS "-kernel shell_history enabled -kernel shell_history_file_bytes 1024000"
set --export --universal BROWSER firefox
set --export --universal EDITOR hx
set --export --universal VISUAL hx
# TODO: helix ($EDITOR) as man/pager
set --export --universal PAGER "less"
set --export --universal MANPAGER "less"
set --export --universal SOPS_AGE_KEY_FILE "$XDG_CONFIG_HOME/sops/age/keys.txt"
set --export --universal SKIM_ALT_C_COMMAND "fd --hidden --type directory"
set --export --universal SKIM_CTRL_T_COMMAND "fd --hidden"
# colors
set -U fish_color_normal normal # default color
set -U fish_color_command white # base command being run (>ls< -la)
set -U fish_color_param white # command's parameters
set -U fish_color_end green # command delimiter/separators (; and &)
set -U fish_color_error red # color of errors
set -U fish_color_escape yellow # color of escape codes (\n, \x2d, etc.)
set -U fish_color_operator blue # expansion operators (~, *)
set -U fish_color_quote yellow
set -U fish_color_redirection blue # redirection operators (|, >, etc.)
set -U fish_color_cancel 333 brblack # sigint at prompt (^C)
set -U fish_color_autosuggestion 666 brblack # as-you-type suggestions
set -U fish_color_match blue # matching parens and the like
set -U fish_color_search_match white\x1e\x2d\x2dbackground\x3d333 # selected pager item
set -U fish_color_selection blue # vi mode visual selection (only fg)
set -U fish_color_valid_path yellow # if an argument is a valid path (only -u?)
set -U fish_color_comment 666 brblack # comments like this one!
set -U fish_pager_color_completion white # main color for pager
set -U fish_pager_color_description magenta # color for meta description
set -U fish_pager_color_prefix blue # the string being completed
set -U fish_pager_color_progress white\x1e\x2d\x2dbackground\x3d333 # status indicator at the bottom
# set -U fish_pager_color_secondary \x2d\x2dbackground\x3d181818 # alternating rows
function has_command --wraps=command --description "Exits non-zero if the given command cannot be found"
command --quiet --search $argv[1]
end

View file

@ -122,6 +122,21 @@
"type": "github"
}
},
"flake-utils_3": {
"locked": {
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"helix": {
"inputs": {
"crane": "crane",
@ -152,11 +167,11 @@
]
},
"locked": {
"lastModified": 1692099905,
"narHash": "sha256-/pSusGhmIdSdAaywQRFA5dVbfdIzlWQTecM+E46+cJ0=",
"lastModified": 1693208669,
"narHash": "sha256-hHFaaUsZ860wvppPeiu7nJn/nXZjJfnqAQEu9SPFE9I=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "2a6679aa9cc3872c29ba2a57fe1b71b3e3c5649f",
"rev": "5bac4a1c06cd77cf8fc35a658ccb035a6c50cd2c",
"type": "github"
},
"original": {
@ -214,6 +229,22 @@
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1693844670,
"narHash": "sha256-t69F2nBB8DNQUWHD809oJZJVE+23XBrth4QZuVd6IE0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3c15feef7770eb5500a4b8792623e2d6f598c9c1",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"api-lyte-dev": "api-lyte-dev",
@ -221,9 +252,29 @@
"helix": "helix",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs_2",
"rtx": "rtx",
"sops-nix": "sops-nix"
}
},
"rtx": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1693923183,
"narHash": "sha256-TH2JC+Cjw+ed1O33QKGq+lonIKlu6pHuY1jtrZh/FMM=",
"owner": "jdx",
"repo": "rtx",
"rev": "f333ac5f8e8de399fcb3ce40576baeef0271081b",
"type": "github"
},
"original": {
"owner": "jdx",
"repo": "rtx",
"type": "github"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": [

View file

@ -1,26 +1,19 @@
{
inputs =
let
followedInput = url: {
url = url;
inputs.nixpkgs.follows = "nixpkgs";
};
in
{
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
api-lyte-dev.url = "git+ssh://gitea@git.lyte.dev/lytedev/api.lyte.dev.git";
home-manager.url = "github:nix-community/home-manager/release-23.05";
disko.url = "github:nix-community/disko/master";
sops-nix.url = "github:Mic92/sops-nix";
helix.url = "github:helix-editor/helix";
rtx.url = "github:jdx/rtx";
};
# TODO: this could be a release tarball? fully recompiling this on every change suuuucks
api-lyte-dev = followedInput "git+ssh://gitea@git.lyte.dev/lytedev/api.lyte.dev.git";
home-manager = followedInput "github:nix-community/home-manager/release-23.05";
disko = followedInput "github:nix-community/disko/master"; # NOTE: lock update!
sops-nix = followedInput "github:Mic92/sops-nix";
helix = followedInput "github:helix-editor/helix";
};
outputs = { self, ... }@inputs: {
outputs = inputs @ { self, ... }: {
diskoConfigurations = import ./disko.nix;
homeConfigurations =
# TODO: per arch?
let
system = "x86_64-linux";
pkgs = inputs.nixpkgs.legacyPackages.${system};
@ -77,7 +70,7 @@
specialArgs = { inherit inputs; };
modules = [
inputs.disko.nixosModules.disko
./machines/thinker-disks.nix
self.diskoConfigurations.standard
{ _module.args.disks = [ "/dev/nvme0n1" ]; }
./machines/thinker.nix
inputs.home-manager.nixosModules.home-manager
@ -97,27 +90,12 @@
system = "x86_64-linux";
};
};
musicbot = inputs.nixpkgs.lib.nixosSystem {
beefcake = inputs.nixpkgs.lib.nixosSystem {
deployment = {
targetHost = "musicbox";
targetPort = 1234;
targetUser = "nixos";
targetHost = "beefcake";
targetUser = "daniel";
};
system = "x86_64-linux";
specialArgs = { inherit inputs; };
modules =
[
inputs.disko.nixosModules.disko
./machines/musicbox-disks.nix
{ _module.args.disks = [ "/dev/sda" ]; }
./machines/musicbox.nix
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.daniel = import ./daniel.nix;
}
];
modules = self.nixosConfigurations.beefcake.modules;
};
};
};

View file

@ -182,6 +182,7 @@ in
git-lfs
grim
inputs.helix.packages."x86_64-linux".helix
inputs.rtx.packages."x86_64-linux".rtx
hexyl
htop
inkscape

View file

@ -20,6 +20,14 @@ $ git push beefcake:~/.config/lytedev-dotfiles
$ ssh -t beefcake 'cd ~/.config/lytedev-dotfiles/os/linux/nix && sudo nixos-rebuild switch --flake .# && echo DONE'
```
# Install For Home Manager
<!-- TODO: document nix+home manager installation for arch boxes -->
```bash
home-manager switch --flake .#daniel
```
# Install From NixOS Bootable Media
Documented below is my process for standing up a new NixOS node configured and
@ -51,7 +59,7 @@ sudo nix-shell --packages git --run "
--extra-experimental-features nix-command \
--extra-experimental-features flakes \
github:nix-community/disko -- \
--flake 'git+https://git.lyte.dev/lytedev/dotfiles?ref=main&dir=/os/linux/nix#diskoConfigOfChoice' \
--flake 'git+https://git.lyte.dev/lytedev/nix#diskoConfigOfChoice' \
--mode disko \
--arg disks '[ \"/dev/your_disk\" ]'
"
@ -63,7 +71,7 @@ And finally install NixOS as specified by this flake:
nix-shell --packages git \
--run "
sudo nixos-install \
--flake 'git+https://git.lyte.dev/lytedev/dotfiles?ref=main&dir=/os/linux/nix#yourNixosConfig'
--flake 'git+https://git.lyte.dev/lytedev/nix#yourNixosConfig'
"
```

8
scripts/bin/? Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env fish
echo "Keys you never remember:"
echo
echo "C-t fuzzy find a file or directory to insert into your command"
echo "C-g fuzzy find a directory to cd to"
# https://github.com/lotabout/skim/blob/master/shell/key-bindings.fish

2
scripts/bin/N Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
fn="${1}"; shift; nf "${fn}.md" "$@"

5
scripts/bin/archive Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
archive_name="$(basename "${1}").tar.zstd"
tar --zstd -cvf "${archive_name}" "${@}"
echo "Archive created at: ${archive_name} "

6
scripts/bin/archupdate Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
yay -Syu --nodiffmenu --nocleanmenu --noeditmenu
# TODO: update kernel with a flag?
# yes | pacman -Syu && kexec -l --initrd=/boot/initramfs-linux.img /boot/vmlinuz-linux && kexec -e

21
scripts/bin/at Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
usage() {
echo "at - waits until after the specified datetime"
echo "Usage:"
echo " at <DATETIME> && command..."
echo
echo "Examples:"
echo " at 15:00:00 && echo \"it is 3 o'clock\""
}
[[ -z "$1" ]] && { echo "Error: No DATE argument provided." >&2; usage; exit 1; }
d="$(date -d "${@}" +%s)"
while [[ "$d" -ge "$(date +%s)" ]]; do
_dt=$((d - $(date +%s)))
days=$((_dt / 86400))
echo -ne "\rTime Remaining: ${days}d $(date -u --date @$((_dt)) +%H:%M:%S) ";
sleep 0.1
done
exit 0

5
scripts/bin/bp Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env sh
printf '\e[?2004h'
printf '\e[?2004l'
echo bp off

View file

@ -0,0 +1,90 @@
#!/usr/bin/env bash
# TODO:
# + trap exit signals to cleanup all temp files and cancel all jobs
# + run in batches to prevent spawning way too many processes
# + detect when piping into another application and suppress colors?
# + temp file control (or none for no disk space)?
# + command line options or env vars?
# + --tlds "com,net,org"
# + --max-concurrent-whois-jobs
# + --avail-regex and --timeout-regex
# suggested usage: ./check_domain | tee /tmp/chkdmn && sort /tmp/chkdmn
# constants
AVAIL_REGEX='^No match|^NOT FOUND|^Not fo|AVAILABLE|^No Data Fou|has not been regi|No entri'
TIMEOUT_REGEX='^Timeout'
COLOR_RESET="\x1b[0m" COLOR_GREEN="\x1b[32m"
COLOR_YELLOW="\x1b[33m"
COLOR_RED="\x1b[31m"
TLDS=( \
'.com' '.net' '.org' '.eu' '.in' '.it' '.sk' '.ac' '.ae' '.af' '.ag' '.al' \
'.am' '.as' '.at' '.ax' '.be' '.bi' '.bo' '.by' '.bz' '.cc' '.cd' '.cf' '.cg' \
'.ch' '.ci' '.cl' '.cm' '.cn' '.co' '.cr' '.cx' '.cz' '.dk' '.dm' '.do' '.ec' \
'.ee' '.es' '.fi' '.fm' '.fo' '.ga' '.gd' '.gf' '.gg' '.gl' '.gp' '.gq' '.gr' \
'.gs' '.gt' '.gy' '.hk' '.hm' '.hn' '.ht' '.id' '.im' '.in' '.io' '.ir' '.is' \
'.je' '.ke' '.kg' '.kz' '.la' '.lc' '.li' '.lt' '.lu' '.lv' '.ly' '.me' '.mg' \
'.mk' '.ml' '.mn' '.mq' '.ms' '.mu' '.mw' '.mx' '.na' '.ne' '.ng' '.nl' '.nu' \
'.nz' '.pe' '.ph' '.pk' '.pl' '.pr' '.pt' '.pw' '.qa' '.ro' '.rs' '.ru' '.rw' \
'.sb' '.sc' '.sd' '.se' '.sh' '.si' '.sl' '.sr' '.st' '.su' '.sx' '.sg' '.tk' \
'.tl' '.to' '.tv' '.tw' '.ug' '.vc' '.ve' '.vg' '.vn' '.vu' '.ws' \
)
# check dependencies
if command -v whois >/dev/null 2>&1; then
:
else
echo "You need to install whois before proceeding!"
exit 2
fi
# check arguments
if [ "$#" == "0" ]; then
echo "You need to supply at least one argument!"
exit 1
fi
# main function
check_domain() {
local tmp
local domain
if [ "$#" == "0" ]; then
echo "No domain specified."
return
fi
domain="$1"
# create a unique temporary file
tmp=$(mktemp "${domain}_XXX")
# dump whois output into temp file
whois "$domain" > "$tmp" 2>&1
# check contents and output appropriately
if grep -E -q "$AVAIL_REGEX" "$tmp" > /dev/null 2>&1; then
echo -e "$COLOR_GREEN$domain / probably available$COLOR_RESET"
elif grep -E -q "$TIMEOUT_REGEX" "$tmp" > /dev/null 2>&1; then
echo -e "$COLOR_YELLOW$domain / timed out$COLOR_RESET"
else
echo -e "$COLOR_RED$domain / unavailable$COLOR_RESET"
fi
# cleanup
rm "$tmp"
}
# iterate all provided domain names combined with all TLDs and check them
# concurrently
elements=${#TLDS[@]}
while (( "$#" )); do
for (( i=0;i<elements;i++ )); do
check_domain "$1${TLDS[${i}]}" &
done
shift
done
wait

17
scripts/bin/check-port Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
if [[ $1 = t ]] || [[ $1 = tcp ]] || \
[[ $1 = T ]] || [[ $1 = TCP ]]; then
echo "TCP is the default. You don't need to specify it." >&2
exit 1
fi
if [[ $1 = u ]] || [[ $1 = udp ]] || \
[[ $1 = U ]] || [[ $1 = UDP ]]; then
shift
set -x
sudo nmap -sU "$1" -p "$2"
else
set -x
nmap "$1" -p "$2"
fi

15
scripts/bin/clip Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# TODO: detect MIME type?
# TODO: figure out how/why these programs "wait" -- can a `clip-once` script exist building on this?
# wl-copy `-o`, xclip `-l 1`?
if [ "$(uname)" == "Linux" ]; then
if is_wayland; then
wl-copy -n "$@"
else
xclip -i -sel c "$@"
fi
elif [ "$(uname)" == "Darwin" ]; then
pbcopy "$@"
fi

29
scripts/bin/clipshot Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -x
umask 077
d="$(date +"%Y-%m-%d_%H-%M-%S")"
fn="$SCROTS_PATH/clipshot_$d.png"
mkdir -p "$SCROTS_PATH"
dim="$(slurp -d -b \#00000066 -c \#ffffffff)"
if [ "$?" -eq 0 ]; then
grim -g "$dim" - | wl-copy -t image/png
wl-paste -n > "$fn"
echo "$fn"
else
exit 1
fi
# TODO: implement for X and other OSs?
# pkill unclutter
# sleep 0.1
# import "$fn"
# < "$fn" xclip -t image/png -i -selection clipboard
# < "$fn" xclip -t image/png -i -selection primary
# < "$fn" xclip -t image/png -i -selection secondary
# < "$fn" xclip -t image/png -i -selection buffer-cut
# unclutter &
# echo "$fn"

21
scripts/bin/copy-git-forge-url Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env sh
usage() {
echo "copy-git-forge-url <$FILE>[#L$LINE_NUMBERS]"
echo " Copies a link to the git forge's web interface for the current branch to the clipboard"
echo
echo " Examples:"
echo " \$ copy-git-forge-url readme.md#L12"
}
if [ "$#" -lt 1 ]; then
usage
exit 1
fi
url="$(gitforge-url.ts "$1")"
case "$(uname)" in
Linux*) echo "$url" | clip;;
Darwin*) echo "$url" | clip;;
*) echo "OS not supported"; exit 1;
esac

15
scripts/bin/countdown Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
[[ $# -lt 1 ]] && { echo "No argument provided." >&2 ; exit 1; }
d=$(($(date +%s) + $1));
echo "Countdown started at $(date)"
while [[ "$d" -ge "$(date +%s)" ]]; do
_dt=$((d - $(date +%s)))
days=$((_dt / 86400))
echo -ne "\r${days}d $(date -u --date @$((_dt)) +%H:%M:%S) ";
sleep 0.1
done
echo -ne "\rCountdown finished $(date)\n"

3
scripts/bin/dns Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
getent hosts "$@"

0
scripts/bin/dns-cleaner Executable file
View file

22
scripts/bin/dns-deleter Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
hostname="${1}"; shift || {
echo "No hostname arg to delete provided."
exit 1
}
API="https://api.netlify.com/api/v1"
TOKEN="$(pass netlify | grep -i token | tr -d ' ' | cut -d ':' -f 2)"
counter=0
curl -sL "$API/dns_zones/lyte_dev/dns_records?access_token=$TOKEN" | \
jq -r '.[] | select(.hostname=="'"$hostname"'") | .hostname+": "+.id' | \
while read -r l; do
counter=$((counter+1))
ID="$(echo $l | awk '{print $2}')"
URL="$API/dns_zones/lyte_dev/dns_records/$ID?access_token=$TOKEN"
curl -vvv -X DELETE -sL "$URL" 2>&1 | grep 'ratelimit-remaining' &
echo "counter: $counter"
jq 'del(.[] | select(.id == "'$ID'"))' /tmp/zone.json > /tmp/zone2.json
mv /tmp/zone2.json /tmp/zone.json
[ $counter -gt 450 ] && break
done
wait

View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
API="https://api.netlify.com/api/v1"
TOKEN="$(pass netlify | grep -i token | tr -d ' ' | cut -d ':' -f 2)"
while read -r l; do
set -x -e
ID="$(echo $l | awk '{print $2}')"
URL="$API/dns_zones/lyte_dev/dns_records/$ID?access_token=$TOKEN"
curl -X DELETE -sL "$URL"
done
wait

View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
command -v git >/dev/null 2>&1 || { echo "git not installed"; exit 1; }
command -v fish >/dev/null 2>&1 || { echo "fish not installed"; exit 2; }
mkdir -p "$HOME/.config"
git clone https://git.lyte.dev/lytedev/dotfiles.git "$HOME/.config/lytedev-dotfiles"
exec "$HOME/.config/lytedev-dotfiles/common/bin/dotfiles-setup"

56
scripts/bin/dotfiles-init Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
export dfp
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
export ENV_PATH="$XDG_CONFIG_HOME/lytedev-env"
export CURDIR
mkdir -p "$ENV_PATH"
mkdir -p "$XDG_CONFIG_HOME"
dfp="$(realpath "$(dirname "$0")"/../..)"
# may not be running from inside the dotfiles repo, may have been curl'd down solo, so we need to check
if [[ ! -d "$dfp/.git" ]]; then
echo "Not running from inside the dotfiles git repo, so we need to download it first!"
# each os needs instructions to install git, then we can clone the repo and proceed
if ! command -v git; then
if head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then
if [[ "$EUID" -ne 0 ]]; then
if ! command -v sudo; then
echo "Error: No sudo command available to try and install 'git'"
exit 1
else
sudo pacman -Sy --needed git
fi
else
pacman -Sy --needed git
fi
fi
fi
dfp="$XDG_CONFIG_HOME/lytedev-dotfiles"
git clone https://git.lyte.dev/lytedev/dotfiles.git "$dfp"
fi
# auto-link any OS-specific environments
if head /etc/os-release --lines 1 | grep 'NixOS$' > /dev/null 2>&1; then
ln -s "$dfp/os/linux/nix" "$ENV_PATH/os-linux-nix" > /dev/null 2>&1
elif head /etc/os-release --lines 1 | grep 'Arch Linux' > /dev/null 2>&1; then
ln -s "$dfp/os/linux/arch" "$ENV_PATH/os-linux-arch" > /dev/null 2>&1
fi
# perform any pre-requisite setup (includes OS-specific setup scripts since we
# just included those)
for s in "$ENV_PATH"/*; do
f="$s/dotfiles-init.d.sh"
if [ -f "$f" ]; then
echo "dotfiles-init: Running $f..."
CURDIR="$s" "$f"
fi
done
# perform final dotfiles setup
echo "dotfiles-init: Running setup..."
"$dfp/common/bin/dotfiles-setup"
# TODO: setup personal files? (ssh keys, gpg keys, password stores, notes)
# these are probably best handled in a dotfiles-init.d.sh script in a particular layer

View file

@ -0,0 +1,39 @@
#!/usr/bin/env fish
has_command sk || begin
echo "sk not installed (skim fuzzy finder)"
exit 1
end
mkdir -p $ENV_PATH
function filter_existing_directory
while read -l line
test -d $DOTFILES_PATH/$line && echo $line
end
end
function reject_empty_lines
while read -l line
test $line = "" || echo $line
end
end
function link
while read -l line
set safe_fn (string replace -a / - $line)
echo "Linking $ENV_PATH/$safe_fn to $DOTFILES_PATH/$line"
rm -f $ENV_PATH/$safe_fn
ln -s $DOTFILES_PATH/$line $ENV_PATH/$safe_fn
end
end
cat $DOTFILES_PATH/common/envs |
filter_existing_directory |
sk --multi \
--prompt "Select applicable environments (multi-select w/ TAB): " \
--preview-window="up:50%:noborder" \
--preview="ls -la --color=always $DOTFILES_PATH/{}" |
string trim |
reject_empty_lines |
link

30
scripts/bin/dotfiles-make-env Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
echo "Not implemented yet!"; exit 1
edfp="$ENV_PATH/$1"
mkdir -p "$edfp/"
mkdir -p "$edfp/.hidden/bash.d/"
mkdir -p "$edfp/bin/"
mkdir -p "$edfp/x/"
mkdir -p "$edfp/sway/waybar"
mkdir -p "$edfp/sway/config.d"
mkdir -p "$HOME/.bin/"
touches=(
"$edfp/bash"
"$edfp/x/init"
"$edfp/x/profile"
"$edfp/x/resources"
"$edfp/vim"
"$edfp/bspwm"
"$edfp/polybar"
"$edfp/app-launcher"
"$edfp/workdock"
)
for t in "${touches[@]}"; do
touch "$t"
done
chmod 700 -R "$edfp"

78
scripts/bin/dotfiles-setup Executable file
View file

@ -0,0 +1,78 @@
#!/usr/bin/env fish
# This script's purpose is to setup the dotfiles configuration for an existing
# and provisioned machine. For provisioning, see `./dotfiles-init`.
set dfp (realpath (dirname (status -f))/../..)
set lock_file $HOME/.using-lytedev-dotfiles.lock
if not test -f $lock_file
echo "This will delete existing files. Make sure you know what you're doing."
echo 'Are you sure you want to continue? [y/N]'
read response
set response (string lower $response)
if string match $response y
echo "agreed" > "$lock_file"
else
exit 1
end
end
set -q XDG_CONFIG_HOME || set XDG_CONFIG_HOME $HOME/.config
set h $HOME; set c $XDG_CONFIG_HOME
if test -d $c/lytedev-env
echo "Warning: no environment-specific configuration detected!"
end
function l -a dot -a target -d "Symlink a dotfile configuration file or directory"
if test -L $target || test -f $target || test -d $target
command rm -rf "$target"
end
# check if the directory that will contain the link exists
set -l d (dirname $target)
test -d $d || mkdir -p $d
ln -s (pwd)/$dot $target
echo Linked $dot to $target
end
pushd $dfp
test -d ~/.tmux/pluginx/tpm || \
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
l common/zellij $c/zellij
l common/tmux/conf $h/.tmux.conf
l common/bat $c/bat
l common/bash/rc $h/.bashrc
l common/wezterm $c/wezterm
l common/kitty $c/kitty
l common/weechat $h/.weechat
l common/scim/rc $h/.scimrc
l common/scim/lua $h/.scim/lua
l common/nnn $c/nnn
l common/kak $c/kak
l common/helix $c/helix
l common/gitui $c/gitui
l common/gpg/agent.conf $h/.gnupg/gpg-agent.conf
chmod og-rwx ~/.gnupg
l common/htop/rc $c/htop/htoprc
l common/kitty $c/kitty
l common/alacritty $c/alacritty
l common/pgcli $c/pgcli
l common/mutt/rc $h/.muttrc
l common/git/config $h/.gitconfig
l common/elixir/iex.exs $h/.iex.exs
l common/blender/userpref.blend $c/blender/2.93/config/userpref.blend
l common/lemonade/config.toml $c/lemonade.toml
l common/tig/rc $h/.tigrc
popd
for s in $c/lytedev-env/*/dotfiles-setup.d.fish
source $s $dfp $h $c
end
set -q ENV_PATH || set ENV_PATH $XDG_CONFIG_HOME/lytedev-env
set -q DOTFILES_PATH || set DOTFILES_PATH $XDG_CONFIG_HOME/lytedev-dotfiles
command rm -f $ENV_PATH/empty
ln -s $DOTFILES_PATH/common/empty-env $ENV_PATH/empty
echo "Dotfiles Installed! Don't forget to setup environments and change the user's shell as needed!"
exec fish

View file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
if [[ $UID -ne 0 ]]; then
echo "Re-running with 'sudo -E'..."
sudo -E "$0" "$@"
exit
fi
dfp=$(cd "$(dirname "${BASH_SOURCE[0]}" )/../../" && pwd)
source "${dfp}/env/common/setup_helpers.bash"
cp "$dfp/apps/de/sway/dm-entry" "/usr/share/wayland-sessions/lsway.desktop"
links=(
# display manager files
"apps/de/sway/init" "/usr/bin/sway-lytedev"
# udev rules
# TODO: how does this work in nix?
"apps/udev-rules/gcadapter" "/etc/udev/rules.d/51-gcadapter.rules"
# tmpfiles
# TODO: does this even do anything anymore?
"apps/tmpfiles/disable-lid-wakeup" "/etc/tmpfiles.d/disable-lid-wakeup.conf"
# lightdm
"apps/de/gnome/gdm-tap-to-click" "/etc/dconf/db/gdm.d/06-tap-to-click"
)
_dotfiles_setup_run_setup "$HOME/.using-lytedev-etcfiles.lock" "${links[@]}"

3
scripts/bin/editscrot Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
opener="$(command -v xdg-open 2>&1 >/dev/null && echo "xdg-open" || echo "open")"
exec nohup "$opener" "$NICE_HOME/img/scrots/$(ls -t "$NICE_HOME/img/scrots/" | head -n1)" >/dev/null 2>&1 &

View file

@ -0,0 +1,72 @@
#!/usr/bin/env bash
err() {
errpre=""
errpost=""
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test "$ncolors" -ge 8; then
errpre="$(tput setaf 1)"
errpost="$(tput setaf 7)"
fi
fi
>&2 echo "${errpre}ERROR: $*${errpost}"; usage; exit 1
}
warn() {
pre=""
post=""
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test "$ncolors" -ge 8; then
pre="$(tput setaf 3)"
post="$(tput setaf 7)"
fi
fi
>&2 echo "${pre}WARNING: $*${post}"
}
usage() { >&2 cat <<USAGEDOC
usage:
email-via-mailgun-smtp [recipient] [subject] [username] [password] <<< 'Hello, world!'
email-via-mailgun-smtp will read all the input from stdin and use the contents as the body of the email.
recipient will default to DEFAULT_MAILGUN_SMTP_RECIPIENT if not set
username will default to DEFAULT_MAILGUN_SMTP_USERNAME if not set
password will default to DEFAULT_MAILGUN_SMTP_PASSWORD if not set
subject will default to DEFAULT_MAILGUN_SMTP_SUBJECT if not set
USAGEDOC
}
recipient="${1:-$DEFAULT_MAILGUN_SMTP_RECIPIENT}"; shift
[[ -z $recipient ]] && err 'No recipient provided.'
subject="${1:-$DEFAULT_MAILGUN_SMTP_SUBJECT}"; shift
[[ -z $subject ]] && warn 'No subject provided. Leaving blank.'
username="${1:-$DEFAULT_MAILGUN_SMTP_USERNAME}"; shift
[[ -z $username ]] && err 'No username provided.'
password="${1:-$DEFAULT_MAILGUN_SMTP_PASSWORD}"; shift
[[ -z $password ]] && err 'No password provided.'
warn "Reading email body from stdin..."
body=""
while read -r line; do
body="${body}\n${line}"
done
[[ -z $body ]] && err 'Body was blank.'
echo "Recipient: $recipient"
>&2 echo "Finished reading body. Sending email..."
swaks --auth \
--server smtp.mailgun.org \
--au "$username" \
--ap "$password" \
--to "$recipient" \
--h-Subject: "$subject" \
--body "$body"

5
scripts/bin/emoji Executable file
View file

@ -0,0 +1,5 @@
#!/usr/bin/env sh
r="$(< "$HOME/.emoji.txt" sk --height 40%)"
echo "$r" | awk '$0=$1' | tr -d '\n' | clip
echo "Copied $r emoji to your clipboard"

6
scripts/bin/ezln Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
SOURCE="$(realpath "$1")" # this one exists
DEST="$(realpath -m "$2")" # this is the link to what exists
mkdir -p "$(dirname "$2")"
ln -s "$SOURCE" "$DEST"

6
scripts/bin/field Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env sh
has_command gawk || { echo "No gawk." >&2 ; exit 1; }
index="${1:-1}"
[ "$#" -lt 1 ] || shift
gawk "$@" '{print $'"${index}"'}'

4
scripts/bin/getip Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
curl -s --connect-timeout 3 --max-time 10 --retry 5 --retry-delay 0 \
--retry-max-time 40 "$@" ifconfig.co/json | jq

8
scripts/bin/git-authors Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
git ls-tree -r -z --name-only HEAD -- "$1" \
| xargs -0 -n1 git blame --line-porcelain HEAD \
| grep "^author " \
| sort \
| uniq -c \
| sort -nr

73
scripts/bin/gitforge-url.ts Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env -S deno run --allow-read --allow-run --allow-net
import * as path from "https://deno.land/std@0.181.0/path/mod.ts";
// output the best guess URL for viewing the file at the current git revision in
// the git forge's web interface
// TODO: --help, -h menu
const file = Deno.args[0];
if (!file) {
console.error("No file argument provided");
Deno.exit(1);
}
async function cmdOutput(cmd: string[]) {
return new TextDecoder().decode(
await Deno.run({
cmd: cmd,
stdout: "piped",
})
.output(),
).trim();
}
type ForgeType = "gitlab" | "github" | "gitea";
function getForgeType(hostname: string): ForgeType {
if (hostname == "git.lyte.dev") {
return "gitea";
} else if (hostname.endsWith("github.com")) {
return "github";
} else {
return "gitlab";
}
}
function getUrl(repoRoot: string, remote: string, commit: string) {
try {
// try http remote
console.log(new URL(remote));
throw new Error("HTTP(S) remotes not implemented");
} catch {
const hostname = remote.split("@").slice(-1)[0].split(":")[0];
const forgeType = getForgeType(hostname);
let repoPath = remote.split(":")[1];
if (repoPath.endsWith(".git")) {
repoPath = repoPath.slice(0, -4);
}
let fileRepoPath = path.resolve(file);
if (fileRepoPath.startsWith(repoRoot)) {
fileRepoPath = fileRepoPath.slice(repoRoot.length + 1); // for the trailing slash
} else {
throw new Error(`File ${fileRepoPath} is not in repo at ${repoRoot}`);
}
switch (forgeType) {
case "gitlab":
return `https://${hostname}/${repoPath}/-/blob/${commit}/${fileRepoPath}`;
case "gitea":
return `https://${hostname}/${repoPath}/src/commit/${commit}/${fileRepoPath}`;
case "github":
return `https://${hostname}/${repoPath}/blob/${commit}/${fileRepoPath}`;
}
}
}
// TODO: cd to dir
const repoRoot = await cmdOutput(["git", "rev-parse", "--show-toplevel"]);
const remote = await cmdOutput(["git", "remote", "get-url", "origin"]);
const commit = await cmdOutput(["git", "rev-parse", "HEAD"]);
const url = getUrl(repoRoot, remote, commit);
console.log(url);

11
scripts/bin/glancepath Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env -S awk -f
{
split(substr($0, 2), p, "/");
for (k in p) {
if (k == length(p)) {
printf "/%s", p[k]
} else {
printf "/%.3s", p[k]
}
}
}

21
scripts/bin/good-morning Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env fish
# create a messages file for subscripts to write to or manipulate for ending
# output
set message_file (mktemp)
for f in (fd good-morning.d.fish $HOME/.config/lytedev-env --max-depth 2)
# run scripts for any linked environments with a hooked script
source $f $message_file
end
# output the messages file's contents
echo
command cat $message_file
echo
# since this script almost always runs in its own window which dies after
# finishing, give the user a chance to read the output
echo "When you're ready, hit enter to finish!"
read

4
scripts/bin/has_command Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
[ "$#" -lt 1 ] && { echo "No arguments provided" >&2 ; exit 1; }
command -v "$1" >/dev/null 2>&1

View file

@ -0,0 +1,21 @@
#!/usr/bin/env fish
set profile_dirs $HOME/.mozilla/firefox/*.dev-edition-default $HOME/.mozilla/firefox/*.default-release
if test (uname) = Darwin
set profile_dirs $HOME/Library/Application\ Support/Firefox/Profiles/*.dev-edition-default $HOME/.mozilla/firefox/*.default-release
end
for p in $profile_dirs
mkdir -p $p/chrome
set user_chrome_css_file $p/chrome/userChrome.css
echo '/* Generated by '(status -f)' -- do not edit manually! */' > $user_chrome_css_file
cat $DOTFILES_PATH/common/firefox/userChrome.d.css >> $user_chrome_css_file
echo >> $user_chrome_css_file
for file_part in $ENV_PATH/*/firefox/userChrome.d.css
cat $file_part >> $user_chrome_css_file
echo >> $user_chrome_css_file
end
echo Built $user_chrome_css_file
end
echo Make sure you set 'toolkit.legacyUserProfileCustomizations.stylesheets' to true in about:config

4
scripts/bin/is_wayland Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
exit 0
# loginctl show-session "$(loginctl | grep "$(whoami)" | head -n 1 | field 1)" -p Type | grep -i wayland >/dev/null

8
scripts/bin/k8s-yaml-diff Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
[ "$#" -lt 2 ] && echo "Need two filenames." && exit 1
f1="$1"; shift
f2="$1"; shift
nvim -d <(k8s-yaml-sort "$f1") <(k8s-yaml-sort "$f2")

17
scripts/bin/k8s-yaml-sort Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
[ "$#" -lt 1 ] && echo "Need a filename." && exit 1
< "$1" yq -s . | jq -S '
sort_by(.metadata.name) |
sort_by(.kind) |
.[] | .spec.template.spec.containers |=
if . == null then empty
else
map(
if . == null then empty
else .env |= sort_by(.name)
| .volumeMounts |= sort_by(.name)
end
)
end
'

3
scripts/bin/keyrepeat Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
xset r rate 250 80

9
scripts/bin/kubeline Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
c="$(kubectl config current-context | tr -d "\n")"
if [ -n "$c" ]; then
printf "%s" "$c"
fi
a="$(kubectl config view --minify --output 'jsonpath={..namespace}')"
if [ -n "$a" ]; then
printf ".%s" "$a"
fi

9
scripts/bin/kubfc Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
kubectl config get-contexts --no-headers | \
uniq | \
sort | \
tr -s ' ' | \
sed -E 's/^\*?[[:space:]]*//g' | \
cut -d ' ' -f1 | \
sk | \
xargs -I{} kubectl config use-context '{}'

12
scripts/bin/kubfn Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env sh
has_command kubectl || {
echo "kubectl command not found"
exit 1
}
kubectl get namespaces --show-labels | \
uniq | \
sort | \
cut -d ' ' -f1 | \
sk | \
xargs -I{} kubectl config set-context --current --namespace='{}'

19
scripts/bin/launch Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
LAUNCHER_HISTORY_FILE="$HOME/.local/share/lytelaunch/launch.log"
mkdir --parents "$(dirname "$LAUNCHER_HISTORY_FILE")"
touch "$LAUNCHER_HISTORY_FILE"
app="$(
< "$LAUNCHER_HISTORY_FILE" \
awk 'NF{NF--};1' | \
cat - <(dmenu_path) | \
sort | uniq -c | sort -nr | \
sd -fm '^\s+' '' | \
cut -d' ' -f2- | \
grep "\S" | \
sk
)"
# if no app is selected, just exit
test -z "$app" && exit 1
echo "$app $(date +%s)" >> "$LAUNCHER_HISTORY_FILE"
echo "$app"

10
scripts/bin/linewise Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
if [[ -n "${1+x}" ]]; then
while read -r line; do
<<< "${line}" "$@"
done
else
echo "No reader program provided."
exit 1
fi

View file

@ -0,0 +1,5 @@
#!/usr/bin/env bash
f="$1"; shift
[ -f "$f" ] && source "$f" "$@"
true

3
scripts/bin/nd Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@"

7
scripts/bin/nf Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env sh
SUBDIR="${2:-./}"
mkdir -p "$NOTES_PATH/$SUBDIR"
cd "$NOTES_PATH/$SUBDIR" || exit 1
"$EDITOR" "$NOTES_PATH/$SUBDIR/$1"
cd - || exit 1

2
scripts/bin/note Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@"

8
scripts/bin/nsync Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: warn on merge conflicts?
cd "${NOTES_PATH}" || exit
git add -A
git commit -m Updates
git fetch && git merge origin/master && git push
cd - || exit

2
scripts/bin/nvimdiff Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
nvim -d "$@"

21
scripts/bin/open-in-git-forge Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env sh
usage() {
echo "open-in-git-forge <$FILE>[#L$LINE_NUMBERS]"
echo " Opens the URL in your browser to the git forge's web interface for the current branch for $FILE"
echo
echo " Examples:"
echo " \$ open-in-git-forge readme.md#L12"
}
if [ "$#" -lt 1 ]; then
usage
exit 1
fi
url="$(gitforge-url.ts "$1")"
case "$(uname)" in
Linux*) xdg-open "$url";;
Darwin*) open "$url";;
*) echo "OS not supported"; exit 1;
esac

View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
mogrify \
-filter Triangle \
-define filter:support=2 \
-resize 2000x2000\> \
-unsharp 0.25x0.08+8.3+0.045 \
-dither None \
-posterize 136 \
-quality 82 \
-define jpeg:fancy-upsampling=off \
-define png:compression-filter=5 \
-define png:compression-level=9 \
-define png:compression-strategy=1 \
-define png:exclude-chunk=all \
-interlace none \
-colorspace sRGB \
"$1"

View file

@ -0,0 +1,6 @@
#!/usr/bin/env fish
set entry $argv[1]
set otp_secret (pass $entry | awk -F': ' '/^otp/{gsub(/\s/,"",$2);print $2}')
set otp_uri "otpauth://totp/totp-secret?secret=$otp_secret&issuer=$entry"
echo $otp_uri | pass otp append $entry

41
scripts/bin/pipeline Executable file
View file

@ -0,0 +1,41 @@
#!/usr/bin/env sh
SAVED_PIPELINE_DIR="$DOTFILES_PATH/env/common/data/pipelines"
mkdir -p "$SAVED_PIPELINE_DIR"
if [ -n "${1+x}" ]; then
pdir="$SAVED_PIPELINE_DIR/$1"; shift
mkdir -p "$pdir"
if [ -z ${1+x} ]; then
td="$(mktemp -p "$pdir" -d "tmp_pipeline.XXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf '$td'" EXIT
else
td="$pdir/$1"; shift
mkdir -p "$td"
fi
transform="$pdir/transform"
else
td="$(mktemp --tmpdir -d pipeline.XXXXXXXX)"
transform="$td/transform"
# shellcheck disable=SC2064
trap "rm -rf '$td'" EXIT
fi
[ ! -e "$transform" ] && \
printf "#!/usr/bin/env bash\n# you must save this buffer manually\n# for %s\n
base64" "${td}" > "$transform"
in="$td/in"; [ -n "${1+x}" ] && in="${1}" && shift
out="$td/out"; [ -n "${1+x}" ] && out="${1}" && shift
# TODO: if no logging, log="/dev/null"
log="$td/log"
touch "$log"
chmod +x "$transform"
# TODO: saved inputs?
echo "Hello World" > "$in"
env PIPELINE_IN="$in" PIPELINE_TRANSFORM="$transform" PIPELINE_OUT="$out" nvim --cmd "source $DOTFILES_PATH/apps/neovim/scripts/pipeline.vim"

12
scripts/bin/poll Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env fish
# make sure our stuff gets loaded so aliases will work
source ~/.config/fish/config.fish
while true
clear
sleep 2 &
echo (tput setaf 0)(date) polled (tput setaf 4)"'"$argv"'"(tput setaf 7)
eval $argv
wait
end

10
scripts/bin/pr-for-commit Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env sh
GITHUB_UPSTREAM="$(git remote -vv | awk '{$0=$2}')"
git log --merges --ancestry-path --oneline "$1"..master \
| grep -i 'pull request' \
| tail -n1 \
| awk '{$0=$5}' \
| cut -c2- \
| xargs -I % open https://github.com/"$GITHUB_UPSTREAM"/"${PWD##*/}"/pull/%

4
scripts/bin/readme.md Normal file
View file

@ -0,0 +1,4 @@
This directory contains scripts and stuff I want in my PATH whether NixOS, some
other Linux, or macOS.
For OS-specific executables, see the OS-specific subdirectories.

11
scripts/bin/remote Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env moon
arg_spec = {
{"target", "REMOTE_MACHINE", "remote"}
{"mpr", "MOSH_PORT_RANGE", "60000:61000"}
{"sargs", "SSH_ARGS", "-XY"}
{"margs", "MOSH_ARGS", ""}
}
args = {v[1], os.getenv(v[2]) or arg[i] or v[3] for i, v in ipairs(arg_spec)}
os.execute "mosh -p '#{args.mpr}' '#{args.target}' --ssh='ssh #{args.sargs}' #{args.margs}"

23
scripts/bin/resource-usage Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
# TODO: radeontop can continuously dump to a file, would be fast to just keep
# last line and have this run in the background
gpu_usage="$(radeontop -l 1 -d - | rg --color never -o "gpu (\d+.\d+)" -r '$1')"
gpu_temp="$(sensors | rg 'amdgpu.*mem:\s+\+(\d+\.\d+)' --multiline-dotall --multiline -o -r '$1')"
# NOTE: this is all cpu usage since boot:
# cpu_usage_data_snapshot="$(cat /proc/stat | head -n 1 | cut -d ' ' -f 2- | sd '^\s+' '')"
# function cpu_usage_data() {
# echo "$cpu_usage_data_snapshot"
# }
# cpu_usage="$(bc -l <<< "100-(100*($(cpu_usage_data | awk '{printf $4}').0/$(cpu_usage_data | sd " " "+" | bc).0))")"
mpstat_samples=2
mpstat_sample_seconds=1
cpu_idle="$(mpstat --dec=2 "$mpstat_sample_seconds" "$mpstat_samples" | tail -n 1 | field 12)"
cpu_usage="$(echo "100.0-$cpu_idle" | bc -l)"
cpu_temp="0.0"
printf "GPU [USAGE: %6.2f%%] [THERMALS: %6.2f°C]\n" "$gpu_usage" "$gpu_temp"
printf "CPU [USAGE: %6.2f%%] [THERMALS: %6.2f°C]\n" "$cpu_usage" "$cpu_temp"

3
scripts/bin/restartbar Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
stopbar && startbar &

3
scripts/bin/s Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
N _scratch

3
scripts/bin/scn Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
EDITOR="sc-im" nf "$@"

6
scripts/bin/screenshot Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
SCROT_DIR="$NICE_HOME/img/scrots"
mkdir -p "$SCROT_DIR/"
FILENAME="$SCROT_DIR/screenshot_$(date +%Y-%m-%d_%H-%M-%S).png"
grim -t png "$@" "${FILENAME}" >/dev/null && echo "Saved screenshot to: ${FILENAME}"

3
scripts/bin/script-opts Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
# TODO: helper for taking a data structure and building bash args?

19
scripts/bin/scrup Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -x
remote_dir="scrots"
url_prefix="https://files.lyte.dev/$remote_dir"
u="$(uuid -v4)"
d="$(date +%Y-%m-%d_%H-%M-%S)"
fn="$(clipshot)"
if [ $? -eq 0 ]; then
echo "Scrot captured. Uploading..."
upload "${fn}" "scrup-$u-$d.png" "$remote_dir"
echo "$url_prefix/scrup-$u-$d.png" | clip
notify-send "Scrot uploaded. URL in clipboard."
else
exit 1
fi

4
scripts/bin/scwd Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
addon=""; [ -n "$1" ] && addon="-${1}"
echo "${PWD}" > "${DOTFILES_PATH}/.cwd${addon}.tmp"

8
scripts/bin/setbg Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
index="${2}"
wp_file="${HOME}/.wallpaper${index}"
rm -f "${wp_file}"
echo "Setting ${1} as ${wp_file}"
ln -s "$(realpath "${1}")" "${wp_file}"
"${HOME}/.fehbg"

8
scripts/bin/simple-otp Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: check for oathtool
key="$1"; shift
args=("$@")
oathtool --totp=sha1 -b "$key" "${args[@]}"

7
scripts/bin/source_if_exists Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
[ "$#" -lt 1 ] && { echo "No arguments provided" >&2 ; exit 1; }
# shellcheck disable=SC1090
f="$1"; shift
{ [ -f "$f" ] && source "$f" "$@"; } || { echo "$f does not exist" >&2 ; exit 3; }

3
scripts/bin/startbar Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
"${DOTFILES_PATH}/apps/de/polybar/run"

8
scripts/bin/stopbar Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# TODO: get the proper monitor!
BAR_MONITOR="$(polybar --list-monitors | tail -n 1 | sed -n 's/^\s*\(.*\):.*$/\1/p')"
bspc config -m "${BAR_MONITOR}" bottom_padding "0"
bspc config -m "${BAR_MONITOR}" top_padding "0"
killall -q polybar
while pgrep -x polybar >/dev/null; do sleep 1; done

17
scripts/bin/sw Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
d="$(date +%s)"
_dt=$(($(date +%s) - d))
echo "Stopwatch started $(date)"
trap 'echo -ne "\nStopwatch stopped at $(date)\n" && exit 0' SIGINT
while true; do
_dt=$(($(date +%s) - d))
days=$((_dt / 86400))
echo -ne "\r${days}d $(date -u --date @$((_dt)) +%H:%M:%S) "
sleep 0.1
done
# TODO: add "lap" capabilities?

2
scripts/bin/tdf Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env fish
tmux-lyte-session dotfiles $DOTFILES_PATH

3
scripts/bin/tenv Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
d="$(command ls "$ENV_PATH" | sk)" && \
tmux-lyte-session "env-$d" "$ENV_PATH/$d"

View file

@ -0,0 +1,25 @@
#!/usr/bin/env bash
# sources:
# https://askubuntu.com/questions/528928/how-to-do-underline-bold-italic-strikethrough-color-background-and-size-i
# https://askubuntu.com/questions/27314/script-to-display-all-terminal-colors
indent=" "
padding=" "
reset="\e[0;39;49m"
for s in {0..8}; do # text styles
for t in {30..37}; do # text color
for b in {40..47}; do # background
echo -ne "${indent}\e[$s;$t;${b}m${padding}\\\e[$s;$t;${b}m${padding}${reset}"
done
echo
done
echo
done
echo -e "Emoji: 😱😍😬🎉"
echo -e "Possible Ligatures:"
echo -r " --> -> == != === ------> ** ++ |> <* := :: |] [| ===>"
echo -r " >= <= =>= ->- >>- <<- <***> =: <. <.> .> ~> ~~> ~~~~>"
echo -r " (* |- -| =!= :> <!-- <==> <--> |} {| >=> <=< ++++ ___"
echo

3
scripts/bin/termrec Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
asciinema rec -i 2 --stdin

2
scripts/bin/tls Executable file
View file

@ -0,0 +1,2 @@
#!/usr/bin/env sh
tmux list-sessions

4
scripts/bin/tmux-edit-buffer Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env sh
f="$(tmux-save-buffer)"
tmux new-window "$EDITOR $f"

11
scripts/bin/tmux-lyte-session Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env fish
set session_name $argv[1]
set dir (set -q argv[2] && echo $argv[2] || pwd)
if set -q TMUX
tmux switch -t $session_name
else
tmux new-session -D -s "$session_name" -c "$dir" $argv[3..-1] &>/dev/null || \
tmux attach -t "$session_name" -c "$dir"
end

9
scripts/bin/tmux-save-buffer Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
d="$(date +%Y-%m-%d_%H-%M-%S)"
f="${USER_LOGS_PATH}/${d}.tmux-buffer.log"
mkdir -p "$(dirname "$f")"
touch "$f"
chmod 600 "$f"
tmux capture-pane -pS -1000000000 > "$f"
echo "$f"

9
scripts/bin/tmux-session-dir Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env sh
# if inside a session, use the current session
# if not, a session must be specified after the dir
d="${1}"
[ -z "$d" ] && d="#{pane_current_path}"
target_session="${2}"
[ -n "$TMUX" ] && target_session="."
tmux attach-session -t "$target_session" -c "$d"

View file

@ -0,0 +1,13 @@
#!/usr/bin/env sh
session_data="$1"
session_id="$(echo "$session_data" | cut -d':' -f1)"
S="$(tmux ls -F'#{session_id} #{session_name}: #{T:tree_mode_format}' | grep ^"$session_id")"
session_info="${S##$s}"
session_name="$(echo "$session_info" | cut -d ':' -f1)"
echo "RAW: $1"
echo "S: $S"
echo "INFO: $session_info"
echo "NAME: $session_name"

22
scripts/bin/tmuxswitcher Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env sh
fmt='#{session_id}:|#S|(#{session_attached} attached)'
t="tmux switch-client -t"
[ -z "$TMUX" ] && t="tmux attach-session -t"
sess="$({ tmux display-message -p -F "$fmt" && tmux list-sessions -F "$fmt"; } \
| awk '!seen[$1]++' \
| column -t -s'|' \
| sk -q '$' --reverse --prompt 'switch session: ' -1 --preview "tmux-session-preview {}" \
| cut -d':' -f1)"
[ -z "$sess" ] && exit 1
$t "$sess"
# | while read w; do
# set W (tmux lsw -t"{}" -F'#{window_id}#{T:tree_mode_format}' | grep ^"$w")
# echo " ﬌ ${W##$w}"
# end

9
scripts/bin/unarchive Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env bash
archive_name="${1}"; shift
to_dir="$(basename "$archive_name")"
mkdir -p "${to_dir}"
pushd "${to_dir}" || ( echo "${to_dir} does not exist" ; exit 1 )
tar --zstd -xvf "${archive_name}"
echo "Unarchived to: ${to_dir}"
popd || exit 2

56
scripts/bin/unbackupify Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env fish
# deps: fish, zstd, gpg, ssh
set -q HOST || set HOST (head -n 1 /etc/hostname | tr -d '\n')
# use the backup-host in the ~/.ssh/config as the default backup remote host
set -q BACKUP_REMOTE_HOST || set BACKUP_REMOTE_HOST backup-host
# use a user-specific dir by default to backup to
set -q BACKUP_REMOTE_DIR || set BACKUP_REMOTE_DIR "/storage/"(whoami)"/backups/$HOST"
set BACKUP_FILE_EXT .tar.zstd.gpg
set target $argv[1]
if test $target = '--list-backup-files'
ssh $BACKUP_REMOTE_HOST "command ls -1 $BACKUP_REMOTE_DIR"
exit 0
else if test (count $argv) -lt 1
echo "No remote backup filename provided (use --list-backup-files to show)"
exit 1
end
ssh $BACKUP_REMOTE_HOST "echo 1" &>/dev/null || begin
echo "Cannot ssh to $BACKUP_REMOTE_HOST"
exit 6
end
ssh $BACKUP_REMOTE_HOST "test -d $BACKUP_REMOTE_DIR/$target" || begin
echo "Remote directory $BACKUP_REMOTE_DIR/$target does not exist on $BACKUP_REMOTE_HOST (use --list-backup-files to show)"
exit 5
end
# TODO: autocomplete?
# TODO: checksum?
# TODO: progress indicator?
set local_dir (echo $target | awk -F. '{print $1}')
mkdir $local_dir || begin
echo "Local unbackup directory '$local_dir' exists"
exit 2
end
pushd $local_dir >/dev/null
ssh $BACKUP_REMOTE_HOST "cat $BACKUP_REMOTE_DIR/$target" |
gpg --decrypt 2>/dev/null |
zstd --ultra -T2 -22 -dc |
tar -xf - || begin
echo "Failed to stream backup"
exit 4
end
popd >/dev/null
echo "Restored to $local_dir"

3
scripts/bin/weather Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env sh
curl 'wttr.in/@h.lyte.dev?format=%l%20%T:%20%t%20%C%20%w%20%h'

4
scripts/bin/work-journal-entry Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env fish
N work/divvy/(date +%Y-%m-%d) && \
pushd $NOTES_PATH && git add -A && \
git commit -m "Edit work journal entry for "(date +%Y-%m-%d) && nsync

8
scripts/bin/yamldiff Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env bash
[ "$#" -lt 2 ] && echo "Need two filenames." && exit 1
f1="$1"; shift; echo "$f1" >&2
f2="$1"; shift; echo "$f2" >&2
nvim -d <(yq . "$f1" | jq -S .) <(yq . "$f2" | jq -S .)