diff --git a/daniel.nix b/daniel.nix index 9dc9973..263ef91 100644 --- a/daniel.nix +++ b/daniel.nix @@ -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? } diff --git a/disko.nix b/disko.nix index ef1144e..2375eaf 100644 --- a/disko.nix +++ b/disko.nix @@ -1,4 +1,4 @@ -{}: { +{ standard = { disks ? [ "/dev/vda" ], ... }: { # this is my standard partitioning scheme for my machines: an LUKS-encrypted # btrfs volume diff --git a/fish/interactiveShellInit.fish b/fish/interactiveShellInit.fish new file mode 100644 index 0000000..70291d7 --- /dev/null +++ b/fish/interactiveShellInit.fish @@ -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 diff --git a/fish/shellInit.fish b/fish/shellInit.fish new file mode 100644 index 0000000..b43fffd --- /dev/null +++ b/fish/shellInit.fish @@ -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 + diff --git a/flake.lock b/flake.lock index 0109a7d..aa39f57 100644 --- a/flake.lock +++ b/flake.lock @@ -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": [ diff --git a/flake.nix b/flake.nix index 00219cf..1d833b5 100644 --- a/flake.nix +++ b/flake.nix @@ -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; }; }; }; diff --git a/machines/thinker.nix b/machines/thinker.nix index 08d762b..315e4f2 100644 --- a/machines/thinker.nix +++ b/machines/thinker.nix @@ -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 diff --git a/readme.md b/readme.md index baecc77..2810685 100644 --- a/readme.md +++ b/readme.md @@ -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 + + + +```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' " ``` diff --git a/scripts/bin/? b/scripts/bin/? new file mode 100755 index 0000000..bbf6d34 --- /dev/null +++ b/scripts/bin/? @@ -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 diff --git a/scripts/bin/N b/scripts/bin/N new file mode 100755 index 0000000..5ec9178 --- /dev/null +++ b/scripts/bin/N @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +fn="${1}"; shift; nf "${fn}.md" "$@" \ No newline at end of file diff --git a/scripts/bin/archive b/scripts/bin/archive new file mode 100755 index 0000000..0b478e6 --- /dev/null +++ b/scripts/bin/archive @@ -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} " diff --git a/scripts/bin/archupdate b/scripts/bin/archupdate new file mode 100755 index 0000000..ec3c4b5 --- /dev/null +++ b/scripts/bin/archupdate @@ -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 diff --git a/scripts/bin/at b/scripts/bin/at new file mode 100755 index 0000000..1c8a1f3 --- /dev/null +++ b/scripts/bin/at @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +usage() { + echo "at - waits until after the specified datetime" + echo "Usage:" + echo " at && 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 \ No newline at end of file diff --git a/scripts/bin/bp b/scripts/bin/bp new file mode 100755 index 0000000..d3c155e --- /dev/null +++ b/scripts/bin/bp @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +printf '\e[?2004h' +printf '\e[?2004l' +echo bp off + diff --git a/scripts/bin/check-domain-availability b/scripts/bin/check-domain-availability new file mode 100755 index 0000000..5afce64 --- /dev/null +++ b/scripts/bin/check-domain-availability @@ -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&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 diff --git a/scripts/bin/clip b/scripts/bin/clip new file mode 100755 index 0000000..0eab0ac --- /dev/null +++ b/scripts/bin/clip @@ -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 diff --git a/scripts/bin/clipshot b/scripts/bin/clipshot new file mode 100755 index 0000000..62f4ba7 --- /dev/null +++ b/scripts/bin/clipshot @@ -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" diff --git a/scripts/bin/copy-git-forge-url b/scripts/bin/copy-git-forge-url new file mode 100755 index 0000000..287a94f --- /dev/null +++ b/scripts/bin/copy-git-forge-url @@ -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 \ No newline at end of file diff --git a/scripts/bin/countdown b/scripts/bin/countdown new file mode 100755 index 0000000..d6f00da --- /dev/null +++ b/scripts/bin/countdown @@ -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" diff --git a/scripts/bin/dns b/scripts/bin/dns new file mode 100755 index 0000000..0a1c7f1 --- /dev/null +++ b/scripts/bin/dns @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +getent hosts "$@" diff --git a/scripts/bin/dns-cleaner b/scripts/bin/dns-cleaner new file mode 100755 index 0000000..e69de29 diff --git a/scripts/bin/dns-deleter b/scripts/bin/dns-deleter new file mode 100755 index 0000000..3df9dd8 --- /dev/null +++ b/scripts/bin/dns-deleter @@ -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 diff --git a/scripts/bin/dns-deleter-matching b/scripts/bin/dns-deleter-matching new file mode 100755 index 0000000..cf6c334 --- /dev/null +++ b/scripts/bin/dns-deleter-matching @@ -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 diff --git a/scripts/bin/dotfiles-clone-and-setup b/scripts/bin/dotfiles-clone-and-setup new file mode 100644 index 0000000..5d90580 --- /dev/null +++ b/scripts/bin/dotfiles-clone-and-setup @@ -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" diff --git a/scripts/bin/dotfiles-init b/scripts/bin/dotfiles-init new file mode 100755 index 0000000..3fe9240 --- /dev/null +++ b/scripts/bin/dotfiles-init @@ -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 diff --git a/scripts/bin/dotfiles-link-environments b/scripts/bin/dotfiles-link-environments new file mode 100755 index 0000000..3fe54d9 --- /dev/null +++ b/scripts/bin/dotfiles-link-environments @@ -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 diff --git a/scripts/bin/dotfiles-make-env b/scripts/bin/dotfiles-make-env new file mode 100755 index 0000000..ca07e0a --- /dev/null +++ b/scripts/bin/dotfiles-make-env @@ -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" diff --git a/scripts/bin/dotfiles-setup b/scripts/bin/dotfiles-setup new file mode 100755 index 0000000..5accd42 --- /dev/null +++ b/scripts/bin/dotfiles-setup @@ -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 diff --git a/scripts/bin/dotfiles-setup-for-root b/scripts/bin/dotfiles-setup-for-root new file mode 100755 index 0000000..3d63b5c --- /dev/null +++ b/scripts/bin/dotfiles-setup-for-root @@ -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[@]}" + diff --git a/scripts/bin/editscrot b/scripts/bin/editscrot new file mode 100755 index 0000000..1fe6f6c --- /dev/null +++ b/scripts/bin/editscrot @@ -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 & diff --git a/scripts/bin/email-via-mailgun-smtp b/scripts/bin/email-via-mailgun-smtp new file mode 100755 index 0000000..86aff63 --- /dev/null +++ b/scripts/bin/email-via-mailgun-smtp @@ -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 <&2 echo "Finished reading body. Sending email..." + +swaks --auth \ + --server smtp.mailgun.org \ + --au "$username" \ + --ap "$password" \ + --to "$recipient" \ + --h-Subject: "$subject" \ + --body "$body" \ No newline at end of file diff --git a/scripts/bin/emoji b/scripts/bin/emoji new file mode 100755 index 0000000..7955e0a --- /dev/null +++ b/scripts/bin/emoji @@ -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" diff --git a/scripts/bin/ezln b/scripts/bin/ezln new file mode 100755 index 0000000..acd54b6 --- /dev/null +++ b/scripts/bin/ezln @@ -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" diff --git a/scripts/bin/field b/scripts/bin/field new file mode 100755 index 0000000..d2bf241 --- /dev/null +++ b/scripts/bin/field @@ -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}"'}' diff --git a/scripts/bin/getip b/scripts/bin/getip new file mode 100755 index 0000000..94c6eaa --- /dev/null +++ b/scripts/bin/getip @@ -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 diff --git a/scripts/bin/git-authors b/scripts/bin/git-authors new file mode 100755 index 0000000..ef75b2a --- /dev/null +++ b/scripts/bin/git-authors @@ -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 diff --git a/scripts/bin/gitforge-url.ts b/scripts/bin/gitforge-url.ts new file mode 100755 index 0000000..fab29dc --- /dev/null +++ b/scripts/bin/gitforge-url.ts @@ -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); diff --git a/scripts/bin/glancepath b/scripts/bin/glancepath new file mode 100755 index 0000000..17e07bb --- /dev/null +++ b/scripts/bin/glancepath @@ -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] + } + } +} diff --git a/scripts/bin/good-morning b/scripts/bin/good-morning new file mode 100755 index 0000000..73eb7aa --- /dev/null +++ b/scripts/bin/good-morning @@ -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 diff --git a/scripts/bin/has_command b/scripts/bin/has_command new file mode 100755 index 0000000..48bb2d6 --- /dev/null +++ b/scripts/bin/has_command @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +[ "$#" -lt 1 ] && { echo "No arguments provided" >&2 ; exit 1; } +command -v "$1" >/dev/null 2>&1 diff --git a/scripts/bin/install-firefox-user-chrome-css.fish b/scripts/bin/install-firefox-user-chrome-css.fish new file mode 100755 index 0000000..94cab31 --- /dev/null +++ b/scripts/bin/install-firefox-user-chrome-css.fish @@ -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 diff --git a/scripts/bin/is_wayland b/scripts/bin/is_wayland new file mode 100755 index 0000000..0bdd24b --- /dev/null +++ b/scripts/bin/is_wayland @@ -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 diff --git a/scripts/bin/k8s-yaml-diff b/scripts/bin/k8s-yaml-diff new file mode 100755 index 0000000..4170390 --- /dev/null +++ b/scripts/bin/k8s-yaml-diff @@ -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") diff --git a/scripts/bin/k8s-yaml-sort b/scripts/bin/k8s-yaml-sort new file mode 100755 index 0000000..9766ba9 --- /dev/null +++ b/scripts/bin/k8s-yaml-sort @@ -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 + ' diff --git a/scripts/bin/keyrepeat b/scripts/bin/keyrepeat new file mode 100755 index 0000000..12686fc --- /dev/null +++ b/scripts/bin/keyrepeat @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +xset r rate 250 80 diff --git a/scripts/bin/kubeline b/scripts/bin/kubeline new file mode 100755 index 0000000..226cc6b --- /dev/null +++ b/scripts/bin/kubeline @@ -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 diff --git a/scripts/bin/kubfc b/scripts/bin/kubfc new file mode 100755 index 0000000..b925485 --- /dev/null +++ b/scripts/bin/kubfc @@ -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 '{}' diff --git a/scripts/bin/kubfn b/scripts/bin/kubfn new file mode 100755 index 0000000..5221a16 --- /dev/null +++ b/scripts/bin/kubfn @@ -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='{}' diff --git a/scripts/bin/launch b/scripts/bin/launch new file mode 100755 index 0000000..58a78ea --- /dev/null +++ b/scripts/bin/launch @@ -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" diff --git a/scripts/bin/linewise b/scripts/bin/linewise new file mode 100755 index 0000000..4780293 --- /dev/null +++ b/scripts/bin/linewise @@ -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 diff --git a/scripts/bin/maybe_source_env_file b/scripts/bin/maybe_source_env_file new file mode 100755 index 0000000..d79a8b8 --- /dev/null +++ b/scripts/bin/maybe_source_env_file @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +f="$1"; shift +[ -f "$f" ] && source "$f" "$@" +true diff --git a/scripts/bin/nd b/scripts/bin/nd new file mode 100755 index 0000000..3c73c80 --- /dev/null +++ b/scripts/bin/nd @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@" diff --git a/scripts/bin/nf b/scripts/bin/nf new file mode 100755 index 0000000..9eaef3f --- /dev/null +++ b/scripts/bin/nf @@ -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 diff --git a/scripts/bin/note b/scripts/bin/note new file mode 100755 index 0000000..0715d73 --- /dev/null +++ b/scripts/bin/note @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +fn="${1}"; shift; N "$(date +%Y-%m-%d)_${fn}" "$@" diff --git a/scripts/bin/nsync b/scripts/bin/nsync new file mode 100755 index 0000000..5e70fcc --- /dev/null +++ b/scripts/bin/nsync @@ -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 diff --git a/scripts/bin/nvimdiff b/scripts/bin/nvimdiff new file mode 100755 index 0000000..9650db8 --- /dev/null +++ b/scripts/bin/nvimdiff @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +nvim -d "$@" diff --git a/scripts/bin/open-in-git-forge b/scripts/bin/open-in-git-forge new file mode 100755 index 0000000..30e4549 --- /dev/null +++ b/scripts/bin/open-in-git-forge @@ -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 \ No newline at end of file diff --git a/scripts/bin/optimize-photo-for-web b/scripts/bin/optimize-photo-for-web new file mode 100755 index 0000000..dfd05d7 --- /dev/null +++ b/scripts/bin/optimize-photo-for-web @@ -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" diff --git a/scripts/bin/pass-migrate-to-pass-otp b/scripts/bin/pass-migrate-to-pass-otp new file mode 100755 index 0000000..a6979aa --- /dev/null +++ b/scripts/bin/pass-migrate-to-pass-otp @@ -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 diff --git a/scripts/bin/pipeline b/scripts/bin/pipeline new file mode 100755 index 0000000..6b62334 --- /dev/null +++ b/scripts/bin/pipeline @@ -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" diff --git a/scripts/bin/poll b/scripts/bin/poll new file mode 100755 index 0000000..63a7210 --- /dev/null +++ b/scripts/bin/poll @@ -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 \ No newline at end of file diff --git a/scripts/bin/pr-for-commit b/scripts/bin/pr-for-commit new file mode 100755 index 0000000..685c41c --- /dev/null +++ b/scripts/bin/pr-for-commit @@ -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/% diff --git a/scripts/bin/readme.md b/scripts/bin/readme.md new file mode 100644 index 0000000..dd2afc2 --- /dev/null +++ b/scripts/bin/readme.md @@ -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. diff --git a/scripts/bin/remote b/scripts/bin/remote new file mode 100755 index 0000000..98490c6 --- /dev/null +++ b/scripts/bin/remote @@ -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}" diff --git a/scripts/bin/resource-usage b/scripts/bin/resource-usage new file mode 100755 index 0000000..90fac80 --- /dev/null +++ b/scripts/bin/resource-usage @@ -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" + diff --git a/scripts/bin/restartbar b/scripts/bin/restartbar new file mode 100755 index 0000000..26da65d --- /dev/null +++ b/scripts/bin/restartbar @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +stopbar && startbar & diff --git a/scripts/bin/s b/scripts/bin/s new file mode 100755 index 0000000..37660b0 --- /dev/null +++ b/scripts/bin/s @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +N _scratch diff --git a/scripts/bin/scn b/scripts/bin/scn new file mode 100755 index 0000000..418774d --- /dev/null +++ b/scripts/bin/scn @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +EDITOR="sc-im" nf "$@" diff --git a/scripts/bin/screenshot b/scripts/bin/screenshot new file mode 100755 index 0000000..0dc661b --- /dev/null +++ b/scripts/bin/screenshot @@ -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}" diff --git a/scripts/bin/script-opts b/scripts/bin/script-opts new file mode 100755 index 0000000..54cf829 --- /dev/null +++ b/scripts/bin/script-opts @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +# TODO: helper for taking a data structure and building bash args? diff --git a/scripts/bin/scrup b/scripts/bin/scrup new file mode 100755 index 0000000..6aabed8 --- /dev/null +++ b/scripts/bin/scrup @@ -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 diff --git a/scripts/bin/scwd b/scripts/bin/scwd new file mode 100755 index 0000000..7363f62 --- /dev/null +++ b/scripts/bin/scwd @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +addon=""; [ -n "$1" ] && addon="-${1}" +echo "${PWD}" > "${DOTFILES_PATH}/.cwd${addon}.tmp" diff --git a/scripts/bin/setbg b/scripts/bin/setbg new file mode 100755 index 0000000..0541dd6 --- /dev/null +++ b/scripts/bin/setbg @@ -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" diff --git a/scripts/bin/simple-otp b/scripts/bin/simple-otp new file mode 100755 index 0000000..889fdc4 --- /dev/null +++ b/scripts/bin/simple-otp @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# TODO: check for oathtool + +key="$1"; shift +args=("$@") + +oathtool --totp=sha1 -b "$key" "${args[@]}" diff --git a/scripts/bin/source_if_exists b/scripts/bin/source_if_exists new file mode 100755 index 0000000..6ef4611 --- /dev/null +++ b/scripts/bin/source_if_exists @@ -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; } diff --git a/scripts/bin/startbar b/scripts/bin/startbar new file mode 100755 index 0000000..c1c1bc1 --- /dev/null +++ b/scripts/bin/startbar @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +"${DOTFILES_PATH}/apps/de/polybar/run" diff --git a/scripts/bin/stopbar b/scripts/bin/stopbar new file mode 100755 index 0000000..af24e17 --- /dev/null +++ b/scripts/bin/stopbar @@ -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 diff --git a/scripts/bin/sw b/scripts/bin/sw new file mode 100755 index 0000000..753bb46 --- /dev/null +++ b/scripts/bin/sw @@ -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? + diff --git a/scripts/bin/tdf b/scripts/bin/tdf new file mode 100755 index 0000000..e712a4a --- /dev/null +++ b/scripts/bin/tdf @@ -0,0 +1,2 @@ +#!/usr/bin/env fish +tmux-lyte-session dotfiles $DOTFILES_PATH diff --git a/scripts/bin/tenv b/scripts/bin/tenv new file mode 100755 index 0000000..fee13a1 --- /dev/null +++ b/scripts/bin/tenv @@ -0,0 +1,3 @@ +#!/usr/bin/env sh +d="$(command ls "$ENV_PATH" | sk)" && \ + tmux-lyte-session "env-$d" "$ENV_PATH/$d" diff --git a/scripts/bin/terminal-rendering-test b/scripts/bin/terminal-rendering-test new file mode 100755 index 0000000..667e0a5 --- /dev/null +++ b/scripts/bin/terminal-rendering-test @@ -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 diff --git a/scripts/bin/termrec b/scripts/bin/termrec new file mode 100755 index 0000000..d4a6e62 --- /dev/null +++ b/scripts/bin/termrec @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +asciinema rec -i 2 --stdin diff --git a/scripts/bin/tls b/scripts/bin/tls new file mode 100755 index 0000000..2ef55ac --- /dev/null +++ b/scripts/bin/tls @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +tmux list-sessions diff --git a/scripts/bin/tmux-edit-buffer b/scripts/bin/tmux-edit-buffer new file mode 100755 index 0000000..c24e6b9 --- /dev/null +++ b/scripts/bin/tmux-edit-buffer @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +f="$(tmux-save-buffer)" +tmux new-window "$EDITOR $f" diff --git a/scripts/bin/tmux-lyte-session b/scripts/bin/tmux-lyte-session new file mode 100755 index 0000000..8a82474 --- /dev/null +++ b/scripts/bin/tmux-lyte-session @@ -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 diff --git a/scripts/bin/tmux-save-buffer b/scripts/bin/tmux-save-buffer new file mode 100755 index 0000000..45698c8 --- /dev/null +++ b/scripts/bin/tmux-save-buffer @@ -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" diff --git a/scripts/bin/tmux-session-dir b/scripts/bin/tmux-session-dir new file mode 100755 index 0000000..105327b --- /dev/null +++ b/scripts/bin/tmux-session-dir @@ -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" diff --git a/scripts/bin/tmux-session-preview b/scripts/bin/tmux-session-preview new file mode 100755 index 0000000..0684b1c --- /dev/null +++ b/scripts/bin/tmux-session-preview @@ -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" diff --git a/scripts/bin/tmuxswitcher b/scripts/bin/tmuxswitcher new file mode 100755 index 0000000..bd51f9c --- /dev/null +++ b/scripts/bin/tmuxswitcher @@ -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 diff --git a/scripts/bin/unarchive b/scripts/bin/unarchive new file mode 100755 index 0000000..b02272e --- /dev/null +++ b/scripts/bin/unarchive @@ -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 diff --git a/scripts/bin/unbackupify b/scripts/bin/unbackupify new file mode 100755 index 0000000..bfd2c20 --- /dev/null +++ b/scripts/bin/unbackupify @@ -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" diff --git a/scripts/bin/weather b/scripts/bin/weather new file mode 100755 index 0000000..332009f --- /dev/null +++ b/scripts/bin/weather @@ -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' diff --git a/scripts/bin/work-journal-entry b/scripts/bin/work-journal-entry new file mode 100755 index 0000000..77414f1 --- /dev/null +++ b/scripts/bin/work-journal-entry @@ -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 diff --git a/scripts/bin/yamldiff b/scripts/bin/yamldiff new file mode 100755 index 0000000..fdecc6f --- /dev/null +++ b/scripts/bin/yamldiff @@ -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 .)