├── .bash_profile
├── .config
├── X11
│ └── Xmodmap
├── abook
│ └── abookrc
├── alacritty
│ └── alacritty.yml
├── bash_profile
├── beets
│ ├── .gitignore
│ └── config.yaml
├── calcurse
│ ├── conf
│ ├── hooks
│ │ ├── post-save
│ │ └── pre-load
│ └── keys
├── clone-repos.yaml
├── clone-repos
│ ├── computer-clone-repos.yaml
│ ├── hpi-clone-repos.yaml
│ ├── ranger-plugins.yaml
│ ├── todotxt-actions.yaml
│ └── update-forks.yaml
├── codespell
│ └── codespell.conf
├── cookiecutterrc
├── directories
├── dunst
│ └── dunstrc
├── flake8
├── fontconfig
│ └── conf.d
│ │ └── 01-emoji.conf
├── fzf_preview
├── gh-dash
│ └── config.yml
├── gh
│ └── config.yml
├── git_doc_history
│ ├── frinkconv
│ ├── mysql
│ ├── newsboat
│ ├── node
│ ├── plaintext_playlist
│ ├── ranger
│ └── todo
├── glow
│ └── glow.yml
├── htop
│ └── htoprc
├── hypr
│ ├── hyprland.conf
│ └── hyprlock.conf
├── i3
│ ├── config
│ ├── config.j2
│ └── config.yaml
├── i3blocks
│ ├── blocks
│ │ ├── b-battery
│ │ ├── b-calendar
│ │ ├── b-calories
│ │ ├── b-comments
│ │ ├── b-date
│ │ ├── b-mail
│ │ ├── b-mpv-description
│ │ ├── b-mpv-paused
│ │ ├── b-network
│ │ ├── b-page-hits
│ │ ├── b-reminder-sink
│ │ ├── b-reminder-sink-json
│ │ ├── b-reminders
│ │ ├── b-rss
│ │ ├── b-to-watch
│ │ ├── b-todo
│ │ ├── b-volume
│ │ ├── b-water
│ │ └── b-water-perc
│ └── config
├── inputrc
├── irbrc
├── kitty
│ ├── .gitignore
│ ├── bgproc.conf
│ ├── custom.conf
│ ├── kitty.conf
│ └── themes
│ │ ├── Dark.conf
│ │ └── Light.conf
├── lftp
│ └── rc
├── lynx
│ └── lynx.cfg
├── mpv
│ ├── input.conf
│ ├── mpv.conf
│ ├── script-opts
│ │ └── encode_web.conf
│ └── scripts
│ │ └── encode.lua
├── muttc
│ ├── mailcap
│ └── muttrc
├── my
│ ├── .gitignore
│ ├── .stignore
│ └── my
│ │ └── config
│ │ ├── __init__.py
│ │ ├── common.py
│ │ ├── feed.py
│ │ ├── pura
│ │ ├── .gitignore
│ │ ├── __init__.pyi
│ │ ├── py.typed
│ │ └── ttally_types.py
│ │ └── reorder_path.py
├── newsboat
│ └── config
├── newsraft
│ └── config
├── nsxiv
│ └── exec
│ │ ├── image-info
│ │ ├── key-handler
│ │ └── win-title
├── nvim
│ ├── .gitignore
│ ├── after
│ │ ├── ftplugin
│ │ │ ├── gitcommit.lua
│ │ │ ├── help.lua
│ │ │ ├── lua.lua
│ │ │ ├── markdown.lua
│ │ │ ├── qf.lua
│ │ │ ├── query.lua
│ │ │ ├── sshconfig.lua
│ │ │ └── zsh.lua
│ │ └── plugin
│ │ │ ├── helpers.lua
│ │ │ ├── highlight.lua
│ │ │ └── key_descriptions.lua
│ ├── init.lua
│ ├── lazy-lock.json
│ ├── lua
│ │ ├── plugins
│ │ │ ├── cloak.lua
│ │ │ ├── cmp.lua
│ │ │ ├── codeium.lua
│ │ │ ├── color.lua
│ │ │ ├── comment.lua
│ │ │ ├── conform.lua
│ │ │ ├── dial.lua
│ │ │ ├── gitsigns.lua
│ │ │ ├── init.lua
│ │ │ ├── language.lua
│ │ │ ├── lint.lua
│ │ │ ├── lsp.lua
│ │ │ ├── luasnip.lua
│ │ │ ├── mini.lua
│ │ │ ├── neogit.lua
│ │ │ ├── octo.lua
│ │ │ ├── spectre.lua
│ │ │ ├── telescope.lua
│ │ │ ├── treesitter.lua
│ │ │ ├── trouble.lua
│ │ │ └── ui.lua
│ │ └── user
│ │ │ ├── autocmds.lua
│ │ │ ├── codespell.lua
│ │ │ ├── init.lua
│ │ │ ├── key_mappings.lua
│ │ │ ├── mapping_helpers.lua
│ │ │ ├── patch_codeium.lua
│ │ │ ├── remsync.lua
│ │ │ ├── settings.lua
│ │ │ ├── snippets.lua
│ │ │ ├── telescope.lua
│ │ │ └── terminal.lua
│ ├── queries
│ │ ├── bash
│ │ │ ├── highlights.scm
│ │ │ └── injections.scm
│ │ ├── go
│ │ │ └── injections.scm
│ │ ├── markdown
│ │ │ └── injections.scm
│ │ ├── python
│ │ │ └── injections.scm
│ │ ├── query
│ │ │ └── injections.scm
│ │ └── rifleconfig
│ │ │ └── injections.scm
│ ├── selene.toml
│ ├── snippets
│ │ ├── cfg.snippets
│ │ ├── python.snippets
│ │ └── sh.snippets
│ ├── stylua.toml
│ └── vim.toml
├── picom.conf
├── plus1_blacklist.txt
├── promnesia
│ └── config.py
├── pura_lua
│ ├── pura_utils.lua
│ └── terminal_colorscheme.lua
├── pyflyby
│ └── imports.py
├── pythonrc
├── ranger
│ ├── .gitignore
│ ├── Makefile
│ ├── commands.py
│ ├── dir-aliases
│ ├── generate_filter
│ ├── generate_image_preview
│ ├── hidden_template.rc
│ ├── make
│ ├── rc.conf
│ ├── rifle.conf
│ └── scope.sh
├── rifleman
│ ├── format.conf
│ ├── image.conf
│ ├── lint.conf
│ └── run.conf
├── rofi
│ ├── config.rasi
│ └── dracula.rasi
├── scramble_history
│ ├── files.yaml
│ └── sourcemap.json
├── screenlayout
│ ├── auto.sh
│ ├── desk_dual_monitor.sh
│ └── single_laptop_screen.sh
├── shortcuts.toml
├── skhd
│ └── skhdrc
├── so
│ └── colors.toml
├── supervisord.conf
├── sway
│ └── config
├── termite
│ └── config
├── thefuck
│ └── settings.py
├── todo
│ └── config
├── tree-sitter
│ └── config.json
├── ttally.py
├── user-dirs.dirs
├── user-dirs.locale
├── waybar
│ ├── config.jsonc
│ └── style.css
├── wezterm
│ ├── clipboard.lua
│ └── wezterm.lua
├── yadm
│ ├── android_bootstrap
│ ├── bootstrap
│ ├── computer_bootstrap
│ ├── copy-system-config
│ ├── dotfiles_ignore_words.txt
│ ├── hooks
│ │ ├── commit-msg
│ │ ├── post-merge
│ │ └── pre-commit
│ ├── linux_bootstrap
│ ├── mac
│ │ ├── set-default-apps
│ │ └── set-macos-defaults
│ ├── mac_bootstrap
│ ├── package_lists
│ │ ├── Brewfile
│ │ ├── android_packages.txt
│ │ ├── arch_packages.txt
│ │ ├── arch_packages_wayland.txt
│ │ ├── arch_packages_x11.txt
│ │ ├── bash_packages.txt
│ │ ├── cargo_packages.txt
│ │ ├── computer_node_packages.txt
│ │ ├── computer_python.txt
│ │ ├── dart_packages.txt
│ │ ├── gh_extension_packages.txt
│ │ ├── go_packages.txt
│ │ ├── linux_python3_packages.txt
│ │ ├── mix_archive_packages.txt
│ │ ├── node_packages.txt
│ │ ├── ocaml_packages.txt
│ │ ├── pipx_packages.txt
│ │ ├── python3_packages.txt
│ │ ├── ruby_packages.txt
│ │ └── wsl_packages.txt
│ ├── windows_bootstrap
│ └── yadm-with-README.md
└── zsh
│ ├── .gitignore
│ ├── .zshrc
│ ├── aliases
│ ├── aliases
│ ├── dev_aliases
│ ├── git_aliases
│ └── project_aliases
│ ├── android.zsh
│ ├── cache_aliases.zsh
│ ├── cd.zsh
│ ├── completion.zsh
│ ├── completions
│ ├── _binary_completion
│ ├── _plainplay
│ ├── _services
│ ├── _trackpad
│ ├── _transparent
│ └── _volume
│ ├── env_config.zsh
│ ├── functions.zsh
│ ├── functions
│ ├── add-to-path
│ ├── cdp
│ ├── cdtmp
│ ├── duck
│ ├── fkill
│ ├── flocate
│ ├── fpick
│ ├── fwait
│ ├── mkcd
│ ├── ranger
│ ├── tm
│ ├── tmpick
│ ├── update
│ └── which-cat
│ ├── generate_completion
│ ├── global_env.sh
│ ├── hpi.zsh
│ ├── lazy.zsh
│ ├── linux.zsh
│ ├── mac.zsh
│ ├── progressive_enhancement.zsh
│ ├── prompt.zsh
│ ├── source_aliases.zsh
│ ├── ssh.zsh
│ ├── updates.zsh
│ └── windows.zsh
├── .gitignore
├── .keynavrc
├── .local
├── scripts
│ ├── README.md
│ ├── cross-platform
│ │ ├── attached-to-terminal
│ │ ├── editor
│ │ ├── launch
│ │ ├── lock-screen
│ │ ├── playping
│ │ └── print-or-notify
│ ├── generic
│ │ ├── abz
│ │ ├── albumify-singles
│ │ ├── ansicolors
│ │ ├── audio2m4a
│ │ ├── audio2mp3
│ │ ├── audio2ogg
│ │ ├── audio2wav
│ │ ├── audio2wavmono
│ │ ├── audio2webm
│ │ ├── audio2wma
│ │ ├── auto-subtitle-install
│ │ ├── autoformat-json
│ │ ├── backup-keepass-db
│ │ ├── basher-upgrade-all
│ │ ├── bashx
│ │ ├── beet-search
│ │ ├── birthdays
│ │ ├── blurred-html
│ │ ├── bookmark-open
│ │ ├── calcurse-nth
│ │ ├── calcurse-upcoming
│ │ ├── center-text
│ │ ├── chafa-cache
│ │ ├── click-repeat
│ │ ├── clp
│ │ ├── compile
│ │ ├── copy-status
│ │ ├── cstimer
│ │ ├── current-week
│ │ ├── datenow
│ │ ├── decode64
│ │ ├── describe-evry-json
│ │ ├── dict
│ │ ├── discord-currently-listening-presence
│ │ ├── discord-suppress
│ │ ├── docx-md
│ │ ├── dragon-sink
│ │ ├── edit-github-readme
│ │ ├── emoji
│ │ ├── env-shebangs
│ │ ├── exifalbumrename
│ │ ├── exifattr
│ │ ├── exifinfo
│ │ ├── favorite-picture
│ │ ├── ffmpeg-then-notify
│ │ ├── figlet-one-line
│ │ ├── file-modified-ago
│ │ ├── file-modified-within
│ │ ├── flipflop.py
│ │ ├── generate-subs
│ │ ├── genpass
│ │ ├── ghstars
│ │ ├── gifpreview
│ │ ├── git-has-untracked-or-changes
│ │ ├── git-https-ssh-swap
│ │ ├── git-swap-remote
│ │ ├── github-linguist
│ │ ├── giturl
│ │ ├── give
│ │ ├── google-contacts-csv-extract
│ │ ├── gpxsplit
│ │ ├── gron-to-csv
│ │ ├── havecmd
│ │ ├── heart
│ │ ├── how-old-am-i
│ │ ├── image-shrink
│ │ ├── in-path
│ │ ├── install-nerd-font
│ │ ├── jqc
│ │ ├── jsonc-to-json
│ │ ├── jumplist
│ │ ├── kindle-send
│ │ ├── linkhandler
│ │ ├── list-git-dirs
│ │ ├── list-my-git-repos
│ │ ├── localize-datetimes
│ │ ├── macho
│ │ ├── mal_sources_toggle
│ │ ├── manual_on_os
│ │ ├── mbox-email-date
│ │ ├── mbox-extract-text
│ │ ├── mpv-album-playback
│ │ ├── mpv-ffmpeg-extract
│ │ ├── mpv-pause-all
│ │ ├── mpv_signal_daemon
│ │ ├── ms
│ │ ├── mv-classify-videos-by-rotation
│ │ ├── norg-to-markdown
│ │ ├── nth-of-the-month
│ │ ├── optigif
│ │ ├── optijpg
│ │ ├── org-to-md
│ │ ├── photo-doc
│ │ ├── photos-unsync-recent
│ │ ├── picofy
│ │ ├── plainplay-m3u
│ │ ├── print-json
│ │ ├── prompt_type
│ │ ├── prune-folders-without-ext
│ │ ├── qr
│ │ ├── recompress-zip
│ │ ├── reminder-sink-silence
│ │ ├── remove-leading-spaces
│ │ ├── rename-image-dt
│ │ ├── rename-mpv-images
│ │ ├── repos-dirty
│ │ ├── repos-list
│ │ ├── repos-pull-all
│ │ ├── rg-nvim
│ │ ├── rifleman-extract
│ │ ├── rread
│ │ ├── run_window_watcher
│ │ ├── server_clipboard_notify
│ │ ├── setup-cfg-fmt-tempfile
│ │ ├── show-pickle
│ │ ├── sign-canvas
│ │ ├── spell-dotfiles
│ │ ├── srt-to-text
│ │ ├── star
│ │ ├── status-code
│ │ ├── sub-rename
│ │ ├── super
│ │ ├── sync-conflicts
│ │ ├── terminal-set-theme
│ │ ├── tiktok-local-rss
│ │ ├── timer-till
│ │ ├── tmux-kill-detached
│ │ ├── to-github
│ │ ├── to-gitlab
│ │ ├── to-json-objects
│ │ ├── todo-new
│ │ ├── todo-prompt
│ │ ├── todos
│ │ ├── treesitter-not-ensured
│ │ ├── ttt
│ │ ├── tttlist
│ │ ├── unstarred-nvim-plugins
│ │ ├── update-my-stars
│ │ ├── urlhandler
│ │ ├── urlview
│ │ ├── video2avi
│ │ ├── video2mkv
│ │ ├── video2mp4
│ │ ├── video2mp4-1080p
│ │ ├── video2mp4-rotate
│ │ ├── video2mpg
│ │ ├── video2webm
│ │ ├── videomp4-hardsub
│ │ ├── vimdiff-syncthing-conflict
│ │ ├── vitamin
│ │ ├── wait-till-files
│ │ ├── water-should-drink
│ │ ├── wca-comps
│ │ ├── wca-upcoming-competitions
│ │ ├── weather
│ │ ├── windows-ppas
│ │ ├── with-secrets
│ │ ├── youtube-dl-section
│ │ ├── youtube-thumbnail
│ │ ├── youtube-user-id
│ │ └── youtube-user-rss-feed
│ ├── linux
│ │ ├── afk
│ │ ├── battery
│ │ ├── brightness
│ │ ├── check-music-extensions
│ │ ├── colorize_number
│ │ ├── cstimer-server
│ │ ├── flashlight
│ │ ├── flatpak-run
│ │ ├── focused-screen-index
│ │ ├── focused-screen-resolution
│ │ ├── gammastep-loc
│ │ ├── gpg_autoclick
│ │ ├── housekeeping
│ │ ├── housekeeping-info
│ │ ├── housekeeping-offline
│ │ ├── hy
│ │ ├── i3-is-floating-window
│ │ ├── i3-launcher
│ │ ├── i3-picture-in-picture
│ │ ├── i3-resize
│ │ ├── i3-sticky
│ │ ├── i3blocks-parse-signals
│ │ ├── i3blocks-refresh
│ │ ├── i3blocks-refresh-all
│ │ ├── i3blocks-refresh-mk
│ │ ├── i3blocks-refresh-mpv
│ │ ├── i3blocks-watch-mpv-daemon-logs
│ │ ├── image-working-dir
│ │ ├── launch-waybar
│ │ ├── linux_tasks
│ │ ├── mailsync-loop
│ │ ├── main-screen-resolution
│ │ ├── mpv-last-screenshot
│ │ ├── notify-mpv-song-description
│ │ ├── randomize-wallpaper
│ │ ├── redshift-loc
│ │ ├── refresh-block
│ │ ├── restic-backup
│ │ ├── screenshot
│ │ ├── services
│ │ ├── sonic-pi-run
│ │ ├── stream-media
│ │ ├── sw
│ │ ├── sway-display-off
│ │ ├── sway-resize
│ │ ├── termcolors
│ │ ├── tiktok-update-rss-feeds
│ │ ├── timedatectl-timezone
│ │ ├── timezone-has-changed
│ │ ├── trackpad
│ │ ├── trackpad-tap-to-click
│ │ ├── transparent
│ │ ├── update-rss
│ │ ├── volume
│ │ ├── warn-battery
│ │ ├── waybar-refresh-all
│ │ ├── waybar-refresh-block
│ │ ├── waybar-signals
│ │ ├── webcam-pic
│ │ └── xmodmap-reset
│ ├── notes_rendered
│ │ ├── Makefile
│ │ └── cache-srt-to-text
│ ├── reminder-sink
│ │ ├── flipflop
│ │ ├── guestbook
│ │ ├── last-export-dates
│ │ └── listen_to_album
│ ├── supervisor_jobs
│ │ ├── all
│ │ │ ├── cached_repo_bases.job
│ │ │ ├── offline_listens_cache.job
│ │ │ ├── promnesia_index.job
│ │ │ ├── pull_dotfiles.job
│ │ │ ├── sync_datafiles.job
│ │ │ └── ttally_cache.job
│ │ ├── android
│ │ │ ├── backup_images.job
│ │ │ ├── create_playlists.job
│ │ │ └── delete_trash.job
│ │ └── linux
│ │ │ ├── build_exobrain.job
│ │ │ ├── copy_images.job
│ │ │ ├── generate_notes_journal_vlogs.job
│ │ │ ├── linkmusic.job
│ │ │ ├── my_feed_index_bg.job
│ │ │ ├── mystars.job
│ │ │ ├── tiktok.job
│ │ │ ├── update_rss.job
│ │ │ └── warn_mailsync.job
│ └── todo-actions
│ │ ├── Makefile
│ │ ├── full
│ │ └── interactive
├── share
│ ├── firefox_addons.txt
│ ├── gpg_autoclick
│ │ ├── ok.png
│ │ └── tick_box.png
│ ├── ipython
│ │ ├── profile_calculator
│ │ │ └── startup
│ │ │ │ └── 00-load-modules.py
│ │ └── profile_default
│ │ │ └── startup
│ │ │ └── 00-pyflyby.ipy
│ └── shortcuts
│ │ ├── abookc
│ │ ├── alacritty-tmux
│ │ ├── alarm
│ │ ├── albums
│ │ ├── beet-export-all
│ │ ├── beet-fix-renamed-files
│ │ ├── boxes-nvim
│ │ ├── boxes-python
│ │ ├── boxes-vim
│ │ ├── calcursed
│ │ ├── camera
│ │ ├── cheat
│ │ ├── cl
│ │ ├── cl-quickfix
│ │ ├── clipedit
│ │ ├── clipreset
│ │ ├── clp-args
│ │ ├── clr
│ │ ├── clrs
│ │ ├── codespell-conf
│ │ ├── core
│ │ ├── create-youtube-dl-resolution-str
│ │ ├── curdir
│ │ ├── current-city
│ │ ├── cycle
│ │ ├── dark-theme
│ │ ├── discogs-search
│ │ ├── discord-browser
│ │ ├── dotfiles
│ │ ├── draglastpic
│ │ ├── drive-mount
│ │ ├── ec
│ │ ├── edit-clipboard
│ │ ├── exo-web
│ │ ├── extracturls
│ │ ├── fdf
│ │ ├── feed-open
│ │ ├── file-mime
│ │ ├── flake8c
│ │ ├── fzf-edit
│ │ ├── fzfp
│ │ ├── genpass-phrase
│ │ ├── gi
│ │ ├── git-color
│ │ ├── google-chrome-wifi-captive
│ │ ├── google-search
│ │ ├── grep-dotfiles
│ │ ├── heart-cl
│ │ ├── html-head-all
│ │ ├── i3-jinja
│ │ ├── i3binds
│ │ ├── i3binds-prompt
│ │ ├── img-download-drag
│ │ ├── ipinfo
│ │ ├── largechar-clipboard
│ │ ├── lastpic
│ │ ├── lastpicdrag
│ │ ├── lastpicpreview
│ │ ├── lessi
│ │ ├── light-theme
│ │ ├── list-config
│ │ ├── list-config-no-hist
│ │ ├── list-images
│ │ ├── list-videos
│ │ ├── listens-desc
│ │ ├── longest-video
│ │ ├── lynx
│ │ ├── lynx-dump
│ │ ├── lynx-from-stdin
│ │ ├── mal-recent
│ │ ├── markdown-list
│ │ ├── mediasearch
│ │ ├── moviesearch
│ │ ├── moviesearch-letterboxd
│ │ ├── moviesearch-trakt
│ │ ├── mpv-corner
│ │ ├── mpv-drag-screenshot
│ │ ├── mpv-last-screenshot-upload
│ │ ├── mpv-logfile
│ │ ├── mtotal
│ │ ├── mvlastpic
│ │ ├── mypy-single-lines
│ │ ├── mystarsfzf
│ │ ├── mz
│ │ ├── neomuttr
│ │ ├── pinta
│ │ ├── pipehtml
│ │ ├── play-music
│ │ ├── play-shortest-video
│ │ ├── playping-loop
│ │ ├── primes
│ │ ├── printer-server
│ │ ├── pygmentize-html-style
│ │ ├── pygmentize-styles
│ │ ├── qf
│ │ ├── qr-clipboard
│ │ ├── realbasename
│ │ ├── reload-browser
│ │ ├── reminder-sink-notify
│ │ ├── render-notes
│ │ ├── repos
│ │ ├── reshortcuts
│ │ ├── rgqf
│ │ ├── rj
│ │ ├── screenshot-upload
│ │ ├── screenshots
│ │ ├── shortest-video
│ │ ├── shuffle-music
│ │ ├── sort-by-line-length
│ │ ├── spell
│ │ ├── spell-fd
│ │ ├── spell-interactive
│ │ ├── spell-list
│ │ ├── sqlitebrowser-
│ │ ├── ssh-keygen-good
│ │ ├── stream-audio
│ │ ├── stream-corner
│ │ ├── stream-corner-1080
│ │ ├── stream-corner-480
│ │ ├── stream-corner-720
│ │ ├── stream-corner-at
│ │ ├── stream-from-firefox
│ │ ├── styluac
│ │ ├── sync-neomutt
│ │ ├── syncgui
│ │ ├── synonym
│ │ ├── text2html
│ │ ├── timer-till-playping
│ │ ├── tmpfile
│ │ ├── to-icon
│ │ ├── todo
│ │ ├── trakt-progress
│ │ ├── tstamp
│ │ ├── tvsearch
│ │ ├── twitch-stream
│ │ ├── tz
│ │ ├── unicode
│ │ ├── unlines
│ │ ├── up-live
│ │ ├── update-forks
│ │ ├── url-echo-redirect
│ │ ├── urldrag
│ │ ├── urlpicpreview
│ │ ├── usdate
│ │ ├── vic
│ │ ├── vix
│ │ ├── watchtwitch
│ │ ├── webcam-pic
│ │ ├── webcam-test
│ │ ├── wfi
│ │ ├── wfib
│ │ ├── which-cat
│ │ ├── yadm-format
│ │ ├── yadm-lint
│ │ ├── yh
│ │ ├── youtube-dl
│ │ ├── youtube-dl-480
│ │ ├── youtube-dl-720
│ │ └── youtube-dl-at
└── system-config
│ └── etc
│ ├── X11
│ └── xorg.conf.d
│ │ ├── 20-amdgpu.conf
│ │ └── 30-trackpad-options.conf
│ ├── pacman.conf
│ ├── pacman.d
│ └── hooks
│ │ └── mirrorupgrade.hook
│ ├── systemd
│ └── system
│ │ └── lockscreen@.service
│ └── tlp.conf
├── .profile
├── .termux
├── colors.properties
└── termux.properties
├── .tmux.conf
├── .xinitrc
└── README.md
/.bash_profile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # bash is usually called from zsh to do some testing, so don't do path configuration
4 |
5 | export HISTTIMEFORMAT="%s "
6 | export HISTFILESIZE=-1
7 | export HISTSIZE=-1
8 | shopt -s histappend # dont overwrite history
9 | shopt -s cmdhist # save al-lines of multi-line commands in the same entry
10 | shopt -s lithist # embedded newlines for multi-line commands
11 |
12 | source "${HOME}/.config/zsh/source_aliases.zsh" 2>/dev/null
13 |
--------------------------------------------------------------------------------
/.config/X11/Xmodmap:
--------------------------------------------------------------------------------
1 | remove Lock = Caps_Lock
2 | keysym Caps_Lock = Escape
3 |
--------------------------------------------------------------------------------
/.config/beets/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !config.yaml
4 |
--------------------------------------------------------------------------------
/.config/calcurse/conf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/purarue/dotfiles/77843d62e8357579d7e8c8e3cd0033cfce803ff6/.config/calcurse/conf
--------------------------------------------------------------------------------
/.config/calcurse/hooks/post-save:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd "$(dirname "$0")" || exit 1
4 |
5 | python3 -m calcurse_load --post-save todotxt >/dev/null 2>&1
6 |
--------------------------------------------------------------------------------
/.config/calcurse/hooks/pre-load:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | cd "$(dirname "$0")" || exit 1
4 |
5 | python3 -m calcurse_load --pre-load gcal --pre-load todotxt --pre-load json >/dev/null 2>&1
6 |
--------------------------------------------------------------------------------
/.config/clone-repos/hpi-clone-repos.yaml:
--------------------------------------------------------------------------------
1 | "https://github.com/purarue/HPI":
2 | # this install script also HPI-karlicoss, git clones into the directory
3 | # its already managed there because it was needed for CI
4 | postinstall: ./install
5 | "https://github.com/purarue/HPI-personal":
6 | postinstall: ./install
7 | "https://github.com/purarue/HPI-fork":
8 | dirname: "HPI-karlicoss" # name of directory to clone into
9 | postinstall:
10 | - pip install pyfzf_iter logzero colorlog cachew
11 | - python3 -c 'import my.config'
12 | - git remote add upstream "https://github.com/karlicoss/HPI"
13 | pipefail: false # don't fail if the postinstall commands fail
14 |
--------------------------------------------------------------------------------
/.config/clone-repos/ranger-plugins.yaml:
--------------------------------------------------------------------------------
1 | "https://github.com/alexanderjeurissen/ranger_devicons":
2 | base: ~/.config/ranger/plugins/
3 | postinstall: "git pull"
4 |
--------------------------------------------------------------------------------
/.config/clone-repos/todotxt-actions.yaml:
--------------------------------------------------------------------------------
1 | "https://git.sr.ht/~proycon/todotxt-more":
2 | base: ~/.cache/todotxt-addons/
3 | preinstall: git pull
4 | postinstall:
5 | - pip install -r ./requirements.txt
6 | - rsync -Pavh ./todo.actions.d/ "$HOME/.local/share/todo-actions/"
7 | - sed -i -e 's#0 - Start task.*#\\#' "$HOME/.local/share/todo-actions/actionmenu" # patch actionmenu to remove the first option (timetrack), this makes complete the default option
8 |
--------------------------------------------------------------------------------
/.config/clone-repos/update-forks.yaml:
--------------------------------------------------------------------------------
1 | "https://github.com/purarue/HPI-fork":
2 | dirname: "HPI-karlicoss"
3 | preinstall: git pull
4 | postinstall:
5 | - git checkout master
6 | - git pull
7 | - git pull upstream master
8 | - git push
9 | pipefail: true
10 | "https://github.com/purarue/promnesia-fork":
11 | preinstall: git pull
12 | postinstall:
13 | - git checkout master
14 | - git pull
15 | - git pull upstream master
16 | - git push
17 | pipefail: true
18 | "https://github.com/purarue/bleanser-fork":
19 | preinstall: git pull
20 | postinstall:
21 | - git checkout master
22 | - git pull
23 | - git pull upstream master
24 | - git push
25 | pipefail: true
26 |
--------------------------------------------------------------------------------
/.config/codespell/codespell.conf:
--------------------------------------------------------------------------------
1 | # vim: ft=dosini
2 | # this is not an official location for the codespell config file,
3 | # I just have a wrapper script that does:
4 | # codespell --config-file ~/.config/codespell/codespell.conf
5 | # https://purarue.xyz/d/codespell-conf?dark
6 | [codespell]
7 | skip = *.lock
8 |
--------------------------------------------------------------------------------
/.config/cookiecutterrc:
--------------------------------------------------------------------------------
1 | default_context:
2 |
--------------------------------------------------------------------------------
/.config/directories:
--------------------------------------------------------------------------------
1 | # shortcuts to commonly used directories
2 | # used in dir-aliases-ranger
3 | # to create bookmarks
4 | D ~/Documents
5 | M ~/Movies
6 | S ~/Pictures/Screenshots
7 | e ~/.local/share/evry/data/
8 | b ~/Files/Books
9 | d ~/Downloads
10 | f ~/Documents/PicturesFavorites
11 | m ~/Music
12 | n ~/Documents/Notes
13 | p ~/data/playlists
14 | P ~/Pictures
15 | r ~/Repos
16 | s ~/Downloads/Sort
17 | y ~/.config/yadm
18 | z ~/.config/zsh
19 |
--------------------------------------------------------------------------------
/.config/flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E501,E402,W503,E266,E203
3 |
--------------------------------------------------------------------------------
/.config/fontconfig/conf.d/01-emoji.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Noto Emoji
7 | emoji
8 |
9 |
10 | Noto Color Emoji
11 | emoji
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.config/gh/config.yml:
--------------------------------------------------------------------------------
1 | # What protocol to use when performing git operations. Supported values: ssh, https
2 | git_protocol: https
3 | # What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.
4 | editor:
5 | # When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
6 | prompt: enabled
7 | # A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager.
8 | pager:
9 | # Aliases allow you to create nicknames for gh commands
10 | aliases:
11 | co: pr checkout
12 | rc: repo create
13 | prc: pr create
14 | rcl: repo clone
15 | ci: run watch
16 | version: "1"
17 |
--------------------------------------------------------------------------------
/.config/git_doc_history/frinkconv:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.local/share/frinkconv
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/frinkconv_history"
3 | COPY_FILES="history.txt"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/mysql:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.cache
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/mysql_history"
3 | COPY_FILES="mysql_history"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/newsboat:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.config/newsboat
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/newsboat_git"
3 | COPY_FILES="urls"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/node:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.cache
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/node_repl"
3 | COPY_FILES="node_repl_history"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/plaintext_playlist:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.cache
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/plaintext_playlist_history"
3 | COPY_FILES="plaintext_playlist_history.txt"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/ranger:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/.local/share/ranger
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/ranger"
3 | COPY_FILES="history"
4 |
--------------------------------------------------------------------------------
/.config/git_doc_history/todo:
--------------------------------------------------------------------------------
1 | SOURCE_DIR=~/data/todo # copy from
2 | BACKUP_DIR="${HPIDATA}/doc/${ON_OS}/todo_git_history" # copy to
3 | COPY_FILES="todo.txt
4 | done.txt"
5 |
--------------------------------------------------------------------------------
/.config/glow/glow.yml:
--------------------------------------------------------------------------------
1 | # style name or JSON path (default "auto")
2 | style: "auto"
3 | # show local files only; no network (TUI-mode only)
4 | local: true
5 | # mouse support (TUI-mode only)
6 | mouse: false
7 | # use pager to display markdown
8 | pager: false
9 |
--------------------------------------------------------------------------------
/.config/hypr/hyprlock.conf:
--------------------------------------------------------------------------------
1 | # BACKGROUND
2 | background {
3 | monitor =
4 | path = ~/Files/wallpaper.png
5 | blur_passes = 2
6 | contrast = 0.8916
7 | brightness = 0.8172
8 | vibrancy = 0.1696
9 | vibrancy_darkness = 0.0
10 | }
11 |
12 | # GENERAL
13 | general {
14 | no_fade_in = false
15 | no_fade_out = true
16 | grace = 1
17 | disable_loading_bar = false
18 | hide_cursor = true
19 | ignore_empty_input = true
20 | }
21 |
22 | # INPUT FIELD
23 | input-field {
24 | monitor =
25 | size = 250, 80
26 | outer_color = rgba(0, 0, 0, 0)
27 | inner_color = rgba(0, 0, 0, 0.3)
28 | font_color = rgb(200, 200, 200)
29 | placeholder_text = '...'
30 | fade_on_empty = true
31 | hide_input = false
32 | position = 0, -120
33 | halign = center
34 | valign = center
35 | }
36 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-calories:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # how many calories I've eaten today
3 |
4 | [[ -n "$BLOCK_BUTTON" ]] && clrs
5 |
6 | {
7 | ttally recent food -o json "${@:-1d}" | jq -r '(.quantity)*(.calories)'
8 | echo 0
9 | } | datamash sum 1 | cut -d'.' -f1
10 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-comments:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # https://purarue.xyz/
3 | # display a count if I have any unapproved comments on my website
4 |
5 | # remove the https://github.com/purarue/evry
6 | # file onclick, causes https://github.com/purarue/bgproc/blob/master/personal_jobs/guestbook_comments.job
7 | # to run again in the next minute or so, which updates the icon
8 | [ -n "$BLOCK_BUTTON" ] && rm -f "$(evry location -guestbook_comments)"
9 |
10 | colorize_number <"${HOME}/.cache/guestbook-comments"
11 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-date:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | case $BLOCK_BUTTON in
4 | 1) notify-send --expire-time=20000 "$(cal)" ;;
5 | 3) notify-send --expire-time=20000 "$(cal -n 2 | cut -c 23-)" ;;
6 | esac
7 |
8 | date '+%b %d (%a) %I:%M%p'
9 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-mail:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://github.com/LukeSmithxyz/voidrice/blob/master/.local/bin/statusbar/sb-mailbox
3 |
4 | # background job checks if mailsync hasn't run in a
5 | # while and creates this file
6 | MAILSYNC_WARN_FILE="${HOME}/.cache/mailsync_warn"
7 |
8 | # if I click with any button, remove the warn file
9 | [[ -n "$BLOCK_BUTTON" ]] && rm -f "${MAILSYNC_WARN_FILE}"
10 |
11 | case $BLOCK_BUTTON in
12 | 3) setsid launch neomuttr ;;
13 | esac
14 |
15 | if [[ -f "${MAILSYNC_WARN_FILE}" ]]; then
16 | echo 'RUN MAILSYNC!'
17 | exit 0
18 | fi
19 |
20 | unread="$(find "${XDG_DATA_HOME:-$HOME/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/ -type f | wc -l 2>/dev/null)"
21 |
22 | if [[ "${unread}" == "0" ]]; then
23 | echo "📪0"
24 | else
25 | printf '📬%s\n' "$(colorize_number "${unread}")"
26 | fi
27 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-mpv-description:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # grab the description -- if nothing is playing; exit
4 | desc="$(MPV_DESC_SKIP_ALBUM=1 mpv-song-description-py 2>/dev/null)" || exit 0
5 | # escape HTML characters (otherwise & in artist names breaks this)
6 | # truncate lines over 70 characters
7 | sed 's_&_&_g; s_<_<_g; s_>_>_g; s/\(.\{67\}\).*/\1.../' <<<"$desc"
8 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-mpv-paused:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # list any paused mpv instances, so I remember I have stuff paused
3 | # waiting in the background
4 |
5 | case "$BLOCK_BUTTON" in
6 | 1)
7 | # left click: send a location of currently playing media
8 | notify-send "$(mpv-currently-playing --all)"
9 | ;;
10 | 3)
11 | # cycle play/pause on current mpv instance
12 | mpv-play-pause >/dev/null 2>&1
13 | i3blocks-refresh-mpv >/dev/null
14 | ;;
15 | esac
16 |
17 | paused_count="$(diff -y --suppress-common-lines <(mpv-currently-playing --socket) <(mpv-active-sockets) | wc -l)"
18 |
19 | colorize_number "${paused_count}"
20 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-network:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # opens rofi interface for networkmanager on click
3 |
4 | # onclick, open networkmanager menu in rofi
5 | [ "$BLOCK_BUTTON" = "3" ] && networkmanager_dmenu
6 |
7 | iwgetid -r || echo "no connection..."
8 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-page-hits:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [[ -n "$BLOCK_BUTTON" ]]; then
4 | notify 'page-hits' 'updating...'
5 | update-recent-page-hits >/dev/null 2>&1
6 | fi
7 |
8 | today="$(date +'%Y-%m-%d')"
9 | jq <"$XDG_CACHE_HOME/recent_page_hits.json" '.epochs.[]' -r | dateq parse - | grep -c "$today"
10 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-reminder-sink:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | case "${BLOCK_BUTTON}" in
4 | 1)
5 | reminder-sink-notify
6 | ;;
7 | 3)
8 | launch reminder-sink-silence
9 | ;;
10 | esac
11 |
12 | reminder-sink run | wc -l | colorize_number
13 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-reminder-sink-json:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | items="$(reminder-sink run)"
4 | if [[ -z "$items" ]]; then
5 | count=0
6 | else
7 | count="$(awk 'NF > 0 { count++ } END { print count }' <<<"$items")"
8 | fi
9 | text="$(colorize_number "$count")"
10 | exec jq --null-input --compact-output --raw-output --monochrome-output --arg text " $text" --arg items "$items" '{"text": $text, "tooltip": $items}'
11 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-reminders:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # checks the bgproc (my background process manager) cachefile
3 | # to make no tasks are hanging
4 | # also reminds me to run housekeeping (https://purarue.xyz/d/.local/scripts/linux/housekeeping?redirect)
5 | # if it hasn't been run in the last day
6 |
7 | declare OUT=''
8 | OUT="$({
9 | ttally_warnings
10 | file-modified-within ~/.cache/bgproc.lastrun 1h || echo " bgproc"
11 | file-modified-within ~/.cache/housekeeping.lastrun 1d || echo " housekeeping"
12 | file-modified-within ~/.cache/restic-backup.lastrun 7d || echo " restic-backup"
13 | } | paste -sd' ')"
14 |
15 | if [[ -n "$OUT" ]]; then
16 | printf "%s\n" "$OUT"
17 | fi
18 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-rss:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # If clicked, updates rss
3 | # Else, prints the number of unread RSS items from
4 | # the cached info in ~/.cache/rss-unread
5 |
6 | case "$BLOCK_BUTTON" in
7 | 1)
8 | notify "Updating RSS feeds..."
9 | wait-for-internet >/dev/null 2>&1
10 | if update-rss; then
11 | notify "Updated RSS feeds"
12 | else
13 | notify -u critical "Couldn't update RSS feeds..."
14 | fi
15 | ;;
16 | 3)
17 | # https://purarue.xyz/d/cross-platform/launch?dark
18 | # https://purarue.xyz/d/newsraft-force?dark
19 | launch newsraft-force
20 | ;;
21 | esac
22 |
23 | colorize_number <"${HOME}/.cache/rss-unread"
24 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-to-watch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | [[ "$BLOCK_BUTTON" == 1 ]] && notify "$(to-watch duration) minutes"
4 |
5 | to-watch || true
6 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-todo:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ -n "$1" ]; then
4 | TODO_DIR="$XDG_DOCUMENTS_DIR/todos/$1"
5 | fi
6 |
7 | if [ -z "$TODO_DIR" ]; then
8 | notify -u critical "TODO_DIR not set"
9 | fi
10 |
11 | case "$BLOCK_BUTTON" in
12 | 1)
13 | todo.sh interactive
14 | ;;
15 | 3)
16 | launch 'todo.sh full'
17 | ;;
18 | esac
19 |
20 | COUNT="$(chomp <"${TODO_DIR}/todo.txt" | wc -l)"
21 | SYNC_CONFLICTS="$(sync-conflicts "$TODO_DIR" | wc -l)"
22 |
23 | if [ "$SYNC_CONFLICTS" -gt 0 ]; then
24 | echo "$COUNT "
25 | else
26 | echo "$COUNT"
27 | fi
28 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-volume:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # https://github.com/LukeSmithxyz/voidrice/blob/archi3/.local/bin/statusbar/volume
3 |
4 | [ "$(pamixer --get-mute)" = "true" ] && printf "🔇\\n" && exit
5 |
6 | vol=$(pamixer --get-volume | tr -d "\n")
7 |
8 | if [ "$vol" -gt "70" ]; then
9 | icon="🔊"
10 | elif [ "$vol" -lt "30" ]; then
11 | icon="🔈"
12 | else
13 | icon="🔉"
14 | fi
15 |
16 | printf "%s %s%%\\n" "$icon" "$vol"
17 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-water:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # how many water I've drank today
3 |
4 | {
5 | ttally recent food -o json "${@:-1d}" | jq '(.quantity)*(.water)'
6 | echo 0
7 | } | datamash sum 1 | cut -d'.' -f1
8 |
--------------------------------------------------------------------------------
/.config/i3blocks/blocks/b-water-perc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Set default value for the HTML flag
4 | declare WATER SHOULD print_html=''
5 |
6 | # Check if the '-h' flag is present
7 | if [[ "$1" == "-h" ]]; then
8 | print_html=1
9 | fi
10 |
11 | WATER="$(b-water)"
12 | SHOULD="$(water-should-drink)"
13 |
14 | if [[ "$WATER" -lt "$SHOULD" ]]; then
15 | if [[ -n "$print_html" ]]; then
16 | printf '%d/%d\n' "$WATER" "$SHOULD"
17 | else
18 | printf '%d/%d\n' "$WATER" "$SHOULD"
19 | fi
20 | else
21 | printf '%d/%d\n' "$WATER" "$SHOULD"
22 | fi
23 |
--------------------------------------------------------------------------------
/.config/inputrc:
--------------------------------------------------------------------------------
1 | set editing-mode vi
2 |
--------------------------------------------------------------------------------
/.config/irbrc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | # custom irbrc to change ruby history location
4 | # frozen_string_literal: true
5 |
6 | require 'irb'
7 | IRB.conf[:SAVE_HISTORY] = 1000
8 | IRB.conf[:HISTORY_FILE] = "#{ENV['XDG_CACHE_HOME']}/irb_history"
9 | IRB.start
10 |
--------------------------------------------------------------------------------
/.config/kitty/.gitignore:
--------------------------------------------------------------------------------
1 | current-theme.conf
2 | # this is generated by 'yadm bootstrap', and just
3 | # includes the current theme
4 | #
5 | # that file changes whenver I change my theme so its
6 | # not useful to sync to git
7 | #
8 | # it looks like:
9 | #
10 | # # BEGIN_KITTY_THEME
11 | # # Light
12 | # include current-theme.conf
13 | # # END_KITTY_THEME
14 | theme.conf
15 |
--------------------------------------------------------------------------------
/.config/kitty/bgproc.conf:
--------------------------------------------------------------------------------
1 | action_alias rJ launch_window with-secrets rj -o
2 | action_alias hk launch_window with-secrets housekeeping-offline
3 |
4 | # launch housekeeping/bgproc_on_machine simultaneously in 8 windows
5 | # typically I run this when first booting my machine, to run all my jobs in parallel quickly
6 | map kitty_mod+p>kitty_mod+u combine : rJ : rJ : rJ : rJ : hk : hk : hk : hk : goto_layout grid
7 |
8 |
--------------------------------------------------------------------------------
/.config/kitty/custom.conf:
--------------------------------------------------------------------------------
1 | # custom bindings in a separate file so they're easier to find
2 | #: Browse output of the last shell command in pager
3 |
4 | map kitty_mod+r launch_window ranger
5 | map kitty_mod+e launch_window editor
6 | map kitty_mod+x send_text all CD-Repos\r
7 |
8 | map kitty_mod+o show_last_command_output
9 |
10 | action_alias copy_last_cmd_output launch --stdin-source=@last_cmd_output --type=clipboard
11 |
12 | # Copy output of last command to clipboard
13 | map kitty_mod+g copy_last_cmd_output
14 |
15 | # custom command to send last buffer to a quickfix list
16 | # https://purarue.xyz/d/cl-quickfix?dark
17 | map kitty_mod+p>kitty_mod+q combine : copy_last_cmd_output : launch_window cl-quickfix
18 |
--------------------------------------------------------------------------------
/.config/lftp/rc:
--------------------------------------------------------------------------------
1 | set ssl:verify-certificate no
2 |
--------------------------------------------------------------------------------
/.config/mpv/input.conf:
--------------------------------------------------------------------------------
1 | # increase subtitle font size
2 | ALT+k add sub-scale +0.1
3 |
4 | # decrease subtitle font size
5 | ALT+j add sub-scale -0.1
6 |
7 | # encode.lua
8 | # https://github.com/occivink/mpv-scripts/tree/master
9 | e script-message-to encode set-timestamp encode_web
10 |
11 | # vim:ft=conf
12 |
--------------------------------------------------------------------------------
/.config/mpv/mpv.conf:
--------------------------------------------------------------------------------
1 | # most recent mpv instance connects to socket
2 | # to be controllable through socat
3 | # see mpv --list-properties
4 | # https://stackoverflow.com/q/35013075/9348376
5 | # https://stackoverflow.com/q/62582594/9348376
6 | # input-ipc-server=/tmp/mpvsocket
7 | # replaced by https://github.com/purarue/mpv-sockets
8 |
9 | screenshot-template="%f-%wH.%wM.%wS.%wT"
10 | script-opts=ytdl_path=~/.local/bin/yt-dlp
11 |
12 | # vim:ft=conf
13 |
--------------------------------------------------------------------------------
/.config/muttc/mailcap:
--------------------------------------------------------------------------------
1 | # to track 'shell-like' history https://github.com/purarue/ttt
2 | # most of these just forward to rifle, my file manager
3 | # for config see https://github.com/purarue/dotfiles/blob/master/.config/ranger/rifle.conf
4 | text/plain; rifle %s ;
5 | text/html; rifle %s ; nametemplate=%s.html
6 | text/html; ttt lynx -assume_charset=%{charset} -display_charset=utf-8 -dump %s; nametemplate=%s.html; copiousoutput;
7 | text/csv; rifle %s ;
8 | image/*; rifle %s ;
9 | video/*; rifle %s ; copiousoutput
10 | audio/*; rifle %s ;
11 | application/zip; ttt unzip %s ;
12 | application/pdf; rifle %s ;
13 | application/pgp-encrypted; ttt gpg -d '%s'; copiousoutput;
14 | application/pgp-keys; ttt gpg --import '%s'; copiousoutput;
15 |
--------------------------------------------------------------------------------
/.config/my/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | .mypy_cache
3 |
--------------------------------------------------------------------------------
/.config/my/.stignore:
--------------------------------------------------------------------------------
1 | .mypy_cache
2 | __pycache__
3 | __init__.py
4 |
--------------------------------------------------------------------------------
/.config/my/my/config/common.py:
--------------------------------------------------------------------------------
1 | from os import environ, path
2 | from my.core.warnings import high
3 |
4 |
5 | def repo(name: str) -> str:
6 | """
7 | e.g., converts to ~/Repos/name
8 | ~/Repos/ is where I store a lot of my git repositories
9 | """
10 | if "REPOS" in environ:
11 | return path.join(environ["REPOS"], name)
12 | else:
13 | high(
14 | r"Hey I use the $REPOS environment variable to determine where repositories are on my computer. If you have some directory you put those -- set something like 'export REPOS=~/projects' in your shell config. Otherwise, you can edit this 'def repo' function, or remove it from whatevers using it -- its probably some of my personal config"
15 | )
16 | return name
17 |
--------------------------------------------------------------------------------
/.config/my/my/config/pura/.gitignore:
--------------------------------------------------------------------------------
1 | *secret.py
2 |
--------------------------------------------------------------------------------
/.config/my/my/config/pura/__init__.pyi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/purarue/dotfiles/77843d62e8357579d7e8c8e3cd0033cfce803ff6/.config/my/my/config/pura/__init__.pyi
--------------------------------------------------------------------------------
/.config/my/my/config/pura/py.typed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/purarue/dotfiles/77843d62e8357579d7e8c8e3cd0033cfce803ff6/.config/my/my/config/pura/py.typed
--------------------------------------------------------------------------------
/.config/nsxiv/exec/image-info:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Example for $XDG_CONFIG_HOME/nsxiv/exec/image-info
4 | # Called by nsxiv(1) whenever an image gets loaded.
5 | # The output is displayed in nsxiv's status bar.
6 | # Arguments:
7 | # $1: path to image file
8 | # $2: image width
9 | # $3: image height
10 |
11 | s=" " # field separator
12 |
13 | exec 2>/dev/null
14 |
15 | filename=$(basename -- "$1")
16 | filesize=$(du -Hh -- "$1" | cut -f 1)
17 | geometry="${2}x${3}"
18 |
19 | echo "${filesize}${s}${geometry}${s}${filename}"
20 |
--------------------------------------------------------------------------------
/.config/nvim/.gitignore:
--------------------------------------------------------------------------------
1 | plugin/packer_compiled.lua
2 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/gitcommit.lua:
--------------------------------------------------------------------------------
1 | vim.opt_local.spell = true
2 | -- Follow 50/72 rule like described here:
3 | -- https://stackoverflow.com/q/2290016
4 | -- I set 72 here for the description
5 | vim.opt_local.textwidth = 72
6 | vim.opt_local.colorcolumn = "+1"
7 | vim.b.codeium_enabled = false
8 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/help.lua:
--------------------------------------------------------------------------------
1 | -- Close help buffer with q
2 | vim.keymap.set("n", "q", "bdelete", { buffer = 0 })
3 | -- 'gd' to go to definition (Ctrl-])
4 | vim.keymap.set("n", "gd", "", { buffer = 0 })
5 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/lua.lua:
--------------------------------------------------------------------------------
1 | vim.bo.shiftwidth = 4
2 | vim.bo.tabstop = 4
3 | vim.bo.expandtab = true
4 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/markdown.lua:
--------------------------------------------------------------------------------
1 | vim.b.codeium_enabled = false
2 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/qf.lua:
--------------------------------------------------------------------------------
1 | -- Close quickfix buffer with q
2 | vim.keymap.set("n", "q", "bdelete", { buffer = 0 })
3 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/query.lua:
--------------------------------------------------------------------------------
1 | -- for treesitter query
2 | vim.bo.shiftwidth = 2
3 | vim.bo.tabstop = 2
4 | vim.bo.expandtab = true
5 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/sshconfig.lua:
--------------------------------------------------------------------------------
1 | vim.bo.shiftwidth = 2
2 | vim.bo.tabstop = 2
3 | vim.bo.expandtab = true
4 |
--------------------------------------------------------------------------------
/.config/nvim/after/ftplugin/zsh.lua:
--------------------------------------------------------------------------------
1 | -- if this is in a directory called 'tmp', this is probably me using the
2 | -- zsh edit-command-line widget set it to bash so I get nice treesitter
3 | -- highlighting, including for embedded languages (e.g. awk/jq)
4 | -- (see queries/bash/injections.scm)
5 | local dirname = vim.fn.expand("%:h")
6 | local parent_dir = vim.fs.basename(dirname)
7 | if parent_dir == "tmp" then
8 | vim.bo.filetype = "bash"
9 | end
10 |
--------------------------------------------------------------------------------
/.config/nvim/after/plugin/helpers.lua:
--------------------------------------------------------------------------------
1 | -- dumps the contents of one or more variables to the console
2 | -- selene: allow(unscoped_variables,unused_variable)
3 | P = function(...)
4 | local args = {}
5 | for _, arg in ipairs({ ... }) do
6 | table.insert(args, vim.inspect(arg))
7 | end
8 | print(unpack(args))
9 | return ...
10 | end
11 |
--------------------------------------------------------------------------------
/.config/nvim/after/plugin/highlight.lua:
--------------------------------------------------------------------------------
1 | -- see queries/bash/injections.scm for where this is set
2 | vim.api.nvim_set_hl(0, "@evry_flag", { italic = true, fg = "lightgrey" })
3 |
--------------------------------------------------------------------------------
/.config/nvim/lua/plugins/cloak.lua:
--------------------------------------------------------------------------------
1 | -- 'https://github.com/laytan/cloak.nvim?tab=readme-ov-file#configuration'
2 | return {
3 | "laytan/cloak.nvim",
4 | event = "BufRead",
5 | keys = { { "C", "CloakToggle", "toggle cloak" } },
6 | opts = {
7 | patterns = {
8 | {
9 | -- Match any file starting with '.env'.
10 | -- This can be a table to match multiple file patterns.
11 | file_pattern = ".env*",
12 | -- Match an equals sign and any character after it.
13 | -- This can also be a table of patterns to cloak,
14 | -- example: cloak_pattern = { ':.+', '-.+' } for yaml files.
15 | cloak_pattern = "=.+",
16 | },
17 | },
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/.config/nvim/lua/plugins/codeium.lua:
--------------------------------------------------------------------------------
1 | local function toggle()
2 | require("user.patch_codeium").toggle_codeium_enabled()
3 | end
4 |
5 | local mh = require("user.mapping_helpers")
6 | mh.map_key("", toggle, "toggle codeium", { "i", "n" })
7 |
8 | return {
9 | "Exafunction/codeium.nvim",
10 | commit = "937667b2cadc7905e6b9ba18ecf84694cf227567",
11 | event = "InsertEnter",
12 | cmd = { "Codeium", "CodeiumToggle" },
13 | cond = not vim.g.on_android,
14 | config = function()
15 | require("codeium").setup()
16 | require("user.patch_codeium").patch_codeium()
17 |
18 | vim.api.nvim_create_user_command("CodeiumToggle", toggle, { desc = "Toggle Codeium" })
19 | end,
20 | }
21 |
--------------------------------------------------------------------------------
/.config/nvim/lua/plugins/mini.lua:
--------------------------------------------------------------------------------
1 | return {
2 | "echasnovski/mini.nvim",
3 | version = false,
4 | event = "VeryLazy",
5 | config = function()
6 | require("mini.ai").setup()
7 | require("mini.surround").setup()
8 | end,
9 | }
10 |
--------------------------------------------------------------------------------
/.config/nvim/lua/plugins/spectre.lua:
--------------------------------------------------------------------------------
1 | return {
2 | "nvim-pack/nvim-spectre",
3 | keys = {
4 | {
5 | "S",
6 | function()
7 | require("spectre").open()
8 | end,
9 | desc = "spectre",
10 | },
11 | },
12 | cmd = "Spectre",
13 | opts = {},
14 | }
15 |
--------------------------------------------------------------------------------
/.config/nvim/lua/user/init.lua:
--------------------------------------------------------------------------------
1 | require("user.settings")
2 | require("user.key_mappings")
3 | require("user.autocmds")
4 | require("user.remsync")
5 |
--------------------------------------------------------------------------------
/.config/nvim/lua/user/snippets.lua:
--------------------------------------------------------------------------------
1 | local ls = require("luasnip")
2 |
3 | -- shorthands
4 | local snippet = ls.s
5 | local f = ls.function_node
6 |
7 | ls.add_snippets("all", {
8 | -- date -> Tue 16 Nov 2021 09:43:49 AM EST
9 | snippet({ trig = "date" }, {
10 | f(function()
11 | return string.format(string.gsub(vim.bo.commentstring, "%%s", " %%s"), os.date())
12 | end, {}),
13 | }),
14 | })
15 |
--------------------------------------------------------------------------------
/.config/nvim/lua/user/terminal.lua:
--------------------------------------------------------------------------------
1 | local M = {}
2 |
3 | function M.set_background()
4 | local ok, mod = pcall(require, "terminal_colorscheme")
5 | if not ok then
6 | vim.o.background = "dark"
7 | else
8 | -- vim.o to set global option
9 | vim.o.background = mod.dark_mode() and "dark" or "light"
10 | end
11 | end
12 |
13 | return M
14 |
--------------------------------------------------------------------------------
/.config/nvim/queries/bash/highlights.scm:
--------------------------------------------------------------------------------
1 | ; extends
2 |
3 | ; https://github.com/purarue/evry
4 | ; evry has syntax like:
5 | ; evry 1 day -do_some_job
6 | ;
7 | ; this identifies the -tag as @evry_flag, so it
8 | ; can be highlighted
9 | (command
10 | name: (command_name
11 | (word) @cmd_name)
12 | (#eq? @cmd_name "evry")
13 | argument: (word) @evry_flag
14 | (#match? @evry_flag "^-")) @evry
15 |
16 | ; can then use a command like this to highlight it specifically:
17 | ; vim.api.nvim_set_hl(0, "@evry_flag", {italic = true, fg = "lightgrey"})
18 |
--------------------------------------------------------------------------------
/.config/nvim/queries/markdown/injections.scm:
--------------------------------------------------------------------------------
1 | ; extends
2 |
3 | ; https://github.com/purarue/pmark
4 | (fenced_code_block
5 | (code_fence_content) @injection.content
6 | (#match? @injection.content "^...PMARK")
7 | ; skip the first line, is a PMARK marker
8 | (#offset! @injection.content 1 0 0 0)
9 | (#set! injection.language "bash"))
10 |
--------------------------------------------------------------------------------
/.config/nvim/queries/query/injections.scm:
--------------------------------------------------------------------------------
1 | ; extends
2 |
3 | ; highlight regex strings in treesitter query files
4 | (predicate
5 | name: (identifier) @query_cond
6 | (#any-of? @query_cond "match" "any-match" "vim-match" "any-match"
7 | "any-vim-match" "lua-match" "any-lua-match")
8 | parameters: (parameters
9 | (string
10 | (string_content) @injection.content))
11 | (#set! injection.language "regex"))
12 |
--------------------------------------------------------------------------------
/.config/nvim/queries/rifleconfig/injections.scm:
--------------------------------------------------------------------------------
1 | ; extends
2 |
3 | ; highlight any commands using the bash tree-sitter parser
4 | (command_list
5 | (command) @injection.content
6 | (#set! injection.include-children)
7 | (#set! injection.language "bash"))
8 |
--------------------------------------------------------------------------------
/.config/nvim/selene.toml:
--------------------------------------------------------------------------------
1 | std = "lua51+vim"
2 |
3 | [lints]
4 | mixed_table = "allow"
5 |
--------------------------------------------------------------------------------
/.config/nvim/snippets/cfg.snippets:
--------------------------------------------------------------------------------
1 | snippet python_defaults
2 | [metadata]
3 | name = $1
4 | version =
5 | description =
6 | license =
7 | license_file = LICENSE
8 | long_description = file: README.md
9 | long_description_content_type = text/markdown
10 | author = purarue
11 | url = https://github.com/purarue/$1
12 |
13 | [options]
14 | packages = find:
15 | include_package_data = True
16 | install_requires =
17 |
18 | python_requires = >=3.8
19 |
20 | [options.packages.find]
21 | exclude =
22 | tests*
23 | include =
24 | $1
25 |
26 | [options.package_data]
27 | $1 = py.typed
28 |
29 | [options.entry_points]
30 | console_scripts =
31 |
32 | [options.extras_require]
33 | testing =
34 | mypy
35 | flake8
36 |
--------------------------------------------------------------------------------
/.config/nvim/snippets/python.snippets:
--------------------------------------------------------------------------------
1 | snippet click_path
2 | from pathlib import Path
3 | import click
4 |
5 | @click.command()
6 | @click.argument("$2", type=click.Path(exists=True, path_type=Path), required=True)
7 | def main($2: Path) -> None:
8 | """
9 | """
10 | click.echo($2)
11 | $0
12 |
13 | if __name__ == "__main__":
14 | main(prog_name="$1")
15 |
16 | snippet click
17 | from pathlib import Path
18 | import click
19 |
20 | @click.command()
21 | def main() -> None:
22 | """
23 | """
24 |
25 | if __name__ == "__main__":
26 | main(prog_name="$1")
27 |
28 | snippet typ
29 | from typing import $1
30 |
--------------------------------------------------------------------------------
/.config/nvim/snippets/sh.snippets:
--------------------------------------------------------------------------------
1 | snippet bash_this_dir
2 | THIS_DIR="$(realpath "$(dirname "\${BASH_SOURCE[0]}")")"
3 | cd "\${THIS_DIR}" || exit $?
4 |
5 | # https://github.com/purarue/bgproc
6 | snippet bgproc_job
7 | #!/usr/bin/env bash
8 |
9 | wait-for-internet -q --timeout "\${WFI_TIMEOUT:-10}" || exit 0
10 |
11 | evry $1 -$2 && {
12 | printlog '$2:'
13 | $0
14 | }
15 |
--------------------------------------------------------------------------------
/.config/nvim/stylua.toml:
--------------------------------------------------------------------------------
1 | column_width = 140
2 | indent_type = "Spaces"
3 | indent_width = 4
4 | collapse_simple_statement = "Never"
5 |
--------------------------------------------------------------------------------
/.config/nvim/vim.toml:
--------------------------------------------------------------------------------
1 | [vim]
2 | any = true
3 |
--------------------------------------------------------------------------------
/.config/plus1_blacklist.txt:
--------------------------------------------------------------------------------
1 | .3g2
2 | .3gp
3 | .7z
4 | .aac
5 | .ac3
6 | .aiff
7 | .alac
8 | .ape
9 | .apk
10 | .arj
11 | .avi
12 | .bak
13 | .bat
14 | .bin
15 | .bmp
16 | .cab
17 | .com
18 | .cpl
19 | .cur
20 | .ddl
21 | .deb
22 | .dmg
23 | .dmp
24 | .doc
25 | .docx
26 | .drv
27 | .exe
28 | .f4p
29 | .f4v
30 | .flac
31 | .flv
32 | .gif
33 | .gifv
34 | .gz
35 | .icns
36 | .ico
37 | .iso
38 | .jar
39 | .jpeg
40 | .jpg
41 | .key
42 | .m2v
43 | .m4a
44 | .m4p
45 | .m4v
46 | .md
47 | .mka
48 | .mkv
49 | .mp2
50 | .mp3
51 | .mp4
52 | .mpe
53 | .mpeg
54 | .mpg
55 | .mpv
56 | .odp
57 | .ogg
58 | .ogv
59 | .opus
60 | .pkg
61 | .png
62 | .pps
63 | .ppt
64 | .pptx
65 | .psd
66 | .pyc
67 | .qt
68 | .rar
69 | .rpm
70 | .svg
71 | .sys
72 | .tar
73 | .tif
74 | .tiff
75 | .tmp
76 | .toast
77 | .vcd
78 | .wav
79 | .webm
80 | .wma
81 | .wmv
82 | .z
83 | .zip
84 |
--------------------------------------------------------------------------------
/.config/pura_lua/pura_utils.lua:
--------------------------------------------------------------------------------
1 | local M = {}
2 |
3 | ---reads the entire file to a string
4 | ---@param filename string
5 | ---@param readmode? readmode
6 | ---@return string?
7 | function M.read_to_string(filename, readmode)
8 | local f = io.open(filename, "r")
9 | if f then
10 | local content = f:read(readmode or "*a")
11 | f:close()
12 | return content
13 | end
14 | return nil
15 | end
16 |
17 | --- removes spaces from start and end of a string
18 | --- trim6 from https://lua-users.org/wiki/StringTrim
19 | ---@param s string
20 | ---@return string
21 | function M.trim(s)
22 | return s:match("^()%s*$") and "" or s:match("^%s*(.*%S)")
23 | end
24 |
25 | return M
26 |
--------------------------------------------------------------------------------
/.config/pura_lua/terminal_colorscheme.lua:
--------------------------------------------------------------------------------
1 | local M = {}
2 |
3 | local terminal_theme_file = os.getenv("HOME") .. "/.cache/terminal-theme"
4 |
5 | ---@return string?
6 | function M.terminal_colorscheme()
7 | return os.getenv("TERMINAL_THEME") or require("pura_utils").read_to_string(terminal_theme_file, "*l")
8 | end
9 |
10 | ---@return boolean
11 | function M.dark_mode()
12 | local colorscheme = M.terminal_colorscheme()
13 | return colorscheme == nil or colorscheme:lower() == "dark"
14 | end
15 |
16 | ---@return boolean
17 | function M.light_mode()
18 | return not M.dark_mode()
19 | end
20 |
21 | return M
22 |
--------------------------------------------------------------------------------
/.config/pythonrc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | import atexit
4 | import os
5 | import readline
6 |
7 | history = os.path.join(
8 | os.environ.get("XDG_CACHE_HOME", os.path.join(os.environ["HOME"], ".cache")),
9 | "python_history",
10 | )
11 | try:
12 | readline.read_history_file(history)
13 | # default history len is -1 (infinite), which may grow unruly
14 | readline.set_history_length(1000)
15 | # https://bugs.python.org/issue20886#msg265568
16 | except FileNotFoundError:
17 | pass
18 |
19 | atexit.register(readline.write_history_file, history)
20 |
--------------------------------------------------------------------------------
/.config/ranger/.gitignore:
--------------------------------------------------------------------------------
1 | preview.rc
2 | hidden_filter.rc
3 |
--------------------------------------------------------------------------------
/.config/ranger/Makefile:
--------------------------------------------------------------------------------
1 | BOOKMARKS_FILE:=~/.local/share/ranger/bookmarks
2 |
3 | all: hidden_filter.rc preview.rc $(BOOKMARKS_FILE)
4 | $(BOOKMARKS_FILE): ./dir-aliases ~/.config/directories
5 | ./dir-aliases
6 | preview.rc: ./generate_image_preview
7 | ./generate_image_preview
8 | hidden_filter.rc: ./hidden_template.rc
9 | ./generate_filter
10 | clean:
11 | rm -f ./hidden_filter.rc ./preview.rc $(BOOKMARKS_FILE)
12 |
--------------------------------------------------------------------------------
/.config/ranger/generate_filter:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [[ -z "$oname" ]]; then
4 | printf "oname not set\n" >&2
5 | exit 1
6 | fi
7 |
8 | THIS_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
9 | cd "${THIS_DIR}" || exit $?
10 |
11 | set -x
12 |
13 | exec jinjanate ./hidden_template.rc >hidden_filter.rc
14 |
--------------------------------------------------------------------------------
/.config/ranger/generate_image_preview:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | TARGET="${XDG_CONFIG_HOME}/ranger/preview.rc"
3 | case "${ON_OS:-$(on_machine)}" in
4 | android*)
5 | # dont think there's any way to do this right now
6 | echo 'set preview_images false' >"${TARGET}"
7 | ;;
8 | linux_arch*)
9 | printf 'set preview_images %s\n' "${RANGER_GENERATE_IMAGE_PREVIEW:-true}" >"${TARGET}"
10 | if [[ "$TERM" == xterm-kitty ]]; then
11 | # use kitty to preview images
12 | echo 'set preview_images_method kitty' >>"${TARGET}"
13 | elif [[ "$TERM" == foot ]]; then
14 | echo 'set preview_images_method sixel' >>"${TARGET}"
15 | else
16 | # use ueberzug to preview images
17 | echo 'set preview_images_method ueberzug' >>"${TARGET}"
18 | fi
19 | ;;
20 | *)
21 | # fallback to w3m?
22 | echo -e 'set preview_images true\nset preview_images_method w3m' >"${TARGET}"
23 | ;;
24 | esac
25 |
--------------------------------------------------------------------------------
/.config/ranger/hidden_template.rc:
--------------------------------------------------------------------------------
1 | ###SETTINGS###
2 | set hidden_filter ^\.|\.(?:pyc|vrb|pyo|class|lof|swp|aux|nav|out|snm|toc|bcf|run\.xml|synctex\.gz|blg|bbl|egg-info)$|^lost\+found$|^__(py)?cache__$|^tags(?:\.lock|\.temp)?$|^_build$|^build$|^dist$|^node_modules$|^target|{{ oname }}$
3 |
--------------------------------------------------------------------------------
/.config/ranger/make:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # non-directory specific make script
3 | exec make -C "${HOME}/.config/ranger" -f "${HOME}/.config/ranger/Makefile"
4 |
--------------------------------------------------------------------------------
/.config/rifleman/image.conf:
--------------------------------------------------------------------------------
1 | # vim: ft=rifleconfig
2 | #
3 | # This is a configuration file for "rifleman"
4 | # https://github.com/purarue/rifleman
5 | #
6 | # This matches any png, jpeg and gif files, and optimizes them in-place
7 | # This uses a couple of my wrapper scripts, but under the hood
8 | # its using:
9 | #
10 | # for gifs: https://github.com/kohler/gifsicle
11 | # for pngs: http://optipng.sourceforge.net/
12 | # for jpegs: http://jpegclub.org/jpegtran/
13 |
14 | # https://purarue.xyz/d/optigif
15 | # for gifs
16 | mime image/gif, has optigif = OPTIGIF_OVERWRITE=1 optigif "$1"
17 |
18 | # https://purarue.xyz/d/optijpg
19 | # for jpegs
20 | mime image/jpeg, has jpegtran = optijpg "$1"
21 |
22 | # for pngs
23 | mime image/png, has optipng = optipng -o5 "$@"
24 |
--------------------------------------------------------------------------------
/.config/rofi/config.rasi:
--------------------------------------------------------------------------------
1 | configuration {
2 | modi: "window,run";
3 | location: 2;
4 | }
5 |
6 | // @theme "dracula"
7 |
--------------------------------------------------------------------------------
/.config/scramble_history/files.yaml:
--------------------------------------------------------------------------------
1 | cstimer:
2 | - ~/data/cubing/cstimer/*.json
3 | twistytimer:
4 | - ~/data/cubing/manual.csv
5 | - ~/data/cubing/phone_twistytimer/*.txt
6 | - ~/data/cubing/cubers_io/*.txt
7 |
--------------------------------------------------------------------------------
/.config/screenlayout/auto.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # automatically fixes my screen layout, depending on whether or not HDMI is plugged in
3 | if xrandr | grep -q 'HDMI-A-0 connected'; then
4 | "${HOME}/.config/screenlayout/desk_dual_monitor.sh"
5 | else
6 | "${HOME}/.config/screenlayout/single_laptop_screen.sh"
7 | fi
8 |
--------------------------------------------------------------------------------
/.config/screenlayout/desk_dual_monitor.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # For when I have monitor plugged in on the right of my laptop screen
3 | xrandr --output eDP --primary --mode 1920x1080 --pos 0x0 --rotate normal --output HDMI-A-0 --mode 3840x2160 --pos 1920x0 --rotate normal --output DisplayPort-0 --off --output DisplayPort-1 --off
4 |
--------------------------------------------------------------------------------
/.config/screenlayout/single_laptop_screen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # For when Im just using my laptop screen
3 | xrandr --output eDP --primary --mode 1920x1080 --pos 0x0 --rotate normal --output HDMI-A-0 --off --output DisplayPort-0 --off --output DisplayPort-1 --off
4 |
--------------------------------------------------------------------------------
/.config/skhd/skhdrc:
--------------------------------------------------------------------------------
1 | # Mac keyboard hotkey daemon
2 | # See https://github.com/koekeishiya/skhd/blob/master/examples/skhdrc for more examples
3 | # Use shkd to bind applications to cmd + alt
4 | # This shouldn't interfere with window manager commands (https://github.com/ianyh/Amethyst)
5 | # since those are prefixed with option + shift or ctrl + option + shift
6 |
7 | cmd + alt - return : kitty -d=~ -1
8 | cmd + alt - f : /Applications/Firefox\ Developer\ Edition.app/Contents/MacOS/firefox
9 |
--------------------------------------------------------------------------------
/.config/thefuck/settings.py:
--------------------------------------------------------------------------------
1 | # The Fuck settings file
2 | #
3 | # The rules are defined as in the example below:
4 | #
5 | # rules = ['cd_parent', 'git_push', 'python_command', 'sudo']
6 | #
7 | # The default values are as follows. Uncomment and change to fit your needs.
8 | # See https://github.com/nvbn/thefuck#settings for more information.
9 | #
10 |
11 | # rules = []
12 | # exclude_rules = []
13 | # wait_command = 3
14 | # require_confirmation = True
15 | # no_colors = False
16 | # debug = False
17 | # priority = {}
18 | # history_limit = None
19 | # alter_history = True
20 | # wait_slow_command = 15
21 | # slow_commands = ['lein', 'react-native', 'gradle', './gradlew', 'vagrant']
22 | # repeat = False
23 | # instant_mode = False
24 | # num_close_matches = 3
25 | # env = {'LC_ALL': 'C', 'LANG': 'C', 'GIT_TRACE': '1'}
26 |
--------------------------------------------------------------------------------
/.config/user-dirs.dirs:
--------------------------------------------------------------------------------
1 | # This file is written by xdg-user-dirs-update
2 | # If you want to change or add directories, just edit the line you're
3 | # interested in. All local changes will be retained on the next run.
4 | # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
5 | # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
6 | # absolute path. No other format is supported.
7 | #
8 | XDG_DESKTOP_DIR="$HOME/"
9 | XDG_DOWNLOAD_DIR="$HOME/Downloads"
10 | XDG_TEMPLATES_DIR="$HOME/.local/share/Templates"
11 | XDG_PUBLICSHARE_DIR="$HOME/.local/share/Public"
12 | XDG_DOCUMENTS_DIR="$HOME/Documents"
13 | XDG_MUSIC_DIR="$HOME/Music"
14 | XDG_PICTURES_DIR="$HOME/Pictures"
15 | XDG_VIDEOS_DIR="$HOME/Movies"
16 |
--------------------------------------------------------------------------------
/.config/user-dirs.locale:
--------------------------------------------------------------------------------
1 | en_US
--------------------------------------------------------------------------------
/.config/wezterm/clipboard.lua:
--------------------------------------------------------------------------------
1 | local wt = require("wezterm")
2 |
3 | -- https://github.com/wez/wezterm/discussions/3469
4 |
5 | local M = {}
6 | M.autoQuotePastedUrls = function(window, pane)
7 | local pasteCmd = "clippaste"
8 | local success, clipb, stderr = wt.run_child_process({ pasteCmd })
9 | if not success then
10 | local msg = "clippaste failed: " .. stderr
11 | wt.log_info(msg)
12 | window:toast_notification(msg, nil, 4000)
13 | return
14 | end
15 | if clipb:find("^https?://") then
16 | clipb = "'" .. clipb .. "'"
17 | end
18 | pane:paste(clipb)
19 | end
20 |
21 | return M
22 |
--------------------------------------------------------------------------------
/.config/yadm/dotfiles_ignore_words.txt:
--------------------------------------------------------------------------------
1 | doubleclick
2 |
--------------------------------------------------------------------------------
/.config/yadm/hooks/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Reverts README.md copy -- what is done by pre-commit
3 | # Delete the README.md since the original at ~/.config/yadm/README.md still exists
4 |
5 | cd || exit $?
6 | [[ -f ~/README.md ]] && rm ~/README.md
7 |
--------------------------------------------------------------------------------
/.config/yadm/hooks/post-merge:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Moves the README.md downloaded from github back to ~/.config/yadm/README.md
3 | # so that changes made through the web interacted stay updated locally
4 |
5 | cd || exit $?
6 | [[ -f ~/README.md ]] && mv ~/README.md ~/.config/yadm/README.md
7 |
--------------------------------------------------------------------------------
/.config/yadm/hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd || exit $?
4 |
5 | # make sure there is no errors with my profile,
6 | # because this causes x11 issues if it can't be sourced
7 | sh ~/.profile || {
8 | echo 'Error in sourcing ~/.profile' >&2
9 | exit 1
10 | }
11 |
12 | # check for spelling errors in my dotfiles
13 | case "$ON_OS" in
14 | linux_*)
15 | spell-dotfiles || exit $?
16 | ;;
17 | *) ;;
18 | esac
19 |
20 | # Copy README for git repo to $HOME so that the github repo README will be updated
21 | # post-commit moves the README.md back so as to not pollute $HOME
22 | cp ~/.config/yadm/README.md ~/README.md
23 | yadm add -f ~/README.md
24 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/arch_packages_wayland.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | # os
4 | gammastep
5 | hyprland
6 | hyprlock
7 | swaybg
8 | pipewire
9 | pipewire-pulse
10 | polkit-kde-agent
11 | qt5-wayland
12 | qt6-wayland
13 | rofi-lbonn-wayland-git
14 | wev
15 | wireplumber
16 | wl-clipboard
17 | xdg-desktop-portal-hyprland
18 | xorg-xwayland
19 |
20 | auto-cpufreq # for battery life
21 | otf-font-awesome # for waybar
22 |
23 | # for clicking without my trackpad
24 | wlrctl
25 | wl-kbptr
26 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/arch_packages_x11.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | # os
4 |
5 | arandr
6 | autorandr
7 | autotiling-git
8 | exfat-utils
9 | i3-wm
10 | i3blocks
11 | i3lock
12 | network-manager-applet
13 | picom
14 | pipewire-alsa
15 | redshift
16 | udiskie
17 | udisks2
18 | ueberzug
19 | unclutter
20 | xorg-server
21 | xorg-xev
22 | xorg-xinput
23 | xorg-xmodmap
24 | xorg-xwininfo
25 | xorg-xinit
26 |
27 | # utilities
28 |
29 | screenkey-git
30 | scrot
31 | w3m
32 | wezterm
33 | xclip
34 | xcolor
35 | xdotool
36 | xorg-xdpyinfo
37 | xorg-xwininfo
38 | xterm
39 | xvkbd
40 |
41 | # applications
42 |
43 | gparted
44 | mupdf-gl
45 | snes9x-gtk
46 | thunar
47 |
48 | # fonts
49 | xorg-font-util
50 | xorg-fonts-encodings
51 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/bash_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | purarue/mpv-sockets
4 | purarue/mpvf
5 | purarue/bgproc
6 | purarue/plaintext-playlist
7 | purarue/pmark
8 | purarue/frinkconv
9 | paulirish/git-open
10 | dylanaraps/neofetch
11 | kadwanev/retry
12 | kdheepak/panvimdoc
13 | reinefjord/wayshot
14 | eschulte/lisp-format
15 | rupa/z
16 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/cargo_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | cargo-license # list licenses
4 | cargo-update # to update these packages
5 | evry # my task scheduler
6 | procs # ps replacement
7 | diskonaut # disk visualizer
8 | kondo # removes node_module/build directories
9 | so # stackoverflow
10 | readenv # renv, for executing a command with a modified environment
11 | wait-for-internet
12 | hexyl # hexdump
13 | monolith # saves webpages as a single HTML file
14 | taplo-cli # TOML library, for formatting
15 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/computer_node_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | elm-format
4 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/computer_python.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=requirements
2 |
3 | # things I would only want to install on a computer
4 | pandas
5 | matplotlib
6 | numpy
7 | scipy
8 | orjson
9 | lxml[html_clean]
10 | jsonc-parser
11 | openmeteo-requests
12 | requests-cache
13 | retry-requests
14 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/dart_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | linkcheck
4 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/gh_extension_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | gennaro-tedesco/gh-i
4 | gennaro-tedesco/gh-s
5 | dlvhdr/gh-dash
6 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/linux_python3_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | beets
4 | beets-filetote
5 | cython
6 | imgur-uploader
7 | iwlib
8 | pyacoustid
9 | pyautogui
10 | pylast
11 | pynvim
12 | python-language-server
13 | python-xlib
14 | thefuck
15 | twine
16 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/mix_archive_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | phx_new
4 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/node_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | # language support
4 | @elm-tooling/elm-language-server
5 | @prettier/plugin-php
6 | @fsouza/prettierd
7 | @astrojs/language-server
8 | @prisma/language-server
9 | @tailwindcss/language-server
10 | bash-language-server
11 | coffeescript
12 | cssmodules-language-server
13 | eslint
14 | fixjson
15 | html-minifier
16 | js-beautify
17 | jsonlint
18 | node-cljfmt
19 | npm
20 | prettier
21 | prettier-plugin-prisma
22 | prettier-plugin-toml
23 | pyright
24 | stylelint
25 | typescript
26 | typescript-language-server
27 | uglifycss
28 | vscode-langservers-extracted
29 | yaml-language-server
30 |
31 | # web tools/packages
32 | serve
33 | vercel
34 |
35 | # other tools
36 | @jamen/lorem
37 | git-stats
38 | mapscii
39 | moby
40 | readability-cli
41 | sqleton
42 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/ocaml_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | dune
4 | merlin
5 | ocaml-lsp-server
6 | odoc
7 | ocamlformat
8 | utop
9 | dune-release
10 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/pipx_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=requirements
2 |
3 | ansi2html
4 | cookiecutter
5 | csvkit
6 | cube-scramble-cli
7 | currencyconverter
8 | diceware
9 | eyeD3
10 | greasyfork-archive
11 | pypyp
12 | setup-cfg-fmt
13 | speedtest-cli
14 | supervisor
15 | termdown
16 | termgraph
17 | time-in
18 | urlscan
19 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/python3_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=requirements
2 |
3 | Pygments
4 | black
5 | codespell
6 | exifread
7 | feedgen
8 | flake8
9 | geopy
10 | giturlparse
11 | idna
12 | ipdb
13 | ipython
14 | jinjanator
15 | mlength
16 | phonenumbers
17 | pip
18 | pipenv
19 | pipx
20 | platformdirs
21 | pyYAML
22 | pyflyby
23 | pyperclip
24 | pysrt
25 | python-frontmatter
26 | reorder_editable
27 | rich
28 | rifleman
29 | rsa
30 | selenium
31 | setuptools
32 | srt
33 | toml
34 | trash-cli
35 | watchfiles
36 | yt-dlp
37 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/ruby_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | # lsp/linting
4 | rubocop
5 |
--------------------------------------------------------------------------------
/.config/yadm/package_lists/wsl_packages.txt:
--------------------------------------------------------------------------------
1 | # vim: ft=conf
2 |
3 | python3-pip
4 | tree
5 | npm
6 | yarn
7 | libicu-dev
8 | libmagic-dev
9 | silversearcher-ag
10 | ripgrep
11 | jq
12 | datamash
13 | entr
14 | ffmpeg
15 | fzf
16 | figlet
17 | lynx
18 | wget
19 | unar
20 | software-properties-common
21 | todotxt-cli
22 | gcc
23 |
--------------------------------------------------------------------------------
/.config/zsh/.gitignore:
--------------------------------------------------------------------------------
1 | personal_aliases
2 | tokens
3 | directory_aliases
4 | secrets
5 |
--------------------------------------------------------------------------------
/.config/zsh/cache_aliases.zsh:
--------------------------------------------------------------------------------
1 | # periodically cache my aliases so I can reconstruct the meaning of commands using them
2 | # should be the last thing run when starting zsh
3 | # meant to be used as part of HPI https://github.com/purarue/HPI
4 |
5 | hash evry && evry 1 week -zsh_alias_cache && {
6 | ALIAS_CACHE_BACKUP_DIR="$(python3 -m my.utils.backup_to 'zsh_aliases')" || exit $?
7 | ALIAS_CACHE_TARGET="${ALIAS_CACHE_BACKUP_DIR}/$(date +'%s')-$(uname)"
8 | alias | sort >"${ALIAS_CACHE_TARGET}"
9 | unset ALIAS_CACHE_BACKUP_DIR ALIAS_CACHE_TARGET
10 | }
11 |
--------------------------------------------------------------------------------
/.config/zsh/cd.zsh:
--------------------------------------------------------------------------------
1 | # bindings to change my directory in the shell
2 | #
3 | # Alt+left arrow/Alt+H to move up a dir
4 | up-dir() {
5 | cd '..'
6 | zle reset-prompt
7 | }
8 | zle -N up-dir
9 | bindkey '^[[1;3D' up-dir
10 | bindkey '^[h' up-dir
11 |
12 | # Alt+right arrow/Alt+L to launch fzf cd (move into dir)
13 | bindkey '^[[1;3C' fzf-cd-widget
14 | bindkey '^[l' fzf-cd-widget
15 |
16 | CD() {
17 | local chosen
18 | cd ~
19 | chosen="$(fd -L --type d | fzf --no-multi --height=10 --reverse --preview="tree -C {}")"
20 | [[ -z "$chosen" ]] && return 1
21 | cd "$chosen" || return $?
22 | }
23 |
--------------------------------------------------------------------------------
/.config/zsh/completions/_binary_completion:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # complete any command that takes another command as its arguments
3 |
4 | function _binary_completion() {
5 | _alternative 'commands: :_path_commands'
6 | }
7 |
--------------------------------------------------------------------------------
/.config/zsh/completions/_services:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | #compdef services
3 |
4 | function _services() {
5 | _arguments '1: :(start stop)'
6 | }
7 |
--------------------------------------------------------------------------------
/.config/zsh/completions/_trackpad:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | #compdef trackpad
3 |
4 | function _trackpad() {
5 | _arguments '1: :(enable disable)'
6 | }
7 |
--------------------------------------------------------------------------------
/.config/zsh/completions/_transparent:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | #compdef transparent
3 |
4 | function _transparent() {
5 | _arguments \
6 | '1: :(enable disable)' \
7 | '2: :(target)'
8 | }
9 |
--------------------------------------------------------------------------------
/.config/zsh/completions/_volume:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | #compdef volume
3 |
4 | function _volume() {
5 | _arguments '1: :(up down mute micmute)'
6 | }
7 |
--------------------------------------------------------------------------------
/.config/zsh/functions/add-to-path:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | # adds the passed directory or the current directory to your $PATH
3 |
4 | add-to-path() {
5 | local toadd
6 | toadd="${1:-$(pwd)}"
7 | if [[ ! -d "$toadd" ]]; then
8 | echo "Not a directory: $toadd" >&2
9 | return 1
10 | fi
11 | # check if already in path
12 | if [[ ":$PATH:" == *":$toadd:"* ]]; then
13 | echo "$toadd already in path" >&2
14 | return 1
15 | fi
16 | export PATH="$toadd:$PATH"
17 | }
18 |
--------------------------------------------------------------------------------
/.config/zsh/functions/cdp:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # cd back to the top of the git repo you're in
3 |
4 | cdp() {
5 | local TEMP_PWD="$PWD"
6 | while [[ ! -d ./.git ]]; do
7 | cd ..
8 | # if we weren't in a git repo, and we hit root
9 | if [[ $PWD == / ]]; then
10 | echo "Could not find a git repo in the current tree..." >&2
11 | cd "$TEMP_PWD"
12 | break
13 | fi
14 | done
15 | OLDPWD="$TEMP_PWD"
16 | }
17 |
--------------------------------------------------------------------------------
/.config/zsh/functions/cdtmp:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # cd to a new tmp directory
3 |
4 | cdtmp() {
5 | local cdto
6 | local basetemp="${TMPDIR:-/tmp}"
7 | local cdtmpbase="${basetemp}/cdtmp"
8 | mkdir -p "$cdtmpbase"
9 | cdto="$(mktemp -p "$cdtmpbase" -d XXXXXXXXXX)"
10 | cd "$cdto"
11 | }
12 |
--------------------------------------------------------------------------------
/.config/zsh/functions/duck:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # searches duckduckgo on the command line using lynx
3 | # duck "TERMS TO SEARCH FOR"
4 |
5 | function duck() {
6 | lynx "duckduckgo.com/lite?kd=-1&kp=-1&q=$*"
7 | }
8 |
--------------------------------------------------------------------------------
/.config/zsh/functions/fkill:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # fkill - kill process
3 | # use fzf to match against a process and kill it
4 |
5 | fkill() {
6 | local pid
7 | pid="$(fpick)" || return $?
8 | kill -${1-15} "$pid"
9 | }
10 |
--------------------------------------------------------------------------------
/.config/zsh/functions/flocate:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # fuzzy search for files on the entire system
3 | # and cd to the enclosing directory
4 |
5 | function flocate() {
6 | case "$ON_OS" in
7 | mac*)
8 | echo "Use 'mdfind' instead" >&2
9 | return 1
10 | ;;
11 | esac
12 | local FZFFOUNDFILENAME="$(locate / | fzf +m --preview='${HOME}/.config/fzf_preview {}')"
13 | # go to directory if its a directory, else go to enclosing directory
14 | if [[ -d "$FZFFOUNDFILENAME" ]]; then
15 | cd "$FZFFOUNDFILENAME"
16 | else
17 | cd "$(dirname "$FZFFOUNDFILENAME")"
18 | fi
19 | }
20 |
--------------------------------------------------------------------------------
/.config/zsh/functions/fpick:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # fpick - pick a process
3 | # use fzf to match against a process, print its PID
4 |
5 | fpick() {
6 | local pid procs
7 | procs="$(ps -ef)"
8 | pid="$(sed 1d <<<"${procs}" | fzf -m --tac | awk '{print $2}')"
9 | [[ -z "$pid" ]] && return 1
10 | printf "%s\n" "$pid"
11 | }
12 |
--------------------------------------------------------------------------------
/.config/zsh/functions/fwait:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # fwait
3 | # use fzf to match against a process and wait for it to finish
4 | # typically used like:
5 | # fwait && echo 'do something else'
6 |
7 | fwait() {
8 | local pid procs
9 | procs="$(ps -ef)"
10 | pid="$(sed 1d <<<"${procs}" | fzf +m --tac -q "$*" | awk '{print $2}')"
11 | [[ -z "$pid" ]] && return 1
12 | ps -opid "${pid}" || return 1 # make sure its still running. might have exited in the time between user selection and now
13 | watch -g ps -opid "${pid}"
14 | }
15 |
--------------------------------------------------------------------------------
/.config/zsh/functions/mkcd:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # Create a new directory and enter it
3 | # Source: https://unix.stackexchange.com/a/9124
4 |
5 | function mkcd() {
6 | case "$1" in
7 | */.. | */../) cd -- "$1" ;; # that doesn't make any sense unless the directory already exists
8 | /*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1" ;;
9 | /*) mkdir -p "$1" && cd "$1" ;;
10 | */../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1" ;;
11 | ../*) (cd .. && mkdir -p "${1#.}") && cd "$1" ;;
12 | *) mkdir -p "./$1" && cd "./$1" ;;
13 | esac
14 | }
15 |
--------------------------------------------------------------------------------
/.config/zsh/functions/ranger:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # wraps ranger to cd to rangers' directory when exiting
3 | # Modified from:
4 | # https://github.com/ranger/ranger/wiki/Integration-with-other-programs#changing-directories
5 |
6 | ranger() {
7 | _call_ranger() {
8 | if [[ -n "$PIPENV_ACTIVE" ]]; then
9 | /usr/bin/ranger "$@" || return $?
10 | else
11 | command ranger "$@" || return $?
12 | fi
13 |
14 | }
15 |
16 | local IFS tempfile
17 | local -a ranger_args=()
18 | IFS=$'\t\n'
19 | tempfile="$(mktemp -t ranger.XXXXXX)"
20 | ranger_args+=(--cmd="map S chain shell echo %d > "$tempfile"; quitall!")
21 | ranger_args+=("$@")
22 |
23 | _call_ranger "${ranger_args[@]}"
24 | [[ -f "$tempfile" ]] && cd -- "$(cat "$tempfile")"
25 | command rm -f "$tempfile"
26 | unfunction _call_ranger
27 | }
28 |
--------------------------------------------------------------------------------
/.config/zsh/functions/tm:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # tm - create new tmux session, or switch to existing one
3 | # `tm` to run tmpick
4 | # `tm irc` will attach to the irc session (if it exists), else it will create it.
5 |
6 | tm() {
7 | [[ -n "$TMUX" ]] && change="switch-client" || change="attach-session"
8 | # if name specified, create/attach
9 | if [[ -n $1 ]]; then
10 | tmux $change -t "$1" 2>/dev/null || (tmux new-session -d -s "$1" && tmux $change -t "$1")
11 | return
12 | fi
13 | tmpick
14 | }
15 |
--------------------------------------------------------------------------------
/.config/zsh/functions/tmpick:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # pick a tmux session if active, else attach/create a new one
3 |
4 | tmpick() {
5 | if [[ -n "$TMUX" ]]; then
6 | # if in tmux, pick a window
7 | tmux choose-window
8 | else
9 | # else
10 | if tmux list-sessions >/dev/null 2>&1; then
11 | # if tmux is active somewhere, attach
12 | tmux attach
13 | else
14 | tmux
15 | fi
16 | fi
17 | }
18 |
--------------------------------------------------------------------------------
/.config/zsh/functions/update:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # Update typically used packages
3 |
4 | function update() {
5 | wait-for-internet --text "(waiting for internet)"
6 | echo "Updating system (pacman/brew/termux) packages..."
7 | case "$ON_OS" in
8 | mac*)
9 | brew update && brew upgrade
10 | brew upgrade --cask
11 | ;;
12 | linux_arch*)
13 | paru -Syu
14 | housekeeping-info
15 | havecmd flatpak && flatpak update
16 | ;;
17 | android*)
18 | pkg update
19 | ;;
20 | windows*)
21 | sudo apt update && sudo apt upgrade
22 | ;;
23 | esac
24 | yadm bootstrap
25 | }
26 |
--------------------------------------------------------------------------------
/.config/zsh/functions/which-cat:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | #runs which, and prints the contents of the function/script
3 |
4 | function which-cat() {
5 | local COMMAND_OUTPUT USER_INPUT
6 | USER_INPUT="${1:?Must provide a command to lookup}"
7 | if COMMAND_OUTPUT="$(which "${USER_INPUT}")"; then
8 | # if the file is readable
9 | if [[ -r "${COMMAND_OUTPUT}" ]]; then
10 | if iconv --from-code="utf-8" --to-code="utf-8" "${COMMAND_OUTPUT}" >/dev/null 2>&1; then
11 | command cat "${COMMAND_OUTPUT}"
12 | else
13 | file "${COMMAND_OUTPUT}"
14 | fi
15 | else
16 | # error finding command, or its an alias/function
17 | printf '%s\n' "${COMMAND_OUTPUT}"
18 | fi
19 | else
20 | printf '%s\n' "${COMMAND_OUTPUT}" >&2
21 | fi
22 | }
23 |
--------------------------------------------------------------------------------
/.config/zsh/hpi.zsh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/zsh
2 | # on some machines (WSL/termux),
3 | # I can't sync to the ~/.config directory easily
4 | # so this is a workaround, which syncs to somewhere
5 | # else syncthing has access to and periodically
6 | # rsyncs to the ~/.config directory
7 | # this is called from android.zsh/windows.zsh files
8 |
9 | sync_hpi_config() {
10 | local hpi_synced_dir
11 | echo 'Syncing HPI config...'
12 | for base in "$WHOME" "$HOME/storage/shared"; do
13 | hpi_synced_dir="${base}/hpi_config"
14 | [[ -d "$hpi_synced_dir" ]] || continue
15 | rsync -Pavh "$hpi_synced_dir/my" ~/.config/my/
16 | chmod -x ~/.config/my/my/config/*.py
17 | return 0
18 | done
19 | printf 'Could not find synced HPI config\n'
20 | }
21 |
--------------------------------------------------------------------------------
/.config/zsh/source_aliases.zsh:
--------------------------------------------------------------------------------
1 | ALIAS_DIR="${ZDOTDIR}/aliases"
2 | source "${ALIAS_DIR}/aliases" # General aliases
3 | source "${ALIAS_DIR}/git_aliases" # Git aliases (from oh-my-zsh)
4 | source "${ALIAS_DIR}/project_aliases" # Aliases for my own projects
5 | source "${ALIAS_DIR}/dev_aliases" # language tooling/programming aliases
6 | # Personal Aliases (e.g. ssh to servers)
7 | source_if_exists "${HPIDATA}/personal_aliases"
8 | # Tokens for interacting with APIs etc
9 | source_if_exists "${HPIDATA}/tokens"
10 |
--------------------------------------------------------------------------------
/.config/zsh/ssh.zsh:
--------------------------------------------------------------------------------
1 | # add both my SSH keys to an agent
2 | # this is so that I can use multiple Github accounts
3 | SHARED_AUTH_SOCK="${TMPDIR:-/tmp}/zsh_shared_socket"
4 | if [[ ! -S "$SHARED_AUTH_SOCK" ]]; then
5 | eval "$(ssh-agent)"
6 | # link socket to a shared location
7 | ln -sf "$SSH_AUTH_SOCK" "$SHARED_AUTH_SOCK"
8 | ssh-add -l >/dev/null || {
9 | for ssh_key in "${HOME}/.ssh/id_rsa" "${HOME}/.ssh/id_ed25519"; do
10 | if [[ -e "$ssh_key" ]]; then
11 | ssh-add "$ssh_key"
12 | else
13 | printf "Key doesn't exist: %s\n" "$ssh_key"
14 | fi
15 | done
16 | }
17 | fi
18 | export SSH_AUTH_SOCK="$SHARED_AUTH_SOCK"
19 |
--------------------------------------------------------------------------------
/.config/zsh/windows.zsh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | # run bgproc jobs once every 2 hours
3 | # https://github.com/purarue/bgproc
4 | evry 1 hour -run_windows_jobs && bgproc_on_machine -on
5 |
6 | # sync HPI config from syncthing directory to WSL .config/my directory
7 | evry 10 minutes -sync_hpi_config && sync_hpi_config
8 |
9 | # update mod time on a file so I can figure out when I last
10 | # used my windows machine, to make sure I update it periodically
11 | touch "${HOME}/data/windows_terminal_opened"
12 |
13 | # In WSL, cache the path to the windows home directory,
14 | # something like /mnt/c/Users/Name
15 | WHOME_FILE="${HOME}/.cache/whome"
16 | [[ -d "${HOME}/.cache" ]] || mkdir -p "${HOME}/.cache"
17 | [[ -f "${WHOME_FILE}" ]] || wslpath "$(wslvar USERPROFILE)" >"${WHOME_FILE}"
18 | WHOME="$(cat "${WHOME_FILE}")"
19 | export WHOME
20 |
--------------------------------------------------------------------------------
/.local/scripts/cross-platform/editor:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec ttt nvim "$@"
3 |
--------------------------------------------------------------------------------
/.local/scripts/cross-platform/lock-screen:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Lock the screen
3 | # the daemon process creates the pixelated image every minute in the background
4 | # so that i3lock doesn't have to wait for the image to be generated when run
5 |
6 | case "$ON_OS" in
7 | mac*)
8 | pmset displaysleepnow
9 | exit 0
10 | ;;
11 | linux*)
12 | if [ -n "$WAYLAND_DISPLAY" ]; then
13 | hyprlock
14 | elif [ "$1" = "-b" ]; then # daemon
15 | while true; do
16 | scrot --silent --overwrite "${HOME}/.cache/desktop.png"
17 | magick -scale 2% -scale 5000% "${HOME}/.cache/desktop.png" "${HOME}/.cache/pixel.png"
18 | sleep 120
19 | done
20 | else
21 | i3lock -ni "${HOME}/.cache/pixel.png"
22 | fi
23 | ;;
24 | *)
25 | echo "Dont know how to lock screen..." >&2
26 | ;;
27 |
28 | esac
29 |
--------------------------------------------------------------------------------
/.local/scripts/cross-platform/playping:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Sends a notification-like ping
3 |
4 | case "$ON_OS" in
5 | linux*)
6 | exec paplay /usr/share/sounds/freedesktop/stereo/message.oga
7 | ;;
8 | mac*)
9 | exec afplay /System/Library/Sounds/Ping.aiff
10 | ;;
11 | windows*)
12 | exec powershell.exe -c '(New-Object Media.SoundPlayer "C:\Windows\Media\ding.wav").PlaySync();'
13 | ;;
14 | android_termux*)
15 | exec termux-vibrate
16 | ;;
17 | *) ;;
18 | esac
19 |
--------------------------------------------------------------------------------
/.local/scripts/cross-platform/print-or-notify:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # if on a terminal, just print what the user passed
3 | # as arguments or from STDIN. otherwise, use the notify script
4 | # here to send a notification
5 |
6 | TEXT="${*:-$(cat)}"
7 |
8 | if attached-to-terminal; then
9 | echo "$TEXT"
10 | else
11 | notify "${TEXT}"
12 | fi
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/albumify-singles:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # assumes you're in the directory with the files you want to run
3 | # converts a bunch of singles to a bunch of albums with the individual
4 | # singles. This is useful to maintain album art for singles
5 |
6 | while read -r line; do
7 | name=$(remove-extension "$line")
8 | if [[ -f "$name" ]]; then
9 | echo "Error: ${name} already exists" >&2
10 | continue
11 | fi
12 | mkdir "$name"
13 | cp "$line" "$name"
14 | done < <(list-music)
15 |
--------------------------------------------------------------------------------
/.local/scripts/generic/ansicolors:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | for attr in 0 1 4 5 7; do
3 | echo "------------------------------------------------"
4 | printf "ESC[%s;Foreground;Background - \n" $attr
5 | for fore in 30 31 32 33 34 35 36 37; do
6 | for back in 40 41 42 43 44 45 46 47; do
7 | printf '\033[%s;%s;%sm %02s;%02s\033[0m' \
8 | $attr $fore $back $fore $back
9 | done
10 | printf '\n'
11 | done
12 | done
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/audio2mp3:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # AUTHOR: gotbletu (@gmail|twitter|youtube|github|lbry)
3 |
4 | helpmsg() {
5 | printf "%s\n" "desc: convert to mp3 audio"
6 | printf "%s\n" "depend: ffmpeg lame"
7 | printf "\n"
8 | printf "%s\n" "usage: ${0##*/} [file]"
9 | printf "\n"
10 | printf "%s\n" " $ ${0##*/} file.m4a"
11 | printf "%s\n" " $ ${0##*/} file1.m4a file2.m4a file3.m4a"
12 | printf "%s\n" " $ ${0##*/} *.m4a"
13 | }
14 | if [ $# -lt 1 ]; then
15 | helpmsg
16 | exit 1
17 | elif [ "$1" = -h ] || [ "$1" = --help ]; then
18 | helpmsg
19 | exit 0
20 | else
21 | myArray=("$@")
22 | for arg in "${myArray[@]}"; do
23 | ffmpeg -i "$arg" -codec:a libmp3lame -qscale:a 2 "${arg%.*}.mp3"
24 | done
25 | fi
26 |
--------------------------------------------------------------------------------
/.local/scripts/generic/auto-subtitle-install:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # uses the auto-subtitle fork which removes a couple bugs
3 | # https://github.com/Irvingouj/auto-subtitle
4 | #
5 | # for whatever reason that doesn't install ffmpeg-python,
6 | # so this injects that into that venv
7 | #
8 | # uses 3.11.9 since that is the last supported version by
9 | # openai-whisper
10 | set -ex
11 | if [[ -z "$PYENV_ROOT" ]]; then
12 | echo "PYENV_ROOT not set" >&2
13 | exit 1
14 | fi
15 | PYTHON_VER="3.11.9"
16 | PYTHON_311="$PYENV_ROOT/versions/$PYTHON_VER/bin/python"
17 | if [[ ! -f "$PYTHON_311" ]]; then
18 | echo "python $PYTHON_VER not found, installing..." >&2
19 | pyenv install "$PYTHON_VER" || exit $?
20 | fi
21 | pipx install --verbose git+https://github.com/Irvingouj/auto-subtitle --python "$PYTHON_311"
22 | pipx inject auto-subtitle ffmpeg-python
23 |
--------------------------------------------------------------------------------
/.local/scripts/generic/basher-upgrade-all:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | while read -r pkg; do
4 | echo "Updating ${pkg}..." 1>&2
5 | basher upgrade "${pkg}" || exit $?
6 | done < <(basher outdated | spkglist)
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/bashx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | SCRIPT="${1?:No script provided}"
3 | shift || true
4 | declare SCRIPT_PATH="$SCRIPT"
5 | if [[ ! -f "$SCRIPT_PATH" ]]; then
6 | SCRIPT_PATH="$(which "$SCRIPT_PATH")"
7 | fi
8 | exec bash -x "$SCRIPT_PATH" "$@"
9 |
--------------------------------------------------------------------------------
/.local/scripts/generic/beet-search:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 | set -e
5 |
6 | search_with_key() {
7 | local key="${1?:must provide key}"
8 | shift
9 | beet ls "${key}:$*" --path
10 | }
11 |
12 | search() {
13 | search_with_key 'albumartist_sort' "$@" || return $?
14 | search_with_key 'artist_sort' "$@" || return $?
15 | search_with_key 'album' "$@" || return $?
16 | search_with_key 'title' "$@" || return $?
17 | search_with_key 'composer_sort' "$@" || return $?
18 | }
19 |
20 | main() {
21 | if [[ -z "$*" ]]; then
22 | echo "Usage: beet-fzf " >&2
23 | return 1
24 | fi
25 | search "$@" | unique | fzf --preview 'beet info {}' --preview-window=right:50%
26 | }
27 |
28 | main "$@" || exit $?
29 |
--------------------------------------------------------------------------------
/.local/scripts/generic/bookmark-open:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # allow me to open a URL from https://github.com/purarue/bookmark.txt
3 |
4 | ENTRY_CHOICE="$(bookmark -p list | head -n -2 | picker -p "Open which bookmark? > ")"
5 | URL="$(echo "${ENTRY_CHOICE}" | urlextract | head -n 1)"
6 | [ -z "${URL}" ] && exit 1
7 | openurl "${URL}"
8 |
--------------------------------------------------------------------------------
/.local/scripts/generic/center-text:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Accepts a string as the first argument
3 | # Centers the text vertically on the screen
4 |
5 | MESSAGE="${1:?Specify the message to print as the first argument}"
6 |
7 | clear
8 | LINES="$(($(tput lines) / 2))"
9 | # center text vertically
10 | for _ in $(seq "${LINES}"); do
11 | echo
12 | done
13 | # center text horizontally
14 | COLUMNS="$(tput cols)"
15 | printf "%*s\n" $(((${#1} + COLUMNS) / 2)) "${MESSAGE}"
16 | # move prompt to bottom of screen
17 | for _ in $(seq $((LINES - 1))); do
18 | echo
19 | done
20 |
--------------------------------------------------------------------------------
/.local/scripts/generic/click-repeat:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import time
4 |
5 | import pyautogui
6 | import click
7 |
8 |
9 | @click.command()
10 | @click.argument("SLEEP_TIME", type=int, default=1)
11 | def main(sleep_time: int) -> None:
12 | """
13 | clicks the mouse (cross-platform) every few seconds
14 | """
15 | click.echo(
16 | f"Clicking the mouse every {sleep_time} second{'s' if sleep_time != 1 else ''}..."
17 | )
18 | while True:
19 | pyautogui.click()
20 | time.sleep(sleep_time)
21 |
22 |
23 | if __name__ == "__main__":
24 | main()
25 |
--------------------------------------------------------------------------------
/.local/scripts/generic/clp:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # accepts input from STDIN, sends text back to STDOUT
3 | # copies what it received to the clipboard
4 | # used in vim:
5 | # https://purarue.xyz/x/programming/languages/shell_tools/vim/magic_wands/
6 | STDIN="$(cat)"
7 | printf '%s\n' "${STDIN}"
8 | printf '%s' "${STDIN}" | clipcopy
9 | if [[ "$(echo "${STDIN}" | wc -l)" == 1 ]]; then
10 | exec notify "${APP:-'clp'}" "$(printf 'Copied to clipboard: %s' "${STDIN}")"
11 | else
12 | exec notify "${APP:-'clp'}" "$(printf 'Copied %d lines to clipboard' "$(echo "${STDIN}" | wc -l)")"
13 | fi
14 |
--------------------------------------------------------------------------------
/.local/scripts/generic/cstimer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Run cstimer on my local machine
3 |
4 | set -e
5 | set -o pipefail
6 |
7 | main() {
8 | local clone_loc cache_dir
9 | # if cstimer server is already running, then open in browser
10 | if curl --silent http://localhost:4633 >/dev/null; then
11 | rm "$(evry location -open-cstimer)"
12 | backup-cubing
13 | else
14 | # otherwise run the server
15 | cache_dir="${XDG_CACHE_DIR:-${HOME}/.cache}"
16 | clone_loc="${cache_dir}/cstimer"
17 | [[ -e "$clone_loc" ]] || git clone 'https://github.com/purarue/cstimer' "$clone_loc"
18 | cd "$clone_loc" || exit 1
19 | make server
20 | fi
21 | }
22 |
23 | main || exit $?
24 |
--------------------------------------------------------------------------------
/.local/scripts/generic/current-week:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import datetime
4 |
5 | print(int(datetime.date.today().strftime("%U")))
6 |
--------------------------------------------------------------------------------
/.local/scripts/generic/datenow:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # prompt current date in lots of formats
3 | # and copy that to your command line
4 |
5 | print_dates() {
6 | date "+%m/%d/%y # us date"
7 | date "+%d/%m/%y # standard date"
8 | date "+%Y/%m/%d # YYYY/MM/DD (blog)"
9 | date "+%F # YYYY-MM-DD"
10 | date "+%F %T # YYYY-MM-DD HH:MM:SS"
11 | date "+%c # full date"
12 | date "+%A, %B %e, %Y, %l:%M:%S%p # now"
13 | date "+%s # epoch"
14 | }
15 |
16 | PICKED="$(print_dates | picker -p "Pick Date > ")" || exit $?
17 | DATESTR="$(cut -d "#" -f1 <<<"${PICKED}" | xargs echo)"
18 | printf '%s\n' "${DATESTR}"
19 | printf '%s' "${DATESTR}" | clipcopy
20 | notify "datenow" "Copied '${DATESTR}' to clipboard"
21 |
--------------------------------------------------------------------------------
/.local/scripts/generic/decode64:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """Usage:
4 | decode64 SUBSTR HASH
5 | decode64 --help
6 |
7 | Will repetitvely base64 decode HASH till SUBSTR is in decoded string
8 | If SUBSTR is a number, will decode HASH that many times
9 | """
10 |
11 | import base64
12 | import docopt
13 |
14 | assert __doc__ is not None
15 | args = docopt.docopt(__doc__)
16 | hash = args["HASH"]
17 |
18 | try:
19 | for _ in range(int(args["SUBSTR"])):
20 | hash = base64.b64decode(hash)
21 | except ValueError:
22 | while args["SUBSTR"].lower() not in str(hash.lower()):
23 | hash = base64.b64decode(hash)
24 |
25 | print(str(hash, "utf-8"))
26 |
--------------------------------------------------------------------------------
/.local/scripts/generic/describe-evry-json:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 |
5 | main() {
6 | jq -r '.[] | select((.type == "tag_name") or .type == "till_next_pretty") | .body' | paste -d " " - - | sed -e 's/ / - /' || return $?
7 | }
8 |
9 | main || exit $?
10 |
--------------------------------------------------------------------------------
/.local/scripts/generic/dict:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # AUTHOR: gotbletu (@gmail|twitter|youtube|github|lbry)
3 |
4 | helpmsg() {
5 | printf "%s\n" "desc: online dictionary lookup"
6 | printf "\n"
7 | printf "%s\n" "usage: ${0##*/} [word]"
8 | printf "\n"
9 | printf "%s\n" " $ ${0##*/} telomere"
10 | }
11 | if [ $# -lt 1 ]; then
12 | helpmsg
13 | exit 1
14 | elif [ "$1" = -h ] || [ "$1" = --help ]; then
15 | helpmsg
16 | exit 0
17 | fi
18 | exec curl -s dict://dict.org/d:"$1" | less
19 |
--------------------------------------------------------------------------------
/.local/scripts/generic/discord-currently-listening-presence:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | wait-for-internet
3 | # https://github.com/purarue/currently_listening
4 | with-secrets currently_listening_py discord-presence --server-url wss://purarue.xyz/currently_listening/ws --image-url https://purarue.xyz/currently_listening/currently-listening-image "$@"
5 | sleep 30m
6 |
--------------------------------------------------------------------------------
/.local/scripts/generic/docx-md:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | # convert a docx to markdown and open it in nvim
4 | TARGET="$(remove-extension "${1:?Provide the docx to convert as the first argument}").md"
5 | pandoc -s "$1" -t markdown -o "${TARGET}"
6 | exec nvim "${TARGET}"
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/dragon-sink:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # brings up a prompt to drag files into.
3 | # If no flags are provided, copies any files
4 | # dragged into the prompt into the current directory.
5 | # if the --mv flag is provided, moves files instead
6 | declare cmd drg files
7 | [[ "$1" = "--mv" ]] && cmd="mv" || cmd="cp"
8 | drg="$(command -v dragon-drop)" || drg="$(command -v dragon)" || {
9 | echo "couldn't find the dragon-drop or dragon command"
10 | exit 1
11 | }
12 | files="$("$drg" --target --and-exit)"
13 | [[ -z "$files" ]] && exit 1
14 | while IFS= read -r f; do
15 | path="${f#file://}"
16 | $cmd -v "${path}" "$(pwd)/$(basename "${path}")"
17 | done <<<"$files"
18 |
--------------------------------------------------------------------------------
/.local/scripts/generic/emoji:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | launch 'sh -c "kitty +kitten unicode_input text | clp"'
3 |
--------------------------------------------------------------------------------
/.local/scripts/generic/exifalbumrename:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Renames a song to use its EXIF attributes
3 | # I use this when downloading stuff using
4 | # https://github.com/iheanyi/bandcamp-dl
5 | # since that slugifies names
6 |
7 | if [[ -z "$1" ]]; then
8 | echo "Must provide paths to rename" >&2
9 | exit 1
10 | fi
11 |
12 | # cd so moving files is easier
13 | # this is best run in the same directory as what you're modifying
14 | cd "$(realpath "$(dirname "$1")")" || exit
15 |
16 | for path in "$@"; do
17 | ppath="$(basename "${path}")" || continue
18 | trackno="$(exifattr "${ppath}" 'Track')" || continue
19 | trackname="$(exifattr "${ppath}" 'Title')" || continue
20 | ext="$(get-extension "${ppath}")" || continue
21 | newpath="$(printf '%d - %s.%s' "${trackno}" "${trackname}" "${ext}")"
22 | mv -v "${ppath}" "${newpath}"
23 | done
24 |
--------------------------------------------------------------------------------
/.local/scripts/generic/exifinfo:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | FILE="${1?Must provide a file as the first argument to dump info about}"
4 | if [ ! -e "${FILE}" ]; then
5 | printf "%s does not exist\n" "${FILE}"
6 | exit 1
7 | fi
8 | if [ -d "${FILE}" ]; then
9 | printf "Path must be a file, %s is a directory\n" "${FILE}"
10 | exit 1
11 | fi
12 |
13 | # Use exiftool to get data, but don't use
14 | # its mime type - doesn't match anything
15 | # I can figure out.
16 | {
17 | exiftool "${FILE}" | grep -v "^MIME Type"
18 | printf "MIME Type : %s" "$(file-mime "${FILE}")"
19 | } | sort
20 |
21 | if [ -n "$2" ]; then
22 | shift
23 | echo "Warning: ignoring additional arguments: $*" >&2
24 | fi
25 |
--------------------------------------------------------------------------------
/.local/scripts/generic/ffmpeg-then-notify:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ffmpeg "$@" >>/tmp/mpv-ffmpeg.log 2>&1 || {
3 | notify -u critical "ffmpeg failed, check log"
4 | exit 1
5 | }
6 | notify "done encoding"
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/figlet-one-line:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """
4 | runs figlet and renders the text so that it can be
5 | embedded into code as a single string with newlines
6 |
7 | copies that to my clipboard
8 | """
9 |
10 |
11 | import subprocess
12 |
13 | import click
14 | from pura.clipboard import clipcopy
15 |
16 |
17 | @click.command(help=__doc__)
18 | @click.argument("TEXT")
19 | def main(text: str) -> None:
20 | resp = subprocess.check_output(["figlet", text]).decode("utf-8")
21 | rendered = repr(resp)
22 | clipcopy(rendered)
23 | click.echo(f"copied to clipboard:\n\n{resp}")
24 |
25 |
26 | if __name__ == "__main__":
27 | main()
28 |
--------------------------------------------------------------------------------
/.local/scripts/generic/file-modified-ago:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # prints how long a file was modified ago in human readable text
3 |
4 | # disable debug mode, if enabled
5 | [[ -n "$EVRY_DEBUG" ]] && unset EVRY_DEBUG
6 | [[ -n "$EVRY_JSON" ]] && unset EVRY_JSON
7 |
8 | FILE="${1?Error: no file given}"
9 | shift
10 |
11 | if [[ ! -r "$FILE" ]]; then
12 | echo "Error: cannot read file: $FILE" >&2
13 | exit 1
14 | fi
15 |
16 | FILE_MODIFIED_AT="$(stat -c %Y "$FILE")" || exit 1
17 | CURRENT_TIME="$(date +%s)" || exit 1
18 |
19 | MODIFIED_AGO="$((CURRENT_TIME - FILE_MODIFIED_AT))"
20 | MODIFIED_PRETTY="$(EVRY_JSON=1 evry duration "$MODIFIED_AGO"s | jq '[.[] | {key: .type, value: .body}] | from_entries | .duration_pretty' -r)"
21 | echo "$MODIFIED_PRETTY"
22 |
--------------------------------------------------------------------------------
/.local/scripts/generic/generate-subs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # uses auto-subtitle (a local openai whisper subtitle generator wrapper) script
3 | # installed in a pipx venv:
4 | # https://purarue.xyz/d/auto-subtitle-install?redirect
5 |
6 | if [[ ! -f "$1" ]]; then
7 | echo "Usage: $0 "
8 | exit 1
9 | fi
10 |
11 | process_file() {
12 | file="$1"
13 | full_path="$(realpath "$file")"
14 | srt_path="${full_path%.*}.srt"
15 | if [[ ! -f "$srt_path" ]]; then
16 | echo "Generating subtitles for $full_path" >&2
17 | auto_subtitle --srt_only true "$full_path" --model medium.en || {
18 | echo "Failed to generate subtitles for $file" >&2
19 | rm -f "$srt_path"
20 | }
21 | fi
22 | }
23 |
24 | for file in "$@"; do
25 | process_file "$file"
26 | done
27 |
--------------------------------------------------------------------------------
/.local/scripts/generic/genpass:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | # generates a password and puts it on your clipboard
7 | # uses https://github.com/purarue/genpasswd
8 | # or 'pip install diceware'
9 | generate() {
10 | if [[ -n "$USE_DICEWARE" ]]; then
11 | if [[ -n "$1" ]]; then
12 | diceware "$@"
13 | else
14 | diceware -d '_' -n 5 "$@"
15 | fi
16 | else
17 | genpasswd "$@" || return $?
18 | fi
19 | }
20 |
21 | pw="$(generate "$@")" || exit $?
22 | echo "$pw"
23 | echo "$pw" | clipcopy
24 | echo 'Copied password to clipboard'
25 | notify 'Copied password to clipboard'
26 |
--------------------------------------------------------------------------------
/.local/scripts/generic/ghstars:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if ! has-git-remote; then
3 | echo 'no git remote' >&2
4 | exit 1
5 | fi
6 | declare url
7 | url="$(git open --print | cut -d'/' -f4-5)"
8 | if [[ -z "$url" ]]; then
9 | echo 'no url' >&2
10 | exit 1
11 | fi
12 | if resp="$(gh api --paginate "repos/${url}/stargazers")"; then
13 | jq '.[].login' -r <<<"$resp"
14 | else
15 | printf 'Could not fetch repos/%s/stargazers\n' "$url"
16 | exit 1
17 | fi
18 |
--------------------------------------------------------------------------------
/.local/scripts/generic/gifpreview:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # accepts a gif as the first argument,
3 | # converts and prints the path to the
4 | # middle frame of the gif
5 |
6 | path="${1:?"No file given to convert to a gif"}"
7 | # validate input
8 | case "$path" in
9 | *.gif) ;;
10 |
11 | *)
12 | echo "Must provide a .gif file as the argument" 1>&2
13 | exit 1
14 | ;;
15 | esac
16 | [ -e /tmp/gifpreview ] && rm -rf /tmp/gifpreview
17 | mkdir /tmp/gifpreview
18 | # convert gif to images
19 | magick -coalesce "$path" /tmp/gifpreview/preview.png || exit 1
20 | # get the middle image
21 | find /tmp/gifpreview >/tmp/gifpreview/images.log
22 | middleline="$(($(wc -l &1
11 | exit 1
12 | fi
13 | verify_giturlparse || {
14 | echo "Couldn't import giturlparse, 'pip install giturlparse'" >&2
15 | exit 1
16 | }
17 | if https_url="$(printf '%s' "${remote_url}" | /usr/bin/env python3 -c "import sys, giturlparse; print(giturlparse.parse(sys.stdin.read().strip()).urls['https'])" 2>/dev/null)"; then
18 | echo "${https_url}"
19 | exit 0
20 | else
21 | printf "Could not parse %s into a HTTP URL properly.\n" "${remote_url}" 2>&1
22 | exit 1
23 | fi
24 | else
25 | echo "Not currently in a git repo" 2>&1
26 | exit 1
27 | fi
28 |
--------------------------------------------------------------------------------
/.local/scripts/generic/gron-to-csv:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # convert gron output to csv
3 | # replace the = with a comma, remove the trailing semicolon
4 | #
5 | # need to re-add those if you want to convert back to json
6 |
7 | input="${1:?Please provide input file}"
8 | gron --monochrome "$input" | sed -e 's/;$//' -e 's/ = /,/'
9 |
--------------------------------------------------------------------------------
/.local/scripts/generic/heart:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import click
4 |
5 | HEARTS = [
6 | "❤️",
7 | "🧡",
8 | "💛",
9 | "💚",
10 | "💙",
11 | "💜",
12 | "🤍",
13 | "🤎",
14 | "💖",
15 | ]
16 |
17 |
18 | @click.command()
19 | @click.option("-a", "--all", "_all", is_flag=True, help="Print all hearts")
20 | def main(_all: bool) -> None:
21 | chosen: str
22 | if _all:
23 | chosen = "".join(HEARTS)
24 | else:
25 |
26 | import random
27 |
28 | chosen = random.choice(HEARTS)
29 | click.echo(chosen)
30 |
31 |
32 | if __name__ == "__main__":
33 | main()
34 |
--------------------------------------------------------------------------------
/.local/scripts/generic/in-path:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # check each directory in $PATH for script name
4 | # if found, print full path to script and exit
5 |
6 | declare script_name="${1?missing script name}"
7 | declare target
8 | for dir in ${PATH//:/ }; do
9 | target="${dir}/${script_name}"
10 | if [[ -f "${target}" ]]; then
11 | echo "${target}"
12 | if [[ ! -x "${target}" ]]; then
13 | echo "Warning: ${target} is not executable" >&2
14 | fi
15 | fi
16 | done
17 |
--------------------------------------------------------------------------------
/.local/scripts/generic/jqc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # pipe data into this, pass any jq filters as arguments
3 |
4 | set -o pipefail
5 | set -e
6 |
7 | jsonc-to-json | jq "$@"
8 |
--------------------------------------------------------------------------------
/.local/scripts/generic/jsonc-to-json:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import json
4 | import fileinput
5 | import contextlib
6 |
7 | from jsonc_parser.parser import JsoncParser
8 |
9 |
10 | def main() -> None:
11 | lines = list(fileinput.input())
12 | data = JsoncParser.parse_str("\n".join(lines))
13 | print(json.dumps(data, indent=4))
14 |
15 |
16 | if __name__ == "__main__":
17 | with contextlib.suppress(KeyboardInterrupt):
18 | main()
19 |
--------------------------------------------------------------------------------
/.local/scripts/generic/jumplist:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # generates a jumplist of directories, so I can cd to one
3 | # https://purarue.xyz/d/cd.zsh?dark
4 | #
5 | # using
6 | # https://purarue.xyz/d/tttlist?dark
7 | # and the commits modules to scan my local repos
8 | # https://github.com/karlicoss/HPI/blob/master/my/coding/commits.py
9 |
10 | set -e
11 | set -o pipefail
12 |
13 | # update tttlist cache once a day
14 | tttlist_cached() {
15 | evry 1d -tttlist && tttlist >~/.cache/tttlist
16 | cat ~/.cache/tttlist
17 | }
18 |
19 | {
20 | tttlist_cached
21 | hpi query my.coding.commits.repos -s | jq -r
22 | } | grep -v '^/tmp' | unique || exit $?
23 |
--------------------------------------------------------------------------------
/.local/scripts/generic/list-git-dirs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | DIR="$1"
4 | shift
5 | if [[ -z "$DIR" ]]; then
6 | echo "Usage: list-git-dirs " >&2
7 | exit 1
8 | fi
9 |
10 | exec fd --base-directory "${DIR}" -LIH --type d '^.git$' "$@" --absolute-path -x echo '{//}'
11 |
--------------------------------------------------------------------------------
/.local/scripts/generic/list-my-git-repos:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | RELATIVE=0
6 | # accept -r to print relative to home directory
7 | [[ "$1" == "-r" ]] && RELATIVE=1
8 |
9 | parallel -j+0 'list-git-dirs {}' <~/.cache/repo_bases.txt | {
10 | if ((RELATIVE)); then
11 | sed -e "s@^$HOME/@~/@"
12 | else
13 | cat
14 | fi
15 | }
16 |
--------------------------------------------------------------------------------
/.local/scripts/generic/mal_sources_toggle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -u
4 |
5 | declare SCRIPT="${HPIDATA}/reminder-sink/mal_sources"
6 |
7 | [[ -e "$SCRIPT" ]] || {
8 | printf 'Could not find script at %s\n' "$SCRIPT" 1>&2
9 | exit 1
10 | }
11 |
12 | if [[ -x "$SCRIPT" ]]; then
13 | echo 'Script is executable, making it non-executable'
14 | chmod -x "$SCRIPT"
15 | else
16 | echo 'Script is not executable, making it executable'
17 | chmod +x "$SCRIPT"
18 | fi
19 |
--------------------------------------------------------------------------------
/.local/scripts/generic/manual_on_os:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | case "$(uname -s)" in
4 | Linux*)
5 | if command -v termux-setup-storage >/dev/null 2>&1; then
6 | ON_OS='android'
7 | else
8 | # check if we're in WSL
9 | case "$(uname -r)" in
10 | *Microsoft*)
11 | ON_OS='windows'
12 | ;;
13 | *)
14 | ON_OS='linux'
15 | ;;
16 | esac
17 | fi
18 | ;;
19 | Darwin*)
20 | ON_OS='mac'
21 | ;;
22 | *)
23 | printf "Unknown Operating System...\n" >&2
24 | ;;
25 | esac
26 |
27 | echo "$ON_OS"
28 |
--------------------------------------------------------------------------------
/.local/scripts/generic/mpv-ffmpeg-extract:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | TMPDIR="${TMPDIR:-/tmp}/mpv-logs"
4 | LOGFILE="$(newest "$TMPDIR")" || exit 1
5 | LINE="$(grep '\[encode\] ffmpeg' "$LOGFILE" | tail -n 1)"
6 | if [[ -z "$LINE" ]]; then
7 | echo "No ffmpeg command found in $LOGFILE" >&2
8 | exit 1
9 | fi
10 |
11 | # remove everything before [encode]
12 | echo "ffmpeg ${LINE#*\[encode\] ffmpeg }"
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/mpv-pause-all:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # pauses or unpauses all mpv instances
3 | # pass 'false' to unpause, 'true' to pause (default)
4 |
5 | case "$1" in
6 | "true" | "false" | '') ;;
7 | *)
8 | echo "Usage: $0 [true|false]" >&2
9 | exit 1
10 | ;;
11 | esac
12 | CMD="${1:-true}"
13 |
14 | for socket in $(mpv-active-sockets); do
15 | printf '{ "command": ["set_property", "pause", %s] }\n' "$CMD" | socat - "$socket"
16 | done
17 |
--------------------------------------------------------------------------------
/.local/scripts/generic/mpv_signal_daemon:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # sends a signal to the mpv_history_daemon to check
3 | # if new sockets have been added or any mpv instances
4 | # have quit
5 | #
6 | # https://github.com/purarue/mpv-history-daemon
7 |
8 | pkill -f 'python3 -m mpv_history_daemon daemon' -RTMIN || true
9 |
10 | # if you launch like 'mpv-history-daemon daemon' then
11 | # you can use this instead
12 | # pkill -f 'mpv_history_daemon daemon' -RTMIN || true
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/mv-classify-videos-by-rotation:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | for vid in "$@"; do
4 | rotation="$(exifattr "$vid" Rotation)" || exit $?
5 | mkdir -p "$rotation"
6 | mv -vn "$vid" "$rotation"
7 | done
8 |
--------------------------------------------------------------------------------
/.local/scripts/generic/norg-to-markdown:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # converts neorg file to markdown
3 | # https://github.com/nvim-neorg/neorg
4 |
5 | FILENAME="${1?Error: No filename given}"
6 | FULL_PATH="$(realpath "$FILENAME")"
7 | TARGET="$(replace-extension "$FULL_PATH" md)"
8 |
9 | GIT_DIR="$XDG_CACHE_HOME/norg-pandoc"
10 |
11 | if [[ ! -d "$GIT_DIR" ]]; then
12 | git clone https://github.com/boltlessengineer/norg-pandoc "$GIT_DIR" || exit 1
13 | fi
14 |
15 | cd "$GIT_DIR" || exit 1
16 | exec pandoc --from ./init.lua --to gfm "$FULL_PATH" -o "$TARGET"
17 |
--------------------------------------------------------------------------------
/.local/scripts/generic/optigif:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # optimize gif
3 | OLD_GIF="${1:?provide gif to optimize as first argument}"
4 | NEW_GIF="$(remove-extension "${OLD_GIF}")-opt.gif"
5 | TMP_GIF='/tmp/optimized.gif'
6 | rm -rf "${TMP_GIF}"
7 | gifsicle --colors 256 -O3 "${OLD_GIF}" -o "${TMP_GIF}" && cp -v "${TMP_GIF}" "${NEW_GIF}" || exit $?
8 | # overwrite if specified
9 | [ -n "${OPTIGIF_OVERWRITE}" ] && du -h "${OLD_GIF}" "${NEW_GIF}" && mv -v "${NEW_GIF}" "${OLD_GIF}"
10 |
--------------------------------------------------------------------------------
/.local/scripts/generic/optijpg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | FILE="${1:?provide jpeg to optimize as first argument}"
3 | exec jpegtran -copy none -optimize -outfile "${FILE}" "${FILE}"
4 |
--------------------------------------------------------------------------------
/.local/scripts/generic/org-to-md:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | readonly INPUT="${1:?Provide the .org file to convert from as the first argument}"
4 | readonly OUTPUT="${2:?Provide the output.md path as the second argument}"
5 |
6 | pandoc -t markdown "${INPUT}" >"${OUTPUT}"
7 | # doesn't convert quotes properly
8 | sed -i -e "s|\\\'|\'|g" "$2"
9 |
--------------------------------------------------------------------------------
/.local/scripts/generic/photo-doc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # this copies some picture I just took on my phone from my Camera roll
3 | # to ~/shared/Shared
4 |
5 | STORAGE="${HOME}/storage/"
6 | IMAGE_DIR="${STORAGE}/dcim/Camera/"
7 |
8 | FILE="$(newest -ignore-hidden "${IMAGE_DIR}")"
9 | if [[ -z "$FILE" ]]; then
10 | echo "No new photos"
11 | exit 1
12 | fi
13 |
14 | printf '%s\nModified: %s ago\nMove? [Y|n] ' "$FILE" "$(file-modified-ago "$FILE")"
15 |
16 | read -r answer
17 | [[ "$answer" == [Nn]* ]] && exit 1
18 | to_folder="${HOME}/shared/Shared/photo-doc"
19 | mkdir -p "$to_folder"
20 | mv -vn "$FILE" "$to_folder"
21 |
22 | photos-unsync-recent 1
23 |
--------------------------------------------------------------------------------
/.local/scripts/generic/photos-unsync-recent:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # sometimes after syncing a recent
3 | # photo with rsync, I want to delete
4 | # it instead. photos remain on my phone
5 | # for 28 days, so I delete photos from
6 | # the synced folder that are less than
7 | # 3 days old.
8 |
9 | from="$(backup_to phone_pictures)/Camera" || exit 1
10 |
11 | days='-3'
12 | [[ -n "$1" ]] && days="-$1"
13 |
14 | list-photos() {
15 | find "$from" -type f -mtime "$days" "$@"
16 | }
17 |
18 | list-photos >&2
19 | printf "delete %d synced files from the last %.1f days? (y/N) " "$(list-photos | wc -l)" "$(cut -c2- <<<"$days")"
20 |
21 | read -r answer
22 | [[ "$answer" == [yY]* ]] || exit 0
23 |
24 | echo "deleting..." >&2
25 | list-photos -print -delete >&2
26 |
--------------------------------------------------------------------------------
/.local/scripts/generic/plainplay-m3u:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://github.com/purarue/plaintext-playlist
3 | # Create a m3u file for each file in my playlist
4 |
5 | set -u
6 | set -o pipefail
7 |
8 | TARGET_DIR="${1:?Provide a directory to put the m3u files into}"
9 |
10 | while read -r -d $'\0' playlist; do
11 | target="${TARGET_DIR}/$(replace-extension "$(basename "${playlist}")" m3u)"
12 | printf 'Creating %s\n' "${target}" >&2
13 | plainplay --abs m3u "${playlist}" >"${target}"
14 | done < <(find "${PLAINTEXT_PLAYLIST_PLAYLISTS}" -type f -name "*.txt" -print0)
15 |
--------------------------------------------------------------------------------
/.local/scripts/generic/print-json:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # format and print colored json output
3 | JSON_FILE="${1:?No JSON file provided}"
4 | jq <"${JSON_FILE}" | highlight --out-format=ansi -S json || exit 1
5 |
--------------------------------------------------------------------------------
/.local/scripts/generic/qr:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # converts a string to a qr code and displays it full screen
3 | # if no URL is passed as the first argument, reads from STDIN
4 |
5 | INPUT="${1:-$(cat)}" # if no URL was passed, read from STDIN
6 | TEMP="$(mktemp -p /tmp -d 'qr-XXXX')/img.png" # temporary dir
7 |
8 | qrencode "${INPUT}" -o "${TEMP}" || exit $?
9 | exec openurl "${TEMP}"
10 |
--------------------------------------------------------------------------------
/.local/scripts/generic/remove-leading-spaces:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """
4 | Given some text that has leading spaces on each line,
5 | remove the leading spaces but keep everything aligned
6 | """
7 |
8 | import sys
9 | import contextlib
10 |
11 |
12 | def leading_spaces(line: str) -> int:
13 | i = 0
14 | for char in line:
15 | if char.isspace():
16 | i += 1
17 | else:
18 | break
19 | return i
20 |
21 |
22 | def main() -> None:
23 | lines = sys.stdin.readlines()
24 | if not lines:
25 | return
26 | min_spaces = min(leading_spaces(line) for line in lines if line.strip())
27 | for line in lines:
28 | print(line[min_spaces:], end="")
29 |
30 |
31 | if __name__ == "__main__":
32 | with contextlib.suppress(KeyboardInterrupt):
33 | main()
34 |
--------------------------------------------------------------------------------
/.local/scripts/generic/repos-dirty:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | # prints the absolute path of all git repos in the given directory that have uncommitted changes/untracked files
3 |
4 | in_dir="${1:-$REPOS}"
5 | if [[ -z "$in_dir" ]]; then
6 | echo "Usage: repos-dirty "
7 | exit 1
8 | fi
9 | list-git-dirs "$in_dir" | parallel -k -j+0 'cd {} && has-git-remote && git-has-untracked-or-changes && pwd'
10 |
--------------------------------------------------------------------------------
/.local/scripts/generic/repos-pull-all:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | set -u
4 |
5 | cd "$REPOS" || return 1
6 | list-git-dirs "$REPOS" | parallel --line-buffered -j "$(nproc)" "cd {} && has-git-remote && { git pull; pwd }"
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/rg-nvim:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # fzf all file contents recursively with rg, open the line
3 | # the user selects in my editor
4 |
5 | set -e
6 | set -o pipefail
7 |
8 | rg_lines() {
9 | PICKED_LINE="$(rg --no-heading --with-filename --line-number --color ansi "$*" | fzf --ansi)" || exit $?
10 | [[ -z "${PICKED_LINE}" ]] && return 1
11 | printf '%s\n' "${PICKED_LINE}" | cut -d':' -f'1-2'
12 | }
13 |
14 | declare -a RG_PARTS
15 | # split into filename and line number
16 | readarray -d ':' -t RG_PARTS < <(rg_lines "$@")
17 | [[ -z "${RG_PARTS[*]}" ]] && exit 1
18 | # arithmetic substitution removes extra newline from number
19 | exec editor "+$((RG_PARTS[1]))" "${RG_PARTS[0]}"
20 |
--------------------------------------------------------------------------------
/.local/scripts/generic/rifleman-extract:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # fd | rifleman-extract 'black' # since we format python with black
3 | # prints all the python files that are in the directory (including
4 | # ones that have a shebang line)
5 |
6 | if [[ -z "$1" ]]; then
7 | echo "Usage: $(basename 0) "
8 | exit 1
9 | fi
10 |
11 | jq_str="$(printf 'to_entries[] | select(.key | startswith("%s")) | .value | .[]' "$1")"
12 | rifleman - -j | jq -r "$jq_str"
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/server_clipboard_notify:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 |
5 | usage() {
6 | printf "Pass 'copy' or 'paste' as the first argument\n" >&2
7 | }
8 |
9 | main() {
10 | local tfile
11 | tfile="$(mktemp)"
12 | # shellcheck disable=SC2064
13 | trap "rm -vf '$tfile'" EXIT
14 |
15 | arg="$1"
16 | if [[ -z "$arg" ]]; then
17 | usage
18 | return 1
19 | fi
20 | case "$arg" in
21 | copy | paste)
22 | case "$arg" in
23 | copy)
24 | notify "Copying to server clipboard..."
25 | ;;
26 | paste)
27 | notify "Pasting from server clipboard..."
28 | ;;
29 | esac
30 | server_clipboard "$@" 2>"$tfile"
31 | resp="$(cat "$tfile")"
32 | [[ -n "$resp" ]] && notify "$resp"
33 | ;;
34 | *)
35 | echo "Unknown command: $arg"
36 | usage
37 | return 1
38 | ;;
39 | esac
40 | }
41 |
42 | main "$@" || exit $?
43 |
--------------------------------------------------------------------------------
/.local/scripts/generic/show-pickle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | """
4 | Reads a pickled (python) object from a file
5 | Accepts the file as the first argument
6 | """
7 |
8 | import os
9 | import sys
10 | import pickle
11 | import pprint
12 |
13 | if len(sys.argv) < 2:
14 | print(
15 | "Error: Must provide a file to read a pickle from as the first argument.",
16 | file=sys.stderr,
17 | )
18 | sys.exit(1)
19 |
20 | filepath = os.path.abspath(sys.argv[1])
21 | with open(filepath, "rb") as picklef:
22 | data = pickle.load(picklef)
23 |
24 | pprint.pprint(data)
25 |
--------------------------------------------------------------------------------
/.local/scripts/generic/sign-canvas:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | URL='https://github.com/szimek/signature_pad'
4 | CACHE_DIR="$HOME/.cache/signature_pad"
5 |
6 | [[ -d ~/.cache ]] || mkdir ~/.cache
7 |
8 | if [[ ! -d "$CACHE_DIR" ]]; then
9 | git clone "$URL" "$CACHE_DIR" || exit $?
10 | fi
11 |
12 | cd "$CACHE_DIR/docs" || {
13 | echo "Failed to cd to docs folder"
14 | exit 1
15 | }
16 | setsid -f sh -c 'sleep 1 && openurl localhost:5059'
17 | exec serve -p 5059
18 |
--------------------------------------------------------------------------------
/.local/scripts/generic/spell-dotfiles:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eo pipefail
4 |
5 | list-config-no-hist |
6 | grep -vE 'alacritty|system-config|lynx' |
7 | exists | tr '\n' '\0' |
8 | xargs -0 codespell-conf -I ~/.config/yadm/dotfiles_ignore_words.txt "$@"
9 |
--------------------------------------------------------------------------------
/.local/scripts/generic/star:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # star or unstar a github repository
3 | # requires you to have githubs cli tool 'gh' setup
4 |
5 | set -e
6 | set -o pipefail
7 |
8 | # expects input like username/repo, or the full https URL
9 | repo="${1:?Provide repository or link to star/unstar}"
10 | method="${2:-PUT}" # provide 'DELETE' as second argument to unstar
11 | # get last two items from link
12 | full_name="$repo"
13 | # if this is an HTTPS, remove that so username/repo remains
14 | if [[ "$full_name" =~ https://github\.com ]]; then
15 | full_name="$(cut -d/ -f4- <<<"$repo")"
16 | fi
17 | set -x
18 | exec gh api --silent -X "${method}" "user/starred/${full_name}"
19 |
--------------------------------------------------------------------------------
/.local/scripts/generic/status-code:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | exec curl -s -o /dev/null -w "%{http_code}\n" "${1:?Missing URL}"
3 |
--------------------------------------------------------------------------------
/.local/scripts/generic/sub-rename:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # rename a subtitle file to match the video file so that
3 | # it automatically gets loaded by mpv/video player
4 |
5 | declare video subs
6 |
7 | video="$(gum file -c 'File >')" || exit $?
8 | subs="$(gum file -c 'Subs >')" || exit $?
9 |
10 | # rename the subtitle file to match the video file
11 | cp -v "$subs" "$(remove-extension "$video").srt"
12 |
--------------------------------------------------------------------------------
/.local/scripts/generic/terminal-set-theme:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if [[ "$TERM" = "xterm-kitty" ]]; then
3 | kitten themes --reload-in=all --config-file-name="${HOME}/.config/kitty/theme.conf" "${1:?Must provide theme as kwarg}" || exit $?
4 | fi
5 | printf '#!/usr/bin/env bash\nexport TERMINAL_THEME=%s\n' "$1" >~/.cache/terminal-theme.sh
6 | echo "$1" >~/.cache/terminal-theme
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/timer-till:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # starts a timer which ends at a particular point in the future
3 | # e.g. timer-till 'today at 10pm'
4 | # I often use this with https://purarue.xyz/d/playping-loop?redirect,
5 | # as a sort of alarm/reminder to do something, like:
6 | # timer-till 'today at 4pm' && playping-loop
7 |
8 | declare at now
9 | now="$(epoch)"
10 | at="$(dateq parse -Fepoch "today at $*")" || return $?
11 | [[ -z "$at" ]] && exit 1
12 |
13 | if [[ "$at" -le "$now" ]]; then
14 | echo "Time must be in the future, parsed $(dateq parse -Ftime "$at"), now is $(dateq parse -Ftime "$now")" >&2
15 | exit 1
16 | fi
17 |
18 | exec timer -f "$((at - now))s"
19 |
--------------------------------------------------------------------------------
/.local/scripts/generic/tmux-kill-detached:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | tmux list-sessions | grep -E -v '\(attached\)$' | while IFS=$'\n' read -r line; do
3 | echo "Killing ${line}"
4 | tmux kill-session -t "${line%%:*}"
5 | done
6 |
--------------------------------------------------------------------------------
/.local/scripts/generic/to-github:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # initializes a github repository
3 | # assumes this is a git repository and has a commit
4 | #
5 | # This uses hub instead of gh since it handles the
6 | # 'current directory' initialization nicely
7 |
8 | in-gitdir || {
9 | echo "Not currently in a git repository" >&2
10 | exit 1
11 | }
12 | hub create "$@"
13 | exec git push --set-upstream origin master
14 |
--------------------------------------------------------------------------------
/.local/scripts/generic/to-gitlab:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # initializes a gitlab repository
3 | # assumes this is a git repository and has a commit
4 | in-gitdir || {
5 | echo "Not currently in a git repository" >&2
6 | exit 1
7 | }
8 | git remote add origin "git@gitlab.com:purarue/$(basename "$(pwd)").git"
9 | exec git push --set-upstream origin master
10 |
--------------------------------------------------------------------------------
/.local/scripts/generic/to-json-objects:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | import json
5 | import contextlib
6 |
7 | import click
8 |
9 |
10 | @click.command()
11 | @click.option(
12 | "-k", "--key", help="key to embed into each object", type=str, required=True
13 | )
14 | def main(key: str) -> None:
15 | """
16 | pipe some lines into this, creates JSON objects with --key. use like:
17 |
18 | seq 10 | to-json-objects -k "number" | jq '. + {"data": "something"}'
19 |
20 | to create a stream of JSON objects
21 | """
22 | for line in map(str.rstrip, sys.stdin):
23 | sys.stdout.write(json.dumps({key: line}))
24 | sys.stdout.write("\n")
25 |
26 | sys.stdout.flush()
27 |
28 |
29 | if __name__ == "__main__":
30 | with contextlib.suppress(KeyboardInterrupt):
31 | main()
32 |
--------------------------------------------------------------------------------
/.local/scripts/generic/todos:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 |
4 | maybe_boxes() {
5 | if havecmd boxes; then
6 | boxes -pv1h1 -dshell
7 | else
8 | cat
9 | fi
10 | }
11 |
12 | chomp <"$XDG_DOCUMENTS_DIR/.todo_names.txt" | while read -r name; do
13 | maybe_boxes <<<"${name/_/ }"
14 | "$name" list
15 | done
16 |
--------------------------------------------------------------------------------
/.local/scripts/generic/treesitter-not-ensured:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | set -o pipefail
4 | # prints any treesitter parsers that are not in ensure_installed in my config, in-case I want to add them to my configuration
5 | comm -23 <(fd -I '.so' ~/.local/share/nvim/lazy/nvim-treesitter/parser/ -x echo '{/.}' | sort) <(awk '/^.*ensure_installed/,/\}/' <~/.config/nvim/lua/plugins/treesitter.lua | sed -e '1d' -e '$d' | tr -d '", ' | sort) | grep -vx rifleconfig
6 |
--------------------------------------------------------------------------------
/.local/scripts/generic/ttt:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # vendorized from https://github.com/purarue/ttt,
3 | # so that I'm not missing it when Im installing stuff on
4 | # my computer
5 | tttlog "$@"
6 | exec "$@"
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/tttlist:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # This prints directories that appear a lot in my ttt history,
3 | # used in https://purarue.xyz/d/cd.zsh?dark to cd to one
4 | # Requires:
5 | # my ttt HPI module (https://github.com/purarue/HPI)
6 | # https://github.com/purarue/exists
7 | # https://github.com/purarue/chomp
8 |
9 | set -e
10 | set -o pipefail
11 |
12 | hpi query my.ttt.history -s | jq -r '.directory' | grep -vx ~ | sort | uniq -c | chomp | sort -nr | cut -d' ' -f2- | exists
13 |
--------------------------------------------------------------------------------
/.local/scripts/generic/unstarred-nvim-plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # to list my currently unstarred nvim plugins
3 | # to star all of these:
4 | # unstarred-nvim-plugins | cut -d'/' -f4- | grep -v purarue | parallel -j1 -k 'star {}'
5 | # uses the 'star' script in this directory which uses 'gh' internally
6 |
7 | lazy-plugins() {
8 | list-git-dirs "${HOME}/.local/share/nvim/lazy" -d 2 | parallel -j+0 'cd {}; giturl' | sed -e 's/.git$//' | sort
9 | }
10 |
11 | already-starred() {
12 | mystars -3 | jq -r '.items | .[].arg' | sort
13 | }
14 |
15 | comm -23 <(lazy-plugins) <(already-starred)
16 |
--------------------------------------------------------------------------------
/.local/scripts/generic/update-my-stars:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | wait-for-internet --timeout 1 || {
4 | echo 'No internet connection, skipping update of my github stars...' >&2
5 | exit 0
6 | }
7 |
8 | update_stars() {
9 | mystars "$@" -c=never | tee -a "${TMPDIR:-/tmp}"/mystars_update.log 2>&1
10 | }
11 |
12 | case "$1" in
13 | -f)
14 | rm "$(evry location -update_my_stars)"
15 | ;;
16 | *) ;;
17 | esac
18 |
19 | evry 6 hours -update_my_stars && {
20 | echo 'Updating my github stars...' >&2
21 | update_stars -u
22 | }
23 |
24 | evry 1 month -re_update_my_stars && {
25 | echo 'Reindexing my github stars...' >&2
26 | update_stars -r
27 | }
28 |
--------------------------------------------------------------------------------
/.local/scripts/generic/urlhandler:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # receives text from STDIN, extracts unique URLs
3 | # prompts me to pick one and opens it
4 |
5 | # --urlextract is used in tmux, urlscan is the default
6 | # (used for things like opening URLs in neomutt)
7 | if [ "$1" = '--urlextract' ]; then
8 | urls="$(extracturls)" || exit $?
9 | else
10 | urls="$(urlscan -n)"
11 | fi
12 |
13 | if [ -z "${urls}" ]; then
14 | notify "No URLs found"
15 | exit 1
16 | fi
17 |
18 | chosen_url="$urls"
19 | [ "$(echo "$urls" | wc -l)" = "1" ] || chosen_url="$(echo "${urls}" | picker -p 'Pick a URL to open > ')"
20 | if [ -n "${chosen_url}" ]; then
21 | echo "${chosen_url}" | clipcopy
22 | openurl "${chosen_url}"
23 | fi
24 |
--------------------------------------------------------------------------------
/.local/scripts/generic/urlview:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if CONTENTS="$(clippaste)"; then
3 | # make sure this looks like text, and there wasn't an image on my clipboard
4 | if iconv --from-code="utf-8" --to-code="utf-8" <(printf '%s' "$CONTENTS") >/dev/null 2>&1; then
5 | openurl "$CONTENTS" || {
6 | notify -u critical "Couldn't open url: $CONTENTS"
7 | }
8 | else
9 | notify -u critical "Clipboard contents don't look like text, ignoring..."
10 | fi
11 | else
12 | notify -u critical "Couldn't get clipboard contents"
13 | fi
14 |
--------------------------------------------------------------------------------
/.local/scripts/generic/vitamin:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # add my vitamins to my food tracker
3 | # https://github.com/purarue/ttally
4 |
5 | set -eu
6 | set -o pipefail
7 |
8 | tf="$(mktemp)"
9 | trap 'rm -f "$tf"' EXIT
10 |
11 | add_to_food() {
12 | local SOURCE_FILE="$HPIDATA/vitamin.json" || return $?
13 | if [[ ! -e "$SOURCE_FILE" ]]; then
14 | printf 'Source file %s does not exist\n' "$SOURCE_FILE" >&2
15 | return 1
16 | fi
17 | jq --arg TIMESTAMP "$(epoch)" '[.[] + {"when": $TIMESTAMP | tonumber}]' <"$HPIDATA/vitamin.json" |
18 | tee "$tf" | jq '.[] | .food' -r | surround "'" | prefix 'added ' || return $?
19 | python3 -m ttally from-json food -f "${tf}" || return $?
20 | }
21 |
22 | add_to_food || exit $?
23 |
--------------------------------------------------------------------------------
/.local/scripts/generic/water-should-drink:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | set -o pipefail
4 |
5 | compute-target() {
6 | # should drink 14.8 ML per pound of weight -- prints how much water I should drink each day
7 | CURRENT_WEIGHT="$(hpi query ttally.__main__.weight --order-key when --limit 1 --reverse -s | jq .pounds)"
8 | MULTIPLIER=1.25 # arbitrary, to account for water in food; just a higher target for myself
9 | perl -E "say int($MULTIPLIER * 14.8 * ${CURRENT_WEIGHT})"
10 | }
11 |
12 | CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/water-should-drink"
13 |
14 | evry 1d -compute-water-should-drink && compute-target >"$CACHE_FILE"
15 | cat "$CACHE_FILE"
16 |
--------------------------------------------------------------------------------
/.local/scripts/generic/wca-comps:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # a cached version of wca-upcoming-competitions to make sure
3 | # I only hit worldcubeassosiation once a week
4 |
5 | CACHE_FILE="$HOME/.cache/wca-comps"
6 | # make sure script works (no imports fail)
7 | evry 1 week -wcacomps && wait-for-internet --quiet --timeout 5 && wca-upcoming-competitions >"${CACHE_FILE}"
8 |
9 | # if we dont have internet and the cachefile exists, just print the old result
10 | if [[ -e "$CACHE_FILE" ]]; then
11 | cat <"${CACHE_FILE}"
12 | else
13 | echo 'wca-comps: No internet, and no cached result' >&2
14 | exit 1
15 | fi
16 |
--------------------------------------------------------------------------------
/.local/scripts/generic/wca-upcoming-competitions:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # fetches all the upcoming wca competitions
3 | current_date="$(date +%Y-%m-%d)"
4 | pagination_size=''
5 | page=1
6 | while true; do
7 | data="$(curl -sL "https://www.worldcubeassociation.org/api/v0/competition_index?include_cancelled=false&sort=start_date%2Cend_date%2Cname&ongoing_and_future=$current_date&page=$page")"
8 | count=$(echo "$data" | jq 'length')
9 | jq '.[]' <<<"$data"
10 | if [[ -z "$pagination_size" ]]; then
11 | pagination_size="$count"
12 | else
13 | # if we hit something without the default pagination size, then were done
14 | if [[ "$count" != "$pagination_size" ]]; then
15 | break
16 | fi
17 | fi
18 | ((page++))
19 | done
20 |
--------------------------------------------------------------------------------
/.local/scripts/generic/windows-ppas:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | sudo add-apt-repository ppa:neovim-ppa/unstable
3 | sudo apt update
4 | sudo apt install neovim
5 |
--------------------------------------------------------------------------------
/.local/scripts/generic/with-secrets:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 |
3 | source ~/.profile 2>/dev/null
4 | source ~/.config/zsh/.zshrc 2>/dev/null
5 |
6 | if [[ -z "$1" ]]; then
7 | echo "Usage: "$(basename "$0")" " >&2
8 | else
9 | exec "$@"
10 | fi
11 |
--------------------------------------------------------------------------------
/.local/scripts/generic/youtube-thumbnail:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # preview a youtube thumbnail fullscreen
3 | YOUTUBE_URL="${1:?Provide Youtube URL as the first argument}"
4 | IMAGE_URL="$(curl -s "${YOUTUBE_URL}" | pup 'link[itemprop="thumbnailUrl"] attr{href}' | head -n 1)" || {
5 | printf "Couldn't download %s\n" "${YOUTUBE_URL}"
6 | exit 1
7 | }
8 |
9 | # https://purarue.xyz/d/urlpicpreview?dark
10 | exec urlpicpreview "${IMAGE_URL}"
11 |
--------------------------------------------------------------------------------
/.local/scripts/generic/youtube-user-id:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Gets the youtube ID for a user from a link
3 | # Could be a link to their channel or a video
4 | # Searches the tags for a channelId value
5 |
6 | yt-dlp --print channel_url --playlist-items 1 "${1:?Pass the URL as the first argument}" | awk -F/ '{print $NF}'
7 |
--------------------------------------------------------------------------------
/.local/scripts/generic/youtube-user-rss-feed:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # users the youtube-user-id script to get the channel ID, and print the corresponding youtube RSS feed and name
3 | # this is the RSS format expected by newsraft
4 | data="$(yt-dlp --print channel_url --print channel --playlist-items 1 "${1?Provide a youtube url}")"
5 | channel_id="$(awk -F'/' 'NR == 1 {print $NF}' <<<"$data")"
6 | name="$(tail -n1 <<<"$data")"
7 | [[ -z "$channel_id" ]] && exit
8 | printf 'https://www.youtube.com/feeds/videos.xml?channel_id=%s "%s"\n' "${channel_id}" "${name}"
9 |
--------------------------------------------------------------------------------
/.local/scripts/linux/afk:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | pkill udiskie
3 | figlet afk
4 | lock-screen
5 | if gum confirm "re-enable disk automounting?"; then
6 | i3-msg exec 'udiskie -t' >/dev/null
7 | fi
8 |
--------------------------------------------------------------------------------
/.local/scripts/linux/battery:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | printf '%s %d%%\n' "$(cat /sys/class/power_supply/*/status)" "$(cat /sys/class/power_supply/*/capacity)"
3 |
--------------------------------------------------------------------------------
/.local/scripts/linux/brightness:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # call like:
3 | # brightness up 5
4 | # brightness down 10
5 |
6 | CMD="${1:?No argument provided (up/down)}"
7 | STEP="${2:-5}" # default to 5%
8 |
9 | case "${CMD}" in
10 | up)
11 | brightnessctl set "${STEP}%+"
12 | ;;
13 | down)
14 | brightnessctl set "${STEP}%-"
15 | ;;
16 | esac
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/colorize_number:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # if a number is 0, leaves it as is
3 | # colors a number to make it more noticeable
4 | # used in my i3blocks scripts
5 | # https://github.com/vivien/i3blocks
6 |
7 | NUM="${1:-$(chomp | tr -d "\n")}"
8 |
9 | if [ "${NUM}" = '0' ]; then
10 | printf '0\n'
11 | else
12 | printf "%s\n" "${NUM}"
13 | fi
14 |
--------------------------------------------------------------------------------
/.local/scripts/linux/cstimer-server:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://github.com/purarue/cstimer-save-server
3 |
4 | main() {
5 | save_to="$(backup_to "cubing/cstimer")" || return $?
6 | secret="$(cat "${HPIDATA}/cstimer_secret.txt")" || return $?
7 | export CSTIMER_SECRET="$secret"
8 | exec cstimer-save-server -save-to "$save_to" -timestamped
9 | }
10 |
11 | main || exit $?
12 |
--------------------------------------------------------------------------------
/.local/scripts/linux/flashlight:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # i.e. I fullscreen the nsxiv (image viewer) instance
3 | # to turn my laptop into a flashlight
4 |
5 | # switch to a newly created 'flashlight' workspace
6 | i3-msg workspace flashlight >/dev/null 2>&1
7 |
8 | # set brightness to 100
9 | light -S 100
10 |
11 | # create a 1x1 white pixel image
12 | FILE=/tmp/flashlight.png
13 | magick -size 1x1 xc:white "${FILE}"
14 |
15 | # and display it
16 | exec nsxiv "${FILE}"
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/flatpak-run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # launches a flatpak application by letting me pick one with rofi
3 |
4 | set -o pipefail
5 |
6 | main() {
7 | local chosen
8 | # https://purarue.xyz/d/picker?dark
9 | chosen="$(flatpak list --columns=application | picker)"
10 | [[ -z "$chosen" ]] && return 1
11 | setsid -f flatpak run "${chosen}" >/dev/null 2>&1
12 | }
13 |
14 | main || exit $?
15 |
--------------------------------------------------------------------------------
/.local/scripts/linux/focused-screen-resolution:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # uses focused-screen-index to get the currently
3 | # focused monitor, and prints the resolution
4 | # using xrandr
5 |
6 | declare screen_index
7 | screen_index="$(focused-screen-index)" || exit $?
8 | xrandr | grep -w connected | sed -e "$((screen_index + 1))q;d" | grep -oP "(\d+x\d+)"
9 |
--------------------------------------------------------------------------------
/.local/scripts/linux/gammastep-loc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 |
5 | main() {
6 | declare loc
7 | declare -a args=()
8 | # https://github.com/purarue/HPI-personal/blob/master/scripts/last-gps-location
9 | loc="$(last-gps-location -d ":" --fuzz 2.0 --precision 0)"
10 | if [[ -n "$loc" ]]; then
11 | args+=(-l "$loc")
12 | fi
13 | exec gammastep -t 6500:4000 "${args[@]}" "$@"
14 | }
15 |
16 | main "$@" || exit $?
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/gpg_autoclick:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # automatically click the 'save in password manager' and 'ok' buttons for the gpg dialog
3 | # see ~/.local/share/gpg_autoclick
4 |
5 | from pathlib import Path
6 | import pyautogui
7 |
8 | datadir = Path("~/.local/share/gpg_autoclick").expanduser()
9 |
10 |
11 | def locate_and_click(p: Path) -> None:
12 | assert p.exists(), f"{p} doesn't exist!"
13 | locations = list(pyautogui.locateAllOnScreen(str(p)))
14 | assert len(locations) > 0, f"Couldn't find {p}"
15 | pyautogui.click(locations[0])
16 |
17 |
18 | def main() -> None:
19 | locate_and_click(datadir / "tick_box.png")
20 | locate_and_click(datadir / "ok.png")
21 |
22 |
23 | if __name__ == "__main__":
24 | main()
25 |
--------------------------------------------------------------------------------
/.local/scripts/linux/housekeeping-info:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | housekeeping
7 | housekeeping
8 | EVRY_JSON=1 housekeeping | describe-evry-json
9 |
--------------------------------------------------------------------------------
/.local/scripts/linux/housekeeping-offline:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | if wait-for-internet --timeout 5 --text 'Running housekeeping...'; then
7 | housekeeping-info
8 | else
9 | echo 'Offline, exiting...' >&2
10 | exit 1
11 | fi
12 |
--------------------------------------------------------------------------------
/.local/scripts/linux/hy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # This is the script that I run when I start my arch system
3 | #
4 | # This is called from the terminal right after I login
5 | # I do not have a login greeter, I launch directly
6 | # into the arch cmdline
7 |
8 | source ~/.profile
9 | exec Hyprland
10 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3-is-floating-window:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # exit code 0 if the window is floating, 1 if its tiling
3 | # accepts a window ID as the first argument, else
4 | # uses the currently focused window
5 | # requires xprop
6 |
7 | if [[ -z "$1" ]]; then
8 | WINDOW_ID="$(xprop -root _NET_ACTIVE_WINDOW | awk '{print $NF}')"
9 | else
10 | WINDOW_ID="$1"
11 | fi
12 |
13 | xprop -id "${WINDOW_ID}" | grep -q "I3_FLOATING_WINDOW" || exit $?
14 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3-resize:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # From: https://github.com/LukeSmithxyz/voidrice/blob/archi3/.local/bin/i3cmds/i3resize
3 |
4 | [ -z "$1" ] && echo "No direction provided" && exit 1
5 | distanceStr="15 px or 5 ppt"
6 |
7 | moveChoice() {
8 | i3-msg resize "$1" "$2" "${distanceStr}" | grep '"success":true' ||
9 | i3-msg resize "$3" "$4" "${distanceStr}"
10 | }
11 |
12 | case "$1" in
13 | up)
14 | moveChoice grow up shrink down
15 | ;;
16 | down)
17 | moveChoice shrink up grow down
18 | ;;
19 | left)
20 | moveChoice shrink right grow left
21 | ;;
22 | right)
23 | moveChoice grow right shrink left
24 | ;;
25 | esac
26 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3-sticky:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # i3-sticky [enable|disable]
3 | # if no argument is provided, toggles sticky
4 |
5 | enable_sticky() {
6 | i3-msg "floating enable; sticky enable"
7 | }
8 |
9 | disable_sticky() {
10 | i3-msg "floating disable; sticky disable"
11 | }
12 |
13 | case "$1" in
14 | enable)
15 | enable_sticky
16 | ;;
17 | disable)
18 | disable_sticky
19 | ;;
20 | *)
21 | if i3-is-floating-window; then
22 | disable_sticky
23 | else
24 | enable_sticky
25 | fi
26 | ;;
27 | esac
28 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3blocks-parse-signals:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o pipefail
3 | awk '/^\[|signal/,//' ~/.config/i3blocks/config | sed -e 's_\[_\["_; s_\]_"\]_;' | tq | jq 'to_entries | .[] | select(.value.signal) | "\(.key) \(.value.signal)"' -r
4 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3blocks-refresh-all:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # grep the i3blocks config file for signals
3 | # which can be refreshed, and refresh them
4 |
5 | set -x
6 |
7 | # remove some cache files which impact block functionality
8 | rm -f "${HOME}/.cache/mailsync_warn"
9 | rm -f "$(evry location -guestbook_comments)"
10 |
11 | grep '^signal' "${HOME}/.config/i3blocks/config" | cut -d'=' -f2 | while read -r signal; do
12 | pkill -RTMIN+"${signal}" i3blocks &
13 | done
14 |
15 | wait
16 |
17 | [[ -z "$QUIET" ]] && {
18 | attached-to-terminal || notify 'Refreshed all blocks'
19 | }
20 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3blocks-refresh-mpv:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | i3blocks-refresh-mk mpv-paused &
3 | i3blocks-refresh-mk mpv-song &
4 | wait
5 |
--------------------------------------------------------------------------------
/.local/scripts/linux/i3blocks-watch-mpv-daemon-logs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | touch /tmp/mpv-history-daemon.log
7 |
8 | # read the logfile which https://github.com/purarue/mpv-history-daemon
9 | # writes to, filtering to lines which specify song has ended/started
10 | #
11 | # when that happens, refresh my i3blocks
12 |
13 | tail -n 1 -f /tmp/mpv-history-daemon.log |
14 | grep --line-buffered -e 'eof|' -e 'playlist-pos|[[:digit:]]' |
15 | while read -r; do i3blocks-refresh-mpv; done
16 |
--------------------------------------------------------------------------------
/.local/scripts/linux/image-working-dir:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # just a script that moves an image to
3 | # my downloads folder so I can work on it
4 | #
5 | # this is bound in ranger (my file manager)
6 |
7 | to_dir="$XDG_DOWNLOAD_DIR/images"
8 | mkdir -p "$to_dir"
9 |
10 | exec cp -p "$1" "$to_dir"
11 |
--------------------------------------------------------------------------------
/.local/scripts/linux/launch-waybar:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CONFIG_FILES="$HOME/.config/waybar/config.jsonc $HOME/.config/waybar/style.css"
4 |
5 | trap "killall waybar" EXIT
6 |
7 | sleep 1
8 | while true; do
9 | waybar &
10 | inotifywait -e create,modify $CONFIG_FILES
11 | killall waybar
12 | done
13 |
--------------------------------------------------------------------------------
/.local/scripts/linux/main-screen-resolution:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # gets the first screen from xrandr and prints
3 | # the resolution. I use this sometimes instead
4 | # of the focused-screen-resolution because it
5 | # gets very complicated determine pixel location
6 | # based on monitor output. xwininfo/xdotool return
7 | # pixel info by adding pixel widths of previous screens,
8 | # so scripts like i3-picture-in-picture just use
9 | # the main monitor instead of trying to figure out
10 | # where to place windows
11 |
12 | xrandr | grep -w connected | head -n 1 | grep -oP "(\d+x\d+)"
13 |
--------------------------------------------------------------------------------
/.local/scripts/linux/mpv-last-screenshot:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # copy the latest mpv screenshot to clipboard
3 |
4 | path="$(mpv-currently-playing | tail -n 1)" || exit $?
5 | dir="$(dirname "$path")" || exit $?
6 | if [[ ! -d "$dir" ]]; then
7 | printf 'error: %s is not a directory\n' "$dir" >&2
8 | exit 1
9 | fi
10 | exec newest "$dir"
11 |
--------------------------------------------------------------------------------
/.local/scripts/linux/notify-mpv-song-description:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if desc="$(mpv-song-description-py)"; then
4 | notify-send "$desc"
5 | else
6 | notify-send 'nothing playing'''
7 | fi
8 |
--------------------------------------------------------------------------------
/.local/scripts/linux/randomize-wallpaper:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if [[ -n "${WAYLAND_DISPLAY:-}" ]]; then
3 | random_wallpaper="$(find "$FILES_DIR/wallpapers" -type f | shuf -n 1)"
4 | oldid="$(pgrep swaybg)"
5 | setsid -f swaybg -i "$random_wallpaper" -m fill
6 | kill "$oldid"
7 | else
8 | # Randomize the wallpaper using feh
9 | exec feh --randomize --bg-fill --no-fehbg "${FILES_DIR}/wallpapers"
10 | fi
11 |
--------------------------------------------------------------------------------
/.local/scripts/linux/redshift-loc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 |
5 | main() {
6 | declare loc
7 | declare -a args=()
8 | # https://github.com/purarue/HPI-personal/blob/master/scripts/last-gps-location
9 | loc="$(last-gps-location -d ":" --fuzz 2.0)"
10 | if [[ -n "$loc" ]]; then
11 | args+=(-l "$loc")
12 | fi
13 | exec redshift -t 6500:4000 "${args[@]}" "$@"
14 | }
15 |
16 | main "$@" || exit $?
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/refresh-block:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | BLOCK="${1?Block name required}"
3 |
4 | if pgrep -x i3blocks >/dev/null; then
5 | i3blocks-refresh-mk "$BLOCK"
6 | elif pgrep -x waybar >/dev/null; then
7 | waybar-refresh-block "$BLOCK"
8 | fi
9 |
--------------------------------------------------------------------------------
/.local/scripts/linux/sonic-pi-run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # wrapper script to handle sonic-pi on arch with pulseaudio
3 | # see https://purarue.xyz/x/devlog/sonic_pi/
4 | # for an explanation
5 |
6 | jackd -R -d alsa -d hw:1 &
7 | qjackctl &
8 | sleep 5
9 | sonic-pi # block
10 |
11 | # shellcheck disable=SC2046
12 | kill -15 $(jobs -p)
13 |
--------------------------------------------------------------------------------
/.local/scripts/linux/sw:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # This is the script that I run when I start my arch system
3 | #
4 | # This is called from the terminal right after I login
5 | # I do not have a login greeter, I launch directly
6 | # into the arch cmdline
7 |
8 | # shellcheck source=/dev/null
9 | source ~/.profile
10 | exec sway
11 |
--------------------------------------------------------------------------------
/.local/scripts/linux/sway-display-off:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | swayidle \
3 | timeout 1 'swaymsg "output * dpms off"' \
4 | resume 'swaymsg "output * dpms on"' &
5 | swaylock -c000000
6 | kill %%
7 |
--------------------------------------------------------------------------------
/.local/scripts/linux/sway-resize:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # From: https://github.com/LukeSmithxyz/voidrice/blob/archi3/.local/bin/i3cmds/i3resize
3 |
4 | [ -z "$1" ] && echo "No direction provided" && exit 1
5 | distanceStr="15 px or 5 ppt"
6 |
7 | moveChoice() {
8 | swaymsg resize "$1" "$2" "${distanceStr}" | grep '"success":true' ||
9 | swaymsg resize "$3" "$4" "${distanceStr}"
10 | }
11 |
12 | case "$1" in
13 | up)
14 | moveChoice grow up shrink down
15 | ;;
16 | down)
17 | moveChoice shrink up grow down
18 | ;;
19 | left)
20 | moveChoice shrink right grow left
21 | ;;
22 | right)
23 | moveChoice grow right shrink left
24 | ;;
25 | esac
26 |
--------------------------------------------------------------------------------
/.local/scripts/linux/termcolors:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | for i in {0..255}; do
3 | # shellcheck disable=SC2059
4 | printf "\x1b[38;5;${i}mcolour${i}\n"
5 | done
6 |
--------------------------------------------------------------------------------
/.local/scripts/linux/tiktok-update-rss-feeds:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | contents="$(cat "$HOME/.config/newsraft/feeds")"
4 | usernames="$(cat "$XDG_DOCUMENTS_DIR/tiktok.txt")"
5 |
6 | while read -r line; do
7 | if grep -q "rss/${line}.xml " <<<"$contents"; then
8 | echo "Skipping @$line, already present" >&2
9 | else
10 | echo "Adding @$line" >&2
11 | file="${HOME}/.cache/tiktok-local-rss/rss/${line}.xml"
12 | if [[ ! -f "$file" ]]; then
13 | echo "While adding $line, $file not found" >&2
14 | continue
15 | fi
16 | printf 'file://%s "%s"\n' "$file" "$line" >>"$HOME/.config/newsraft/feeds"
17 | fi
18 | done <<<"$usernames"
19 |
--------------------------------------------------------------------------------
/.local/scripts/linux/timedatectl-timezone:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | main() {
7 | local tz
8 | tz="$(timedatectl | grep 'Time zone' | cut -d':' -f2- | awk '{print $1}')"
9 | [[ -z "$tz" ]] && {
10 | echo 'Failed to get timezone from timedatectl' >&2
11 | return 1
12 | }
13 | printf '%s\n' "$tz"
14 | }
15 |
16 | main || exit $?
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/timezone-has-changed:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o pipefail
4 |
5 | main() {
6 | local geotz curtz
7 | flock ~/.local/tz-lock with-secrets hpi doctor -S my.time.tz.via_location 2>/dev/null
8 | geotz="$(current-timezone)" || return $?
9 | curtz="$(timedatectl-timezone)" || return $?
10 | if [[ "${geotz}" != "${curtz}" ]]; then
11 | printf 'Set timezone %s and current timezone %s do not match!\n' "${curtz}" "${geotz}" >&2
12 | return 0
13 | else
14 | printf 'System and Geolocated timezones match: %s\n' "${curtz}" >&2
15 | fi
16 | return 1
17 | }
18 |
19 | main || exit $?
20 |
--------------------------------------------------------------------------------
/.local/scripts/linux/transparent:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # enable/disable transparency for the currently moused over application
3 | # Usage:
4 | # transparent [target]
5 | # optionally, specify target to change the moues into a target -- the next click will target that application
6 | # target exists because some applications can't be 'moused over' (e.g. mpv)
7 |
8 | if [ "$1" = "enable" ]; then
9 | if [ "$2" = "target" ]; then
10 | picom-trans -s 85
11 | else
12 | picom-trans -c 85
13 | fi
14 | elif [ "$1" = "disable" ]; then
15 | if [ "$2" = "target" ]; then
16 | picom-trans -s 100
17 | else
18 | picom-trans -c 100
19 | fi
20 | else
21 | printf "You must specify either enable or disable\n" 1>&2
22 | fi
23 |
--------------------------------------------------------------------------------
/.local/scripts/linux/update-rss:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # updates my rss feed, if I don't already have it open
3 | # If newsraft is not open, this reloads all items and
4 | # saves how many items are unread to ~/.cache/rss-unread
5 | # If it fails, does not write
6 |
7 | readonly CACHE_FILE="${XDG_CACHE_HOME:-${HOME}/.cache}/rss-unread"
8 |
9 | if pgrep -x newsraft >/dev/null; then
10 | echo "Newsraft is active, skipping update..." >&2
11 | exit 1
12 | else
13 | newsraft -e reload-all >/dev/null
14 | unread="$(newsraft -e print-unread-items-count)" || exit $?
15 | if [[ -z "$unread" ]]; then
16 | echo '0' >"${CACHE_FILE}"
17 | else
18 | # delete a space followed by anything
19 | echo "${unread%% *}" >"${CACHE_FILE}"
20 | fi
21 | fi
22 |
--------------------------------------------------------------------------------
/.local/scripts/linux/volume:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # volume [volume_step]
3 |
4 | CMD="${1:?No command provided. Provide one of: up|down|mute|micmute}"
5 | VOLUME_STEP="${2:-5}"
6 |
7 | case "${CMD}" in
8 | up)
9 | pactl set-sink-volume @DEFAULT_SINK@ +"$VOLUME_STEP"%
10 | ;;
11 | down)
12 | pactl set-sink-volume @DEFAULT_SINK@ -"$VOLUME_STEP"%
13 | ;;
14 | mute)
15 | pactl set-sink-mute @DEFAULT_SINK@ toggle
16 | ;;
17 | micmute)
18 | pactl set-source-mute @DEFAULT_SOURCE@ toggle
19 | ;;
20 | *)
21 | echo "Unknown command: ${CMD}" 1>&2
22 | exit 1
23 | ;;
24 | esac
25 |
--------------------------------------------------------------------------------
/.local/scripts/linux/waybar-refresh-all:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | waybar-signals | cut -d'=' -f2 | while read -r signal; do
4 | pkill "-RTMIN+${signal}" waybar &
5 | done
6 | wait
7 | [[ "$1" == "no-notify" ]] || notify "Refreshed all blocks"
8 |
--------------------------------------------------------------------------------
/.local/scripts/linux/waybar-refresh-block:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | chosen="${1?Usage: $0 }"
3 | signal="$(waybar-signals | grep -m1 "$chosen")"
4 | if [[ -z "$signal" ]]; then
5 | echo "Could not find signal for query: $chosen" >&2
6 | printf "Known signals:\n%s\n" "$(waybar-signals)" >&2
7 | exit 1
8 | fi
9 |
10 | # split by '=' into name and value
11 | readarray -d= -t parts < <(printf '%s' "$signal")
12 | name="${parts[0]}"
13 | signal="${parts[1]}"
14 |
15 | pkill -RTMIN+"$signal" waybar
16 | printf "Refreshed %s (%d)\n" "$name" "$signal" >&2
17 |
--------------------------------------------------------------------------------
/.local/scripts/linux/waybar-signals:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import os
4 | from jsonc_parser.parser import JsoncParser
5 |
6 |
7 | def main() -> None:
8 | config_dir = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
9 | config_file = os.path.join(config_dir, "waybar/config.jsonc")
10 | data = JsoncParser.parse_file(config_file)
11 | for k, v in data.items():
12 | if not isinstance(v, dict):
13 | continue
14 | if "signal" in v:
15 | print(f"{k}={v['signal']}")
16 |
17 |
18 | if __name__ == "__main__":
19 | main()
20 |
--------------------------------------------------------------------------------
/.local/scripts/linux/webcam-pic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # open mpv to save a picture (using webcam) in ~/Pictures/pics
3 |
4 | declare pics
5 | pics="${XDG_PICTURES_DIR:?Pictures environment variable not set}/pics"
6 | [[ ! -d "${pics}" ]] && mkdir -p "${pics}"
7 | cd "${pics}" || exit 1
8 | # open mpv so I can take a picture
9 | mpv /dev/video0
10 | exec launch ranger "${pics}"
11 |
--------------------------------------------------------------------------------
/.local/scripts/linux/xmodmap-reset:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -ux
4 |
5 | exec setxkbmap -layout us
6 |
--------------------------------------------------------------------------------
/.local/scripts/notes_rendered/cache-srt-to-text:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | INPUT="${1:?Give .srt file as input}"
4 | TARGET="${2:?Give .txt file as target}"
5 |
6 | # if SRT file modification time is newer than target file, then we need to re-convert
7 | CONVERT=0
8 | if [[ ! -e "$TARGET" ]]; then
9 | CONVERT=1
10 | elif (($(stat -c %Y "$INPUT") > $(stat -c %Y "$TARGET"))); then
11 | CONVERT=1
12 | fi
13 |
14 | if ((CONVERT)); then
15 | echo "Converting $INPUT to $TARGET" >&2
16 | srt-to-text "$1" | uniq >"$TARGET"
17 | fi
18 |
--------------------------------------------------------------------------------
/.local/scripts/reminder-sink/flipflop:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://purarue.xyz/d/flipflop.py?redirect
3 |
4 | set -o pipefail
5 |
6 | # shellcheck disable=SC1091
7 | source "$HPIDATA/tokens"
8 |
9 | EXIT=0
10 | OUTPUT="$(flipflop.py status --filter-on -o json | jq 'keys[]' -r | tr '_' ' ')" || {
11 | notify "flipflop failed to run"
12 | exit 1
13 | }
14 |
15 | if [[ -n "$OUTPUT" ]]; then
16 | echo "${OUTPUT/_/ }"
17 | EXIT=3
18 | fi
19 | exit "$EXIT"
20 |
--------------------------------------------------------------------------------
/.local/scripts/reminder-sink/guestbook:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # if there are comments to approve, warn me
3 |
4 | CACHE_FILE="$HOME/.cache/guestbook-comments"
5 | [[ ! -f $CACHE_FILE ]] && exit 0
6 |
7 | EXIT=0
8 | if COMMENT_COUNT="$(is-integer "$(cat "$CACHE_FILE")")"; then
9 | ((COMMENT_COUNT > 0)) && EXIT=2
10 | fi
11 |
12 | exit "$EXIT"
13 |
--------------------------------------------------------------------------------
/.local/scripts/reminder-sink/last-export-dates:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # uses the cache file generated by last-export-dates.job:
3 | # https://github.com/purarue/HPI-personal/blob/master/jobs/linux/last_export_dates.job
4 |
5 | CACHE_FILE="${HPIDATA}/last-export-dates.txt"
6 |
7 | # i.e. skip running this on my phone if the cache
8 | # file doesn't exist, only need to be warned about
9 | # this when I'm able to do something about it
10 | [[ ! -f "${CACHE_FILE}" ]] && exit 0
11 |
12 | DATA="$(cat "${CACHE_FILE}")"
13 | if [[ -n "$DATA" ]]; then
14 | echo "$DATA"
15 | exit 3
16 | else
17 | exit 0
18 | fi
19 |
--------------------------------------------------------------------------------
/.local/scripts/reminder-sink/listen_to_album:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # if I haven't listened to a new album in the past week, notify me
3 |
4 | set -o pipefail
5 |
6 | EXIT=0
7 | LISTENCOUNT="$(hpi query -r 2w my.nextalbums.history | jq 'length')" || {
8 | notify "listen_to_album: hpi query failed"
9 | exit 1
10 | }
11 |
12 | [[ "${LISTENCOUNT}" == '0' ]] && EXIT=2
13 | exit "$EXIT"
14 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/cached_repo_bases.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 1 week -cached-repo-bases && {
4 | printlog 'cached-repo-bases:caching locations of my git repos'
5 | python3 -c 'import my.config; print("\n".join(map(str, my.config.commits.roots)))' >"${XDG_CACHE_HOME?:No cache dir set}/repo_bases.txt"
6 | }
7 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/offline_listens_cache.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 4 weeks -update-offline-listens-cache && {
4 | printlog "offline_listens:updating cache..."
5 | python3 -m offline_listens update-cache
6 | dust --no-colors ~/.cache/offline-listens.json
7 | }
8 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/promnesia_index.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # https://github.com/karlicoss/promnesia
3 | # run the promnesia indexer
4 |
5 | case "$ON_OS" in
6 | windows* | android*)
7 | exit 0
8 | ;;
9 | esac
10 |
11 | havecmd promneisa || exit 0
12 |
13 | evry 1 day -promnesia_index && {
14 | # source environment variables that may be needed (e.g. ipinfo token)
15 | printlog "promnesia_index:running index..."
16 | with-secrets remove-broken-sms-files
17 | with-secrets promnesia index --overwrite >>/tmp/promnesia_index.log 2>&1 || send-error "promnesia index failed..."
18 | }
19 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/pull_dotfiles.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # pull dotfiles repo in $REPOS so commits are accurate in
3 | # https://github.com/karlicoss/HPI/blob/master/my/coding/commits.py
4 |
5 | wait-for-internet -q --timeout "${WFI_TIMEOUT:-10}" || exit 0
6 |
7 | evry 1 day -pull-dotfiles && {
8 | TARGET="$REPOS/dotfiles"
9 | [[ -e "${TARGET}" ]] && cd "${TARGET}" && git pull
10 | }
11 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/sync_datafiles.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # sync from local datadir ~/.local/share/window_watcher/
3 | # to ~/data
4 | # otherwise this is constantly writing to ~/data/ and
5 | # syncthing syncs the file *all the time*
6 |
7 | evry 1 hour -sync-window-watcher && {
8 | FROM="${HOME}/.local/share/window_watcher"
9 | [[ -e "${FROM}" ]] || exit 0
10 | run_window_watcher tasks || send-error 'couldnt sync window_watcher files'
11 | }
12 |
13 | evry 1 hour -sync-ttt && {
14 | FROM="${HOME}/.local/share/ttt"
15 | [[ -e "${FROM}" ]] || exit 0
16 | rsync -Pavh "$FROM/" "$(backup_to ttt)"
17 | }
18 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/all/ttally_cache.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 15 minutes -update-ttally-cache && {
4 | printlog "ttally:updating ttally cache..."
5 | if ttally update-cache; then
6 | :
7 | else
8 | (($? != 2)) && send-error "error updating ttally cache"
9 | fi
10 | }
11 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/android/backup_images.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | STORAGE="${HOME}/storage/"
4 |
5 | IMAGE_DIRS=(
6 | "${STORAGE}/dcim/Camera/"
7 | "${STORAGE}/pictures/Screenshots/"
8 | )
9 |
10 | evry 5 minutes -backup_images && {
11 | BACKUP_TO="$(backup_to phone_pictures)"
12 | for idir in "${IMAGE_DIRS[@]}"; do
13 | [[ -d "${idir}" ]] || continue
14 | rsync -Pavh --exclude=".*" "${idir}" "${BACKUP_TO}/$(basename "${idir}")" &&
15 | find "${idir}" -type f -mtime +180 -print -delete
16 | done
17 | }
18 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/android/create_playlists.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 1 day -create_playlists && {
4 | printlog 'creating playlists...'
5 | cd "$PLAINTEXT_PLAYLIST_MUSIC_DIR" && find . "$PLAINTEXT_PLAYLIST_MUSIC_DIR" -maxdepth 1 -type f -name '*.m3u8' -print -delete
6 | cd "$PLAINTEXT_PLAYLIST_MUSIC_DIR" && fd . -I "$PLAINTEXT_PLAYLIST_PLAYLISTS" -d 1 | parallel -j "$(($(nproc) * 4))" -t 'plainplay m3u {/.} > {/.}.m3u8'
7 |
8 | m3u-shuf "${PLAINTEXT_PLAYLIST_MUSIC_DIR}/car.m3u8" -o "${PLAINTEXT_PLAYLIST_MUSIC_DIR}/car.m3u8"
9 | }
10 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/android/delete_trash.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 1 week -android-empty-trash && {
4 | printlog 'empty-trash:removing trash files manually on android'
5 | rm -rvf ~/.local/share/Trash
6 | }
7 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/build_exobrain.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | wait-for-internet -q --timeout "${WFI_TIMEOUT:-10}" || exit 0
4 |
5 | evry 6 hours -exobrain && {
6 | printlog 'exobrain:building exobrain w/ search index...'
7 | cd "$REPOS/exobrain" || return $?
8 | # if Im currently changing stuff, dont build/push
9 | git-has-untracked-or-changes && {
10 | printlog 'exobrain:uncommitted changes, not building'
11 | exit 0
12 | }
13 | git pull
14 | make link_personal_notes
15 | make built_and_stork
16 | ./scripts/sync_with_retry
17 | }
18 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/copy_images.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # sync photos from my data directory to my XDG_PICTURES_DIR
3 | # on my phone, this is synced from the underlying dcim/Camera folder:
4 | # https://purarue.xyz/d/backup_images.job?dark
5 |
6 | evry 5 minutes -copy_images && {
7 | rsync -Pavh --exclude=".*" "${HPIDATA}/phone_pictures" "${XDG_PICTURES_DIR}" &&
8 | find "${HPIDATA}/phone_pictures" -type f -mtime +180 -print -delete
9 | }
10 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/generate_notes_journal_vlogs.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # update generated journal/notes HTML pages so I can reference on my phone
3 |
4 | evry 10 minutes -update-journal-vlog-html-transcripts && render-notes
5 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/linkmusic.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # sync music in playlists to my phone
3 | # https://github.com/purarue/plaintext-playlist
4 | # https://purarue.xyz/d/linkmusic?dark
5 |
6 | evry 30 minutes -linkmusic && linkmusic ~/.local/share/musicsync/ --delete
7 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/mystars.job:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # update https://github.com/purarue/oh-my-stars
3 |
4 | # this script internally has the evry call
5 | # it is like this so I can decouple it running
6 | # on my phone
7 | # https://purarue.xyz/d/update-my-stars?dark
8 | update-my-stars
9 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/tiktok.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | wait-for-internet -q --timeout "${WFI_TIMEOUT:-10}" || exit 0
4 |
5 | evry 6 hours -tiktok-update-rss && {
6 | printlog 'tiktok-update-rss:downloading new videos...'
7 | tiktok-local-rss download
8 | tiktok-local-rss rss
9 | tiktok-update-rss-feeds
10 | }
11 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/update_rss.job:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # update rss feeds on my computer
3 | # purarue.xyz/d/update-rss
4 |
5 | wait-for-internet -q --timeout "${WFI_TIMEOUT:-10}" || exit 0
6 |
7 | evry 1 hour -update-rss && {
8 | if update-rss; then
9 | printlog "updaterss:updated RSS feeds:$(cat ~/.cache/rss-unread)"
10 | else
11 | printlog "updaterss:failed to update RSS feeds"
12 | fi
13 | }
14 |
--------------------------------------------------------------------------------
/.local/scripts/supervisor_jobs/linux/warn_mailsync.job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | evry 10 minutes -warn_mailsync && {
4 | # dont warn if obs is open
5 | pgrep -x obs >/dev/null && exit 0
6 | wait-for-internet --quiet --timeout "${WFI_TIMEOUT:-5}" || exit 0
7 | # if mailsync hasn't been run in 30 minutes, set a cache file
8 | # that files' existence is checked for in my status bar, which then displays an error
9 | MAILSYNC_WARN_FILE="${HOME}/.cache/mailsync_warn"
10 | if file-modified-within "${XDG_CONFIG_HOME:-$HOME/.config}/mutt/.mailsynclastrun" '30 minutes'; then
11 | rm -f "${MAILSYNC_WARN_FILE}"
12 | else
13 | touch "${MAILSYNC_WARN_FILE}"
14 | fi
15 | refresh-block mail
16 | }
17 |
--------------------------------------------------------------------------------
/.local/scripts/todo-actions/Makefile:
--------------------------------------------------------------------------------
1 | sync:
2 | # find all items in this dir which are executable, and sync them to ~/.local/share/todo-actions
3 | find . -maxdepth 1 -type f -executable -exec cp -auv {} ~/.local/share/todo-actions \;
4 | touch:
5 | find . -maxdepth 1 -type f -executable -exec touch {} \;
6 |
--------------------------------------------------------------------------------
/.local/scripts/todo-actions/full:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if [[ -z "$TODO_DIR" ]]; then
6 | echo "TODO_DIR is not set" >&2
7 | exit 1
8 | fi
9 |
10 | export TODO_DIR="$TODO_DIR"
11 | # https://github.com/purarue/full_todotxt
12 | full_todotxt -ps || exit $?
13 |
--------------------------------------------------------------------------------
/.local/scripts/todo-actions/interactive:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | if attached-to-terminal; then
6 | "$TODO_FULL_SH" fzf
7 | else
8 | "$TODO_FULL_SH" rofi
9 | fi
10 |
--------------------------------------------------------------------------------
/.local/share/gpg_autoclick/ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/purarue/dotfiles/77843d62e8357579d7e8c8e3cd0033cfce803ff6/.local/share/gpg_autoclick/ok.png
--------------------------------------------------------------------------------
/.local/share/gpg_autoclick/tick_box.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/purarue/dotfiles/77843d62e8357579d7e8c8e3cd0033cfce803ff6/.local/share/gpg_autoclick/tick_box.png
--------------------------------------------------------------------------------
/.local/share/ipython/profile_calculator/startup/00-load-modules.py:
--------------------------------------------------------------------------------
1 | # load modules for doing math
2 | from math import * # noqa: F401,F403
3 |
--------------------------------------------------------------------------------
/.local/share/ipython/profile_default/startup/00-pyflyby.ipy:
--------------------------------------------------------------------------------
1 | # loads https://github.com/deshaw/pyflyby which
2 | # auto-imports modules as they are used
3 | # %load_ext pyflyby
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/abookc:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec abook -C "$XDG_CONFIG_HOME/abook/abookrc" -f "$XDG_DOCUMENTS_DIR/addressbook" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/alacritty-tmux:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec alacritty -e tmux
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/alarm:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec paplay /usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/albums:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl "https://purarue.xyz/s/albums"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/beet-export-all:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec beet export "" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/beet-fix-renamed-files:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec beet update -F=path "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/boxes-nvim:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec boxes -dada-box -pv1h2
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/boxes-python:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # create a comment box as a python comment, text piped from STDIN
3 | exec boxes -dshell -pv1h2 "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/boxes-vim:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | boxes-python | tr '#' '"'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/calcursed:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | exec calcurse --datadir "$CALCURSE_DIR" --confdir "$XDG_CONFIG_HOME/calcurse" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/camera:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # open mpv to save a picture (using webcam) in ~/Pictures/pics
3 |
4 | declare pics
5 | pics="${XDG_PICTURES_DIR:?XDG_PICTURES_DIR environment variable not set}/pics"
6 | [[ ! -d "$pics" ]] && mkdir -p "$pics"
7 | cd "$pics" || exit 1
8 | # open mpv so I can take a picture
9 | mpv /dev/video0
10 | exec launch ranger "$pics"
11 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/cheat:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0") $*"
3 | exec curl -s "https://cheat.sh/$*"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/cl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | clipcopy
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/cl-quickfix:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # pastes text from the clipboard and creates a quickfist list
3 | # this is typically called from kitty -- which saves the
4 | # output of the previous command, then calls this in a new window
5 | # https://github.com/purarue/dotfiles/blob/cdae322fa6b735d5ca12dd3248354b5eeaaab0be/.config/kitty/kitty.conf#L1581-L1588
6 | set -e
7 | exec nvim -q <(clippaste) +copen
8 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/clipedit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # edit your clipboard in vim
3 | launch "clippaste | vipe | clipcopy"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/clipreset:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # reset the clipboard formatting
3 | notify "resetting clipboard..."
4 | clippaste | clipcopy
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/clp-args:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # clp, but accepts input as arguments
3 | echo "$*" | clp
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/clr:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # I need to spell this out with 'attached-to-terminal' even though print-or-notify does that exact thing because:
3 | # - if I pipe, then the pipe causes print-or-notify to always send a notification because stdin is not a tty or something
4 | # - if I send it like the notify below, if the data returned by ttally recent food is too long in the terminal, it will
5 | # fail since the argument list is too long
6 | args=("$@")
7 | if [[ -z "$1" ]]; then
8 | args+=("--human-readable")
9 | fi
10 | if attached-to-terminal; then
11 | ttally recent food "${args[@]}"
12 | else
13 | notify "$(ttally recent food "${args[@]}")"
14 | fi
15 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/clrs:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec clr -hr quantity,water "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/codespell-conf:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | declare -a args=()
3 | if [[ -n "$NVIM_SPELLFILE" ]]; then
4 | args+=("--ignore-words=$NVIM_SPELLFILE")
5 | fi
6 | exec codespell --config ~/.config/codespell/codespell.conf "${args[@]}" "$@"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/core:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export BASE_URL='https://purarue.xyz/c/'
3 | exec give
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/create-youtube-dl-resolution-str:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # defaults to about 480p
3 | # otherwise, grabs the format from the FORMAT environment variable
4 | # prints the format string for a particular resolution
5 | FORMAT="${FORMAT:-550}"
6 | exec printf 'bestvideo[height<=%d]+bestaudio/best[height<=%d]' "$FORMAT" "$FORMAT"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/curdir:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec basename "$(realpath "$(pwd)")"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/current-city:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | ipinfo | grep -m1 city | cut -d':' -f2- | chomp
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/cycle:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # moves the first argument to the end of the list
3 | exec awk "$@" '{ for (i = 2; i <= NF; i++) printf $i "\t" ; print $1 }'
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/dark-theme:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec terminal-set-theme Dark
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/discogs-search:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # https://www.discogs.com/search?q=sampha&type=all
3 | # searches discogs for an album
4 | SEARCH_STR=$(input-dialog "Search for an album > " | chomp | tr " " "+")
5 | [ -z "$SEARCH_STR" ] && exit 1
6 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0") $SEARCH_STR"
7 | exec openurl "https://www.discogs.com/search/?q=${SEARCH_STR}&type=all"
8 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/discord-browser:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl 'https://discord.com/login'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/dotfiles:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # open the dotfiles git repository
3 | yadm open --print | openurl
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/draglastpic:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | dragon-drop -x "$(lastpic)"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/drive-mount:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # start the ldm (light device mounter) daemon, to mount devices
3 | echo "use lsblk -f to view disk IDs"
4 | exec sudo ldm -u "$(whoami)"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/ec:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd ~ || exit $?
3 | # fuzzy match list-config names, open one to edit (Edit Config)
4 | fzfcache list-config-no-hist | sed "s#^$HOME/##g" | fzf-edit
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/edit-clipboard:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # edit your clipboard in vim
3 | launch "clippaste | vipe | clipcopy"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/exo-web:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl "https://purarue.xyz/x/notes/?search"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/extracturls:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # receives text from STDIN, extracts unique URLs
3 | # pypi.org/project/urlextract
4 | urls="$(urlextract | sort -u)"
5 | if [ -z "${urls}" ]; then
6 | notify "No URLs found in text"
7 | exit 1
8 | fi
9 | printf "%s\n" "${urls}"
10 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/fdf:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec fd --type=file "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/feed-open:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl 'https://purarue.xyz/feed/'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/file-mime:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # get mime type for one or more files
3 | # this is the same as what rifle (ranger) does
4 | exec file --mime-type -Lb "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/flake8c:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # flake8 with my default config -- https://purarue.xyz/d/.config/flake8?dark
3 | exec flake8 --config ~/.config/flake8 "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/fzf-edit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | FILE="$(fzfp +m -q "$*")"
3 | if [[ -n "$FILE" ]]; then
4 | editor "$FILE"
5 | else
6 | echo "No file selected" >&2
7 | exit 1
8 | fi
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/fzfp:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec fzf --preview="${HOME}/.config/fzf_preview {}" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/genpass-phrase:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | USE_DICEWARE=1 exec genpass "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/gi:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # get gitignores for different languages
3 | if [ ! "$(echo "$@" | tr -d "\n\r")" = "" ] && [ ! "$1" = "list" ]; then
4 | printf "*.pdf\n"
5 | fi
6 | curl -sL "https://gitignore.io/api/$*"
7 | printf "\n"
8 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/git-color:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec git -c color.ui=always "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/google-chrome-wifi-captive:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec google-chrome-stable 'http://clients3.google.com/generate_204'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/google-search:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | TEXT="$(cat)"
3 | if [[ -z "$TEXT" ]]; then
4 | TEXT="$(clippaste)"
5 | fi
6 | exec openurl "https://www.google.com/search?q=${TEXT// /+}"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/grep-dotfiles:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # searches all my configuration for a string
3 | # passes arguments received to grep
4 | list-config-no-hist | xargs grep -Hrin "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/heart-cl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | heart "$@" | APP=heart clp
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/html-head-all:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec html-head -a css-dark-mode -a css-pre-wrap "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/i3-jinja:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -x
3 | I3_DIR="${HOME}/.config/i3"
4 | cd "${I3_DIR}" || exit $?
5 | exec jinjanate config.j2 -o config -f yaml " | sed 's/--no-startup-id //g' | cut -d" " -f 2-)"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/img-download-drag:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | img-download "$@" || exit $?
3 | dragon-drop -x "$(clippaste)"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/ipinfo:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # get my ip information
3 | curl -s ipinfo.io | gron | grep -v 'json.readme' | gron -u | jq -r 'to_entries[] | "\(.key): \(.value)"'
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/largechar-clipboard:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | CONTENTS="$(clippaste)"
3 | [ -z "${CONTENTS}" ] && exit 1
4 | printf '%s' "${CONTENTS}" | largechar -c
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lastpic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | case "$ON_OS" in
3 | linux*)
4 | exec newest "$@" "${SCREENSHOTS:?No SCREENSHOTS environment variable set}"
5 | ;;
6 | mac*)
7 | find "${HOME}/Desktop" -iname 'screen shot*' | tail -n1 || exit $?
8 | ;;
9 | esac
10 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lastpicdrag:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | dragon-drop -x "$(lastpic)"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lastpicpreview:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec rifle "$(lastpic)"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lessi:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec less -i "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/light-theme:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec terminal-set-theme Light
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/list-config:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # list all of my configuration files, by matching combining
3 | # yadm list and a couple search commands
4 | cd # home
5 | {
6 | yadm list | sed "s#^#$HOME/#"
7 | echo "$HOME/.config/yadm/README.md"
8 | echo "$HPIDATA/personal_aliases"
9 | fd --type=file -H -E '__pycache__' -E '.mypy_cache' --full-path "${HOME}" "${XDG_CONFIG_HOME}/todo" "${ZDOTDIR}"
10 | } | grep -v "system-config" | exists | sort -u
11 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/list-config-no-hist:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | list-config | grep -vE -e "zsh_history|compdump" -e "$SHORTCUTS_DIR"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/list-images:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec fd '.*\.(png|jpeg|jpg|heic)$' "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/list-videos:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec list-movies "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/listens-desc:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # https://github.com/purarue/HPI-personal/blob/master/scripts/listens
3 | exec listens --desc "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/longest-video:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec shortest-video -o max "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lynx:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | # override the lynx binary by
3 | # placing the lynx shortcut
4 | # on $PATH first
5 | LYNX_PATH="$(where lynx | grep -m1 -v "$SHORTCUTS_DIR")" || exit $?
6 | exec "$LYNX_PATH" -accept_all_cookies -cfg="${XDG_CONFIG_HOME}/lynx/lynx.cfg" "$@"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lynx-dump:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec lynx -stdin -dump
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/lynx-from-stdin:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec lynx -stdin
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mal-recent:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl "myanimelist.net/animelist/purplepinapples?status=7&order=5"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/markdown-list:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec prefix '- '
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mediasearch:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | if SELECTED=$(printf "moviesearch\ntvsearch" | picker -p "Search Media Type > "); then
3 | exec "$SELECTED"
4 | fi
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/moviesearch:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # searches trakt/letterboxd for a movie
3 | SEARCH_STR=$(input-dialog "Search for a movie > " | chomp | tr " " "+")
4 | [ -z "$SEARCH_STR" ] && exit 1
5 | export SEARCH_STR
6 | moviesearch-trakt &
7 | moviesearch-letterboxd &
8 | wait
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/moviesearch-letterboxd:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # searches letterboxd for a movie
3 | [ -z "$SEARCH_STR" ] && SEARCH_STR=$(input-dialog "Search for a movie > " | chomp | tr " " "+")
4 | [ -z "$SEARCH_STR" ] && exit 1
5 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0") $SEARCH_STR"
6 | exec openurl "https://letterboxd.com/search/films/${SEARCH_STR}"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/moviesearch-trakt:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # searches trakt for a movie
3 | [ -z "$SEARCH_STR" ] && SEARCH_STR=$(input-dialog "Search for a movie > " | chomp | tr " " "+")
4 | [ -z "$SEARCH_STR" ] && exit 1
5 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0") $SEARCH_STR"
6 | exec openurl "https://trakt.tv/search/movies?query=${SEARCH_STR}&utf8=%E2%9C%93"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mpv-corner:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # mpv wrapper to open a video with mpv and put it in the bottom right corner
3 | setsid -f mpv --x11-name=mpv_stream_media "$@" >/dev/null 2>&1
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mpv-drag-screenshot:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | path="$(mpv-last-screenshot)"
3 | [ -n "$path" ] && exec dragon-drop -x "$path"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mpv-last-screenshot-upload:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec remsync-image "$(mpv-last-screenshot)"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mpv-logfile:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | MPV_LOGFILE_TMPDIR="${TMPDIR:-/tmp}/mpv-logs"
3 | mkdir -p "$MPV_LOGFILE_TMPDIR"
4 | exec mpv --log-file="$MPV_LOGFILE_TMPDIR/$(date +%s%N).log" "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mtotal:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec mlength -o sum -d m "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mvlastpic:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | FILE="$(lastpic)" || exit 1
3 | exec mv -v "${FILE}" "./$1"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mypy-single-lines:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec mypy --show-column-numbers --hide-error-codes --hide-error-context --no-color-output --no-error-summary --no-pretty "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mystarsfzf:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | update-my-stars
3 | # https://github.com/purarue/oh-my-stars
4 | PICKED="$(fzfcache mystars "$@" | fzf --ansi -0)" || exit $?
5 | printf '%s\n' "${PICKED}"
6 | URL="$(echo "${PICKED}" | urlextract)"
7 | # if a URL was extracted, copy it to my clipboard
8 | [[ -n "${URL}" ]] && {
9 | printf '%s' "${URL}" | clipcopy
10 | printf '%s\n' "${URL}"
11 | }
12 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/mz:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # use cached https://github.com/purarue/projects repository information
3 | # to quickly open one of my Github repositories
4 | chosen="$(jq -r '.[] | .html_url' <"${REPOS}/projects/cache.json" | fzf -0)" || exit $?
5 | echo "$chosen" | clipcopy
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/neomuttr:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # neomutt and refresh my menu bar block
3 | neomutt && refresh-block mail
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/pinta:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec flatpak run com.github.PintaProject.Pinta "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/pipehtml:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # given HTML on STDIN, create a tempfile with its contents
3 | tmpf="$(tmpfile html "$1")"
4 | cat >"$tmpf"
5 | exec printf '%s\n' "$tmpf"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/play-music:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # play music in the current directory, recursively
3 | list-music | sort -n | mpv --playlist=- --no-audio-display
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/play-shortest-video:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | if file="$(shortest-video)"; then
4 | exec rifle "$file"
5 | fi
6 | exit 1
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/playping-loop:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # I use this as a pleasant sounding alarm often, e.g.
3 | # timer 15m && playping-loop
4 | watch playping
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/primes:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec primesieve "$@" -p
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/printer-server:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # open the printer interface in the browser
3 | PRINTER_PORT=$(sudo cat /etc/cups/cupsd.conf | grep -i "Listen localhost" | cut -d":" -f2)
4 | printf "localhost:%d" "$PRINTER_PORT" | openurl
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/pygmentize-html-style:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | style="$(pygmentize-styles | fzf)" || exit $?
3 | exec pygmentize -P style="$style" -O noclasses=True -f html "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/pygmentize-styles:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # shellcheck disable=SC2063
3 | pygmentize -L styles | grep '* ' | cut -c3- | sed -e 's/:$//'
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/qf:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # usually used like qf <(grep -Hrin ...) or qf <(!!)
3 | # to repeat last command and create a quickfix list
4 | exec nvim -q "$@" +copen
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/qr-clipboard:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | clippaste | qr
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/realbasename:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec basename "$(realpath "$(pwd)")"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/reload-browser:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec xvkbd -window Navigator -text "i\Cr"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/reminder-sink-notify:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | SR="$(reminder-sink run)"
3 | exec notify "${SR:-No reminders}"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/render-notes:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec make -f "$HOME/.local/scripts/notes_rendered/Makefile" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/repos:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec repos-list -f "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/reshortcuts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o pipefail
3 | cd || exit $?
4 | [[ -n "${SHORTCUTS_DIR}" ]] && [[ -d "${SHORTCUTS_DIR}" ]] && rm -rf "${SHORTCUTS_DIR}"
5 | echo "Creating/formatting shortcuts..."
6 | DEBUG_OUTPUT="$(shortcuts create --debug && fd . "${SHORTCUTS_DIR}" -X rifleman 2>&1)" || {
7 | echo "$DEBUG_OUTPUT"
8 | }
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/rgqf:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec rg --no-heading --with-filename --line-number "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/rj:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | if [[ "$1" == "-o" ]]; then
3 | : # skip internet check, just run the loop once
4 | elif wait-for-internet --quiet --timeout 0; then
5 | exec bgproc_on_machine -pn
6 | fi
7 | export WFI_TIMEOUT=0
8 | exec bgproc_on_machine -on
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/screenshot-upload:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec remsync-image "$(lastpic)"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/screenshots:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec nsxiv -t "${SCREENSHOTS}"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/shortest-video:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | file="$(list-movies -X mlength -o min -d path "$@")"
3 | if [ -n "$file" ]; then
4 | echo "$file"
5 | else
6 | echo "No media found" >&2
7 | exit 1
8 | fi
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/shuffle-music:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Plays songs from this folder, recursively, randomly
3 | list-music | shuf | mpv --playlist=- --no-audio-display
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/sort-by-line-length:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -o pipefail
3 | awk '{ print length, $0 }' | sort -n | cut -d' ' -f2-
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/spell:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | spell-list "$@" || true
4 | spell-interactive "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/spell-fd:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec fd --type f --exclude package-lock.json --exclude yarn.lock "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/spell-interactive:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec spell-fd "$@" --exec-batch codespell-conf --write-changes --interactive 3
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/spell-list:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec spell-fd "$@" --exec-batch codespell-conf
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/sqlitebrowser-:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # on linux, call the binary directly
3 | havecmd 'sqlitebrowser' && exec sqlitebrowser "$@"
4 | # on mac, this is installed into /Applications/
5 | exec open -a DB\ Browser\ for\ SQLite "$@"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/ssh-keygen-good:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec ssh-keygen -t ed25519
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-audio:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | STREAM_MEDIA_CMD=mpv exec stream-media --no-video "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-corner:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # streams and sets the instance name on the mpv window
3 | # this is used with a for_window hook in i3 to put the
4 | # window in the bottom right
5 | exec stream-media --x11-name=mpv_stream_media "$@"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-corner-1080:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export FORMAT=1100
3 | exec stream-corner-at "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-corner-480:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec stream-corner-at "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-corner-720:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export FORMAT=850
3 | exec stream-corner-at "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-corner-at:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # set the FORMAT environment variable to specify maximum height/width
3 | # defaults to about 480p
4 | STREAM_MEDIA_CMD=mpv exec stream-corner --ytdl-format="$(create-youtube-dl-resolution-str)" "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/stream-from-firefox:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # copies the current URL from firefox, and starts streaming it with stream-at-480
3 | # escape, then yy (yank the URL; using the vimium extension)
4 | xvkbd -window Navigator -text "\Eyy"
5 | sleep 1 # just to make sure its copied
6 | exec stream-corner-480
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/styluac:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec stylua --config-path "$HOME/.config/nvim/stylua.toml" "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/sync-neomutt:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # wait for internet, sync my mail, then launch neomutt
3 | wait-for-internet && mailsync
4 | i3blocks-refresh-mk mail
5 | neomutt || return $?
6 | i3blocks-refresh-mk mail
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/syncgui:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl 'localhost:8384'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/synonym:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | word="${1:?Provide the word to list synonyms as first argument}"
3 | moby "${word}" | grep , | tr , '\n' | chomp
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/text2html:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec pygmentize -f html "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/timer-till-playping:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | timer-till "$*" && playping-loop
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/tmpfile:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | ext="${1:-tmp}"
3 | filename="${2:-$(genpasswd -rsym -rnum)}"
4 | echo "$(mktemp -d)/${filename}.${ext}"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/to-icon:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # convert an image to a 16x16 icon - to favicon size
3 | FILEPATH=${1:?Must provide image to convert}
4 | NEW_FILEPATH="$(remove-extension "${FILEPATH}")-icon.png"
5 | exec magick -resize x16 -gravity center -crop 16x16+0+0 -flatten -colors 256 "${FILEPATH}" "${NEW_FILEPATH}"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/todo:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec todo.sh "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/trakt-progress:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec openurl "https://trakt.tv/users/purplepinapples/progress"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/tstamp:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec date +'%Y%m%d%H%M%S'
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/tvsearch:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # searches trakt for a tv show
3 | SEARCH_STR=$(input-dialog "Search for a TV show > " | chomp | tr " " "+")
4 | [ -z "$SEARCH_STR" ] && exit 1
5 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0") $SEARCH_STR"
6 | exec openurl "https://trakt.tv/search/shows?query=${SEARCH_STR}&utf8=%E2%9C%93"
7 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/twitch-stream:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # open chatterino and use mpv to stream from twitch
3 | STREAMER="${1:?Pass the twitch user to stream from as the first argument.}"
4 | pgrep -x chatterino >/dev/null || setsid chatterino >/dev/null 2>&1 &
5 | MPVF_PICKER=rofi setsid mpvf "https://www.twitch.tv/${STREAMER}" >/dev/null &
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/tz:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec time-in tz "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/unicode:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | file="${TMPDIR:-/tmp}/unicode_input"
3 | kitty -- sh -c "kitten unicode_input >\"$file\"" || exit $?
4 | contents="$(cat "$file")"
5 | [[ -z "$contents" ]] && exit 1
6 | clp <<<"$contents"
7 | rm -f "$file"
8 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/unlines:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec paste -sd " "
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/up-live:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 | TERM=xterm exec up --unsafe-full-throttle
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/update-forks:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec clone-repos ~/.config/clone-repos/update-forks.yaml
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/url-echo-redirect:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # echo the URL that would be redirected to
3 | URL="${1:-"$(cat)"}"
4 | if [[ -z "$URL" ]]; then
5 | echo "No URL provided" >&2
6 | exit 1
7 | fi
8 | exec curl -w "%{url_effective}\n" -ILsS "$URL" -o /dev/null
9 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/urldrag:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # dragon a picture from my clipboard https://github.com/mwh/dragon
3 | img-download || exit $?
4 | exec dragon-drop -x "$(clippaste)"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/urlpicpreview:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # preview a picture from a URL
3 | img-download "$@" || exit $?
4 | rifle "$(clippaste)"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/usdate:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # print the date in the us format
3 | exec date "+%m/%d/%y"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/vic:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | EXECUTABLE="${1:?No Executable provided}"
3 | LOCATION="$(command -v "${EXECUTABLE}")" || exit $?
4 | cd "$(dirname "${LOCATION}")" || exit $?
5 | exec editor "$(basename "${LOCATION}")"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/vix:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec ix -v
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/watchtwitch:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | twitchlive -output-format json | jq -r '.[] | .username' | picker -p "who to watch? " | xargs -r twitch
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/webcam-pic:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # open mpv to save a picture (using webcam) in ~/Pictures/pics
3 |
4 | declare pics
5 | pics="${XDG_PICTURES_DIR:?XDG_PICTURES_DIR environment variable not set}/pics"
6 | [[ ! -d "$pics" ]] && mkdir -p "$pics"
7 | cd "$pics" || exit 1
8 | # open mpv so I can take a picture
9 | mpv /dev/video0
10 | exec launch ranger "$pics"
11 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/webcam-test:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec /usr/bin/mpv /dev/video0
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/wfi:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # wait for internet connection and ping me
3 | command -v tttlog >/dev/null 2>&1 && tttlog "$(basename "$0")"
4 | wait-for-internet "$@" && {
5 | notify "INTERNET"
6 | playping
7 | }
8 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/wfib:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # wfi, and then reload the browser
3 | wfi
4 | exec reload-browser
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/which-cat:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # I have a which-cat zsh function as well, this is a fallback for scripts
3 | # or when I'm in nvim
4 | EXEC="${1:?Must provide executable as first argument}"
5 | if LOC="$(which "$EXEC")" >/dev/null 2>&1; then
6 | cat "$LOC"
7 | else
8 | printf "Could not find %s\n" "$EXEC" >&2
9 | fi
10 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/yadm-format:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | # autoformat all my dotfiles
3 | set -o pipefail
4 | cd
5 | yadm list | exists | grep -v 'lazy-lock.json' | rifleman - "$@"
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/yadm-lint:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | # run linters on all my dotfiles
3 | set -o pipefail
4 | cd
5 | yadm list | exists | rifleman - -a lint
6 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/yh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd ~/.local/share/yadm/repo.git/ || exit $?
3 | exec gh "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/youtube-dl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec python3 -m yt_dlp -o '%(title)s.%(ext)s' -ci "$@"
3 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/youtube-dl-480:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # download at about 480p
3 | exec youtube-dl-at "$@"
4 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/youtube-dl-720:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # download at about 720p
3 | export FORMAT=850
4 | exec youtube-dl-at "$@"
5 |
--------------------------------------------------------------------------------
/.local/share/shortcuts/youtube-dl-at:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # set the FORMAT environment variable to control resolution
3 | exec youtube-dl -f "$(create-youtube-dl-resolution-str)" "$@"
4 |
--------------------------------------------------------------------------------
/.local/system-config/etc/X11/xorg.conf.d/20-amdgpu.conf:
--------------------------------------------------------------------------------
1 | Section "Device"
2 | Identifier "AMD"
3 | Driver "amdgpu"
4 | Option "TearFree" "true"
5 | EndSection
6 |
--------------------------------------------------------------------------------
/.local/system-config/etc/X11/xorg.conf.d/30-trackpad-options.conf:
--------------------------------------------------------------------------------
1 | # This applies the option any libinput device also matched by the other
2 | # directives. See the xorg.conf(5) man page for more info on
3 | # matching devices.
4 | #
5 | # Apply Natural Scrolling - Flip the Scroll direction for the trackpad
6 |
7 | Section "InputClass"
8 | Identifier "flip touchpad scrolling"
9 | Driver "libinput"
10 | Option "Natural Scrolling" "true"
11 | Option "Accel Speed" "0.2"
12 | EndSection
13 |
--------------------------------------------------------------------------------
/.local/system-config/etc/pacman.d/hooks/mirrorupgrade.hook:
--------------------------------------------------------------------------------
1 | [Trigger]
2 | Operation = Upgrade
3 | Type = Package
4 | Target = pacman-mirrorlist
5 |
6 | [Action]
7 | Description = Updating pacman-mirrorlist with reflector and removing pacnew...
8 | When = PostTransaction
9 | Depends = reflector
10 | Exec = /bin/sh -c "reflector --country 'United States' --download-timeout 30 --latest 200 --age 24 --sort rate --save /etc/pacman.d/mirrorlist; rm -f /etc/pacman.d/mirrorlist.pacnew"
11 |
--------------------------------------------------------------------------------
/.local/system-config/etc/systemd/system/lockscreen@.service:
--------------------------------------------------------------------------------
1 | # enable this like 'sudo systemctl enable lockscreen@$(whoami).service --now'
2 |
3 | [Unit]
4 | Description=Lock the screen on sleep
5 | Before=sleep.target
6 | Before=suspend.target
7 |
8 | [Service]
9 | User=%i
10 | Type=simple
11 | Environment=DISPLAY=:0
12 | ExecStartPre=/usr/bin/xset dpms force suspend
13 | ExecStart=%h/.local/scripts/cross-platform/lock-screen
14 | TimeoutSec=infinity
15 |
16 | [Install]
17 | WantedBy=sleep.target
18 | WantedBy=suspend.target
19 |
--------------------------------------------------------------------------------
/.termux/colors.properties:
--------------------------------------------------------------------------------
1 | # https://github.com/catppuccin/catppuccin
2 | foreground=#cad3f5
3 | background=#24273a
4 | cursor=#f4dbd6
5 |
6 | color0=#494d64
7 | color1=#ed8796
8 | color2=#a6da95
9 | color3=#eed49f
10 | color4=#8aadf4
11 | color5=#f5bde6
12 | color6=#8bd5ca
13 | color7=#b8c0e0
14 |
15 | color8=#5b6078
16 | color9=#ed8796
17 | color10=#a6da95
18 | color11=#eed49f
19 | color12=#8aadf4
20 | color13=#f5bde6
21 | color14=#8bd5ca
22 | color15=#a5adcb
23 |
24 | color16=#f5a97f
25 | color17=#f4dbd6
26 |
--------------------------------------------------------------------------------
/.xinitrc:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # source keymap configuration
4 | # move xmodmap somewhere else so it doesn't pollute my home directory
5 | usermodmap="$HOME/.config/X11/Xmodmap"
6 |
7 | if [ -f "$usermodmap" ]; then
8 | xmodmap "$usermodmap"
9 | fi
10 |
11 | # source user profile
12 | # sets a bunch of global-ish environment variables, detects which OS I'm
13 | # on and sets the ON_OS environment variable which I use in lots of my scripts
14 | if [ -f "${HOME}/.profile" ]; then
15 | . "${HOME}/.profile"
16 | fi
17 |
18 | # start some nice programs
19 |
20 | if [ -d /etc/X11/xinit/xinitrc.d ]; then
21 | for f in /etc/X11/xinit/xinitrc.d/?*.sh; do
22 | # shellcheck disable=SC1090
23 | [ -x "$f" ] && . "$f"
24 | done
25 | unset f
26 | fi
27 |
28 | # set key repeat rate
29 | xset r rate 300 25
30 |
31 | exec i3
32 |
--------------------------------------------------------------------------------