Compare commits
No commits in common. "main" and "feat/wezterm-timg" have entirely different histories.
main
...
feat/wezte
373 changed files with 45648 additions and 24840 deletions
1
.assets/.stow-local-ignore
Normal file
1
.assets/.stow-local-ignore
Normal file
|
@ -0,0 +1 @@
|
|||
^/.* # everything
|
|
@ -1,111 +0,0 @@
|
|||
[helpers]
|
||||
|
||||
# BASE: A base system. Sets up a nice xdg (zsh) shell environment, utility scripts and
|
||||
# a development environment based on git and nvim.
|
||||
|
||||
[base]
|
||||
depends = ["shell", "vcs", "nvim", "scripts", "ssh", "terminal", "bootstrap"]
|
||||
|
||||
[bootstrap.files]
|
||||
"bootstrap/dotlink.sh" = "~/.config/sh/alias.d/dotlink.sh"
|
||||
|
||||
[shell.files]
|
||||
"sh/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
sh = "~"
|
||||
|
||||
[vcs.files]
|
||||
"vcs/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
"vcs/git/config" = "~/.config"
|
||||
"vcs/jj/config" = "~/.config"
|
||||
"vcs/gitignore/config" = "~/.config"
|
||||
"vcs/gitignore/local" = "~/.local"
|
||||
vcs = "~"
|
||||
|
||||
[nvim.files]
|
||||
"nvim/.config/nvim/spell/de.utf-8.add.spl" = { target = "~/.config/nvim/spell/de.utf-8.add.spl", type = "symbolic" }
|
||||
"nvim/.config/nvim/spell/en.utf-8.add.spl" = { target = "~/.config/nvim/spell/en.utf-8.add.spl", type = "symbolic" }
|
||||
nvim = "~"
|
||||
|
||||
[scripts.files]
|
||||
"scripts/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
scripts = "~"
|
||||
|
||||
[ssh.files]
|
||||
ssh = "~"
|
||||
|
||||
[terminal.files]
|
||||
"terminal/.config/vifm" = "~/.config/vifm"
|
||||
"terminal/.config/vifm/vifmrc" = { target = "~/.config/vifm/vifmrc", type = "symbolic" }
|
||||
terminal = "~"
|
||||
|
||||
# LINUX: A linux machine, with systemd enabled, auto-mounting set up and a nice productivity suite.
|
||||
|
||||
[linux]
|
||||
depends = ["base", "disks", "pass", "office", "services", "social", "writing"]
|
||||
|
||||
[disks.files]
|
||||
"disks/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
disks = "~"
|
||||
|
||||
[pass.files]
|
||||
"pass/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
"pass/.local/share/pass-pick/assets/rofi-menu.gif" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
pass = "~"
|
||||
|
||||
[office.files]
|
||||
"office/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
"office/.config/glow/email.json" = { target = "~/.config/glow/email.json", type = "symbolic" }
|
||||
"office/.config/isync/mbsyncrc" = { target = "~/.config/isync/mbsyncrc", type = "template" }
|
||||
"office/.config/msmtp/config" = { target = "~/.config/msmtp/config", type = "template" }
|
||||
"office/.config/neomutt/account" = { target = "~/.config/neomutt/account", type = "template" }
|
||||
"office/.config/neomutt/profile.gmail" = { target = "~/.config/neomutt/profile.gmail", type = "template" }
|
||||
"office/.config/neomutt/profile.private" = { target = "~/.config/neomutt/profile.private", type = "template" }
|
||||
office = "~"
|
||||
|
||||
[services.files]
|
||||
"services/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
services = "~"
|
||||
|
||||
[social.files]
|
||||
social = "~"
|
||||
|
||||
[writing.files]
|
||||
"writing/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
"writing/jrnl/config" = "~/.config"
|
||||
"writing/papis/config/papis/papistui.yaml" = { target = "~/.config/papis/papistui.yaml", type = "symbolic" }
|
||||
"writing/papis/config" = "~/.config"
|
||||
"writing/sioyek/config/sioyek/prefs_user.config" = { target = "~/.config/sioyek/prefs_user.config", type = "template", prepend = "# TEMPLATED BY DOTTER\n" }
|
||||
"writing/sioyek/config" = "~/.config"
|
||||
"writing/zathura/config" = "~/.config"
|
||||
"writing/zk/config" = "~/.config"
|
||||
"writing/pandoc/local" = "~/.local"
|
||||
writing = "~"
|
||||
|
||||
# WORKSTATION: A desktop machine, with wayland environment and display attached.
|
||||
|
||||
[workstation]
|
||||
depends = ["linux", "desktop", "multimedia", "qutebrowser"]
|
||||
|
||||
[desktop.files]
|
||||
"desktop/.config/flavours/templates" = { target = "~/.config/flavours/templates", type = "symbolic" }
|
||||
"desktop/.config/waybar/config" = { target = "~/.config/waybar/config", type = "symbolic" }
|
||||
"desktop/.config/mako/config" = { target = "~/.config/mako/config", type = "template", prepend = "# TEMPLATED BY DOTTER\n" }
|
||||
"desktop/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
desktop = "~"
|
||||
|
||||
[multimedia.files]
|
||||
"multimedia/README.md" = { target = "~/NOWHERE", type = "symbolic", if = "false" }
|
||||
"multimedia/.config/mpv/scripts" = { target = "~/.config/mpv/scripts", type = "symbolic" }
|
||||
"multimedia/.config/ncmpcpp/config" = { target = "~/.config/ncmpcpp/config", type = "symbolic" }
|
||||
"multimedia/.config/mpv/fonts/uosc_icons.otf" = { target = "~/.config/mpv/fonts/uosc_icons.otf", type = "symbolic" }
|
||||
"multimedia/.config/mpv/fonts/uosc_textures.ttf" = { target = "~/.config/mpv/fonts/uosc_textures.ttf", type = "symbolic" }
|
||||
"multimedia/.config/vimiv/styles/base16" = { target = "~/.config/vimiv/styles/base16", type = "template" }
|
||||
multimedia = "~"
|
||||
|
||||
[qutebrowser.files]
|
||||
"qutebrowser/config" = "~/.config/qutebrowser"
|
||||
"qutebrowser/scripts" = "~/.local/bin"
|
||||
"qutebrowser/data" = "~/.local/share/qutebrowser"
|
||||
|
||||
[system.files]
|
||||
"bootstrap/system-packages" = { target = "/", type = "symbolic", owner = "root" }
|
|
@ -1,13 +0,0 @@
|
|||
includes = []
|
||||
packages = ["workstation"]
|
||||
|
||||
[files]
|
||||
|
||||
[variables]
|
||||
|
||||
multimedia_beets_musicbrainz_user = ""
|
||||
multimedia_beets_musicbrainz_pass = ""
|
||||
multimedia_mopidy_subidy_url = ""
|
||||
multimedia_mopidy_subidy_user = ""
|
||||
multimedia_mopidy_subidy_pass = ""
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
packages = ["system", "workstation"]
|
||||
|
||||
[files]
|
||||
|
||||
[variables]
|
1
.githooks/.stow-local-ignore
Normal file
1
.githooks/.stow-local-ignore
Normal file
|
@ -0,0 +1 @@
|
|||
^/.* # everything
|
|
@ -4,8 +4,8 @@ COMMIT_MSG_FILE="$1"
|
|||
COMMIT_SOURCE="$2"
|
||||
|
||||
BOOTSTRAPDIR="bootstrap"
|
||||
pkg_committed="$(cat "$(git rev-parse --show-toplevel)"/$BOOTSTRAPDIR/packages*.tsv | grep -v -e '^Name Description Source Target' | cut -f1 | sort)"
|
||||
pkg_onsystem=$(pacman -Qqett | sort)
|
||||
pkg_committed="$(cat $(git rev-parse --show-toplevel)/$BOOTSTRAPDIR/packages.tsv | tail +2 | cut -f1 | sort)"
|
||||
pkg_onsystem=$(pacman -Qqett | grep -v "$(pacman -Qqg base-devel)" | sort)
|
||||
|
||||
# get files only in repo, and only on machine
|
||||
only_committed=$(comm -23 <(echo "$pkg_committed") <(echo "$pkg_onsystem"))
|
||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,7 +1,3 @@
|
|||
# don't move the cache into repo
|
||||
/.dotter/cache/
|
||||
/.dotter/cache.toml
|
||||
|
||||
# no idea why gopass adds this image to config path
|
||||
gopass-logo-small.png
|
||||
#
|
||||
|
@ -31,8 +27,6 @@ sponsorblock.txt
|
|||
/qutebrowser/.config/qutebrowser/stylesheets
|
||||
# ignore the generated readability file for webpages
|
||||
readability.html
|
||||
# ignore the adblock file generated by qutebrowser
|
||||
blocked-hosts
|
||||
|
||||
# ignore vifm & ueberzug utility files
|
||||
vifm-help.txt
|
||||
|
@ -45,5 +39,5 @@ vifminfo.json
|
|||
colorscheme.yml
|
||||
|
||||
# taskwarrior
|
||||
office/.config/task/task-sync.rc
|
||||
office/.config/task/contexts
|
||||
taskwarrior/.config/task/task-sync.rc
|
||||
taskwarrior/.config/task/contexts
|
||||
|
|
37
.gitlab-ci.yml
Normal file
37
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
# install moreutils to enable ifne (if not empty)
|
||||
# will only run the respective analyzers when files to test
|
||||
# are acutally found
|
||||
image: fnichol/check-shell:latest
|
||||
|
||||
analyze:
|
||||
stage: test
|
||||
before_script:
|
||||
- apk add moreutils
|
||||
- shellcheck --version
|
||||
script:
|
||||
- echo "--------- CHECKING POSIX SHELLSCRIPTS -------------"
|
||||
- find . -type f -name '*.sh' | ifne xargs shellcheck -Calways
|
||||
- echo "--------- CHECKING ZSH SHELLSCRIPTS -------------"
|
||||
- find . -type f -name '*.zsh' | ifne xargs shellcheck -Calways -s bash -e SC2034
|
||||
|
||||
lint:
|
||||
stage: test
|
||||
before_script:
|
||||
- apk add moreutils
|
||||
- shfmt -version
|
||||
script:
|
||||
- echo "--------- CHECKING POSIX SHELLSCRIPTS -------------"
|
||||
- find . -type f -name '*.sh' -not -path '*/pomo-app/*' | ifne xargs shfmt -d -i 4
|
||||
- echo "--------- CHECKING ZSH SHELLSCRIPTS -------------"
|
||||
- find . -type f -name '*.zsh' -not -path '*/pomo-app/*' | ifne xargs shfmt -d -i 4
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image: alpine
|
||||
before_script:
|
||||
- apk add git bash
|
||||
- git clone https://github.com/bats-core/bats-core.git /bats
|
||||
- /bats/bin/bats --version
|
||||
script:
|
||||
- /bats/bin/bats -r .
|
9
.gitmodules
vendored
9
.gitmodules
vendored
|
@ -1,9 +1,6 @@
|
|||
[submodule "polybar/.local/share/pomo-app"]
|
||||
path = polybar/.local/share/pomo-app
|
||||
url = https://github.com/jsspencer/pomo.git
|
||||
[submodule "pass/.local/share/pass-pick"]
|
||||
path = pass/.local/share/pass-pick
|
||||
url = https://git.martyoeh.me/Marty/pass-pick.git
|
||||
[submodule "scripts/.local/share/uoeia"]
|
||||
path = scripts/.local/share/uoeia
|
||||
url = https://git.martyoeh.me/Marty/uoeia.git
|
||||
[submodule "multimedia/.local/share/vimiv/plugins/batchmark"]
|
||||
path = multimedia/.local/share/vimiv/plugins/batchmark
|
||||
url = https://github.com/jcjgraf/BatchMark
|
||||
|
|
5
.stowrc
Normal file
5
.stowrc
Normal file
|
@ -0,0 +1,5 @@
|
|||
--target=~
|
||||
--ignore='^.gitlab-ci.yml$'
|
||||
--ignore='^.stowrc$'
|
||||
--ignore='^.githooks$'
|
||||
--ignore='^README.md$'
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2023 Marty Oehme
|
||||
Copyright (c) 2019 Marty Oehme
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
36
README.md
36
README.md
|
@ -1,43 +1,38 @@
|
|||
# `~/🌹`
|
||||
|
||||
Note that the below screenshots still show the X configuration from [v0.1](https://gitlab.com/marty-oehme/dotfiles/-/tags/v0.1) which is *very* old by now.
|
||||
Note that the below screenshots still show the X configuration from [v0.1](https://gitlab.com/marty-oehme/dotfiles/-/tags/v0.1).
|
||||
The current dotfiles are geared toward wayland for which the setup looks similar but not identical to the previews below.
|
||||
|
||||
## What's in these dotfiles
|
||||
|
||||
* [x] wayland setup using `riverwm` with quick access to many overlays and picking tools for styles, downloads, browsing history, passwords and more
|
||||
* [x] vim configuration for simple programming tasks (especially python/bash/lua) and prose (markdown/quarto/latex)
|
||||
* [x] vim configuration for simple programming tasks (especially go/typescript/python/bash) and prose
|
||||
* [x] academic workflow tools, to allow quick citation, pdf compilation, and preview
|
||||
* [x] simple, efficient waybar with package update notification and mpris integration
|
||||
* [x] system-wide color management (terminals, vim, qutebrowser, polybar, xresources) through [`flavours`](https://github.com/Misterio77/flavours) application using [base16](http://chriskempson.com/projects/base16/) themes
|
||||
* [x] quick theme switching by activating `flavours` and fuzzy-searching themes with hot-key (default `<Super>=<Shift>+S`)
|
||||
* [x] simple, efficient waybar with package update notification, and spotify (mpris) integration
|
||||
* [x] tmux session management through `tm` and `tl` tools
|
||||
* [x] tmux fuzzy-searching of terminal sessions to switch to with hot-key (`<C-A><C-s>`) in addition to normal session switching
|
||||
* [x] system-wide color management (terminals, vim, qutebrowser, polybar, xresources) through `styler` command using [base16](http://chriskempson.com/projects/base16/) themes
|
||||
* [x] quick theme switching by activating `styler` and fuzzy-searching themes with hot-key (default `<Super>=<Shift>+S`)
|
||||
* [x] many vim color-schemes with quick light/dark switching (`F8`) and individual theme switch (`<Space>+F8`)
|
||||
* [x] quick directory jumping using `z`, with `fzf` integration
|
||||
* [x] `fzf`-like integrations for bibtex citation, vim buffer management, most recently used switching, shell command history, and more
|
||||
* [x] password management with `pass` and picking it with automatic typing into any window
|
||||
|
||||
[![Styler recoloring demo](https://gitlab.com/marty-oehme/dotfiles/-/wikis/uploads/bde87deda694590a2e08e21552e11309/styler.webp)](https://gitlab.com/marty-oehme/dotfiles/-/wikis/uploads/90894e53eff378db4d7f9f49e7a69fab/styler.mp4)
|
||||
|
||||
## Quick-Start
|
||||
|
||||
The dotfiles use `dotter` to link themselves in the home directory. You can clone this repository anywhere (though I have mine in `~/.dotfiles` as it seemed most logical for me).
|
||||
The dotfiles use `GNU stow` to link themselves in the home directory. You can clone this repository anywhere (though I have mine in `~/.dotfiles` as it seemed most logical for me).
|
||||
|
||||
I would recommend doing an initial `git clone --recursive` for this repository, since it contains git [submodules](https://nering.dev/2016/git-submodules-vs-subtrees/), which will then automatically get pulled in as well.
|
||||
Of course, you can do it non-recursively and then just pull those modules selectively which you actually want.
|
||||
I would recommend doing a `git clone --recursive` for this repository, since it contains git [submodules](https://nering.dev/2016/git-submodules-vs-subtrees/), which will then automatically get pulled in as well. Of course, you can do it non-recursively and then just pull those modules selectively which you actually want.
|
||||
|
||||
Once in the repository directory, when you then run `./install.sh` it will install many of the packages I use (though they are probably slightly out-of-date) and link the dotfiles into the home directory.
|
||||
I would mostly recommend this on fresh machines or a test machine first - it *will* link my personal dotfiles and, if you allow it, *will* install quite a few packages.
|
||||
By default it will ask your consent for some steps -- use `./install.sh -f` to force yes to everything.
|
||||
|
||||
The dotfile installation procedure is based on `dotter`, it will generally *not overwrite* anything already in the home directory, but of course be observant when doing ptentially destructive operations.
|
||||
|
||||
> **NOTE**
|
||||
> The same non-destructive installation procedure does *not* apply to the package installation and system setting file linking, where it can potentially overwrite or remove existing files.
|
||||
If you do not want to install any packages, but only link the dotfiles run `stow -S */` from the main repository directory.
|
||||
Since dotfiles management is based on `stow`, it will not overwrite anything already in the home directory (though you can force it to if you really want, using `stow --override='.*'` -- I do not recommend this).
|
||||
|
||||
After all files are linked and you open a new shell session, the `dotlink` alias will allow you to re-link all dotfiles from anywhere on the system.[^1]
|
||||
|
||||
[^1]: This alias only works when the dotfiles are cloned into `~/.dotfiles`, mirroring my setup.
|
||||
This is due to a hard-coded cd into this directory.
|
||||
If your dotfiles lie in another directory and you want to use the dotlink alias, simply change the corresponding line in `bootstrap/.config/sh/alias.d/dotlink.sh`
|
||||
If your dotfiles lie in another directory and you want to use the dotlink alias, simply change the corresponding line in `bootstrap/.config/sh/alias.d/dotlink.sh`]
|
||||
|
||||
Both automatic installation paths are presumably somewhat brittle. In any case, I would suggest to manually look through the files for things you want instead of copying and activating everything.
|
||||
Dotfiles are too personal to be standardized like that.
|
||||
|
@ -59,9 +54,8 @@ Enjoy!
|
|||
* [`vifm`](https://github.com/vifm/vifm) - vim-like file-manager
|
||||
* [`qutebrowser`](https://github.com/qutebrowser/qutebrowser) - vim-key enabled web browser
|
||||
* [`pass`](pass/README.md) - Password management suite
|
||||
* [`bibtex`] - LateX/BibteX/pandoc plaintext writing & reference suite
|
||||
* [`bibtex`](bibtex/README.md) - LateX/BibteX/pandoc plaintext writing & reference suite
|
||||
* [`git`](git/README.md) - distributed version control system.
|
||||
* [`office`](office/README.md) - office/productivity software for writing e-mail and setting appointments
|
||||
|
||||
## Notes
|
||||
|
||||
|
@ -71,7 +65,7 @@ Enjoy!
|
|||
* Whereas `sh` module scripts are requirements for other scripts, `.local/bin` in the `scripts` module contains most executable user scripts. Most of these have been migrated to other corresponding modules (e.g. if a script exclusively targets git functionality, it will live there), some useful --- or left-over --- stand-alone scripts remain however.
|
||||
* `.local/share/pandoc` contains configuration for academic latex writing (pandoc, really) and is of interest if you want to use this functionality.
|
||||
* `.xinitrc` is used for x initialization and program startup. At some point, some of the consistently running applications may be moved to systemd/runit as supervised services.
|
||||
* Generally, top-level directories starting with a . are only meaningful for the *repository* not for the functionality of the machine that these dotfiles are deployed on. That means `.gitlab-ci.yml`, `.assets/`, `.gitignore` and similar files and directories will not show up in the final deployment in any home directory. Perhaps they should be called dotdot-files since they're the dotfiles for my dotfiles. 🙂 (Also, '[dotfiles](https://en.wikipedia.org/wiki/Semantic_satiation)'.)
|
||||
* Generally, top-level directories starting with a . are only meaningful for the *repository* not for the functionality of the machine that these dotfiles are deployed on. That means `.gitlab-ci.yml`, `.assets/`, `.stowrc` and similar files and directories will not show up in the final deployment in any home directory. Perhaps they should be called dotdot-files since they're the dotfiles for my dotfiles. 🙂 (Also, '[dotfiles](https://en.wikipedia.org/wiki/Semantic_satiation)'.)
|
||||
|
||||
[^shreq]: I may remove this requirement in the future to make modules more self-contained. However, relying on some base utility scripts makes it easier to avoid duplicating such functionality for each individual script in other modules.
|
||||
|
||||
|
|
|
@ -12,25 +12,17 @@ CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
|
|||
[ -f "$CONFDIR/sh/alias" ] && source "$CONFDIR/sh/alias"
|
||||
# load additional aliases
|
||||
if [ -d "$CONFDIR/sh/alias.d" ]; then
|
||||
for _alias in "$CONFDIR/sh/alias.d"/*.sh; do
|
||||
. "$_alias"
|
||||
done
|
||||
unset _alias
|
||||
for _alias in "$CONFDIR/sh/alias.d"/*.sh; do
|
||||
. "$_alias"
|
||||
done
|
||||
unset _alias
|
||||
fi
|
||||
if [ -d "$CONFDIR/bash/alias.d" ]; then
|
||||
for _alias in "$CONFDIR/bash/alias.d"/*.sh; do
|
||||
. "$_alias"
|
||||
done
|
||||
unset _alias
|
||||
for _alias in "$CONFDIR/bash/alias.d"/*.sh; do
|
||||
. "$_alias"
|
||||
done
|
||||
unset _alias
|
||||
fi
|
||||
|
||||
alias ls='ls --color=auto'
|
||||
|
||||
eval "$(starship init bash)"
|
||||
eval "$(zoxide init bash)"
|
||||
|
||||
set -o vi
|
||||
stty time 0
|
||||
bind 'set keyseq-timeout 1'
|
||||
|
||||
eval "$(atuin init bash)"
|
||||
PS1='[\u@\h \W]\$ '
|
147
bibtex/.local/bin/bib-due
Executable file
147
bibtex/.local/bin/bib-due
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env sh
|
||||
# shows due entries of bibtex file passed in
|
||||
# HACK: brittle! will break on various bibfile abnormities (even just on due date w/o priority)
|
||||
# FIXME: reimplementation with real library needed
|
||||
#
|
||||
|
||||
OPTIND=1 # Reset in case getopts has been used previously in the shell.
|
||||
fields="due|priority|\bauthor\b|\btitle\b"
|
||||
filterby="due"
|
||||
file="${BIBFILE}"
|
||||
until=""
|
||||
|
||||
show_help() {
|
||||
printf "%s\n" \
|
||||
"" \
|
||||
" bib-due Show due readings from bibtex file." \
|
||||
"" \
|
||||
" Usage: bib-due [-hv] -i input.bib -r 'due|priority|\bauthor|\btitle' -l 'due' -u '2020-05-12'" \
|
||||
"" \
|
||||
" Options:" \
|
||||
"" \
|
||||
" -i [bibtex-file] Input bibtex file to scrape and get items from." \
|
||||
"" \
|
||||
" -r [fields] Field values to read in file." \
|
||||
"" \
|
||||
" -l [filter] Field to use as filter entity." \
|
||||
" This field is required for the scraper to pick entries up." \
|
||||
"" \
|
||||
" help | -h | --help Print out this help." \
|
||||
"" \
|
||||
" Invoked without arguments, bib-due will scrape the file defined in BIBFILE environment variable, " \
|
||||
" filtering entries with the 'due' field, and getting the values for 'due', 'priority', 'author', " \
|
||||
" and 'title' fields. It will then print the entries to stdout." \
|
||||
"" \
|
||||
" Example output line:" \
|
||||
"" \
|
||||
' 2020-06-25 (1): Sergei Gerasymchuk -- “Ze” time in Ukraine (Gerasymchuk2019) ' \
|
||||
""
|
||||
}
|
||||
|
||||
filter_until() {
|
||||
# filter for dates, with line numbers
|
||||
filtered=$(echo "$entries" | grep -noE '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}')
|
||||
|
||||
# redirect entries to fifo pipe
|
||||
mkfifo filteredentries
|
||||
finish() {
|
||||
rm filteredentries
|
||||
}
|
||||
trap finish EXIT
|
||||
echo "$filtered" >filteredentries &
|
||||
|
||||
# find first date past until filter
|
||||
lastline=""
|
||||
while IFS= read -r line; do
|
||||
cond=$(printf '%s' "$line" | cut -d: -f2)
|
||||
cond=$(date -d "$cond" +%s)
|
||||
if [ "$cond" -gt "$until" ]; then
|
||||
lastline=$(printf '%s' "$line" | cut -d: -f1)
|
||||
break
|
||||
fi
|
||||
done <filteredentries
|
||||
|
||||
# special cases all in filter, or none in filter
|
||||
if [ -z "$lastline" ]; then
|
||||
return
|
||||
elif [ "$lastline" -eq 1 ]; then
|
||||
entries=""
|
||||
# filter
|
||||
else
|
||||
# remove lines below found
|
||||
lastprinted="$((lastline - 1))"
|
||||
entries=$(echo "$entries" | sed -n "1,${lastprinted}p;${lastline}q")
|
||||
fi
|
||||
}
|
||||
|
||||
filter_priority() {
|
||||
priority="$1"
|
||||
# filter for dates, with line numbers
|
||||
# filtered=$(echo "$entries" | grep -noE '[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}')
|
||||
filtered=""
|
||||
while [ "$priority" -gt 0 ]; do
|
||||
current=$(echo "$entries" | grep -E "\($priority\)")
|
||||
|
||||
# append found to filtered entries
|
||||
filtered=$(printf "%s\n%s" "$filtered" "$current")
|
||||
|
||||
# go to next 'higher' priority
|
||||
priority="$((priority - 1))"
|
||||
done
|
||||
# sort them chronologically again, remove empty lines
|
||||
entries="$(echo "$filtered" | sed -e '/^$/d' | sort)"
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ -z "$file" ]; then
|
||||
echo "Requires a bibtex file as argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# filter all entries for those containing filterby field (default: due)
|
||||
# retain values of all fields mentioned in fields variable
|
||||
entries=$(grep -E "^@|$fields" "$file" | awk 1 ORS=' ' | sed -E 's/@\w+\{/\n/g' | grep "$filterby" | tail -n +2 | sed -E 's/(,\s+(\w+)\s+=\s+|,\s*$)/\t/g' | awk -F'\t' '{ print $4 "\t" $5 "\t" $2 "\t" $3 "\t" $1 }')
|
||||
|
||||
# prettify and sort the entries for display (remove {}, order by date,prio,author,title)
|
||||
entries=$(echo "$entries" | awk -F'\t' '{ gsub(/{/,""); gsub(/}/,""); gsub(/prio/,"",$2) } { print $1 " (" $2 "): " $3 " -- " $4 " (" $5 ")"}' | sort)
|
||||
|
||||
if [ -n "$until" ]; then
|
||||
filter_until
|
||||
fi
|
||||
if [ -n "$priority" ]; then
|
||||
filter_priority "$priority"
|
||||
fi
|
||||
|
||||
echo "$entries"
|
||||
}
|
||||
|
||||
while getopts "h?i:u:r:l:p:" opt; do
|
||||
case "$opt" in
|
||||
h | \?)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
# v) verbose=1
|
||||
# ;;
|
||||
r)
|
||||
fields="$OPTARG"
|
||||
;;
|
||||
l)
|
||||
filterby="$OPTARG"
|
||||
;;
|
||||
i)
|
||||
file="$OPTARG"
|
||||
;;
|
||||
u)
|
||||
until="$(date -d "$OPTARG" +%s)"
|
||||
;;
|
||||
p)
|
||||
priority="$OPTARG"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
[ "${1:-}" = "--" ] && shift
|
||||
|
||||
main "$@"
|
29
bibtex/.local/bin/rofi-bib-due
Executable file
29
bibtex/.local/bin/rofi-bib-due
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
exist rofi normal
|
||||
|
||||
_rofi() {
|
||||
rofi -dmenu -no-auto-select -i -theme themes/dropdown -p "papers" -l 25 -yoffset 20 -columns 1 -u "$urgent"
|
||||
}
|
||||
|
||||
# call for whatever file is passed in
|
||||
results="$(bib-due "$@")"
|
||||
|
||||
# mark priority 1 items as urgent in rofi
|
||||
urgent="$(
|
||||
# find all lines with priority 1, (marked as `(1):` );
|
||||
# print them on 1 line, -1 since dmenu is 0 indexed
|
||||
echo "$results" | grep -n '(1):' | cut -d: -f1 | awk '{ $0=$0-1; print $0 }' ORS=','
|
||||
)"
|
||||
|
||||
# get user choice, exit if nothing selected
|
||||
choice=$(echo "$results" | _rofi)
|
||||
[ -z "$choice" ] && exit 0
|
||||
|
||||
key=$(echo "$choice" | sed -E 's/.*\((\w+)\)$/\1/')
|
||||
|
||||
# get library pdf folder (only searches for default ./pdf path)
|
||||
library="$(dirname "$(realpath "$BIBFILE")")/pdf"
|
||||
|
||||
# find and open the key-associated pdf file
|
||||
${FILEREADER:-xdg-open} "$(find "$library" -type f -name "$key *.pdf")"
|
59
bibtex/README.md
Normal file
59
bibtex/README.md
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Bibtex module
|
||||
|
||||
[bibtex](https://en.wikipedia.org/wiki/BibTeX) - plain-text reference management
|
||||
|
||||
## bib-due
|
||||
|
||||
The `bib-due` script depends on (gnu) grep, awk, and sed, date if using date filtering capabilities. It is currently written in a rather haphazard way, and prone to breakage.
|
||||
On the other hand, it does what it's supposed to do: list bibtex entries which have their due-date coming up.
|
||||
|
||||
The script needs bibtex entries to be marked with two fields: `due`, containing a due date (ideally in YYYY-MM-DD format, for easy sorting), and `priority` containing a read priority. It will also, by default attempt to grab the values of the fields `author` and `title`, as well as the name of the bibtex key of the entry.
|
||||
|
||||
It can be invoked with the path to a bibtex file `bib-due path/to/library.bib`, and will gather the entries from the respective file. It can be invoked without an argument if the environment variable `$BIBFILE` is declared (pointing to a bibtex file).
|
||||
|
||||
Example output looks as follows:
|
||||
|
||||
![bib-due example output](.assets/bibtex/list.png)
|
||||
|
||||
The output can then be filtered further through other programs.
|
||||
|
||||
Bib-due itself allows 2 filtering options: *until* a certain date (`-u`), and *at least* a certain priority (`-p`).
|
||||
|
||||
Using priority is relatively self-explanatory: 1 is the highest priority, 3 the lowest (technically, no priority is the lowest). Choosing `-p3` means priority 1, 2, and 3 will be displayed. Choosing `-p1` will only display the highest priority items.
|
||||
|
||||
Using the date works as a cut-off for the future, and it uses gnu `date` to calculate the correct date. That makes things like `-u 'fri this week'` possible, showing only upcoming items until the end of the week. Read the `date` manual for more information.
|
||||
There will likely not be a new option for filtering dates *from* a certain point forward since I don't need it and before implementing more stuff what's there should be more solid. (and read your damn overdue texts!)
|
||||
|
||||
Again, this script will (for now[^time]) break when bibtex files are formatted in any way other than what it expects.
|
||||
An example of a working entry:
|
||||
|
||||
[^time]: And probably for some time since I don't see myself sinking too much more time into this in the near future. I actually need to get some of the upcoming readings done that I can now list! 🙂
|
||||
|
||||
```
|
||||
@InBook{Borhi2016,
|
||||
author = {László Borhi},
|
||||
chapter = {1956: Self-Liberation},
|
||||
pages = {117--137},
|
||||
publisher = {Indiana University Press},
|
||||
title = {Dealing with dictators: the {United States}, {Hungary}, and {East Central Europe}, 1942-1989},
|
||||
year = {2016},
|
||||
due = {2020-05-07},
|
||||
file = {:Borhi2016 - Dealing with Dictators_ the United States, Hungary, and East Central Europe, 1942 1989.pdf:PDF},
|
||||
pagetotal = {564},
|
||||
priority = {prio1},
|
||||
timestamp = {2020-05-08},
|
||||
}
|
||||
```
|
||||
|
||||
Important fields are author, title, due, priority. These need to exist, and need to be ordered alphabetically. Otherwise there will probably be some breakage.
|
||||
|
||||
## rofi-bib-due
|
||||
|
||||
The `rofi-bib-due` script utilizes the `bib-due` script and depends on an existing installed `rofi` module (see [here](rofi/)).
|
||||
On invocation, it creates a list of upcoming readings, and allows selecting one of the readings. The selected reading will be passed along to `$FILEREADER` if it is declared, falling back to `xdg-open` if not.
|
||||
|
||||
Currently, the path to the reading pdf is hard-coded to be `path/to/bibtex.bib/pdf`, and the name has to begin with the exact bibtex key; otherwise the script will not be able to find the pdf.
|
||||
|
||||
An example of the script in action: (window size has been reduced for the recording, cutting off most entry names)
|
||||
|
||||
![rofi-bib-due demonstration](.assets/bibtex/rofi.gif)
|
|
@ -9,7 +9,6 @@
|
|||
#
|
||||
# to customize this to your own needs, change the `push folder` to the
|
||||
# location of your dotfiles (stow) repository
|
||||
|
||||
alias dotlink="pushd ~/.dotfiles;\
|
||||
dotter deploy;\
|
||||
popd"
|
||||
stow -R */ 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2) ;\
|
||||
popd"
|
7
bootstrap/.stow-local-ignore
Normal file
7
bootstrap/.stow-local-ignore
Normal file
|
@ -0,0 +1,7 @@
|
|||
# TODO find a more generic way to express 'ignore any non-folder files'
|
||||
|
||||
^/install_packages.sh
|
||||
^/update_package_list.sh
|
||||
^/packages.*.tsv
|
||||
^/README.md
|
||||
^/system-packages
|
|
@ -1,22 +0,0 @@
|
|||
FROM archlinux:latest
|
||||
|
||||
# First build then run this dockerfile with:
|
||||
# `podman build -t bootstrap .`
|
||||
# `podman run -it -v /path/to/my/dotfiles:/path/to/my/dotfiles:ro bootstrap`
|
||||
|
||||
RUN pacman-key --init
|
||||
RUN pacman -Syu --noconfirm git vi base-devel sudo zsh man man-pages
|
||||
|
||||
RUN useradd -m -G wheel -s /usr/bin/zsh marty
|
||||
RUN echo "%wheel ALL=(ALL:ALL) ALL" >> /etc/sudoers
|
||||
RUN echo "marty:password" | chpasswd
|
||||
|
||||
# RUN su marty
|
||||
# RUN cd /home/marty
|
||||
# RUN git clone "https://git.martyoeh.me/Marty/dotfiles" .dotfiles
|
||||
# link it directly from dotfile development dir to experiment
|
||||
|
||||
USER marty
|
||||
VOLUME /home/marty/.dotfiles
|
||||
WORKDIR /home/marty/.dotfiles
|
||||
CMD ["/usr/bin/bash"]
|
|
@ -7,10 +7,7 @@
|
|||
# DESCRIPTION: Display usage information for this script.
|
||||
# PARAMETERS: see usage function
|
||||
#==============================================================================
|
||||
PKG_TSV_FILE=${PKG_TSV_FILE:-bootstrap/packages_stable.tsv}
|
||||
packages_repo="${BOOTSTRAP_PACKAGES:-$(grep -e ' R ' "$PKG_TSV_FILE" | cut -f1 -d' ')}"
|
||||
packages_aur="${BOOTSTRAP_PACKAGES_AUR:-$(grep -e ' A ' "$PKG_TSV_FILE" | cut -f1 -d' ')}"
|
||||
packages_pipx="${BOOTSTRAP_PACKAGES_PIPX:-$(grep -e ' P ' "$PKG_TSV_FILE" | cut -f1,5 -d' ')}"
|
||||
packages="${BOOTSTRAP_PACKAGES:-packages.txt}"
|
||||
|
||||
main() {
|
||||
local cmd=""
|
||||
|
@ -37,80 +34,59 @@ main() {
|
|||
exit $ret
|
||||
}
|
||||
|
||||
install_paru() {
|
||||
# check for existing paru installation
|
||||
if type paru >/dev/null 2>&1; then
|
||||
echo "Existing paru installation found ..........................................."
|
||||
install_yay() {
|
||||
# check for existing yay installation
|
||||
if type yay >/dev/null 2>&1; then
|
||||
echo "Existing yay installation found ..........................................."
|
||||
return
|
||||
fi
|
||||
|
||||
# use tmp dir to make paru
|
||||
tempdir=".paru"
|
||||
git clone https://aur.archlinux.org/paru.git "$tempdir"
|
||||
pushd "$tempdir" || exit 1
|
||||
# use tmp dir to make yay
|
||||
target=$(mktemp -d)
|
||||
git clone https://aur.archlinux.org/yay.git "$target"
|
||||
cd "$target" || exit
|
||||
makepkg -si
|
||||
popd || exit 1
|
||||
rm -rf "$tempdir"
|
||||
}
|
||||
|
||||
update_repos() {
|
||||
unattended="$1"
|
||||
if "$unattended"; then
|
||||
paru -Sqyy --noconfirm
|
||||
yay -Sqyy --noconfirm
|
||||
else
|
||||
paru -Syy
|
||||
yay -Syy
|
||||
fi
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
unattended="$1"
|
||||
if "$unattended"; then
|
||||
echo "$packages_repo" "$packages_aur" | paru -Squ --noconfirm --needed -
|
||||
yay -Squ --noconfirm --needed - <"$packages"
|
||||
else
|
||||
echo "$packages_repo" | paru -Squ --needed -
|
||||
echo "$packages_aur" | paru -S --needed -
|
||||
yay -Su --needed - <"$packages"
|
||||
fi
|
||||
}
|
||||
|
||||
install_pipx() {
|
||||
if type pipx >/dev/null 2>&1; then
|
||||
echo "Existing pipx installation found .........................................."
|
||||
return
|
||||
check_consent() {
|
||||
echo "This will take a while and install many packages. Proceed [y/N]?"
|
||||
read -r yes
|
||||
if [[ "$yes" != y* ]]; then
|
||||
echo "Exiting."
|
||||
exit
|
||||
fi
|
||||
if "$unattended"; then
|
||||
paru -S --noconfirm python-pipx
|
||||
else
|
||||
paru -S python-pipx
|
||||
fi
|
||||
}
|
||||
|
||||
install_pipx_pkgs() {
|
||||
while IFS= read -r line; do
|
||||
if [ -z "$line" ]; then return; fi
|
||||
prog=$(echo "$line" | cut -f1 -d' ')
|
||||
pipx install "$prog"
|
||||
|
||||
injections=$(echo "$line" | cut -f2 -d' ')
|
||||
for inject_args in ${injections//,/ }; do
|
||||
pipx inject "$prog" "$inject_args"
|
||||
done
|
||||
done <<<"$packages_pipx"
|
||||
}
|
||||
|
||||
install() {
|
||||
unattended=$1
|
||||
echo "Beginning package bootstrap ..............................................."
|
||||
echo "Installing paru ............................................................"
|
||||
install_paru
|
||||
if ! "$unattended"; then
|
||||
check_consent
|
||||
fi
|
||||
echo "Installing yay ............................................................"
|
||||
install_yay
|
||||
echo "Installing apps ..........................................................."
|
||||
update_repos "$unattended"
|
||||
install_packages "$unattended"
|
||||
echo "Done ......................................................................"
|
||||
echo "Installing pipx ..........................................................."
|
||||
install_pipx
|
||||
echo "Installing pipx packages .................................................."
|
||||
install_pipx_pkgs
|
||||
echo "Done ......................................................................"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
Name Description Source Target Injections
|
||||
Name Description Source Target
|
||||
aaxtomp3 Convert Audible's .aax filetype to MP3, FLAC, M4A, or OPUS A
|
||||
abduco Tool for session {at,de}tach support which allows a process to run independently from its controlling terminal R
|
||||
acpid A daemon for delivering ACPI power management events with netlink support R
|
||||
afew Initial tagging script for notmuch mail R
|
||||
alias-tips-git An oh-my-zsh plugin to help remembering those aliases you defined once A
|
||||
alsa-utils Advanced Linux Sound Architecture - Utilities R
|
||||
anki-bin Helps you remember facts (like words/phrases in a foreign language) efficiently. Installed with wheel. A
|
||||
anki Helps you remember facts (like words/phrases in a foreign language) efficiently A
|
||||
ansible Official assortment of Ansible collections R
|
||||
ansible-lint Checks playbooks for practices and behaviour that could potentially be improved. R
|
||||
arch-wiki-lite Arch Wiki without HTML. 1/9 as big, easily searched & viewable on console R
|
||||
arch-wiki-lite The wiki without html. 1/9 as big, easily searched and viewable on console. R
|
||||
arduino Arduino prototyping platform SDK R
|
||||
arduino-avr-core Arduino AVR core with upstream avr-gcc and avrdude R
|
||||
arduino-cli Arduino command line interface R
|
||||
|
@ -17,84 +16,76 @@ asix-ax88179-dkms A kernel module for ASIX AX88178A AX88179 USB 3.0 network adap
|
|||
aspell-de German dictionary for aspell R
|
||||
aspell-en English dictionary for aspell R
|
||||
atool A script for managing file archives of various types R
|
||||
atuin Magical shell history R
|
||||
aubio A tool for extracting annotations from audio signals R
|
||||
auto-cpufreq Automatic CPU speed & power optimizer A
|
||||
autofs A kernel-based automounter for Linux A
|
||||
awesome Highly configurable framework window manager R
|
||||
barrier Open-source KVM software based on Synergy (GUI) R
|
||||
base Minimal package set to define a basic Arch Linux installation R
|
||||
base-devel Basic tools to build Arch Linux packages R
|
||||
bash-bats Bash Automated Testing System R
|
||||
bash-completion Programmable completion for the bash shell R
|
||||
bash-language-server Bash language server implementation based on Tree Sitter and its grammar for Bash R
|
||||
bat Cat clone with syntax highlighting and git integration R
|
||||
bats Bash Automated Testing System R
|
||||
bc An arbitrary precision calculator language R
|
||||
beancount A personal double entry accounting and budgeting software P git+https://github.com/bratekarate/beancount-categorizer.git,beancount-dkb,fava,python-magic,smart-importer
|
||||
bearssl Implementation of the SSL/TLS protocol (RFC 5246) written in C R
|
||||
beets Organize your music collection from the command line P beetcamp,deets-describe,beets-ydl,pyacoustid,pylast
|
||||
bemenu-dmenu Symlink for using bemenu (native wayland support) as a drop-in replacement to dmenu A
|
||||
bemoji Emoji picker that remembers your favorites A
|
||||
bemoji-git Emoji picker that remembers your favorites. A
|
||||
bibclean BibTeX and Scribe bibliography prettyprinter and syntax checker A
|
||||
biber A Unicode-capable BibTeX replacement for biblatex users R
|
||||
bibtool A tool for manipulating BibTeX files R
|
||||
bind A complete, highly portable implementation of the DNS protocol R
|
||||
bluetuith-bin A TUI based bluetooth manager A
|
||||
bluez-utils Development and debugging utilities for the bluetooth protocol stack R
|
||||
booster Fast and secure initramfs generator R
|
||||
brightnessctl Lightweight brightness control tool R
|
||||
btop A monitor of system resources, bpytop ported to C++ R
|
||||
caddy Fast web server with automatic HTTPS R
|
||||
calcurse A text-based personal organizer R
|
||||
catdoc A convertor for Microsoft Word, Excel, PowerPoint and RTF Files to text R
|
||||
chafa Image-to-text converter supporting a wide range of symbols and palettes, transparency, animations, etc. R
|
||||
cinny-desktop-bin Matrix client focusing primarily on a simple, elegant and secure interface (binary release) A
|
||||
clipman A simple clipboard manager for Wayland A
|
||||
cups-pdf PDF printer for cups R
|
||||
cups-pk-helper A helper that makes system-config-printer use PolicyKit R
|
||||
dbus-broker Linux D-Bus Message Broker R
|
||||
dcnnt Yet another tool to connect Android phone with desktop similar to KDE Connect A
|
||||
dconf-editor GSettings editor for GNOME R
|
||||
dell-command-configure Configure various BIOS features on Dell laptops A
|
||||
devour Window Manager agnostic swallowing feature for terminal emulators A
|
||||
dhcpcd RFC2131 compliant DHCP client daemon R
|
||||
distrobox Use any linux distribution inside your terminal. A
|
||||
dnsmasq Lightweight, easy to configure DNS forwarder and DHCP server R
|
||||
diff-so-fancy Good-looking diffs with diff-highlight and more R
|
||||
docker Pack, ship and run any application as a lightweight container R
|
||||
docker-compose Fast, isolated development environments using Docker R
|
||||
docx2txt Recovers text from DOCX files, with good formatting. R
|
||||
dos2unix Text file format converter R
|
||||
dotter-rs-bin A dotfile manager and templater written in Rust A
|
||||
duf Disk Usage/Free Utility R
|
||||
dunst Customizable and lightweight notification-daemon R
|
||||
dust A more intuitive version of du in rust R
|
||||
efm-langserver General purpose Language Server A
|
||||
element-desktop Glossy Matrix collaboration client — desktop version. R
|
||||
enca Charset analyser and converter R
|
||||
entr Run arbitrary commands when files change R
|
||||
euporie View and work with ipnb Python notebooks from the cli P
|
||||
evince Document viewer (PDF, PostScript, XPS, djvu, dvi, tiff, cbr, cbz, cb7, cbt) R
|
||||
exa ls replacement R
|
||||
exercism-bin Command line client for exercism.io A
|
||||
exfat-utils Utilities for exFAT file system R
|
||||
eza A modern replacement for ls (community fork of exa) R
|
||||
f3 Simple tool that tests flash cards capacity and performance to see if they live up to claimed specifications A
|
||||
fasd Command-line productivity booster, offers quick access to files and directories R
|
||||
fd Simple, fast and user-friendly alternative to find R
|
||||
ffmpegthumbnailer Lightweight video thumbnailer that can be used by file managers R
|
||||
firefox Standalone web browser from mozilla.org R
|
||||
flavours A simple and easy cli to build and use base16 schemes A
|
||||
fonts-cjk Linux 下的免费商用字体包 A
|
||||
freerdp Free implementation of the Remote Desktop Protocol (RDP) R
|
||||
fvextra Extensions to fancyvrb, including automatic line breaking and improved math mode R
|
||||
fwupd Simple daemon to allow session software to update firmware R
|
||||
fzf-tab-bin-git Replace zsh's default completion selection menu with fzf (git version). This package also compiles the optional binary module. A
|
||||
fzf-tab-git Replace zsh's default completion selection menu with fzf. R
|
||||
gallery-dl Command-line program to download image-galleries and collections from several image hosting sites A
|
||||
gamemode A daemon/lib combo that allows games to request a set of optimisations be temporarily applied to the host OS R
|
||||
gimp GNU Image Manipulation Program R
|
||||
git-delta Syntax-highlighting pager for git and diff output R
|
||||
git-lfs Git extension for versioning large files R
|
||||
gitlint Git commit message linter A
|
||||
gitui Blazing fast terminal-ui for git written in Rust R
|
||||
gk6x-bin Configure keys, macros, and lighting on GK6X keyboards (GK64, GK84, GK61, etc) A
|
||||
glances CLI curses-based monitoring tool R
|
||||
glfw-wayland A free, open source, portable framework for graphical application development (wayland) R
|
||||
glow Command-line markdown renderer R
|
||||
glow Markdown renderer for the CLI R
|
||||
gnome-keyring Stores passwords and encryption keys R
|
||||
gnu-netcat GNU rewrite of netcat, the network piping application R
|
||||
gnumeric A GNOME Spreadsheet Program R
|
||||
gnuplot Plotting package which outputs to X11, PostScript, PNG, GIF, and others R
|
||||
go Core compiler tools for the Go programming language R
|
||||
go-md2man A markdown to manpage generator R
|
||||
gomuks A terminal based Matrix client written in Go A
|
||||
gopls Language server for Go programming language R
|
||||
|
@ -102,6 +93,7 @@ gotty-bin Simple command line tool that turns your CLI tools into web applicatio
|
|||
grim Screenshot utility for Wayland R
|
||||
grub GNU GRand Unified Bootloader (2) R
|
||||
gsimplecal Simple and lightweight GTK calendar R
|
||||
gst-libav Multimedia graph framework - libav plugin R
|
||||
gst-plugins-bad Multimedia graph framework - bad plugins R
|
||||
gstreamer-vaapi Multimedia graph framework - vaapi plugin R
|
||||
gucharmap Gnome Unicode Charmap R
|
||||
|
@ -111,33 +103,26 @@ htop Interactive process viewer R
|
|||
hugo Fast and Flexible Static Site Generator in Go R
|
||||
iftop Display bandwidth usage on an interface R
|
||||
imapfilter A mail filtering utility for processing IMAP mailboxes A
|
||||
imv Image viewer for Wayland and X11 R
|
||||
intel-ucode Microcode update files for Intel CPUs R
|
||||
iputils Network monitoring tools, including ping R
|
||||
ipython An enhanced Interactive Python shell. R
|
||||
isbntools A variety of tools to work with isbn addresses P
|
||||
iucode-tool Tool to manipulate Intel® IA-32/X86-64 microcode bundles R
|
||||
iwd Internet Wireless Daemon R
|
||||
jc Converts the output of popular command-line tools and file-types to JSON R
|
||||
jabref-latest GUI frontend for BibTeX, written in Java; latest main (master) version from git A
|
||||
jiq-bin Interactive JSON query tool using jq expressions A
|
||||
jmtpfs FUSE and libmtp based filesystem for accessing MTP (Media Transfer Protocol) devices A
|
||||
jpdftweak A Swiss Army Knife GUI application for PDF documents A
|
||||
jrnl Collect your thoughts and notes without leaving the command line R
|
||||
jupyter-nbclient A tool for running Jupyter Notebooks in different execution contexts. R
|
||||
kanshi Dynamic output configuration for Wayland WMs R
|
||||
keyd A key remapping daemon for linux R
|
||||
khal CLI calendar application built around CalDAV R
|
||||
khard Console address book manager R
|
||||
keyd A key remapping daemon for linux. A
|
||||
khal CLI calendar application build around CalDAV R
|
||||
khard Console CardDAV client R
|
||||
kitty A modern, hackable, featureful, OpenGL-based terminal emulator R
|
||||
kubo IPFS implementation in Go R
|
||||
lazygit Simple terminal UI for git commands R
|
||||
lib32-gamemode A daemon/lib combo that allows games to request a set of optimisations be temporarily applied to the host OS R
|
||||
libdvdcss Portable abstraction library for DVD decryption R
|
||||
libfido2 Library functionality for FIDO 2.0, including communication with a device over USB R
|
||||
libqalculate Multi-purpose desktop calculator R
|
||||
libreoffice-fresh LibreOffice branch which contains new features and program enhancements R
|
||||
libva-intel-driver VA-API implementation for Intel G45 and HD Graphics family R
|
||||
libvirt API for controlling virtualization engines (openvz,kvm,qemu,virtualbox,xen,etc) R
|
||||
linux The Linux kernel and modules R
|
||||
licenses A set of common license files R
|
||||
linux-firmware Firmware files for Linux R
|
||||
linux-headers Headers and scripts for building modules for the Linux kernel R
|
||||
linux-lts The LTS Linux kernel and modules R
|
||||
|
@ -150,15 +135,12 @@ lua-language-server Lua Language Server coded by Lua R
|
|||
lua51 Powerful lightweight programming language designed for extending applications R
|
||||
luacheck A tool for linting and static analysis of Lua code R
|
||||
lutris Open Gaming Platform R
|
||||
ly TUI display manager R
|
||||
ly TUI display manager A
|
||||
lynx A text browser for the World Wide Web R
|
||||
magic-wormhole Securely transfer data between computers R
|
||||
maestral Open-source Dropbox client A
|
||||
maim Utility to take a screenshot using imlib2 R
|
||||
mako Lightweight notification daemon for Wayland R
|
||||
man-db A utility for reading man pages R
|
||||
man-pages Linux man pages R
|
||||
markdown-anki-decks Construct and modify anki decks directly with markdown P
|
||||
markdownlint-cli MarkdownLint Command Line Interface A
|
||||
masterpdfeditor-free A complete solution for creation and editing PDF files - Free version without watermark A
|
||||
mbsync-git free (GPL) mailbox synchronization program A
|
||||
mediainfo Supplies technical and tag information about a video or audio file (CLI interface) R
|
||||
|
@ -166,87 +148,72 @@ mermaid-cli Generation of diagram and flowchart from text in a similar manner as
|
|||
mimeo Open files by MIME-type or file name using regular expressions. A
|
||||
minidlna A DLNA/UPnP-AV Media server (aka ReadyDLNA) R
|
||||
minio-client Replacement for ls, cp, mkdir, diff and rsync commands for filesystems and object storage R
|
||||
mopidy-bandcamp Mopidy backend for Bandcamp A
|
||||
mopidy-iris A Mopidy Web client that utilizes the Spotify and EchoNest frameworks. (Formerly Spotmop) A
|
||||
mopidy-local Mopidy extension for local media playback A
|
||||
mopidy-mpd Mopidy extension for controlling playback from MPD clients A
|
||||
mopidy-mpris Mopidy extension for controlling Mopidy through the MPRIS D-Bus interface A
|
||||
mopidy-scrobbler Mopidy extension for scrobbling played tracks to Last.fm A
|
||||
mopidy-somafm Mopidy extension for playing music from SomaFM A
|
||||
mopidy-youtube Mopidy extension for playing music from Youtube A
|
||||
mopidy-spotify Mopidy extension for playing music from Spotify A
|
||||
moreutils A growing collection of the unix tools that nobody thought to write thirty years ago R
|
||||
mosh Mobile shell, surviving disconnects with local echo and line editing R
|
||||
mpv-mpris MPRIS plugin for mpv R
|
||||
msmtp A mini smtp client R
|
||||
mupdf-gl Lightweight PDF and XPS viewer with OpenGL backend R
|
||||
mutt-ics Show calendar event details in mutt A
|
||||
nano Pico editor clone with enhancements R
|
||||
ncmpcpp Almost exact clone of ncmpc with some new features R
|
||||
needrestart Restart daemons after library updates. A
|
||||
neomutt A version of mutt with added features R
|
||||
neovim Fork of Vim aiming to improve user experience, plugins, and GUIs R
|
||||
net-tools Configuration tools for Linux networking R
|
||||
netbird-bin WireGuard-based mesh network A
|
||||
netctl Profile based systemd network management R
|
||||
nethogs A net top tool which displays traffic used per process instead of per IP or interface R
|
||||
network-manager-applet Applet for managing network connections R
|
||||
networkmanager-openconnect NetworkManager VPN plugin for OpenConnect R
|
||||
newsboat RSS/Atom feed reader for text terminals R
|
||||
newsboat An RSS/Atom feed reader for text terminals R
|
||||
nextcloud-client Nextcloud desktop client R
|
||||
nfs-utils Support programs for Network File Systems R
|
||||
nmap Utility for network discovery and security auditing R
|
||||
nodejs-markdownlint-cli MarkdownLint Command Line Interface A
|
||||
nodejs-pandiff Prose diffs for any document format supported by Pandoc A
|
||||
noto-fonts-emoji Google Noto emoji fonts R
|
||||
npm A package manager for javascript R
|
||||
nss-mdns glibc plugin providing host name resolution via mDNS R
|
||||
nsxiv Neo (or New or Not) Simple (or Small or Suckless) X Image Viewer A
|
||||
ntfs-3g NTFS filesystem driver and utilities R
|
||||
ntp Network Time Protocol reference implementation R
|
||||
nushell A new type of shell R
|
||||
nvm Node Version Manager - Simple bash script to manage multiple active node.js versions R
|
||||
nzbget Download from Usenet using .nzb files R
|
||||
offpunk Fork of the command-line Gemini client AV-98 with added offline capabilities A
|
||||
oh-my-zsh-git A community-driven framework for managing your zsh configuration. Includes 180+ optional plugins and over 120 themes to spice up your morning, and an auto-update tool so that makes it easy to keep up with the latest updates from the community A
|
||||
offpunk-git Fork of the command-line Gemini client AV-98 with added offline capabilities A
|
||||
oh-my-zsh-git A community-driven framework for managing your zsh configuration. Includes 180+ optional plugins and over 120 themes to spice up your morning, and an auto-update tool so that makes it easy to keep up with the latest updates from the community R
|
||||
os-prober Utility to detect other OSes on a set of drives R
|
||||
pacman-contrib Contributed scripts and tools for pacman systems R
|
||||
papis Papis is a powerful and highly extensible command-line based document and bibliography manager. P whoosh,papis-zotero,papis-scihub,git+https://git.martyoeh.me/Marty/papis-extract.git,git+https://github.com/supersambo/papis-tui,pybtex-apa-style,git+https://git.martyoeh.me/Marty/papis-bbt-formatter.git
|
||||
otf-nerd-fonts-fira-code Monospaced font with programming ligatures. Patched with Nerd Fonts icons. A
|
||||
parallel A shell tool for executing jobs in parallel R
|
||||
parsec-bin Remotely connect to a gaming pc for a low latency remote computing experience A
|
||||
paru-bin Feature packed AUR helper A
|
||||
pass-coffin A password store extension that hides data inside a signed and encrypted coffin A
|
||||
pass-ssh A pass extension that creates ssh keys with an automatically generated passphrases stored in pass and outputs the public key using fzf or rofi A
|
||||
pavucontrol PulseAudio Volume Control R
|
||||
pbzip2 Parallel implementation of the bzip2 block-sorting file compressor R
|
||||
pdfjs PDF reader in javascript R
|
||||
pdftk Command-line tool for working with PDFs R
|
||||
peek Simple screen recorder with an easy to use interface R
|
||||
perf Linux kernel performance auditing tool R
|
||||
perl-authen-sasl Perl/CPAN Module Authen::SASL : SASL authentication framework R
|
||||
piavpn-bin Private Internet Access client A
|
||||
pigz Parallel implementation of the gzip file compressor R
|
||||
pipewire-alsa Low-latency audio/video router and processor - ALSA configuration R
|
||||
pipewire-roc Low-latency audio/video router and processor - ROC streaming support R
|
||||
playerctl mpris media player controller and lib for spotify, vlc, audacious, bmp, xmms2, and others. R
|
||||
podman Tool and library for running OCI-based containers in pods R
|
||||
powertop A tool to diagnose issues with power consumption and power management R
|
||||
prettier An opinionated code formatter for JS, JSON, CSS, YAML and much more R
|
||||
protonvpn Official ProtonVPN metapackage that installs protonvpn-gui and protonvpn-cli, maintained by the ProtonVPN team. A
|
||||
ptpython Python REPL build on top of prompt_toolkit A
|
||||
pulsemixer CLI and curses mixer for pulseaudio R
|
||||
pup Command line tool for processing HTML A
|
||||
pv A terminal-based tool for monitoring the progress of data through a pipeline. R
|
||||
pyright Type checker for the Python language R
|
||||
python-adblock Brave's adblock library in Python R
|
||||
python-dictcc commandline tool for dict.cc A
|
||||
python-docs Set of HTML documentation for python R
|
||||
python-html2text A HTML to markdown-structured text converter R
|
||||
python-jupytext Jupyter notebooks as Markdown documents, Julia, Python or R scripts A
|
||||
python-openpyxl A Python library to read/write Excel 2007 xlsx/xlsm files R
|
||||
python-pagelabels Python library to manipulate PDF page numbers and labels. A
|
||||
python-pancritic CriticMarkdup parser with optional pandoc backend A
|
||||
python-pdfminer Python PDF Parser R
|
||||
python-pip The PyPA recommended tool for installing Python packages R
|
||||
python-pipx Install and Run Python Applications in Isolated Environments R
|
||||
python-poethepoet A task runner that works well with poetry A
|
||||
python-polars-bin Blazingly fast DataFrames library using Apache Arrow Columnar Format as memory model A
|
||||
python-pybluez Python wrapper for the BlueZ Bluetooth stack R
|
||||
python-pybtex A BibTeX-compatible bibliography processor written in Python R
|
||||
python-pynvim Python client for Neovim R
|
||||
|
@ -256,125 +223,104 @@ python-pyqt6-datavisualization Python bindings for QtDataVisualization R
|
|||
python-pyqt6-networkauth Python bindings for QtNetworkAuth R
|
||||
python-readability-lxml Fast html to text parser (article readability tool) python library R
|
||||
python-slugify A Python slugify application that handles unicode R
|
||||
python-tasklib Python library for interacting with taskwarrior databases R
|
||||
qemu-desktop A QEMU setup for desktop environments R
|
||||
qt5-wayland Provides APIs for Wayland R
|
||||
qt5-xmlpatterns Support for XPath, XQuery, XSLT and XML schema validation R
|
||||
qt6-svg Classes for displaying the contents of SVG files R
|
||||
qt6-wayland Provides APIs for Wayland R
|
||||
qtcurve-gtk2 A configurable set of widget styles for KDE and Gtk R
|
||||
quarto-cli-bin An open-source scientific and technical publishing system built on Pandoc (binary from official repo) A
|
||||
qutebrowser A keyboard-driven, vim-like browser based on Python and Qt R
|
||||
qutebrowser A keyboard-driven, vim-like browser based on PyQt5 R
|
||||
redshift Adjusts the color temperature of your screen according to your surroundings. R
|
||||
refind An EFI boot manager R
|
||||
refind-btrfs Generate rEFInd manual boot stanzas from Btrfs snapshots A
|
||||
reflector A Python 3 module and script to retrieve and filter the latest Pacman mirror list. R
|
||||
remind A sophisticated calendar and alarm program. R
|
||||
remmina remote desktop client written in GTK+ R
|
||||
restic Fast, secure, efficient backup program R
|
||||
ripgrep-all rga: ripgrep, but also search in PDFs, E-Books, Office documents, zip, tar.gz, etc. R
|
||||
river A dynamic tiling wayland compositor R
|
||||
river A dynamic tiling wayland compositor. A
|
||||
rivercarro A slightly modified version of rivertile layout generator for river. A
|
||||
rng-tools Random number generator related utilities R
|
||||
sc-im A spreadsheet program based on SC A
|
||||
scc Sloc, Cloc and Code: a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go A
|
||||
scc-bin Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go A
|
||||
scrcpy Display and control your Android device R
|
||||
screen Full-screen window manager that multiplexes a physical terminal R
|
||||
sd Intuitive find & replace R
|
||||
sfz A simple static file server A
|
||||
shellcheck-bin Shell script analysis tool (binary release, static) A
|
||||
shfmt Format shell programs R
|
||||
sioyek PDF viewer for research papers and technical books. A
|
||||
slurp Select a region in a Wayland compositor R
|
||||
smartmontools Control and monitor S.M.A.R.T. enabled ATA and SCSI Hard Drives R
|
||||
snap-pac Pacman hooks that use snapper to create pre/post btrfs snapshots like openSUSE's YaST R
|
||||
speedtest-cli Command line interface for testing internet bandwidth using speedtest.net R
|
||||
sshfs FUSE client based on the SSH File Transfer Protocol R
|
||||
starship The cross-shell prompt for astronauts R
|
||||
steam Valve's digital software delivery system R
|
||||
sudo Give certain users the ability to run some commands as root R
|
||||
stow Manage installation of multiple softwares in the same directory tree R
|
||||
surfraw Shell Users' Revolutionary Front Rage Against the Web R
|
||||
swaybg Wallpaper tool for Wayland compositors R
|
||||
swayidle Idle management daemon for Wayland R
|
||||
swww A Solution to your Wayland Wallpaper Woes R
|
||||
systemd-sysvcompat sysvinit compat for systemd R
|
||||
task-spooler Queue up tasks from the shell for batch execution A
|
||||
taskopen Script for taking notes and open urls with taskwarrior A
|
||||
tasksh A shell command that wraps Taskwarrior commands A
|
||||
tea A command line tool to interact with Gitea servers R
|
||||
tectonic Modernized, complete, self-contained TeX/LaTeX engine, powered by XeTeX and TeXLive R
|
||||
termdown Countdown timer and stopwatch in your terminal R
|
||||
tex-gyre-fonts Substitute PostScript fonts in OpenType format R
|
||||
texlab A cross-platform implementation of the Language Server Protocol for LaTeX. R
|
||||
tgpt-bin ChatGPT in terminal without needing API keys A
|
||||
thermald The Linux Thermal Daemon program from 01.org R
|
||||
tidy-viewer CLI csv pretty printer that uses column styling A
|
||||
tigervnc Suite of VNC servers and clients. Based on the VNC 4 branch of TightVNC. R
|
||||
timew Timewarrior, A command line time tracking application R
|
||||
tinyxxd Standalone version of the hex dump utility that comes with ViM R
|
||||
timg Terminal Image and Video Viewer A
|
||||
tlp Linux Advanced Power Management R
|
||||
tmux Terminal multiplexer R
|
||||
tmux A terminal multiplexer R
|
||||
toilet free replacement for the FIGlet utility. A
|
||||
topgrade-bin Invoke the upgrade procedure of multiple package managers A
|
||||
tomb Crypto Undertaker, a simple tool to manage encrypted storage R
|
||||
topgrade Invoke the upgrade procedure of multiple package managers R
|
||||
traceroute Tracks the route taken by packets over an IP network R
|
||||
translate-shell A command-line interface and interactive shell for Google Translate R
|
||||
transmission-qt Fast, easy, and free BitTorrent client (Qt GUI) R
|
||||
ttf-brill Brill Typeface by John Hudson for Brill Publishing House A
|
||||
ttf-comic-neue Casual font that fixes the shortcomings of Comic Sans A
|
||||
ttf-comic-neue Comic Neue aspires to be the casual script choice for everyone including the typographically savvy. A
|
||||
ttf-heuristica A serif latin & cyrillic font, derived from the "Adobe Utopia" font by Apanov A
|
||||
ttf-iosevka-nerd Patched font Iosevka from nerd fonts library R
|
||||
ttf-iosevka-nerd Typeface family designed for coding, terminal use and technical documents (Nerd Fonts) R
|
||||
ttf-signika Sans-serif typeface from Google by Anna Giedryś A
|
||||
ttf-victor-mono-nerd Patched font Victor Mono from nerd fonts library R
|
||||
tuir Browse Reddit from your terminal A
|
||||
tut A TUI for Mastodon with vim inspired keys A
|
||||
typescript-language-server Language Server Protocol (LSP) implementation for TypeScript using tsserver R
|
||||
udiskie Removable disk automounter using udisks R
|
||||
ufw Uncomplicated and easy to use CLI tool for managing a netfilter firewall R
|
||||
unclutter A small program for hiding the mouse cursor R
|
||||
unrar The RAR uncompression program R
|
||||
unrtf Command-line program which converts RTF documents to other formats R
|
||||
urlview-xdg-git A curses URL parser for text files. Git version, adds support for QUITONLAUNCH option and XDG Base Directory specification compliance. A
|
||||
usql A universal command-line interface for SQL databases A
|
||||
v4l2loopback-dkms v4l2-loopback device – module sources R
|
||||
vagrant Build and distribute virtualized development environments R
|
||||
vale-bin A customizable, syntax-aware linter for prose A
|
||||
vdirsyncer Synchronize CalDAV and CardDAV. R
|
||||
viddy A modern watch command A
|
||||
vifm A file manager with curses interface, which provides Vi[m]-like environment R
|
||||
vifm-git Ncurses based file manager with vi like keybindings A
|
||||
vim-language-server VimScript language server A
|
||||
vimiv-qt-git An image viewer with vim-like keybindings A
|
||||
virt-manager Desktop user interface for managing virtual machines R
|
||||
virtualbox Powerful x86 virtualization for enterprise as well as home use R
|
||||
virtualbox-guest-iso The official VirtualBox Guest Additions ISO image R
|
||||
visidata Terminal spreadsheet multitool for discovering and arranging data R
|
||||
viu Simple terminal image viewer R
|
||||
wallabag-client Command line client for the self hosted read-it-later app Wallabag A
|
||||
vulkan-intel Intel's Vulkan mesa driver R
|
||||
wavemon Ncurses-based monitoring application for wireless network devices R
|
||||
waybar Highly customizable Wayland bar for Sway and Wlroots based compositors R
|
||||
waylock A simple screenlocker for wayland compositors R
|
||||
wdisplays GUI display configurator for wlroots compositors A
|
||||
wev tool for debugging wayland events, similar to xev A
|
||||
wezterm A GPU-accelerated cross-platform terminal emulator and multiplexer R
|
||||
wf-recorder Screen recorder for wlroots-based compositors such as sway R
|
||||
wget Network utility to retrieve files from the Web R
|
||||
wireguard-tools next generation secure network tunnel - tools for configuration R
|
||||
wireless_tools Tools allowing to manipulate the Wireless Extensions R
|
||||
wl-mirror a simple Wayland output mirror client R
|
||||
wlopm Wayland output power management. A
|
||||
wlsunset Day/night gamma adjustments for Wayland compositors A
|
||||
wlsunset Day/night gamma adjustments for Wayland compositors R
|
||||
wpa_actiond Daemon that connects to wpa_supplicant and handles connect and disconnect events A
|
||||
wtype xdotool type for wayland R
|
||||
xdg-user-dirs Manage user directories like ~/Desktop and ~/Music R
|
||||
xsv A CLI for indexing, slicing, analyzing, splitting and joining CSV files R
|
||||
xxd-standalone Hexdump utility from vim A
|
||||
yaml-language-server YAML Language Server R
|
||||
yarn Fast, reliable, and secure dependency management R
|
||||
yt-dlp A youtube-dl fork with additional features and fixes R
|
||||
youtube-dl A command-line program to download videos from YouTube.com and a few more sites R
|
||||
yt-dlp-git A youtube-dl fork with additional features and fixes (git) A
|
||||
ytfzf A POSIX script to find and watch youtube videos from the terminal R
|
||||
yubikey-manager Python library and command line tool for configuring a YubiKey R
|
||||
zathura-cb Adds comic book support to zathura R
|
||||
zathura-djvu DjVu support for Zathura R
|
||||
zathura-pdf-mupdf PDF support for Zathura (MuPDF backend) (Supports PDF, ePub, and OpenXPS) R
|
||||
zk A command-line tool helping you to maintain a Zettelkasten or personal wiki R
|
||||
zotero-bin Zotero Standalone. Is a free, easy-to-use tool to help you collect, organize, cite, and share your research sources. A
|
||||
zoxide A smarter cd command for your terminal R
|
||||
zq Tooling for super-structured data A
|
||||
zsh-autosuggestions Fish-like autosuggestions for zsh R
|
||||
zsh-fast-syntax-highlighting Optimized and extended zsh-syntax-highlighting A
|
||||
zsh-fast-syntax-highlighting-git Optimized and extended zsh-syntax-highlighting R
|
||||
zsh-pure-prompt Pretty, minimal and fast ZSH prompt A
|
Can't render this file because it has a wrong number of fields in line 32.
|
|
@ -1,16 +0,0 @@
|
|||
Name Description Source Target
|
||||
adbfs-rootless-git fuse filesystem over adb tool for android devices, no device root required A
|
||||
arch-install-scripts Scripts to aid in installing Arch Linux R
|
||||
blueberry Bluetooth configuration tool R
|
||||
dotter-rs-bin A dotfile manager and templater written in Rust A
|
||||
eza A modern replacement for ls (community fork of exa) R
|
||||
feishin-appimage A modern self-hosted music player. A
|
||||
khal CLI calendar application built around CalDAV R
|
||||
m4b-tool-bin A command line utility to merge, split and chapterize audiobook files such as mp3, ogg, flac, m4a or m4b A
|
||||
nodejs-markmap-cli Create markmaps (mindmaps from markdown) from CLI A
|
||||
pv A terminal-based tool for monitoring the progress of data through a pipeline R
|
||||
qpwgraph PipeWire Graph Qt GUI Interface R
|
||||
texlive-latexextra TeX Live - LaTeX additional packages R
|
||||
toilet Free replacement for the FIGlet utility R
|
||||
vifm A file manager with curses interface, which provides Vi[m]-like environment R
|
||||
woeusb-ng Simple tool that enable you to create your own usb stick with Windows installer. A
|
|
|
@ -1,100 +0,0 @@
|
|||
#
|
||||
# /etc/pacman.conf
|
||||
#
|
||||
# See the pacman.conf(5) manpage for option and repository directives
|
||||
|
||||
#
|
||||
# GENERAL OPTIONS
|
||||
#
|
||||
[options]
|
||||
# The following paths are commented out with their default values listed.
|
||||
# If you wish to use different paths, uncomment and update the paths.
|
||||
#RootDir = /
|
||||
#DBPath = /var/lib/pacman/
|
||||
#CacheDir = /var/cache/pacman/pkg/
|
||||
#LogFile = /var/log/pacman.log
|
||||
#GPGDir = /etc/pacman.d/gnupg/
|
||||
#HookDir = /etc/pacman.d/hooks/
|
||||
HoldPkg = pacman glibc
|
||||
#XferCommand = /usr/bin/curl -L -C - -f -o %o %u
|
||||
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
|
||||
#CleanMethod = KeepInstalled
|
||||
Architecture = auto
|
||||
|
||||
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
|
||||
#IgnorePkg =
|
||||
#IgnoreGroup =
|
||||
|
||||
#NoUpgrade =
|
||||
#NoExtract =
|
||||
|
||||
# Misc options
|
||||
UseSyslog
|
||||
Color
|
||||
#NoProgressBar
|
||||
CheckSpace
|
||||
VerbosePkgLists
|
||||
ParallelDownloads = 5
|
||||
|
||||
# By default, pacman accepts packages signed by keys that its local keyring
|
||||
# trusts (see pacman-key and its man page), as well as unsigned packages.
|
||||
SigLevel = Required DatabaseOptional
|
||||
LocalFileSigLevel = Optional
|
||||
#RemoteFileSigLevel = Required
|
||||
|
||||
# NOTE: You must run `pacman-key --init` before first using pacman; the local
|
||||
# keyring can then be populated with the keys of all official Arch Linux
|
||||
# packagers with `pacman-key --populate archlinux`.
|
||||
|
||||
#
|
||||
# REPOSITORIES
|
||||
# - can be defined here or included from another file
|
||||
# - pacman will search repositories in the order defined here
|
||||
# - local/custom mirrors can be added here or in separate files
|
||||
# - repositories listed first will take precedence when packages
|
||||
# have identical names, regardless of version number
|
||||
# - URLs will have $repo replaced by the name of the current repo
|
||||
# - URLs will have $arch replaced by the name of the architecture
|
||||
#
|
||||
# Repository entries are of the format:
|
||||
# [repo-name]
|
||||
# Server = ServerName
|
||||
# Include = IncludePath
|
||||
#
|
||||
# The header [repo-name] is crucial - it must be present and
|
||||
# uncommented to enable the repo.
|
||||
#
|
||||
|
||||
# The testing repositories are disabled by default. To enable, uncomment the
|
||||
# repo name header and Include lines. You can add preferred servers immediately
|
||||
# after the header, and they will be used before the default mirrors.
|
||||
|
||||
#[testing]
|
||||
#Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[core]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[extra]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
#[community-testing]
|
||||
#Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[community]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
# If you want to run 32 bit applications on your x86_64 system,
|
||||
# enable the multilib repositories as required here.
|
||||
|
||||
#[multilib-testing]
|
||||
#Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
[multilib]
|
||||
Include = /etc/pacman.d/mirrorlist
|
||||
|
||||
# An example of a custom package repository. See the pacman manpage for
|
||||
# tips on creating your own repositories.
|
||||
#[custom]
|
||||
#SigLevel = Optional TrustAll
|
||||
#Server = file:///home/custompkgs
|
|
@ -1,3 +0,0 @@
|
|||
[Sleep]
|
||||
HibernateDelaySec=120min
|
||||
SuspendEstimationSec=30min
|
|
@ -1 +0,0 @@
|
|||
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="0000", ATTRS{idProduct}=="3825", ATTR{power/wakeup}="disabled"
|
|
@ -1,18 +1,16 @@
|
|||
#!/usr/bin/env bash
|
||||
BOOTSTRAP_DIR=${BOOTSTRAP_DIR:-$(pwd)/bootstrap}
|
||||
INPUTFILES=$(find "${BOOTSTRAP_DIR}" -type f -name 'packages*.tsv')
|
||||
OUTPUTFILE=${BOOTSTRAP_DIR}/packages_testing.tsv
|
||||
BOOTSTRAP_DIR=~/.dotfiles/bootstrap
|
||||
OUTPUT=${BOOTSTRAP_DIR}/packages.tsv
|
||||
|
||||
pkg_all=$(pacman -Qqett)
|
||||
pkg_all=$(pacman -Qqett | grep -v "$(pacman -Qqg base-devel)")
|
||||
|
||||
pkg_repo=$(pacman -Qqn)
|
||||
pkg_aur=$(pacman -Qqm)
|
||||
|
||||
while getopts "nvhf:" opt; do
|
||||
while getopts "nvh" opt; do
|
||||
case "$opt" in
|
||||
n) DRYRUN=true ;;
|
||||
v) VERBOSE=true ;;
|
||||
f) OUTPUTFILE="$OPTARG" ;;
|
||||
h | *)
|
||||
{
|
||||
printf "\nUpdate the list of installed packages.\n\nWill compare packages committed to the dotfile repository\nand those currently installed (on an Arch system, using pacman).\nUpdates the list of committed packages in repository\nand prints out the differences as a diff.\n\nOptions:\n\n\t-h\tDisplay this help.\n\t-v\tShow verbose information.\n\t-n\tPrint out changes without changing anything (dry-run).\n"
|
||||
|
@ -22,13 +20,6 @@ while getopts "nvhf:" opt; do
|
|||
esac
|
||||
done
|
||||
|
||||
# get all existing written packages
|
||||
if [ -n "$INPUTFILES" ]; then
|
||||
INPUT=$(cat $INPUTFILES | grep -v -e '^Name Description Source Target' | sort)
|
||||
else
|
||||
INPUT=""
|
||||
fi
|
||||
|
||||
print_msg() {
|
||||
# shellcheck disable=2059
|
||||
[ -n "$VERBOSE" ] && printf "$@"
|
||||
|
@ -38,10 +29,10 @@ print_msg() {
|
|||
# packagename, description, source, target
|
||||
# toot a toot manager A D
|
||||
|
||||
if [ -f "${OUTPUTFILE}_TEMP" ]; then
|
||||
rm "${OUTPUTFILE}_TEMP"
|
||||
if [ -f "${OUTPUT}_TEMP" ]; then
|
||||
rm "${OUTPUT}_TEMP"
|
||||
fi
|
||||
touch "${OUTPUTFILE}_TEMP"
|
||||
touch "${OUTPUT}_TEMP"
|
||||
|
||||
# create new package list
|
||||
for pkg in $pkg_all; do
|
||||
|
@ -61,7 +52,9 @@ for pkg in $pkg_all; do
|
|||
desc="${desc#"${desc%%[![:space:]]*}"}"
|
||||
|
||||
target=""
|
||||
found_line=$(echo "$INPUT" | grep -e "^$pkg")
|
||||
if [ -f "$OUTPUT" ]; then
|
||||
found_line=$(grep -e "^$pkg" "$OUTPUT")
|
||||
fi
|
||||
if [ -n "$found_line" ]; then
|
||||
target=$(echo "$found_line" | cut -f4)
|
||||
print_msg "Updating pkg: %s:%s from: %s, for: %s\n" "$pkg" "$desc" "$source" "$target"
|
||||
|
@ -69,29 +62,26 @@ for pkg in $pkg_all; do
|
|||
print_msg "Adding pkg: %s:%s from: %s, for: %s\n" "$pkg" "$desc" "$source" "$target"
|
||||
fi
|
||||
|
||||
printf "%s\t%s\t%s\t%s\n" "$pkg" "$desc" "$source" "$target" >>"${OUTPUTFILE}_TEMP"
|
||||
printf "%s\t%s\t%s\t%s\n" "$pkg" "$desc" "$source" "$target" >>"${OUTPUT}_TEMP"
|
||||
done
|
||||
|
||||
# notify on any removed packages
|
||||
while read -r line; do
|
||||
if ! echo "$line" | cut -f1 | xargs -I _ grep -F -q -x _ <(echo "$pkg_all"); then
|
||||
printf "REMOVED: %s\n" "$line"
|
||||
fi
|
||||
done <<<"<(echo $INPUT | tail +2)"
|
||||
if [ -f "$OUTPUT" ]; then
|
||||
while read -r line; do
|
||||
if ! echo "$line" | cut -f1 | xargs -I _ grep -F -q -x _ <(echo "$pkg_all"); then
|
||||
printf "REMOVED: %s\n" "$line"
|
||||
fi
|
||||
done <<<"$(tail +2 $OUTPUT)"
|
||||
fi
|
||||
|
||||
# show file changes
|
||||
if [ -f "$OUTPUTFILE"_TEMP ]; then
|
||||
changes=$(diff --color=always -y --suppress-common-lines <(echo "$INPUT") <(sort "$OUTPUTFILE"_TEMP | tail -n+2))
|
||||
if [ -f "$OUTPUT" ] && [ -f "$OUTPUT"_TEMP ]; then
|
||||
changes=$(diff --color=always -y --suppress-common-lines "$OUTPUT" "$OUTPUT"_TEMP | tail -n+2)
|
||||
printf "FILE CHANGES:\n=============\n%s" "$changes"
|
||||
fi
|
||||
|
||||
# actually write changes to file
|
||||
# actually write to file
|
||||
if [ -z "$DRYRUN" ]; then
|
||||
|
||||
while IFS= read -r line; do
|
||||
sed -i -e "/^${line//\//\\/}$/d" "$OUTPUTFILE"_TEMP
|
||||
done <<< "$INPUT"
|
||||
|
||||
cat <(printf "Name\tDescription\tSource\tTarget\n") "${OUTPUTFILE}_TEMP" > "$OUTPUTFILE"
|
||||
cat <(printf "Name\tDescription\tSource\tTarget\n") "${OUTPUT}_TEMP" >"$OUTPUT"
|
||||
fi
|
||||
rm "${OUTPUTFILE}_TEMP"
|
||||
rm "${OUTPUT}_TEMP"
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
# Configuration for flavours
|
||||
# https://github.com/Misterio77/flavours
|
||||
#
|
||||
# This file should contain a [[items]] section for each application you want themed
|
||||
# You can also set a shell (outside items) on which to run hooks
|
||||
# Check flavours repository for more information and examples
|
||||
|
||||
|
||||
# Explanation and default values for keys:
|
||||
|
||||
# # Through which shell command hooks will run. The command will be replaced in '{}'
|
||||
shell = "bash -c '{}'"
|
||||
#
|
||||
# [[items]]
|
||||
# # File to inject to, supports tilde and env var expansion. required
|
||||
# file = "~/.config/example"
|
||||
# # Template to use. required
|
||||
# template = "example"
|
||||
#
|
||||
# # Subtemplate to use
|
||||
# subtemplate = "default"
|
||||
# # If not rewriting, on which line (usually a comment) to start replacing
|
||||
# start = "# Start flavours"
|
||||
# # If not rewriting, on which line (usually a comment) to stop replacing
|
||||
# end = "# End flavours"
|
||||
# # Should we rewrite the entire file, instead of using the above delimiters?
|
||||
# rewrite = false
|
||||
# # Command to execute after injecting (goes through shell)
|
||||
# hook = ""
|
||||
# # Whether this hook should be executed when flavours is ran with lightweight flag
|
||||
# light = true
|
||||
|
||||
[[items]]
|
||||
template = "waybar"
|
||||
file = "~/.local/state/waybar/colorscheme.css"
|
||||
rewrite = true
|
||||
light = false
|
||||
hook = "killall -SIGUSR2 waybar"
|
||||
|
||||
[[items]]
|
||||
# Uses custom nvim template to work together with
|
||||
# RRethy base16 neovim plugin
|
||||
template = "nvim"
|
||||
file = "~/.local/state/nvim/colorscheme.lua"
|
||||
rewrite = true
|
||||
|
||||
[[items]]
|
||||
# For newer wezterm versions (missing cursor= field)
|
||||
# make use of my custom wezterm template
|
||||
template = "wezterm"
|
||||
file = "~/.local/state/wezterm/colors.toml"
|
||||
rewrite = true
|
||||
|
||||
[[items]]
|
||||
template = "zathura"
|
||||
file = "~/.local/state/zathura/colors.config"
|
||||
rewrite = true
|
||||
|
||||
[[items]]
|
||||
template = "qutebrowser"
|
||||
subtemplate = "minimal"
|
||||
file = "~/.local/state/qutebrowser/colorscheme.py"
|
||||
rewrite = true
|
||||
hook = "pgrep -x qutebrowser && qutebrowser :config-source"
|
||||
|
||||
# CSS Webpage styling in qutebrowser
|
||||
[[item]]
|
||||
file = "~/.config/qutebrowser/stylesheets/stylesheet.css"
|
||||
template = "styles"
|
||||
subtemplate = "css-variables"
|
||||
rewrite = false
|
||||
start = "/* Start flavours */"
|
||||
end = "/* End flavours */"
|
||||
|
||||
[[items]]
|
||||
# MAKO DOES NOT SUPPORT INCLUDES YET
|
||||
template = "mako"
|
||||
file = "~/.config/mako/config"
|
||||
light = false
|
||||
rewrite = false
|
||||
start = "# Start flavours"
|
||||
end = "# End flavours"
|
||||
hook = "killall mako"
|
||||
|
||||
[[items]]
|
||||
# SIOYEK does not support includes afaik
|
||||
template = "sioyek"
|
||||
file = "~/.config/sioyek/prefs_user.config"
|
||||
rewrite = false
|
||||
start = "# START FLAVOURS"
|
||||
end = "# END FLAVOURS"
|
||||
|
||||
[[items]]
|
||||
# additionally requires style = base16 to be set
|
||||
# in the [GENERAL] section of ~/.config/vimiv/vimiv.conf
|
||||
template = "vimiv"
|
||||
file = "~/.config/vimiv/styles/base16"
|
||||
rewrite = true
|
||||
|
||||
[[items]]
|
||||
template = "fzf"
|
||||
subtemplate = "sh"
|
||||
file = "~/.config/sh/env.d/fzf-base16.sh"
|
||||
rewrite = true
|
||||
hook = "source ~/.config/sh/env.d/fzf-base16.sh"
|
|
@ -1,9 +0,0 @@
|
|||
# Scheme name: {{scheme-name}}
|
||||
# Scheme system: {{scheme-system}}
|
||||
# Scheme author: {{scheme-author}}
|
||||
# Template author: Tinted Theming (https://github.com/tinted-theming)
|
||||
|
||||
export FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS"\
|
||||
" --color=bg+:#{{base01-hex}},bg:#{{base00-hex}},spinner:#{{base0C-hex}},hl:#{{base0D-hex}}"\
|
||||
" --color=fg:#{{base04-hex}},header:#{{base0D-hex}},info:#{{base0A-hex}},pointer:#{{base0C-hex}}"\
|
||||
" --color=marker:#{{base0C-hex}},fg+:#{{base06-hex}},prompt:#{{base0A-hex}},hl+:#{{base0D-hex}}"
|
|
@ -1,42 +0,0 @@
|
|||
-- base16-nvim (https://github.com/wincent/base16-nvim)
|
||||
-- by Greg Hurrell (https://github.com/wincent)
|
||||
-- based on
|
||||
-- base16-vim (https://github.com/chriskempson/base16-vim)
|
||||
-- by Chris Kempson (https://github.com/chriskempson)
|
||||
-- using nvim-base16 neovim plugin
|
||||
-- by RRethy (https://github.com/RRethy/nvim-base16)
|
||||
-- {{scheme-name}} scheme by {{scheme-author}}
|
||||
|
||||
local function exists(plugin)
|
||||
local status, lib = pcall(require, plugin)
|
||||
if(status) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
if exists("mini.base16") then
|
||||
require('mini.base16').setup({
|
||||
palette = {
|
||||
base00 = '#{{base00-hex}}',
|
||||
base01 = '#{{base01-hex}}',
|
||||
base02 = '#{{base02-hex}}',
|
||||
base03 = '#{{base03-hex}}',
|
||||
base04 = '#{{base04-hex}}',
|
||||
base05 = '#{{base05-hex}}',
|
||||
base06 = '#{{base06-hex}}',
|
||||
base07 = '#{{base07-hex}}',
|
||||
base08 = '#{{base08-hex}}',
|
||||
base09 = '#{{base09-hex}}',
|
||||
base0A = '#{{base0A-hex}}',
|
||||
base0B = '#{{base0B-hex}}',
|
||||
base0C = '#{{base0C-hex}}',
|
||||
base0D = '#{{base0D-hex}}',
|
||||
base0E = '#{{base0E-hex}}',
|
||||
base0F = '#{{base0F-hex}}'
|
||||
},
|
||||
})
|
||||
end
|
||||
if exists("lualine") then
|
||||
require("lualine").setup()
|
||||
end
|
||||
|
||||
-- vim: filetype=lua
|
|
@ -1,20 +0,0 @@
|
|||
# base16-sioyek (https://github.com/loiccoyle/base16-sioyek)
|
||||
# by Loic Coyle
|
||||
# {{scheme-name}} scheme by{{scheme-author}}
|
||||
|
||||
custom_background_color #{{base00-hex}}
|
||||
custom_color_mode_empty_background_color #{{base00-hex}}
|
||||
custom_text_color #{{base06-hex}}
|
||||
|
||||
page_separator_color #{{base00-hex}}
|
||||
search_highlight_color #{{base0A-hex}}
|
||||
status_bar_color #{{base00-hex}}
|
||||
status_bar_text_color #{{base06-hex}}
|
||||
ui_text_color #{{base06-hex}}
|
||||
ui_selected_text_color #{{base06-hex}}
|
||||
ui_background_color #{{base01-hex}}
|
||||
ui_selected_background_color #{{base03-hex}}
|
||||
visual_mark_color {{base03-dec-r}} {{base03-dec-g}} {{base03-dec-b}} 0.2
|
||||
text_highlight_color #{{base03-hex}}
|
||||
link_highlight_color #{{base0D-hex}}
|
||||
synctex_highlight_color #{{base08-hex}}
|
|
@ -1,44 +0,0 @@
|
|||
# Base16 {{scheme-name}} - wezterm color config
|
||||
# Scheme by {{scheme-author}}
|
||||
|
||||
[colors]
|
||||
foreground = "#{{base05-hex}}"
|
||||
background = "#{{base00-hex}}"
|
||||
cursor_bg = "#{{base05-hex}}"
|
||||
cursor_border = "#{{base05-hex}}"
|
||||
selection_bg = "#{{base05-hex}}"
|
||||
selection_fg = "#{{base00-hex}}"
|
||||
|
||||
ansi = [
|
||||
"#{{base00-hex}}",
|
||||
"#{{base08-hex}}",
|
||||
"#{{base0B-hex}}",
|
||||
"#{{base0A-hex}}",
|
||||
"#{{base0D-hex}}",
|
||||
"#{{base0E-hex}}",
|
||||
"#{{base0C-hex}}",
|
||||
"#{{base05-hex}}"
|
||||
]
|
||||
|
||||
brights = [
|
||||
"#{{base03-hex}}",
|
||||
"#{{base08-hex}}",
|
||||
"#{{base0B-hex}}",
|
||||
"#{{base0A-hex}}",
|
||||
"#{{base0D-hex}}",
|
||||
"#{{base0E-hex}}",
|
||||
"#{{base0C-hex}}",
|
||||
"#{{base07-hex}}"
|
||||
]
|
||||
|
||||
[colors.tab_bar]
|
||||
background = "#{{base00-hex}}"
|
||||
[colors.tab_bar.inactive_tab]
|
||||
bg_color = "#{{base00-hex}}"
|
||||
fg_color = "#{{base05-hex}}"
|
||||
[colors.tab_bar.active_tab]
|
||||
bg_color = "#{{base05-hex}}"
|
||||
fg_color = "#{{base00-hex}}"
|
||||
[colors.tab_bar.new_tab]
|
||||
bg_color = "#{{base05-hex}}"
|
||||
fg_color = "#{{base00-hex}}"
|
|
@ -1,32 +0,0 @@
|
|||
profile docked {
|
||||
output "LG Electronics W2442 0x000574FD" position 1920,0
|
||||
output "LG Electronics W2442 0x000574E1" position 0,0
|
||||
output eDP-1 disable
|
||||
exec notify-send "💻 Display changed" "Applying docked LG profile"
|
||||
}
|
||||
|
||||
profile docked {
|
||||
output "Goldstar Company Ltd W2442 0x000574FD" position 1920,0
|
||||
output "Goldstar Company Ltd W2442 0x000574E1" position 0,0
|
||||
output eDP-1 disable
|
||||
exec notify-send "💻 Display changed" "Applying docked Goldstar profile"
|
||||
}
|
||||
|
||||
profile dockedall {
|
||||
output "LG Electronics W2442 0x000574FD" position 1920,0
|
||||
output "LG Electronics W2442 0x000574E1" position 0,0
|
||||
output eDP-1 enable position 960,1080
|
||||
exec notify-send "💻 Display changed" "Applying docked 3-screen profile"
|
||||
}
|
||||
|
||||
profile portable {
|
||||
output "LG Electronics W2442 0x000574FD" disable
|
||||
output "LG Electronics W2442 0x000574E1" disable
|
||||
output eDP-1 enable position 0,0
|
||||
exec notify-send "💻 Display changed" "Applying portable profile"
|
||||
}
|
||||
|
||||
profile portable {
|
||||
output eDP-1 enable position 0,0
|
||||
exec notify-send "💻 Display changed" "Applying portable profile"
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
sort=-time
|
||||
layer=overlay
|
||||
width=300
|
||||
height=110
|
||||
border-size=2
|
||||
border-radius=15
|
||||
max-icon-size=64
|
||||
default-timeout=5000
|
||||
ignore-timeout=1
|
||||
font=monospace 14
|
||||
|
||||
# Intentionally left empty, automatically filled by flavours
|
||||
# on switching theme.
|
||||
# Start flavours
|
||||
|
||||
# End flavours
|
||||
|
||||
[urgency=critical]
|
||||
#on-notify=exec mpv /usr/share/sounds/freedesktop/stereo/message.oga
|
||||
default-timeout=0
|
||||
|
||||
[mode=do-not-disturb]
|
||||
invisible=1
|
||||
|
||||
[category=mpd]
|
||||
default-timeout=2000
|
||||
group-by=category
|
|
@ -1,15 +0,0 @@
|
|||
# This file is written by xdg-user-dirs-update
|
||||
# If you want to change or add directories, just edit the line you're
|
||||
# interested in. All local changes will be retained on the next run.
|
||||
# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
|
||||
# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
|
||||
# absolute path. No other format is supported.
|
||||
#
|
||||
XDG_DESKTOP_DIR="$HOME/desktop"
|
||||
XDG_DOCUMENTS_DIR="$HOME/documents"
|
||||
XDG_DOWNLOAD_DIR="$HOME/downloads"
|
||||
XDG_MUSIC_DIR="$HOME/media/audio/music"
|
||||
XDG_PICTURES_DIR="$HOME/pictures"
|
||||
XDG_PUBLICSHARE_DIR="$HOME/"
|
||||
XDG_TEMPLATES_DIR="$HOME/"
|
||||
XDG_VIDEOS_DIR="$HOME/media/videos"
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
picker=dmenu
|
||||
if exist bemenu; then
|
||||
picker=bemenu
|
||||
elif exist wofi; then
|
||||
picker=wofi
|
||||
elif exist rofi; then
|
||||
picker=rofi
|
||||
fi
|
||||
|
||||
list=$(flavours list -l)
|
||||
flavour=$(printf "%s\nrandom\nlight" "$list" | "$picker")
|
||||
if [ -z "$flavour" ]; then
|
||||
return
|
||||
elif [ "$flavour" = "random" ]; then
|
||||
flavours apply '*'
|
||||
elif [ "$flavour" = "light" ]; then
|
||||
flavours apply '*light'
|
||||
else
|
||||
flavours apply "$flavour"
|
||||
fi
|
||||
|
||||
if [ "$1" = '-v' ]; then
|
||||
notify-send "Theme set" "set to: $flavour"
|
||||
fi
|
417
dunst/.config/dunst/dunstrc
Normal file
417
dunst/.config/dunst/dunstrc
Normal file
|
@ -0,0 +1,417 @@
|
|||
[global]
|
||||
### Display ###
|
||||
|
||||
# Which monitor should the notifications be displayed on.
|
||||
monitor = 0
|
||||
|
||||
# Display notification on focused monitor. Possible modes are:
|
||||
# mouse: follow mouse pointer
|
||||
# keyboard: follow window with keyboard focus
|
||||
# none: don't follow anything
|
||||
#
|
||||
# "keyboard" needs a window manager that exports the
|
||||
# _NET_ACTIVE_WINDOW property.
|
||||
# This should be the case for almost all modern window managers.
|
||||
#
|
||||
# If this option is set to mouse or keyboard, the monitor option
|
||||
# will be ignored.
|
||||
follow = mouse
|
||||
|
||||
# The geometry of the window:
|
||||
# [{width}]x{height}[+/-{x}+/-{y}]
|
||||
# The geometry of the message window.
|
||||
# The height is measured in number of notifications everything else
|
||||
# in pixels. If the width is omitted but the height is given
|
||||
# ("-geometry x2"), the message window expands over the whole screen
|
||||
# (dmenu-like). If width is 0, the window expands to the longest
|
||||
# message displayed. A positive x is measured from the left, a
|
||||
# negative from the right side of the screen. Y is measured from
|
||||
# the top and down respectively.
|
||||
# The width can be negative. In this case the actual width is the
|
||||
# screen width minus the width defined in within the geometry option.
|
||||
geometry = "300x5-30+20"
|
||||
|
||||
# Show how many messages are currently hidden (because of geometry).
|
||||
indicate_hidden = yes
|
||||
|
||||
# Shrink window if it's smaller than the width. Will be ignored if
|
||||
# width is 0.
|
||||
shrink = no
|
||||
|
||||
# The transparency of the window. Range: [0; 100].
|
||||
# This option will only work if a compositing window manager is
|
||||
# present (e.g. xcompmgr, compiz, etc.).
|
||||
transparency = 20
|
||||
|
||||
# The height of the entire notification. If the height is smaller
|
||||
# than the font height and padding combined, it will be raised
|
||||
# to the font height and padding.
|
||||
notification_height = 0
|
||||
|
||||
# Draw a line of "separator_height" pixel height between two
|
||||
# notifications.
|
||||
# Set to 0 to disable.
|
||||
separator_height = 2
|
||||
|
||||
# Padding between text and separator.
|
||||
padding = 8
|
||||
|
||||
# Horizontal padding.
|
||||
horizontal_padding = 8
|
||||
|
||||
# Defines width in pixels of frame around the notification window.
|
||||
# Set to 0 to disable.
|
||||
frame_width = 3
|
||||
|
||||
# Defines color of the frame around the notification window.
|
||||
frame_color = "#aaaaaa"
|
||||
|
||||
# Define a color for the separator.
|
||||
# possible values are:
|
||||
# * auto: dunst tries to find a color fitting to the background;
|
||||
# * foreground: use the same color as the foreground;
|
||||
# * frame: use the same color as the frame;
|
||||
# * anything else will be interpreted as a X color.
|
||||
separator_color = auto
|
||||
|
||||
# Sort messages by urgency.
|
||||
sort = yes
|
||||
|
||||
# Don't remove messages, if the user is idle (no mouse or keyboard input)
|
||||
# for longer than idle_threshold seconds.
|
||||
# Set to 0 to disable.
|
||||
# A client can set the 'transient' hint to bypass this. See the rules
|
||||
# section for how to disable this if necessary
|
||||
idle_threshold = 120
|
||||
|
||||
### Text ###
|
||||
|
||||
font = Monospace 10
|
||||
|
||||
# The spacing between lines. If the height is smaller than the
|
||||
# font height, it will get raised to the font height.
|
||||
line_height = 0
|
||||
|
||||
# Possible values are:
|
||||
# full: Allow a small subset of html markup in notifications:
|
||||
# <b>bold</b>
|
||||
# <i>italic</i>
|
||||
# <s>strikethrough</s>
|
||||
# <u>underline</u>
|
||||
#
|
||||
# For a complete reference see
|
||||
# <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
|
||||
#
|
||||
# strip: This setting is provided for compatibility with some broken
|
||||
# clients that send markup even though it's not enabled on the
|
||||
# server. Dunst will try to strip the markup but the parsing is
|
||||
# simplistic so using this option outside of matching rules for
|
||||
# specific applications *IS GREATLY DISCOURAGED*.
|
||||
#
|
||||
# no: Disable markup parsing, incoming notifications will be treated as
|
||||
# plain text. Dunst will not advertise that it has the body-markup
|
||||
# capability if this is set as a global setting.
|
||||
#
|
||||
# It's important to note that markup inside the format option will be parsed
|
||||
# regardless of what this is set to.
|
||||
markup = full
|
||||
|
||||
# The format of the message. Possible variables are:
|
||||
# %a appname
|
||||
# %s summary
|
||||
# %b body
|
||||
# %i iconname (including its path)
|
||||
# %I iconname (without its path)
|
||||
# %p progress value if set ([ 0%] to [100%]) or nothing
|
||||
# %n progress value if set without any extra characters
|
||||
# %% Literal %
|
||||
# Markup is allowed
|
||||
format = "<b>%s</b>\n%b"
|
||||
|
||||
# Alignment of message text.
|
||||
# Possible values are "left", "center" and "right".
|
||||
alignment = left
|
||||
|
||||
# Show age of message if message is older than show_age_threshold
|
||||
# seconds.
|
||||
# Set to -1 to disable.
|
||||
show_age_threshold = 60
|
||||
|
||||
# Split notifications into multiple lines if they don't fit into
|
||||
# geometry.
|
||||
word_wrap = yes
|
||||
|
||||
# When word_wrap is set to no, specify where to make an ellipsis in long lines.
|
||||
# Possible values are "start", "middle" and "end".
|
||||
ellipsize = middle
|
||||
|
||||
# Ignore newlines '\n' in notifications.
|
||||
ignore_newline = no
|
||||
|
||||
# Stack together notifications with the same content
|
||||
stack_duplicates = true
|
||||
|
||||
# Hide the count of stacked notifications with the same content
|
||||
hide_duplicate_count = false
|
||||
|
||||
# Display indicators for URLs (U) and actions (A).
|
||||
show_indicators = yes
|
||||
|
||||
### Icons ###
|
||||
|
||||
# Align icons left/right/off
|
||||
icon_position = left
|
||||
|
||||
# Scale larger icons down to this size, set to 0 to disable
|
||||
max_icon_size = 128
|
||||
|
||||
# Paths to default icons.
|
||||
icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
|
||||
|
||||
### History ###
|
||||
|
||||
# Should a notification popped up from history be sticky or timeout
|
||||
# as if it would normally do.
|
||||
sticky_history = yes
|
||||
|
||||
# Maximum amount of notifications kept in history
|
||||
history_length = 20
|
||||
|
||||
### Misc/Advanced ###
|
||||
|
||||
# dmenu path.
|
||||
dmenu = /usr/bin/dmenu -p dunst:
|
||||
|
||||
# Browser for opening urls in context menu.
|
||||
browser = xdg-open
|
||||
|
||||
# Always run rule-defined scripts, even if the notification is suppressed
|
||||
always_run_script = true
|
||||
|
||||
# Define the title of the windows spawned by dunst
|
||||
title = Dunst
|
||||
|
||||
# Define the class of the windows spawned by dunst
|
||||
class = Dunst
|
||||
|
||||
# Print a notification on startup.
|
||||
# This is mainly for error detection, since dbus (re-)starts dunst
|
||||
# automatically after a crash.
|
||||
startup_notification = false
|
||||
|
||||
# Manage dunst's desire for talking
|
||||
# Can be one of the following values:
|
||||
# crit: Critical features. Dunst aborts
|
||||
# warn: Only non-fatal warnings
|
||||
# mesg: Important Messages
|
||||
# info: all unimportant stuff
|
||||
# debug: all less than unimportant stuff
|
||||
verbosity = mesg
|
||||
|
||||
# Define the corner radius of the notification window
|
||||
# in pixel size. If the radius is 0, you have no rounded
|
||||
# corners.
|
||||
# The radius will be automatically lowered if it exceeds half of the
|
||||
# notification height to avoid clipping text and/or icons.
|
||||
corner_radius = 1
|
||||
|
||||
### Legacy
|
||||
|
||||
# Use the Xinerama extension instead of RandR for multi-monitor support.
|
||||
# This setting is provided for compatibility with older nVidia drivers that
|
||||
# do not support RandR and using it on systems that support RandR is highly
|
||||
# discouraged.
|
||||
#
|
||||
# By enabling this setting dunst will not be able to detect when a monitor
|
||||
# is connected or disconnected which might break follow mode if the screen
|
||||
# layout changes.
|
||||
force_xinerama = false
|
||||
|
||||
### mouse
|
||||
|
||||
# Defines action of mouse event
|
||||
# Possible values are:
|
||||
# * none: Don't do anything.
|
||||
# * do_action: If the notification has exactly one action, or one is marked as default,
|
||||
# invoke it. If there are multiple and no default, open the context menu.
|
||||
# * close_current: Close current notification.
|
||||
# * close_all: Close all notifications.
|
||||
mouse_left_click = close_current
|
||||
mouse_middle_click = close_all
|
||||
mouse_right_click = do_action
|
||||
|
||||
# Experimental features that may or may not work correctly. Do not expect them
|
||||
# to have a consistent behaviour across releases.
|
||||
[experimental]
|
||||
# Calculate the dpi to use on a per-monitor basis.
|
||||
# If this setting is enabled the Xft.dpi value will be ignored and instead
|
||||
# dunst will attempt to calculate an appropriate dpi value for each monitor
|
||||
# using the resolution and physical size. This might be useful in setups
|
||||
# where there are multiple screens with very different dpi values.
|
||||
per_monitor_dpi = false
|
||||
|
||||
[shortcuts]
|
||||
|
||||
# Shortcuts are specified as [modifier+][modifier+]...key
|
||||
# Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
|
||||
# "mod3" and "mod4" (windows-key).
|
||||
# Xev might be helpful to find names for keys.
|
||||
|
||||
# Close notification.
|
||||
close = ctrl+space
|
||||
|
||||
# Close all notifications.
|
||||
close_all = ctrl+shift+space
|
||||
|
||||
# Redisplay last message(s).
|
||||
# On the US keyboard layout "grave" is normally above TAB and left
|
||||
# of "1". Make sure this key actually exists on your keyboard layout,
|
||||
# e.g. check output of 'xmodmap -pke'
|
||||
history = ctrl+grave
|
||||
|
||||
# Context menu.
|
||||
context = ctrl+shift+period
|
||||
|
||||
[urgency_low]
|
||||
# IMPORTANT: colors have to be defined in quotation marks.
|
||||
# Otherwise the "#" and following would be interpreted as a comment.
|
||||
background = "#222222"
|
||||
foreground = "#888888"
|
||||
timeout = 10
|
||||
# Icon for notifications with low urgency, uncomment to enable
|
||||
#icon = /path/to/icon
|
||||
|
||||
[urgency_normal]
|
||||
background = "#285577"
|
||||
foreground = "#ffffff"
|
||||
timeout = 10
|
||||
# Icon for notifications with normal urgency, uncomment to enable
|
||||
#icon = /path/to/icon
|
||||
|
||||
[urgency_critical]
|
||||
background = "#900000"
|
||||
foreground = "#ffffff"
|
||||
frame_color = "#ff0000"
|
||||
timeout = 0
|
||||
# Icon for notifications with critical urgency, uncomment to enable
|
||||
#icon = /path/to/icon
|
||||
|
||||
# Every section that isn't one of the above is interpreted as a rules to
|
||||
# override settings for certain messages.
|
||||
#
|
||||
# Messages can be matched by
|
||||
# appname (discouraged, see desktop_entry)
|
||||
# body
|
||||
# category
|
||||
# desktop_entry
|
||||
# icon
|
||||
# match_transient
|
||||
# msg_urgency
|
||||
# stack_tag
|
||||
# summary
|
||||
#
|
||||
# and you can override the
|
||||
# background
|
||||
# foreground
|
||||
# format
|
||||
# frame_color
|
||||
# fullscreen
|
||||
# new_icon
|
||||
# set_stack_tag
|
||||
# set_transient
|
||||
# timeout
|
||||
# urgency
|
||||
#
|
||||
# Shell-like globbing will get expanded.
|
||||
#
|
||||
# Instead of the appname filter, it's recommended to use the desktop_entry filter.
|
||||
# GLib based applications export their desktop-entry name. In comparison to the appname,
|
||||
# the desktop-entry won't get localized.
|
||||
#
|
||||
# SCRIPTING
|
||||
# You can specify a script that gets run when the rule matches by
|
||||
# setting the "script" option.
|
||||
# The script will be called as follows:
|
||||
# script appname summary body icon urgency
|
||||
# where urgency can be "LOW", "NORMAL" or "CRITICAL".
|
||||
#
|
||||
# NOTE: if you don't want a notification to be displayed, set the format
|
||||
# to "".
|
||||
# NOTE: It might be helpful to run dunst -print in a terminal in order
|
||||
# to find fitting options for rules.
|
||||
|
||||
# Disable the transient hint so that idle_threshold cannot be bypassed from the
|
||||
# client
|
||||
#[transient_disable]
|
||||
# match_transient = yes
|
||||
# set_transient = no
|
||||
#
|
||||
# Make the handling of transient notifications more strict by making them not
|
||||
# be placed in history.
|
||||
#[transient_history_ignore]
|
||||
# match_transient = yes
|
||||
# history_ignore = yes
|
||||
|
||||
# fullscreen values
|
||||
# show: show the notifications, regardless if there is a fullscreen window opened
|
||||
# delay: displays the new notification, if there is no fullscreen window active
|
||||
# If the notification is already drawn, it won't get undrawn.
|
||||
# pushback: same as delay, but when switching into fullscreen, the notification will get
|
||||
# withdrawn from screen again and will get delayed like a new notification
|
||||
#[fullscreen_delay_everything]
|
||||
# fullscreen = delay
|
||||
[fullscreen_show_critical]
|
||||
msg_urgency = critical
|
||||
fullscreen = show
|
||||
[stack-volumes]
|
||||
appname = "pavolume"
|
||||
set_stack_tag = "volume"
|
||||
|
||||
#[espeak]
|
||||
# summary = "*"
|
||||
# script = dunst_espeak.sh
|
||||
|
||||
#[script-test]
|
||||
# summary = "*script*"
|
||||
# script = dunst_test.sh
|
||||
|
||||
#[ignore]
|
||||
# # This notification will not be displayed
|
||||
# summary = "foobar"
|
||||
# format = ""
|
||||
|
||||
#[history-ignore]
|
||||
# # This notification will not be saved in history
|
||||
# summary = "foobar"
|
||||
# history_ignore = yes
|
||||
|
||||
#[skip-display]
|
||||
# # This notification will not be displayed, but will be included in the history
|
||||
# summary = "foobar"
|
||||
# skip_display = yes
|
||||
|
||||
#[signed_on]
|
||||
# appname = Pidgin
|
||||
# summary = "*signed on*"
|
||||
# urgency = low
|
||||
#
|
||||
#[signed_off]
|
||||
# appname = Pidgin
|
||||
# summary = *signed off*
|
||||
# urgency = low
|
||||
#
|
||||
#[says]
|
||||
# appname = Pidgin
|
||||
# summary = *says*
|
||||
# urgency = critical
|
||||
#
|
||||
#[twitter]
|
||||
# appname = Pidgin
|
||||
# summary = *twitter.com*
|
||||
# urgency = normal
|
||||
#
|
||||
#[stack-volumes]
|
||||
# appname = "some_volume_notifiers"
|
||||
# set_stack_tag = "volume"
|
||||
#
|
||||
# vim: ft=cfg
|
|
@ -4,30 +4,16 @@
|
|||
signingkey = 73BA40D5AFAF49C9
|
||||
[init]
|
||||
defaultBranch = main
|
||||
[core]
|
||||
pager = git delta
|
||||
[pager]
|
||||
difftool = true
|
||||
[interactive]
|
||||
diffFilter = git delta --color-only
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
[delta]
|
||||
navigate = true
|
||||
line-numbers = true
|
||||
syntax-theme = base16
|
||||
[sendemail]
|
||||
smtpserver = "/usr/bin/msmtp"
|
||||
annotate = yes
|
||||
smtpserver = "/usr/bin/msmtp"
|
||||
annotate = yes
|
||||
[alias]
|
||||
ignore = "!gitignore -f"
|
||||
pushmerge = "push -o merge_request.merge_when_pipeline_succeeds" # see https://docs.gitlab.com/ce/user/project/push_options.html # merge-when-pipeline-succeeds-alias
|
||||
last = "diff HEAD~ HEAD"
|
||||
pushall = "!git remote | xargs -I R git push R" # push to all connected remotes
|
||||
fetchall = "!git remote | xargs -I R git fetch R" # fetch from all connected remotes
|
||||
diffword = "!git diff --word-diff=color --word-diff-regex='[0-9A-Za-z_]+'" # word-wise diff, good for prose
|
||||
diffsyn = "!git difftool --tool difftastic" # add syntax-driven diff using treesitter
|
||||
diffside = "!DELTA_FEATURES='+side-by-side' git diff" # add side-by-side diffing
|
||||
delta = "![ $TERM_DARK = false ] && delta --light || delta" # Take care that we always display right color scheme
|
||||
pushall = "!git remote | xargs -I R git push R" # push to all connected remotes
|
||||
fetchall = "!git remote | xargs -I R git fetch R" # fetch from all connected remotes
|
||||
|
||||
[commit]
|
||||
gpgsign = true # sign commits as me
|
||||
verbose = true # Always show diff when preparing commit message
|
||||
|
@ -37,18 +23,16 @@
|
|||
rebase = true # always rebase on pulling, obviates merge commits
|
||||
[diff]
|
||||
colorMoved = zebra # also color stuff that has simply been moved, in a classy zebra-color
|
||||
[difftool]
|
||||
prompt = false
|
||||
[difftool "difftastic"]
|
||||
cmd = difft "$LOCAL" "$REMOTE"
|
||||
[color "diff"]
|
||||
[pager]
|
||||
diff = dsf | less --tabs=4 -RFXS --pattern '(^(Date|added|deleted|modified): |^diff --git )'
|
||||
[color.diff]
|
||||
meta = "9"
|
||||
frag = "magenta bold"
|
||||
commit = "yellow bold"
|
||||
old = "red bold"
|
||||
new = "green bold"
|
||||
whitespace = "red reverse"
|
||||
[color "diff-highlight"]
|
||||
[color.diff-highlight]
|
||||
oldNormal = "red bold"
|
||||
oldHighlight = "red bold 52"
|
||||
newNormal = "green bold"
|
|
@ -9,13 +9,12 @@ git_version=$(git --version 2>/dev/null)
|
|||
git_version="${git_version##git version }"
|
||||
|
||||
alias g='git'
|
||||
if exist lazygit; then
|
||||
alias lg="lazygit"
|
||||
fi
|
||||
|
||||
alias ga='git add'
|
||||
alias gaa='git add --all'
|
||||
alias gai='git add -i'
|
||||
alias gb='git branch'
|
||||
alias gbd='git branch -d'
|
||||
|
||||
alias gc='git commit -v'
|
||||
alias gc!='git commit -v --amend'
|
||||
|
@ -24,9 +23,7 @@ alias gcn!='git commit -v --no-edit --amend'
|
|||
if version_at_least 2.23 "$git_version"; then
|
||||
alias gcm='git switch master 2>/dev/null || git switch main'
|
||||
alias gcd='git switch develop 2>/dev/null || git switch staging'
|
||||
gcb() {
|
||||
git switch "$@" 2>/dev/null || git switch -c "$@"
|
||||
}
|
||||
alias gcb='git switch -c'
|
||||
else
|
||||
alias gcm='git checkout master 2>/dev/null || git checkout main'
|
||||
alias gcd='git checkout develop'
|
||||
|
@ -34,33 +31,16 @@ else
|
|||
fi
|
||||
alias gco='git checkout'
|
||||
|
||||
alias gi='git ignore'
|
||||
|
||||
# normal diff
|
||||
alias gd='git diff'
|
||||
alias gds='git diff --staged'
|
||||
# word-based diff (with custom word regex)
|
||||
alias gdw='git diffword'
|
||||
alias gdws='git diffword --staged'
|
||||
# side-by-side diff
|
||||
alias gdd='git diffside'
|
||||
alias gdds='git diffside --staged'
|
||||
# syntax-based diff
|
||||
if exist difft; then
|
||||
alias gdy='git diffsyn'
|
||||
alias gdys='git diffsyn --staged'
|
||||
fi
|
||||
alias gdd='git diffside'
|
||||
alias gdds='git diffside --staged'
|
||||
# show last committed content
|
||||
alias gdl='git last'
|
||||
|
||||
alias gi='git ignore'
|
||||
|
||||
# show last committed content
|
||||
alias gll='git last'
|
||||
# show quick log overview
|
||||
alias glg='git log --oneline --decorate --graph'
|
||||
alias glga='git log --oneline --decorate --graph --remotes --all'
|
||||
# show quick log overview - with dates
|
||||
alias glgd="git log --graph --pretty=format:'%C(auto)%h%Creset %C(cyan)%ar%Creset%C(auto)%d%Creset %s'"
|
||||
alias glgad="git log --graph --remotes --all --pretty=format:'%C(auto)%h%Creset %C(cyan)%ar%Creset%C(auto)%d%Creset %s'"
|
||||
# show detailed log overview
|
||||
alias glog='git log --stat'
|
||||
# show detailed log overview with contents
|
||||
|
@ -97,22 +77,4 @@ else
|
|||
alias gsta='git stash save'
|
||||
fi
|
||||
|
||||
if exist git-bug; then
|
||||
gb() {
|
||||
if [ "$#" -eq 1 ]; then
|
||||
git bug show "$1"
|
||||
else
|
||||
git bug ls "$@"
|
||||
fi
|
||||
}
|
||||
alias gbt='git bug termui'
|
||||
|
||||
alias gba='git bug add'
|
||||
alias gbm='git bug comment add'
|
||||
alias gbc='git bug status close'
|
||||
|
||||
alias gbp='git bug push'
|
||||
alias gbl='git bug pull'
|
||||
fi
|
||||
|
||||
unset -v git_version
|
18
git/.local/bin/dsf
Executable file
18
git/.local/bin/dsf
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env sh
|
||||
# Pretty git diff display
|
||||
|
||||
# degrade diffs gracefully:
|
||||
# prefer diff-so-fancy if it is installed,
|
||||
# otherwise fallback to git's own prettifier,
|
||||
# if nothing exists just pass it on
|
||||
dsf() {
|
||||
if exist diff-so-fancy; then
|
||||
diff-so-fancy
|
||||
elif exist /usr/share/git/diff-highlight/diff-highlight; then
|
||||
/usr/share/git/diff-highlight/diff-highlight
|
||||
else
|
||||
cat
|
||||
fi
|
||||
}
|
||||
|
||||
dsf
|
|
@ -1,17 +1,15 @@
|
|||
# Version control software module
|
||||
# Git module
|
||||
|
||||
[git](https://git-scm.com/) - a distributed version control system
|
||||
[jujutsu](https://martinvonz.github.io/jj/latest/) - a change-based version control system
|
||||
|
||||
## What's in this module
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
## Global vcs settings
|
||||
## Global git settings
|
||||
|
||||
This are probably the first things that need to be customized, since it points to a different identity for each git user.
|
||||
This is probably the first thing that needs to be customized, since it points to a different identity for each git user.
|
||||
I sign all my commits by default, so take out the corresponding lines if you don't, or exchange it with your gpg key.
|
||||
Similarly for jujutsu, change the identity and remove the lines concerning gpg signing if you don't use it.
|
||||
|
||||
Git will rewrite any remotes using http(s) to use the ssh notation for pushes to github and gitlab so that, even if you set up the repository using an https url you can utilize your usual ssh key for pushing.
|
||||
|
167
install.sh
167
install.sh
|
@ -7,35 +7,29 @@
|
|||
#
|
||||
# Will first install yay, then all my used packages (read from bootstrap/packages.txt)
|
||||
#
|
||||
# Finally, symlinks all dotfiles into their correct locations using dotter
|
||||
# Finally, symlinks all dotfiles into their correct locations using stow
|
||||
|
||||
bootstrap_dir="${DOT_BOOTSTRAP_DIR:-./bootstrap}"
|
||||
unattended_install="${DOT_UNATTENDED_INSTALL:-false}"
|
||||
link_systemfiles="${DOT_LINK_SYSTEMFILES:-true}"
|
||||
|
||||
help() {
|
||||
printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f Do not ask for any confirmations but force update and installation.\n"
|
||||
exit "${1:-0}"
|
||||
}
|
||||
bootstrap_dir="${BOOTSTRAP_DIRECTORY:-./bootstrap}"
|
||||
|
||||
main() {
|
||||
local cmd=""
|
||||
local ret=0
|
||||
case "$1" in
|
||||
-v | --version)
|
||||
printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n"
|
||||
;;
|
||||
-h | --help)
|
||||
help 0
|
||||
;;
|
||||
-f | --force)
|
||||
unattended_install=true
|
||||
;;
|
||||
*)
|
||||
install
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
|
||||
case "$1" in
|
||||
-v | --version)
|
||||
printf "Personal system bootstrap script.\n\nby Marty Oehme\n\nv0.2\n"
|
||||
;;
|
||||
-h | --help)
|
||||
printf "Usage: install [-f|--force][-v|--version][-h|--help]\n\n-f Do not ask for any confirmations but force update and installation.\n"
|
||||
;;
|
||||
-f | --force)
|
||||
install true
|
||||
;;
|
||||
*)
|
||||
install false
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
|
||||
$cmd "$@"
|
||||
ret=$((ret + $?))
|
||||
|
@ -45,94 +39,83 @@ main() {
|
|||
# takes default value (y/n), question, abort message as arguments
|
||||
# automatically answers yes if unattended install
|
||||
check_consent() {
|
||||
if [ "$unattended_install" == "true" ]; then
|
||||
true
|
||||
else
|
||||
[[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]"
|
||||
printf "%b %b " "$2" "$default_consent"
|
||||
read -r answer
|
||||
if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
if [ "$UNATTENDED" == "true" ]; then
|
||||
true
|
||||
else
|
||||
[[ "$1" == "y" ]] && default_consent="[Y/n]" || default_consent="[y/N]"
|
||||
printf "%s %s " "$2" "$default_consent"
|
||||
read -r answer
|
||||
if [[ "$1" == "n" ]] && [[ "$answer" != y* ]]; then
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
elif [[ "$1" == "y" ]] && [[ "$answer" == n* ]]; then
|
||||
echo second
|
||||
printf "%s\n" "$3"
|
||||
false
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
entry_question() {
|
||||
check_consent n "This will take a while and install many packages and link dotfiles all over the place depending on your selections.\nYou need to be in the base directory of the dotfiles repository.\nProceed?" "Aborting." || exit
|
||||
check_consent n "This will take a while, install many packages and link dotfiles all over the place. Proceed?" "Aborting." || exit
|
||||
}
|
||||
|
||||
enable_git_hooks() {
|
||||
check_consent y "Should we enable git hooks for this repository, so that missing or additionally installed packages are automatically compared to the repository when committing?" "Not changing repository settings." || return
|
||||
git config --local core.hooksPath .githooks/
|
||||
echo "Changed repository settings."
|
||||
check_consent y "Should we enable git hooks for this repository, so that installed packages are automatically compared when committing?" "Not changing repository settings." || return
|
||||
git config --local core.hooksPath .githooks/
|
||||
echo "Changed repository settings."
|
||||
}
|
||||
|
||||
manage_dotfiles() {
|
||||
check_consent y "Link dot files?" "Not linking dotfiles." || return
|
||||
check_consent n "Link system settings files? This will require sudo access but will not overwrite existing files." "Not touching system files." || link_systemfiles=false
|
||||
if [ "$link_systemfiles" == "false" ]; then
|
||||
dotter deploy
|
||||
echo "Linked dotfiles."
|
||||
else
|
||||
if [ -e "/etc/pacman.conf" ]; then
|
||||
check_consent n "Found an existing pacman.conf file, installation will error if it exists. Remove file?" && run_elevated rm "/etc/pacman.conf"
|
||||
fi
|
||||
dotter deploy -l .dotter/systemwide.toml
|
||||
echo "Linked dotfiles and system files."
|
||||
fi
|
||||
stow_dotfiles() {
|
||||
check_consent y "Link home directory dot files?" "Not linking dotfiles." || return
|
||||
# get all top level directories, remove their slashes and dots
|
||||
# finally get rid of .dot-directories, since they are for the repo not for my homedir
|
||||
targets="$(find . -maxdepth 1 -type d | sed -e 's/^\.\/\(.*\)$/\1/' | sed -e '/^\./d')"
|
||||
|
||||
# shellcheck disable=2086
|
||||
# -- for some reason stow only works with unqoted var expansion
|
||||
stow -R ${targets} 2> >(grep -v 'Absolute/relative mismatch between Stow dir' 1>&2)
|
||||
echo "Linked dotfiles."
|
||||
}
|
||||
|
||||
run_elevated() {
|
||||
if command -v doas >/dev/null 2>&1; then
|
||||
doas "$@"
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
sudo "$@"
|
||||
fi
|
||||
stow_system_packages() {
|
||||
check_consent n "Link system settings as well? This will require sudo access." "Not touching system files." || return
|
||||
sudo stow --dir="$bootstrap_dir" --target="/" -R system-packages/
|
||||
echo "Linked system files."
|
||||
}
|
||||
|
||||
|
||||
install_packages() {
|
||||
check_consent n "Install pre-designated packages? This will take a while, install a lot of packages and require super user privileges." "Not installing packages." || return
|
||||
if [ "$unattended_install" == "true" ]; then
|
||||
"$bootstrap_dir"/install_packages.sh -f
|
||||
else
|
||||
"$bootstrap_dir"/install_packages.sh
|
||||
fi
|
||||
echo "Installed packages."
|
||||
}
|
||||
|
||||
headline() {
|
||||
len="${#1}"
|
||||
target_len=85
|
||||
side_len=$(((target_len - len) / 2))
|
||||
for ((i = 1; i <= side_len; i++)); do printf '='; done
|
||||
printf " %s " "$1"
|
||||
for ((i = 1; i <= side_len; i++)); do printf '='; done
|
||||
printf "\n"
|
||||
check_consent n "Install pre-designated packages? This will take a while." "Not installing packages." || return
|
||||
export BOOTSTRAP_PACKAGES="bootstrap/packages.txt"
|
||||
if ! "$UNATTENDED"; then
|
||||
"$bootstrap_dir"/install_packages.sh
|
||||
else
|
||||
"$bootstrap_dir"/install_packages.sh -f
|
||||
fi
|
||||
unset BOOTSTRAP_PACKAGES
|
||||
echo "Installed packages."
|
||||
}
|
||||
|
||||
install() {
|
||||
if [ "$unattended_install" == false ] ; then
|
||||
entry_question
|
||||
fi
|
||||
UNATTENDED=$1
|
||||
if ! "$UNATTENDED"; then
|
||||
entry_question
|
||||
fi
|
||||
|
||||
headline "BEGINNING PACKAGE INSTALLATION"
|
||||
install_packages
|
||||
echo "====================== BEGINNING INSTALLATION ============================="
|
||||
install_packages
|
||||
|
||||
headline "BEGINNING DOTFILE MANAGEMENT"
|
||||
manage_dotfiles
|
||||
echo "=================== BEGINNING DOTFILE MANAGEMENT =========================="
|
||||
stow_dotfiles
|
||||
stow_system_packages
|
||||
|
||||
headline "ENABLING GIT REPOSITORY HOOKS"
|
||||
enable_git_hooks
|
||||
echo "================== ENABLING GIT REPOSITORY HOOKS =========================="
|
||||
enable_git_hooks
|
||||
|
||||
echo "INSTALLATION FINISHED"
|
||||
exit 0
|
||||
echo "====================== INSTALLATION FINISHED =============================="
|
||||
exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
8
kitty/.config/kitty/kitty.conf
Normal file
8
kitty/.config/kitty/kitty.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
enable_audio_bell no
|
||||
include current-theme.conf
|
||||
|
||||
font_family Liga Iosevka
|
||||
bold_font Iosevka Term Bold Nerd Font Complete
|
||||
italic_font Iosevka Term Italic Nerd Font Complete
|
||||
bold_italic_font Iosevka Term Heavy Italic Nerd Font Complete
|
||||
|
15
mail/.config/imapfilter/accounts.lua
Normal file
15
mail/.config/imapfilter/accounts.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
local accounts = {}
|
||||
|
||||
local status, gmailuser = pipe_from(
|
||||
'gpg2 --decrypt --no-tty --quiet --no-verbose --for-your-eyes-only --pinentry-mode ask ~/.local/share/pass/misc/aerc-gmail-app-password.gpg | grep username | cut -d: -f2')
|
||||
local status, gmailpass = pipe_from(
|
||||
'gpg2 --decrypt --no-tty --quiet --no-verbose --for-your-eyes-only --pinentry-mode ask ~/.local/share/pass/misc/aerc-gmail-app-password.gpg | head -n1')
|
||||
-- Setup an imap account called gmail
|
||||
accounts.gmail = IMAP {
|
||||
server = "imap.gmail.com",
|
||||
username = gmailuser,
|
||||
password = gmailpass,
|
||||
ssl = "auto"
|
||||
}
|
||||
|
||||
return accounts
|
|
@ -20,64 +20,67 @@ CONTINUOUS = false
|
|||
UPDATE_TIME = 120
|
||||
|
||||
-- implement simple wait function in case server does not support IDLE mode
|
||||
function sleep(n)
|
||||
os.execute("sleep " .. tonumber(n))
|
||||
end
|
||||
function sleep(n) os.execute("sleep " .. tonumber(n)) end
|
||||
|
||||
-- will set filters to be grabbed from XDG-compliant filter directory
|
||||
-- can be overridden with env var IMAPFILTER_FILTERDIR
|
||||
function getConfigDir()
|
||||
-- -- set directory for imapfilter files
|
||||
local configdir
|
||||
if os.getenv("IMAPFILTER_CONFIGDIR") then
|
||||
configdir = os.getenv("IMAPFILTER_CONFIGDIR")
|
||||
elseif os.getenv("XDG_CONFIG_HOME") then
|
||||
configdir = os.getenv("XDG_CONFIG_HOME") .. "/imapfilter"
|
||||
else
|
||||
configdir = os.getenv("HOME") .. "/.config/imapfilter"
|
||||
end
|
||||
return configdir
|
||||
-- -- set directory for imapfilter files
|
||||
local configdir
|
||||
if os.getenv("IMAPFILTER_CONFIGDIR") then
|
||||
configdir = os.getenv("IMAPFILTER_CONFIGDIR")
|
||||
elseif os.getenv("XDG_CONFIG_HOME") then
|
||||
configdir = os.getenv("XDG_CONFIG_HOME") .. "/imapfilter"
|
||||
else
|
||||
configdir = os.getenv("HOME") .. "/.config/imapfilter"
|
||||
end
|
||||
return configdir
|
||||
end
|
||||
|
||||
-- will set filters to be grabbed from XDG-compliant filter directory
|
||||
-- can be overridden with env var IMAPFILTER_FILTERDIR
|
||||
function getFilterDir()
|
||||
-- -- set directory for imapfilter files
|
||||
local imapfilterdir
|
||||
if os.getenv("IMAPFILTER_FILTERDIR") then
|
||||
imapfilterdir = os.getenv("IMAPFILTER_FILTERDIR")
|
||||
else
|
||||
imapfilterdir = configDir .. "/filters"
|
||||
end
|
||||
return imapfilterdir
|
||||
-- -- set directory for imapfilter files
|
||||
local imapfilterdir
|
||||
if os.getenv("IMAPFILTER_FILTERDIR") then
|
||||
imapfilterdir = os.getenv("IMAPFILTER_FILTERDIR")
|
||||
else
|
||||
imapfilterdir = configDir .. "/filters"
|
||||
end
|
||||
return imapfilterdir
|
||||
end
|
||||
|
||||
-- dirlist, from https://stackoverflow.com/a/25266573
|
||||
function applyFilters(dir)
|
||||
local p = io.popen('find "' .. dir .. '" -type f -name "*.lua"') -- Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
|
||||
for file in p:lines() do -- Loop through all files
|
||||
loadfile(file)()
|
||||
end
|
||||
local p = io.popen('find "' .. dir .. '" -type f -name "*.lua"') -- Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
|
||||
for file in p:lines() do -- Loop through all files
|
||||
loadfile(file)()
|
||||
end
|
||||
end
|
||||
|
||||
-- create global variable containing the configuration files
|
||||
configDir = getConfigDir()
|
||||
assert(configDir, "No configuration directory found. Ensure " .. os.getenv("HOME") .. "/.config/imapfilter exists.")
|
||||
assert(configDir,
|
||||
"No configuration directory found. Ensure " .. os.getenv("HOME") ..
|
||||
"/.config/imapfilter exists.")
|
||||
|
||||
-- create global variable containing account access
|
||||
accounts = loadfile(configDir .. "/accounts.lua")()
|
||||
assert(accounts, "No accounts configured. Ensure accounts.lua exists and returns a table of accounts.")
|
||||
assert(accounts,
|
||||
"No accounts configured. Ensure accounts.lua exists and returns a table of accounts.")
|
||||
|
||||
-- immediately act on the filters once
|
||||
applyFilters(getFilterDir())
|
||||
|
||||
-- continuously watch for mail if needed
|
||||
while CONTINUOUS == true do
|
||||
local has_idle = accounts.gmail["Inbox"]:enter_idle()
|
||||
applyFilters(getFilterDir())
|
||||
local has_idle = accounts.gmail['Inbox']:enter_idle()
|
||||
applyFilters(getFilterDir())
|
||||
|
||||
if has_idle == false then
|
||||
print("Server does not support idle, application will be polling again in " .. UPDATE_TIME .. "minutes.")
|
||||
sleep(UPDATE_TIME)
|
||||
end
|
||||
if has_idle == false then
|
||||
print(
|
||||
"Server does not support idle, application will be polling again in " ..
|
||||
UPDATE_TIME .. "minutes.")
|
||||
sleep(UPDATE_TIME)
|
||||
end
|
||||
end
|
40
mail/.config/imapfilter/filters/rollup-dump.lua
Normal file
40
mail/.config/imapfilter/filters/rollup-dump.lua
Normal file
|
@ -0,0 +1,40 @@
|
|||
function sendToFolder(folderFrom, folderTo, senders)
|
||||
local messages = folderFrom:select_all()
|
||||
for _, sender in pairs(senders) do
|
||||
local filtered = messages:contain_from(sender)
|
||||
filtered:mark_seen()
|
||||
filtered:move_messages(folderTo)
|
||||
end
|
||||
end
|
||||
|
||||
-- will set filters to be grabbed from XDG-compliant filter directory
|
||||
-- can be overridden with env var IMAPFILTER_ROLLUPFILE
|
||||
function getRollupFile(fname)
|
||||
local f
|
||||
local fname = fname or "rollup.txt"
|
||||
if os.getenv("IMAPFILTER_ROLLUPFILE") then
|
||||
f = os.getenv("IMAPFILTER_ROLLUPFILE")
|
||||
elseif os.getenv("XDG_DATA_HOME") then
|
||||
f = os.getenv("XDG_DATA_HOME") .. "/imapfilter/" .. fname
|
||||
else
|
||||
f = os.getenv("HOME") .. "/.local/share/imapfilter/" .. fname
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
function getSenderList(rollupfile)
|
||||
local rollupSenders = {}
|
||||
|
||||
local file = io.open(rollupfile)
|
||||
if file then
|
||||
for line in file:lines() do table.insert(rollupSenders, line) end
|
||||
else
|
||||
print(
|
||||
"ERROR: rollup did not find rollup.txt file containing mail addresses at " ..
|
||||
rollupfile or "")
|
||||
end
|
||||
return rollupSenders
|
||||
end
|
||||
|
||||
sendToFolder(accounts.gmail["Inbox"], accounts.gmail["Dump"],
|
||||
getSenderList(getRollupFile()))
|
68
mail/.config/isync/mbsyncrc
Normal file
68
mail/.config/isync/mbsyncrc
Normal file
|
@ -0,0 +1,68 @@
|
|||
# documentation: https://wiki.archlinux.org/index.php/isync
|
||||
|
||||
IMAPAccount gmail
|
||||
# Address to connect to
|
||||
Host imap.gmail.com
|
||||
UserCmd "pass show misc/gmail-app-password | grep username | cut -d: -f2"
|
||||
PassCmd "pass show misc/gmail-app-password | head -n1"
|
||||
# To store the password in an encrypted file use PassCmd instead of Pass
|
||||
# PassCmd "gpg2 -q --for-your-eyes-only --no-tty -d ~/.mailpass.gpg"
|
||||
#
|
||||
# Use SSL
|
||||
SSLType IMAPS
|
||||
CertificateFile /etc/ssl/certs/ca-certificates.crt
|
||||
# Throttle simultaneous access to make google happy
|
||||
PipelineDepth 60
|
||||
|
||||
IMAPStore gmail-remote
|
||||
Account gmail
|
||||
|
||||
MaildirStore mail-local
|
||||
Subfolders Verbatim
|
||||
# The trailing "/" is important
|
||||
Path ~/documents/mail/
|
||||
Inbox ~/documents/mail/Inbox
|
||||
# define generous maximum size to store locally
|
||||
MaxSize 50M
|
||||
|
||||
Channel gmail-inbox
|
||||
Far :gmail-remote:INBOX
|
||||
Near :mail-local:inbox
|
||||
# Exclude everything under the internal [Gmail] folder, except the interesting folders
|
||||
# Automatically create missing mailboxes, both locally and on the server
|
||||
Create Near
|
||||
# Save the synchronization state files in the relevant directory
|
||||
SyncState *
|
||||
|
||||
Channel gmail-sent
|
||||
Far :gmail-remote:"[Google Mail]/Sent Mail"
|
||||
Near :mail-local:sent
|
||||
Create Near
|
||||
|
||||
Channel gmail-trash
|
||||
Far :gmail-remote:"[Google Mail]/Trash"
|
||||
Near :mail-local:trash
|
||||
Create Near
|
||||
|
||||
Channel gmail-important
|
||||
Far :gmail-remote:"[Google Mail]/Starred"
|
||||
Near :mail-local:important
|
||||
Create Near
|
||||
|
||||
Channel gmail-drafts
|
||||
Far :gmail-remote:"[Google Mail]/Drafts"
|
||||
Near :mail-local:drafts
|
||||
Create Near
|
||||
|
||||
Channel gmail-all
|
||||
Far :gmail-remote:"[Google Mail]/All Mail"
|
||||
Near :mail-local:archive
|
||||
Create Near
|
||||
|
||||
# Put all the channels into one group
|
||||
Group googlemail
|
||||
Channel gmail-inbox
|
||||
Channel gmail-important
|
||||
Channel gmail-sent
|
||||
Channel gmail-trash
|
||||
Channel gmail-all
|
|
@ -2,17 +2,17 @@
|
|||
defaults
|
||||
auth on
|
||||
tls on
|
||||
# disable starttls to use whole connection through ssl
|
||||
tls_starttls off
|
||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
||||
# logfile ~/.msmtp.log
|
||||
|
||||
# Gmail
|
||||
account personal-gmail
|
||||
tls_starttls on
|
||||
host smtp.gmail.com
|
||||
port 587
|
||||
from marty.oehme@gmail.com
|
||||
user marty.oehme@gmail.com
|
||||
# password plain-text-password-goes-here
|
||||
passwordeval "pass show misc/gmail-app-password | head -n1"
|
||||
|
||||
# Set a default account
|
||||
account default : personal-gmail
|
16
mail/.config/neomutt/account
Normal file
16
mail/.config/neomutt/account
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Account settings
|
||||
# local maildir settings
|
||||
set mbox_type = Maildir
|
||||
set folder = ~/documents/mail # This has the shortcut '+' or '='
|
||||
set spoolfile = "+inbox" # This has the shortcut '!'
|
||||
set postponed = "+drafts"
|
||||
set trash = "+trash"
|
||||
# Disable saving outgoing mail since Gmail saves them by default.
|
||||
unset record
|
||||
mailboxes ! \
|
||||
"+important" \
|
||||
"+sent" \
|
||||
"+drafts" \
|
||||
"+trash" \
|
||||
"+archive"
|
||||
|
|
@ -62,8 +62,8 @@ color index_number blue default
|
|||
color index_subject cyan default '.*'
|
||||
|
||||
# For new mail:
|
||||
color index brightyellow brightblack "~N"
|
||||
color index_author brightred brightblack "~N"
|
||||
color index brightyellow black "~N"
|
||||
color index_author brightred black "~N"
|
||||
color index_subject brightcyan black "~N"
|
||||
|
||||
color progress black cyan
|
||||
|
@ -73,12 +73,12 @@ color progress black cyan
|
|||
|
||||
# Formatting ----------------------------------------------------------------------
|
||||
set date_format = "%a %d %h %H:%M"
|
||||
set index_format=" %zc %zs %zt | %-35.35L %?X?📎& ? %M %-30.100s %> %?Y?%Y ? %(!%a %d %h %H:%M) "
|
||||
set index_format=" %zc %zs %zt | %-35.35L %@attachment_info@ %?M10?~(%1M) ?%-30.100s %> %?Y?%Y ? %(!%a %d %h %H:%M) "
|
||||
set pager_format="%n %T %s%* %{!%d %b · %H:%M} %?X? %X?%P"
|
||||
set status_format = " %D %?u? %u ?%?R? %R ?%?d? %d ?%?t? %t ?%?F? %F ?%?p? %p? \n \n"
|
||||
set status_format = " %D %?u? %u ?%?R? %R ?%?d? %d ?%?t? %t ?%?F? %F ?%?p? %p? \n \n"
|
||||
set compose_format="-- NeoMutt: Compose [Approx. msg size: %l Atts: %a]%>-"
|
||||
# set vfolder_format = "%N %?n?%3n& ? %8m · %f"
|
||||
set attach_format = "%u%D %T %-75.20d %T %5s %m/%M"
|
||||
set attach_format = "%u%D %T%-75.75d %?T?%& ? %5s · %m/%M"
|
||||
set sidebar_format = '%D%?Z? [%Z]?%* %?S?%S?'
|
||||
index-format-hook attachment_info '=B text/calendar ~X 1' ' '
|
||||
index-format-hook attachment_info '=B text/calendar' " "
|
||||
|
@ -104,7 +104,7 @@ color status color8 default '(|)' # statusline "bubbl
|
|||
color status color69 black '(\` )' # bubble account variation
|
||||
color status white color69 '([a-zA-Z0-9\.]+)( )' # account text
|
||||
color status green color8 '' # Unread messages count
|
||||
color status blue color8 '' # Read messages count icon
|
||||
color status blue color8 '' # Read messages count icon
|
||||
color status yellow color8 '' # Flagged icon
|
||||
color status red color8 '' # Pending delete icon
|
||||
|
||||
|
@ -155,7 +155,7 @@ color attachment color8 default
|
|||
color signature color8 default
|
||||
|
||||
# emails
|
||||
color body color14 default '[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+'
|
||||
# color body color14 default '[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+'
|
||||
|
||||
# hide "mailto"
|
||||
color body color0 color0 '<mailto:[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+>'
|
||||
|
@ -212,7 +212,7 @@ color body color8 default '(^(To|From|Sent|Subject):.*)'
|
|||
set to_chars=" "
|
||||
|
||||
# unchanged mailbox, changed, read only, attach mode
|
||||
set status_chars = " "
|
||||
set status_chars = " "
|
||||
ifdef crypt_chars set crypt_chars = " "
|
||||
set flag_chars = " "
|
||||
|
||||
|
@ -221,7 +221,7 @@ set hidden_tags = "unread,draft,flagged,passed,replied,attachment,signed,encrypt
|
|||
tag-transforms "replied" "↻ " \
|
||||
"encrytpted" "" \
|
||||
"signed" "" \
|
||||
"attachment" "" \
|
||||
"attachment" "" \
|
||||
|
||||
# The formats must start with 'G' and the entire sequence is case sensitive.
|
||||
tag-formats "replied" "GR" \
|
|
@ -1,16 +1,16 @@
|
|||
# open html emails in browser (or whatever GUI program is used to render HTML)
|
||||
text/html; open %s ; nametemplate=%s.html
|
||||
text/html; xdg-open %s ; nametemplate=%s.html
|
||||
# render html emails inline using magic (uncomment the line below to use lynx instead)
|
||||
# text/html; lynx -assume_charset=%{charset} -display_charset=utf-8 -collapse_br_tags -dump %s; nametemplate=%s.html; copiousoutput
|
||||
text/html; render-prettyhtml %s; nametemplate=%s.html; copiousoutput;
|
||||
text/plain; $EDITOR %s ;
|
||||
|
||||
# show calendar invites
|
||||
text/calendar; mutt-ics; description=ics details; copiousoutput; print=khal import %s; needsterminal
|
||||
application/ics; mutt-ics; description=ics details; copiousoutput; print=khal import %s; needsterminal
|
||||
text/calendar; mutt-ics; copiousoutput
|
||||
application/ics; mutt-ics; copiousoutput
|
||||
|
||||
# open images externally
|
||||
image/*; imv %s ;
|
||||
image/*; nsxiv %s ;
|
||||
|
||||
# open videos in mpv
|
||||
video/*; mpv --autofit-larger=90\%x90\% %s; needsterminal;
|
||||
|
@ -20,9 +20,9 @@ video/*; setsid mpv --quiet %s &; copiousoutput
|
|||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; sc-im %s; needsterminal
|
||||
|
||||
# open anything else externally
|
||||
application/pdf; open %s;
|
||||
application/pdf; xdg-open %s;
|
||||
|
||||
application/*; mkdir -p /tmp/mutt \; cp %s /tmp/mutt \; open /tmp/mutt/$(basename %s) &
|
||||
application/*; mkdir -p /tmp/mutt \; cp %s /tmp/mutt \; xdg-open /tmp/mutt/$(basename %s) &
|
||||
application/pgp-encrypted; gpg -d '%s'; copiousoutput;
|
||||
application/pgp-keys; gpg --import '%s'; copiousoutput;
|
||||
|
61
mail/.config/neomutt/maps
Normal file
61
mail/.config/neomutt/maps
Normal file
|
@ -0,0 +1,61 @@
|
|||
# index navigation
|
||||
bind index l display-message
|
||||
bind index L limit
|
||||
bind index,pager g noop # don't send group-replies with g
|
||||
bind index gg first-entry
|
||||
bind index G last-entry
|
||||
bind index <space> collapse-thread
|
||||
bind index,pager \CF next-page
|
||||
bind index,pager \CB previous-page
|
||||
bind index,pager N search-opposite # vim-like search
|
||||
bind index s toggle-new
|
||||
macro index \CS "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
|
||||
|
||||
# Email completion bindings
|
||||
bind editor <Tab> complete-query
|
||||
bind editor ^T complete
|
||||
# Press A to add contact to Khard address book
|
||||
macro index,pager A \
|
||||
"<pipe-message>khard add-email<return>" \
|
||||
"add the sender email address to khard"
|
||||
|
||||
# mailbox navigation
|
||||
macro index,pager gi "<change-folder>=inbox<enter>" "go to inbox"
|
||||
macro index,pager gm "<change-folder>=important<enter>" "go to important"
|
||||
macro index,pager gs "<change-folder>=sent<enter>" "go to sent"
|
||||
macro index,pager gd "<change-folder>=drafts<enter>" "go to drafts"
|
||||
macro index,pager gt "<change-folder>=trash<enter>" "go to trash"
|
||||
macro index,pager ga "<change-folder>=archive<enter>" "go to archive"
|
||||
# sidebar navigation
|
||||
bind index,pager B sidebar-toggle-visible
|
||||
bind index,pager <down> sidebar-next
|
||||
bind index,pager <up> sidebar-prev
|
||||
bind index,pager <right> sidebar-open
|
||||
# search navigation
|
||||
macro index a "<limit>all\n" "show all messages (undo limit)"
|
||||
# notmuch search navigation
|
||||
bind index \\ vfolder-from-query # notmuch search
|
||||
# pager navigation
|
||||
bind pager,attach h exit
|
||||
bind pager l view-attachments
|
||||
bind pager k previous-line
|
||||
bind pager j next-line
|
||||
bind pager gg top
|
||||
bind pager G bottom
|
||||
# compose postpone
|
||||
bind compose p postpone-message
|
||||
# markdown to html for composition
|
||||
macro compose M "F pandoc -s -f markdown -t html \ny^T^Utext/html; charset=UTF-8\n" "Convert from MD to HTML"
|
||||
|
||||
# since we unbound the original g
|
||||
bind index,pager R group-reply
|
||||
# open urls found in the e-mail
|
||||
macro index,pager \CU "|urlview<enter>" "call urlview to open links"
|
||||
|
||||
# Refresh far imap email
|
||||
macro index O "<sync-mailbox><shell-escape>export MBSYNC_PRE=true; mail-check<enter><sync-mailbox>" "refresh all e-mail"
|
||||
macro index o "<sync-mailbox><shell-escape>export MBSYNC_PRE=true; mail-check gmail-inbox<enter><sync-mailbox>" "refresh inbox e-mail"
|
||||
|
||||
# Saner copy/move dialogs
|
||||
macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
|
||||
macro index M "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
|
|
@ -1,3 +1,12 @@
|
|||
# Identity
|
||||
#
|
||||
set realname = "Marty Oehme"
|
||||
set from = "marty.oehme@gmail.com"
|
||||
# # If you have another address:
|
||||
# alternates "^neomutt@example\.com$"
|
||||
# # Or, if you use the entire domain:
|
||||
# alternates "@example\.com$"
|
||||
# set reverse_name
|
||||
|
||||
set mail_check = 60
|
||||
set mail_check_stats
|
||||
|
@ -43,7 +52,7 @@ set fcc_attach # attachments saved with body
|
|||
# set editor = "vim"
|
||||
set mime_type_query_command = "xdg-mime query filetype"
|
||||
# send settings
|
||||
set sendmail = "/usr/bin/msmtp"
|
||||
set sendmail = "/usr/bin/msmtp -a personal-gmail"
|
||||
set sendmail_wait = 0
|
||||
|
||||
# Display Settings
|
4
mail/.config/sh/env.d/neomutt-create-cache-dir.sh
Normal file
4
mail/.config/sh/env.d/neomutt-create-cache-dir.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env sh
|
||||
# Ensure the neomutt cache directories exist
|
||||
|
||||
[ -d "${XDG_CACHE_HOME:-~/.cache}/neomutt" ] || mkdir -p "${XDG_CACHE_HOME:-~/.cache}/neomutt/hcache"
|
|
@ -47,7 +47,6 @@ prehook() {
|
|||
eval "$MBSYNC_PRE"
|
||||
return 0
|
||||
fi
|
||||
checkwarnuser
|
||||
imapfilter -c "${XDG_CONFIG_HOME:-$HOME/.config}/imapfilter/config.lua"
|
||||
}
|
||||
|
||||
|
@ -143,6 +142,7 @@ elif [ -n "$1" ]; then
|
|||
fi
|
||||
|
||||
main() {
|
||||
checkwarnuser
|
||||
enablegpgagent
|
||||
prehook
|
||||
|
15
mail/README.md
Normal file
15
mail/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# e-mail module
|
||||
|
||||
[aerc](https://aerc-mail.org/) - terminal mail client
|
||||
[isync](https://isync.sourceforge.io/mbsync.html) - mirror your Imapped mail directory locally with two way synchronization
|
||||
[notmuch](https://notmuchmail.org/) - index and search your mail
|
||||
|
||||
The current mail setup uses `mbsync` (from the isync project) to locally mirror the GMail imap folder.
|
||||
It, as of now, needs to be manually run by invoking `mbsync gmail` -- which expects your username and password to reside in a [`pass`](/pass) accessible file called `misc/aerc-gmail-app-password`.
|
||||
In other words --- this is very specific to my setup and if transferring the options, please customize to your needs.
|
||||
|
||||
Then, `notmuch` can be run on the local maildir to generate and indexed full-text search engine.
|
||||
Right now, `notmuch` can only be used through its cli, it is not yet connected to `aerc`.
|
||||
|
||||
`aerc` picks up the maildir created by `mbsync` in `~/documents/mail` and works on it.
|
||||
`mbsync` syncs any changes made back to the remote imap directory.
|
|
@ -37,9 +37,8 @@ I script-message playlistmanager show filename
|
|||
R cycle-values video-aspect "16:9" "4:3" "3.25:1" "no" "-1" # cycle aspect ratios
|
||||
|
||||
# uosc definitions and menu
|
||||
o script-message-to uosc toggle-elements timeline
|
||||
O script-binding uosc/toggle-ui
|
||||
m script-binding uosc/menu
|
||||
o script-binding uosc/peek-timeline
|
||||
m script-binding uosc/menu
|
||||
|
||||
# script-binding uosc/open-file #! Open file
|
||||
# script-binding uosc/load-subtitles #! Load subtitles
|
||||
|
@ -49,4 +48,3 @@ m script-binding uosc/menu
|
|||
# script-binding uosc/playlist #! Utils > Playlist
|
||||
# script-binding uosc/chapters #! Utils > Chapters
|
||||
# script-binding uosc/open-config-directory #! Utils > Open config directory
|
||||
|
|
@ -35,8 +35,8 @@ screenshot-tag-colorspace=yes
|
|||
osc=no
|
||||
osd-bar=no
|
||||
|
||||
osd-font='Iosevka Nerd Font'
|
||||
osd-font-size=15
|
||||
osd-font='Iosevka Mono'
|
||||
osd-font-size=16
|
||||
|
||||
### Subtitles
|
||||
|
||||
|
@ -81,13 +81,18 @@ volume-max=150
|
|||
audio-file-auto=fuzzy
|
||||
# playing at different speed will pitch-correct
|
||||
audio-pitch-correction=yes
|
||||
# no audio popping on seek
|
||||
audio-stream-silence
|
||||
# lets mpv calc latency instead of PA; disable if errors on network playback or similar
|
||||
pulse-latency-hacks=yes
|
||||
|
||||
### Video
|
||||
|
||||
hwdec=auto
|
||||
profile=opengl-hq
|
||||
opengl-early-flush=auto
|
||||
opengl-pbo=no
|
||||
# brigheen video slightly to account for daylight displaying
|
||||
gamma-factor=1.1
|
||||
# ever so slightly up saturation
|
||||
saturation=12
|
||||
# interpolation options, will take some more cpu
|
220
mpv/.config/mpv/scripts/autoload.lua
Normal file
220
mpv/.config/mpv/scripts/autoload.lua
Normal file
|
@ -0,0 +1,220 @@
|
|||
-- This script automatically loads playlist entries before and after the
|
||||
-- the currently played file. It does so by scanning the directory a file is
|
||||
-- located in when starting playback. It sorts the directory entries
|
||||
-- alphabetically, and adds entries before and after the current file to
|
||||
-- the internal playlist. (It stops if it would add an already existing
|
||||
-- playlist entry at the same position - this makes it "stable".)
|
||||
-- Add at most 5000 * 2 files when starting a file (before + after).
|
||||
|
||||
--[[
|
||||
To configure this script use file autoload.conf in directory script-opts (the "script-opts"
|
||||
directory must be in the mpv configuration directory, typically ~/.config/mpv/).
|
||||
|
||||
Example configuration would be:
|
||||
|
||||
disabled=no
|
||||
images=no
|
||||
videos=yes
|
||||
audio=yes
|
||||
|
||||
--]]
|
||||
|
||||
MAXENTRIES = 5000
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
local options = require 'mp.options'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
o = {
|
||||
disabled = false,
|
||||
images = true,
|
||||
videos = true,
|
||||
audio = true
|
||||
}
|
||||
options.read_options(o)
|
||||
|
||||
function Set (t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do set[v] = true end
|
||||
return set
|
||||
end
|
||||
|
||||
function SetUnion (a,b)
|
||||
local res = {}
|
||||
for k in pairs(a) do res[k] = true end
|
||||
for k in pairs(b) do res[k] = true end
|
||||
return res
|
||||
end
|
||||
|
||||
EXTENSIONS_VIDEO = Set {
|
||||
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp'
|
||||
}
|
||||
|
||||
EXTENSIONS_AUDIO = Set {
|
||||
'mp3', 'wav', 'ogm', 'flac', 'm4a', 'wma', 'ogg', 'opus'
|
||||
}
|
||||
|
||||
EXTENSIONS_IMAGES = Set {
|
||||
'jpg', 'jpeg', 'png', 'tif', 'tiff', 'gif', 'webp', 'svg', 'bmp'
|
||||
}
|
||||
|
||||
EXTENSIONS = Set {}
|
||||
if o.videos then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_VIDEO) end
|
||||
if o.audio then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_AUDIO) end
|
||||
if o.images then EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_IMAGES) end
|
||||
|
||||
function add_files_at(index, files)
|
||||
index = index - 1
|
||||
local oldcount = mp.get_property_number("playlist-count", 1)
|
||||
for i = 1, #files do
|
||||
mp.commandv("loadfile", files[i], "append")
|
||||
mp.commandv("playlist-move", oldcount + i - 1, index + i - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extension(path)
|
||||
match = string.match(path, "%.([^%.]+)$" )
|
||||
if match == nil then
|
||||
return "nomatch"
|
||||
else
|
||||
return match
|
||||
end
|
||||
end
|
||||
|
||||
table.filter = function(t, iter)
|
||||
for i = #t, 1, -1 do
|
||||
if not iter(t[i]) then
|
||||
table.remove(t, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- splitbynum and alnumcomp from alphanum.lua (C) Andre Bogus
|
||||
-- Released under the MIT License
|
||||
-- http://www.davekoelle.com/files/alphanum.lua
|
||||
|
||||
-- split a string into a table of number and string values
|
||||
function splitbynum(s)
|
||||
local result = {}
|
||||
for x, y in (s or ""):gmatch("(%d*)(%D*)") do
|
||||
if x ~= "" then table.insert(result, tonumber(x)) end
|
||||
if y ~= "" then table.insert(result, y) end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function clean_key(k)
|
||||
k = (' '..k..' '):gsub("%s+", " "):sub(2, -2):lower()
|
||||
return splitbynum(k)
|
||||
end
|
||||
|
||||
-- compare two strings
|
||||
function alnumcomp(x, y)
|
||||
local xt, yt = clean_key(x), clean_key(y)
|
||||
for i = 1, math.min(#xt, #yt) do
|
||||
local xe, ye = xt[i], yt[i]
|
||||
if type(xe) == "string" then ye = tostring(ye)
|
||||
elseif type(ye) == "string" then xe = tostring(xe) end
|
||||
if xe ~= ye then return xe < ye end
|
||||
end
|
||||
return #xt < #yt
|
||||
end
|
||||
|
||||
local autoloaded = nil
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = utils.split_path(path)
|
||||
msg.trace(("dir: %s, filename: %s"):format(dir, filename))
|
||||
if o.disabled then
|
||||
msg.verbose("stopping: autoload disabled")
|
||||
return
|
||||
elseif #dir == 0 then
|
||||
msg.verbose("stopping: not a local path")
|
||||
return
|
||||
end
|
||||
|
||||
local pl_count = mp.get_property_number("playlist-count", 1)
|
||||
-- check if this is a manually made playlist
|
||||
if (pl_count > 1 and autoloaded == nil) or
|
||||
(pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil) then
|
||||
msg.verbose("stopping: manually made playlist")
|
||||
return
|
||||
else
|
||||
autoloaded = true
|
||||
end
|
||||
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos-1", 1)
|
||||
msg.trace(("playlist-pos-1: %s, playlist: %s"):format(pl_current,
|
||||
utils.to_string(pl)))
|
||||
|
||||
local files = utils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
msg.verbose("no other files in directory")
|
||||
return
|
||||
end
|
||||
table.filter(files, function (v, k)
|
||||
if string.match(v, "^%.") then
|
||||
return false
|
||||
end
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, alnumcomp)
|
||||
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
|
||||
local current
|
||||
for i = 1, #files do
|
||||
if files[i] == filename then
|
||||
current = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if current == nil then
|
||||
return
|
||||
end
|
||||
msg.trace("current file position in files: "..current)
|
||||
|
||||
local append = {[-1] = {}, [1] = {}}
|
||||
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
|
||||
for i = 1, MAXENTRIES do
|
||||
local file = files[current + i * direction]
|
||||
local pl_e = pl[pl_current + i * direction]
|
||||
if file == nil or file[1] == "." then
|
||||
break
|
||||
end
|
||||
|
||||
local filepath = dir .. file
|
||||
if pl_e then
|
||||
-- If there's a playlist entry, and it's the same file, stop.
|
||||
msg.trace(pl_e.filename.." == "..filepath.." ?")
|
||||
if pl_e.filename == filepath then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if direction == -1 then
|
||||
if pl_current == 1 then -- never add additional entries in the middle
|
||||
msg.info("Prepending " .. file)
|
||||
table.insert(append[-1], 1, filepath)
|
||||
end
|
||||
else
|
||||
msg.info("Adding " .. file)
|
||||
table.insert(append[1], filepath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_files_at(pl_current + 1, append[1])
|
||||
add_files_at(pl_current, append[-1])
|
||||
end
|
||||
|
||||
mp.register_event("start-file", find_and_add_entries)
|
25
mpv/.config/mpv/scripts/battery.lua
Normal file
25
mpv/.config/mpv/scripts/battery.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
-- If the laptop is on battery, the profile 'lq' will be loaded; otherwise 'hq' is used
|
||||
--
|
||||
local lqprofile = "lowquality"
|
||||
local hqprofile = "highquality"
|
||||
|
||||
local function powerstate()
|
||||
local f = io.open("/sys/class/power_supply/AC/online")
|
||||
if f == nil then return end
|
||||
local t = f:read("*n")
|
||||
f:close()
|
||||
return t
|
||||
end
|
||||
|
||||
local function adjust()
|
||||
local state = powerstate()
|
||||
-- this actually overrides automatically applied profiles
|
||||
-- like 'protocol.http'
|
||||
if state == 0 then
|
||||
mp.msg.info("Running on battery, setting low-quality options.")
|
||||
mp.set_property("profile", lqprofile)
|
||||
else
|
||||
mp.msg.info("Not running on battery, setting high-quality options.")
|
||||
end
|
||||
end
|
||||
mp.add_hook("on_load", 1, adjust)
|
32
mpv/.config/mpv/scripts/gallery-dl.lua
Normal file
32
mpv/.config/mpv/scripts/gallery-dl.lua
Normal file
|
@ -0,0 +1,32 @@
|
|||
-- gallery-dl_hook.lua
|
||||
--
|
||||
-- load online image galleries as playlists using gallery-dl
|
||||
-- https://github.com/mikf/gallery-dl
|
||||
--
|
||||
-- to use, prepend the gallery url with: gallery-dl://
|
||||
-- e.g.
|
||||
-- `mpv gallery-dl://https://imgur.com/....`
|
||||
|
||||
local utils = require 'mp.utils'
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
local function exec(args)
|
||||
local ret = utils.subprocess({args = args})
|
||||
return ret.status, ret.stdout, ret
|
||||
end
|
||||
|
||||
mp.add_hook("on_load", 15, function()
|
||||
local url = mp.get_property("stream-open-filename", "")
|
||||
if (url:find("gdl://") ~= 1) then
|
||||
msg.debug("not a gdl:// url: " .. url)
|
||||
return
|
||||
end
|
||||
local url = string.gsub(url,"gdl://","")
|
||||
|
||||
local es, urls, result = exec({"gallery-dl", "-g", url})
|
||||
if (es < 0) or (urls == nil) or (urls == "") then
|
||||
msg.error("failed to get album list.")
|
||||
end
|
||||
|
||||
mp.commandv("loadlist", "memory://" .. urls)
|
||||
end)
|
1011
mpv/.config/mpv/scripts/playlistmanager.lua
Normal file
1011
mpv/.config/mpv/scripts/playlistmanager.lua
Normal file
File diff suppressed because it is too large
Load diff
94
mpv/.config/mpv/scripts/sponsorblock_minimal.lua
Normal file
94
mpv/.config/mpv/scripts/sponsorblock_minimal.lua
Normal file
|
@ -0,0 +1,94 @@
|
|||
-- sponsorblock_minimal.lua
|
||||
--
|
||||
-- This script skips sponsored segments of YouTube videos
|
||||
-- using data from https://github.com/ajayyy/SponsorBlock
|
||||
--
|
||||
-- original from https://codeberg.org/jouni/mpv_sponsorblock_minimal
|
||||
-- adapted for local playback skipping and some refactoring by me
|
||||
local options = {
|
||||
API = "https://sponsor.ajay.app/api/skipSegments",
|
||||
|
||||
-- Categories to fetch and skip
|
||||
categories = '"sponsor","intro","outro","interaction","selfpromo"'
|
||||
}
|
||||
|
||||
local function getranges()
|
||||
local args = {
|
||||
"curl", "-s", "-d", "videoID=" .. Youtube_id, "-d",
|
||||
"categories=[" .. options.categories .. "]", "-G", options.API
|
||||
}
|
||||
local sponsors = mp.command_native({
|
||||
name = "subprocess",
|
||||
capture_stdout = true,
|
||||
playback_only = false,
|
||||
args = args
|
||||
})
|
||||
|
||||
if string.match(sponsors.stdout, "%[(.-)%]") then
|
||||
Ranges = {}
|
||||
for i in string.gmatch(string.sub(sponsors.stdout, 2, -2), "%[(.-)%]") do
|
||||
local k, v = string.match(i, "(%d+.?%d*),(%d+.?%d*)")
|
||||
Ranges[k] = v
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function skip_ads(name, pos)
|
||||
if pos ~= nil then
|
||||
for k, v in pairs(Ranges) do
|
||||
if tonumber(k) <= pos and tonumber(v) > pos then
|
||||
-- this message may sometimes be wrong
|
||||
-- it only seems to be a visual thing though
|
||||
mp.osd_message("[sponsorblock] skipping forward " ..
|
||||
math.floor(
|
||||
tonumber(v) - mp.get_property("time-pos")) ..
|
||||
"s")
|
||||
-- need to do the +0.01 otherwise mpv will start spamming skip sometimes
|
||||
-- example: https://www.youtube.com/watch?v=4ypMJzeNooo
|
||||
mp.set_property("time-pos", tonumber(v) + 0.01)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function file_loaded()
|
||||
local video_path = mp.get_property("path")
|
||||
local youtube_id1 = string.match(video_path,
|
||||
"https?://youtu%.be/([%w-_]+).*")
|
||||
local youtube_id2 = string.match(video_path,
|
||||
"https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*")
|
||||
local youtube_id3 = string.match(video_path, "/watch.*[?&]v=([%w-_]+).*")
|
||||
local youtube_id4 = string.match(video_path, "/embed/([%w-_]+).*")
|
||||
local localytfile = string.match(video_path,
|
||||
"-([%a%d%-_]+)%.[mw][kpe][v4b][m]?$")
|
||||
Youtube_id = youtube_id1 or youtube_id2 or youtube_id3 or youtube_id4 or
|
||||
localytfile
|
||||
if not Youtube_id or string.len(Youtube_id) < 11 then return end
|
||||
Youtube_id = string.sub(Youtube_id, 1, 11)
|
||||
|
||||
getranges()
|
||||
if Ranges then
|
||||
ON = true
|
||||
mp.add_key_binding("b", "sponsorblock", toggle)
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function toggle()
|
||||
if ON then
|
||||
mp.unobserve_property(skip_ads)
|
||||
mp.osd_message("[sponsorblock] off")
|
||||
ON = false
|
||||
return
|
||||
end
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
mp.osd_message("[sponsorblock] on")
|
||||
ON = true
|
||||
return
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", file_loaded)
|
3655
mpv/.config/mpv/scripts/uosc.lua
Normal file
3655
mpv/.config/mpv/scripts/uosc.lua
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,12 +1,6 @@
|
|||
# Multimedia module
|
||||
# mpv module
|
||||
|
||||
[mpv](https://mpv.io) -- free, open-source, cross-platform media player
|
||||
beets -- organize your music library
|
||||
mopidy -- serve your music library
|
||||
ncmpcpp -- actually play your music (and twist your tongue pronouncing it)
|
||||
|
||||
The largest modifications so far are definitely to mpv (described below),
|
||||
with beets and mopidy being somewhat configured to my tastes as well.
|
||||
|
||||
mpv is set up to hopefully strike a balance between high quality playback, streaming with a reasonable speed and saving battery power.
|
||||
It is set up to play both local files and streams from the web (especially youtube with playlisting and ad skipping), via a qutebrowser mapping if the corresponding module is installed.
|
|
@ -1,118 +0,0 @@
|
|||
# much of this such as the whitelist, canonical list for lasgenre
|
||||
# is stolen from https://github.com/montchr/beets-config/ with much gratitude
|
||||
|
||||
directory: ~/media/audio/music
|
||||
library: ~/.local/share/beets/library.db
|
||||
|
||||
threaded: true
|
||||
art_filename: albumart
|
||||
# Use the album's original date instead of the release's date
|
||||
original_date: yes
|
||||
# Use safer pathnames
|
||||
asciify_paths: yes
|
||||
max_filename_length: 255
|
||||
|
||||
# Long format - I don't need all the extra info for each invocation
|
||||
#format_item: '[$id] [$album_id] [$singleton] $albumartist - $title - $album - $original_year - [$format - $bitrate $length $filesize]'
|
||||
#format_album: '[$id] $albumartist - $album - $original_year [$catalognum]'
|
||||
|
||||
clutter:
|
||||
- Thumbs.db
|
||||
- .DS_Store
|
||||
- '*.m3u'
|
||||
- '*.pls'
|
||||
- '*.db'
|
||||
|
||||
import:
|
||||
copy: false
|
||||
move: true
|
||||
write: true
|
||||
bell: true
|
||||
# incremental: true
|
||||
languages:
|
||||
- en
|
||||
log: ~/.cache/beets.log
|
||||
quiet_fallback: skip
|
||||
timid: false
|
||||
|
||||
ignore_hidden: yes
|
||||
paths:
|
||||
default: "%the{$albumartist}/$album/$track $title"
|
||||
singleton: "singletons/%the{$artist - $title}"
|
||||
comp: compilations/$album/$track $title
|
||||
albumtype:soundtrack: soundtracks/$album/$track $title
|
||||
|
||||
item_fields:
|
||||
multidisc: 1 if disctotal > 1 else 0
|
||||
artist_differs: 1 if albumartist != artist else 0
|
||||
|
||||
musicbrainz:
|
||||
extra_tags: [year, catalognum, country, media, label]
|
||||
user: {{multimedia_beets_musicbrainz_user}}
|
||||
pass: {{multimedia_beets_musicbrainz_pass}}
|
||||
auto: yes
|
||||
remove: yes
|
||||
|
||||
match:
|
||||
preferred:
|
||||
countries: ["US", "UK|GB", "DE", "NL", "SE"]
|
||||
media: ["Digital Media|File", "CD"]
|
||||
strong_rec_thresh: 0.15
|
||||
medium_red_thresh: 0.25
|
||||
rec_gap_thresh: 0.25
|
||||
|
||||
plugins:
|
||||
- bandcamp
|
||||
- chroma
|
||||
- deezer
|
||||
- describe
|
||||
- edit
|
||||
- embedart
|
||||
- export
|
||||
- fetchart
|
||||
- fromfilename
|
||||
- ftintitle
|
||||
- fuzzy
|
||||
- importadded
|
||||
- info
|
||||
- inline
|
||||
- lastgenre
|
||||
- lastimport
|
||||
- lyrics
|
||||
- mbcollection
|
||||
- mbsync
|
||||
- missing
|
||||
- spotify
|
||||
- the
|
||||
- ydl
|
||||
|
||||
edit:
|
||||
itemfields: track title artist album
|
||||
albumfields: album albumartist albumtype
|
||||
ignore_fields: id path
|
||||
|
||||
fetchart:
|
||||
sources: filesystem coverart itunes discogs amazon albumart
|
||||
store_source: yes
|
||||
|
||||
lastgenre:
|
||||
auto: true
|
||||
canonical: ~/.config/beets/lastgenre_canonicallist.yaml
|
||||
count: 4
|
||||
fallback: ""
|
||||
force: yes
|
||||
min_weight: 6
|
||||
prefer_specific: false
|
||||
separator: "; "
|
||||
source: album
|
||||
whitelist: ~/.config/beets/lastgenre_whitelist.txt
|
||||
|
||||
lastfm:
|
||||
user: schmitzkater
|
||||
|
||||
lyrics:
|
||||
sources: musixmatch genius
|
||||
fallback: ''
|
||||
|
||||
bandcamp:
|
||||
art: true
|
|
@ -1,783 +0,0 @@
|
|||
- 2-step
|
||||
- acapella
|
||||
- acid
|
||||
- acid house
|
||||
- acid jazz
|
||||
- acid techno
|
||||
- adult contemporary
|
||||
- african
|
||||
- african blues
|
||||
- african heavy metal
|
||||
- african hip hop
|
||||
- afrobeat
|
||||
- aggrotech
|
||||
- alternative country
|
||||
- alternative metal
|
||||
- alternative rock
|
||||
- ambient
|
||||
- ambient dub
|
||||
- ambient house
|
||||
- ambient space jazz
|
||||
- ambient techno
|
||||
- american folk revival
|
||||
- americana
|
||||
- anison
|
||||
- anti-folk
|
||||
- apala
|
||||
- arab pop
|
||||
- asian underground
|
||||
- atlanta hip hop:
|
||||
- snap music
|
||||
- australian country music
|
||||
- avant-garde
|
||||
- avant-garde jazz
|
||||
- axé
|
||||
- bachata
|
||||
- baithak gana
|
||||
- bakersfield sound
|
||||
- balearic beat
|
||||
- ballet
|
||||
- baltimore club
|
||||
- barbershop
|
||||
- baroque pop
|
||||
- baroque:
|
||||
- baroque music
|
||||
- bebop
|
||||
- benga
|
||||
- berlin school:
|
||||
- berlin school of electronic music
|
||||
- berlin-school
|
||||
- big band
|
||||
- big beat
|
||||
- bikutsi
|
||||
- black metal:
|
||||
- viking metal
|
||||
- blue-eyed soul
|
||||
- bluegrass:
|
||||
- progressive bluegrass
|
||||
- reactionary bluegrass
|
||||
- blues
|
||||
- blues country
|
||||
- blues rock
|
||||
- blues shouter
|
||||
- bolero
|
||||
- bongo flava
|
||||
- boogie
|
||||
- boogie-woogie
|
||||
- bossa nova
|
||||
- bounce music
|
||||
- brazilian
|
||||
- brazilian rock
|
||||
- breakbeat:
|
||||
- 4-beat
|
||||
- acid breaks
|
||||
- breakbeat hardcore
|
||||
- broken beat
|
||||
- florida breaks
|
||||
- nu skool breaks
|
||||
- breakcore
|
||||
- brega
|
||||
- british blues
|
||||
- british folk revival
|
||||
- britpop:
|
||||
- post-britpop
|
||||
- bubblegum pop
|
||||
- c-pop:
|
||||
- cantopop
|
||||
- cajun:
|
||||
- cajun fiddle tunes
|
||||
- calypso
|
||||
- canadian blues
|
||||
- cantata
|
||||
- cape jazz
|
||||
- celtic music
|
||||
- chamber jazz
|
||||
- chamber music:
|
||||
- string quartet
|
||||
- chanson
|
||||
- chicago blues
|
||||
- chicago house
|
||||
- chillwave:
|
||||
- chill wave
|
||||
- chimurenga
|
||||
- chiptune:
|
||||
- bitpop
|
||||
- game boy music
|
||||
- nintendocore
|
||||
- video game music
|
||||
- yorkshire bleeps and bass
|
||||
- choro
|
||||
- christian country music
|
||||
- christian hip hop
|
||||
- christian metal
|
||||
- christian pop
|
||||
- christian rock
|
||||
- chutney
|
||||
- chutney soca
|
||||
- classic country
|
||||
- classical crossover
|
||||
- classical:
|
||||
- classical music
|
||||
- orchestra:
|
||||
- orchestral
|
||||
- symphonic
|
||||
- symphony
|
||||
- close harmony
|
||||
- coldwave
|
||||
- comedy:
|
||||
- comedy music
|
||||
- comedy rock
|
||||
- humor
|
||||
- parody music
|
||||
- stand-up
|
||||
- compas
|
||||
- computer music
|
||||
- concerto:
|
||||
- concerto grosso
|
||||
- contemporary folk
|
||||
- contemporary r&b
|
||||
- continental jazz
|
||||
- cool jazz
|
||||
- country
|
||||
- country blues
|
||||
- country pop
|
||||
- country rap
|
||||
- country rock
|
||||
- country soul
|
||||
- country-rap
|
||||
- coupé-décalé
|
||||
- cowpunk
|
||||
- crunkcore
|
||||
- cybergrind
|
||||
- dance-punk
|
||||
- dance-rock
|
||||
- dancehall
|
||||
- dansband music
|
||||
- dark ambient
|
||||
- dark electro
|
||||
- darkwave:
|
||||
- dark wave
|
||||
- death industrial
|
||||
- death metal:
|
||||
- goregrind
|
||||
- deconstructed club
|
||||
- deep house
|
||||
- deep techno
|
||||
- delta blues
|
||||
- detroit blues
|
||||
- detroit techno
|
||||
- digital hardcore:
|
||||
- bouncy house
|
||||
- bouncy techno
|
||||
- hardstyle
|
||||
- jumpstyle
|
||||
- makina
|
||||
- uk hardcore
|
||||
- disco:
|
||||
- disco polo:
|
||||
- euro disco
|
||||
- nu-disco
|
||||
- diva house
|
||||
- dixieland
|
||||
- doo wop
|
||||
- doom metal
|
||||
- doomcore
|
||||
- downtempo:
|
||||
- chill out
|
||||
- ethnic electronica
|
||||
- moombahton
|
||||
- nu jazz
|
||||
- dream pop
|
||||
- drone metal
|
||||
- drone:
|
||||
- drone music
|
||||
- drum and bass:
|
||||
- darkcore
|
||||
- darkstep
|
||||
- drumfunk
|
||||
- drumstep
|
||||
- hardstep
|
||||
- intelligent drum and bass
|
||||
- jump-up
|
||||
- liquid funk
|
||||
- neurofunk
|
||||
- raggacore
|
||||
- sambass
|
||||
- techstep
|
||||
- dub poetry
|
||||
- dub techno
|
||||
- dub:
|
||||
- dub music
|
||||
- dubstep
|
||||
- dubtronica
|
||||
- dungeon synth
|
||||
- dutch house
|
||||
- east coast hip hop:
|
||||
- brick city club
|
||||
- hardcore hip hop
|
||||
- mafioso rap
|
||||
- new jersey hip hop
|
||||
- easy listening:
|
||||
- background music
|
||||
- beautiful music
|
||||
- elevator music
|
||||
- furniture music
|
||||
- middle of the road
|
||||
- ebm:
|
||||
- electronic body music:
|
||||
- futurepop
|
||||
- edm:
|
||||
- electronic dance music
|
||||
- electric blues
|
||||
- electro
|
||||
- electro house
|
||||
- electro-grime
|
||||
- electro-industrial
|
||||
- electroacoustic:
|
||||
- acousmatic music
|
||||
- electroacoustic improvisation
|
||||
- live electronics
|
||||
- electroclash
|
||||
- electrofunk
|
||||
- electronic rock:
|
||||
- alternative dance:
|
||||
- baggy
|
||||
- madchester
|
||||
- electronicore
|
||||
- ethereal wave
|
||||
- new rave
|
||||
- electropop
|
||||
- electropunk
|
||||
- emo
|
||||
- enka
|
||||
- eurodance:
|
||||
- bubblegum dance
|
||||
- italo dance
|
||||
- turbofolk
|
||||
- europop:
|
||||
- austropop
|
||||
- balkan pop
|
||||
- french pop
|
||||
- latin pop
|
||||
- laïkó
|
||||
- nederpop
|
||||
- russian pop
|
||||
- experimental pop
|
||||
- experimental rock
|
||||
- experimental:
|
||||
- experimental music
|
||||
- fann at-tanbura
|
||||
- field recording
|
||||
- fijiri
|
||||
- filmi
|
||||
- folk metal:
|
||||
- celtic metal
|
||||
- medieval metal
|
||||
- folk punk:
|
||||
- celtic punk
|
||||
- gypsy punk
|
||||
- folk rock
|
||||
- folk:
|
||||
- filk music
|
||||
- folk music
|
||||
- folktronica
|
||||
- footwork
|
||||
- forró
|
||||
- fourth world:
|
||||
- ethnic ambient
|
||||
- tribal ambient
|
||||
- franco-country
|
||||
- freak folk
|
||||
- free jazz
|
||||
- free funk
|
||||
- free improvisation
|
||||
- freestyle house
|
||||
- freestyle rap
|
||||
- freestyle:
|
||||
- freestyle music
|
||||
- french house
|
||||
- frevo
|
||||
- fuji music
|
||||
- funk carioca
|
||||
- funk metal
|
||||
- funk:
|
||||
- deep funk
|
||||
- go-go
|
||||
- funky house
|
||||
- g-funk
|
||||
- gabber
|
||||
- gamelan
|
||||
- gangsta rap
|
||||
- garage rock
|
||||
- garage:
|
||||
- 4x4
|
||||
- bassline
|
||||
- breakstep
|
||||
- funky
|
||||
- speed garage
|
||||
- genge
|
||||
- ghetto house
|
||||
- ghettotech
|
||||
- glam metal
|
||||
- glam rock
|
||||
- glitch-hop
|
||||
- glitch:
|
||||
- clicks 'n' cuts
|
||||
- goa:
|
||||
- dark psytranceon
|
||||
- goa trance
|
||||
- psybreaks
|
||||
- psyprog
|
||||
- gospel blues
|
||||
- goth rock:
|
||||
- gothic rock
|
||||
- gothic metal
|
||||
- grime
|
||||
- grindcore:
|
||||
- crustgrind
|
||||
- noisegrind
|
||||
- grunge:
|
||||
- post-grunge
|
||||
- gulf and western
|
||||
- gypsy jazz
|
||||
- happy hardcore
|
||||
- hard bop
|
||||
- hard rock
|
||||
- hardbag
|
||||
- hardcore punk:
|
||||
- street punk
|
||||
- hellbilly music
|
||||
- hi-nrg:
|
||||
- eurobeat
|
||||
- hard nrg
|
||||
- new beat
|
||||
- highlife
|
||||
- hill country blues
|
||||
- hip house
|
||||
- hip-hop:
|
||||
- alternative hip hop
|
||||
- avant-garde hip hop
|
||||
- chap hop
|
||||
- chicago hip hop
|
||||
- conscious hip hop
|
||||
- detroit hip hop
|
||||
- hip hop
|
||||
- hip hop soul
|
||||
- hip pop
|
||||
- horrorcore
|
||||
- hyphy
|
||||
- jazz rap
|
||||
- low bap
|
||||
- lyrical hip hop
|
||||
- merenrap
|
||||
- motswako
|
||||
- new jack swing
|
||||
- new school hip hop
|
||||
- old school hip hop
|
||||
- political hip hop
|
||||
- rap opera
|
||||
- songo-salsa
|
||||
- st. louis hip hop
|
||||
- twin cities hip hop
|
||||
- underground hip hop
|
||||
- urban pasifika
|
||||
- hiplife
|
||||
- hokum
|
||||
- hokum blues
|
||||
- hong kong english pop
|
||||
- honky tonk
|
||||
- horror punk
|
||||
- house
|
||||
- houston hip hop:
|
||||
- chopped and screwed
|
||||
- idm
|
||||
- illbient
|
||||
- indian pop
|
||||
- indie folk
|
||||
- indie pop:
|
||||
- dunedin sound
|
||||
- twee pop
|
||||
- indie rock
|
||||
- indietronica
|
||||
- industrial
|
||||
- industrial dance
|
||||
- industrial folk
|
||||
- industrial hip hop
|
||||
- industrial metal:
|
||||
- neue deutsche härte
|
||||
- industrial rock
|
||||
- instrumental country
|
||||
- instrumental hip hop
|
||||
- iranian pop
|
||||
- isicathamiya
|
||||
- isolationism
|
||||
- italo disco
|
||||
- italo house
|
||||
- j-pop
|
||||
- jazz blues
|
||||
- jazz fusion:
|
||||
- fusion
|
||||
- fusion jazz
|
||||
- jazz rock
|
||||
- jazz-funk
|
||||
- jazz:
|
||||
- british dance band
|
||||
- crossover jazz
|
||||
- cubop
|
||||
- ethno jazz
|
||||
- european free jazz
|
||||
- m-base
|
||||
- mainstream jazz
|
||||
- novelty ragtime
|
||||
- orchestral jazz
|
||||
- shibuya-kei
|
||||
- stride jazz
|
||||
- third stream
|
||||
- trad jazz
|
||||
- vocal jazz
|
||||
- west coast gypsy jazz
|
||||
- west coast jazz
|
||||
- jit
|
||||
- jump blues
|
||||
- jungle:
|
||||
- oldschool jungle:
|
||||
- darkside jungle
|
||||
- ragga jungle
|
||||
- jùjú
|
||||
- k-pop:
|
||||
- korean pop
|
||||
- kansas city blues
|
||||
- kansas city jazz
|
||||
- kapuka
|
||||
- kayōkyoku
|
||||
- khaliji
|
||||
- kizomba
|
||||
- kosmische:
|
||||
- kraut rock
|
||||
- krautrock
|
||||
- kuduro
|
||||
- kwaito
|
||||
- kwela
|
||||
- lambada
|
||||
- latin house
|
||||
- latin jazz
|
||||
- latin:
|
||||
- chicha
|
||||
- criolla
|
||||
- cumbia
|
||||
- huayno
|
||||
- mariachi
|
||||
- ranchera
|
||||
- tejano
|
||||
- live coding
|
||||
- liwa
|
||||
- lo-fi
|
||||
- louisiana blues
|
||||
- lounge:
|
||||
- lounge music
|
||||
- lovers rock
|
||||
- lowercase
|
||||
- lubbock sound
|
||||
- luk thung:
|
||||
- luk krung
|
||||
- makossa
|
||||
- maloya
|
||||
- mambo
|
||||
- mandopop
|
||||
- manila sound
|
||||
- maracatu
|
||||
- marrabenta
|
||||
- martial industrial
|
||||
- mass
|
||||
- math rock
|
||||
- mbalax
|
||||
- mbaqanga
|
||||
- mbube
|
||||
- melodic death metal
|
||||
- memphis blues
|
||||
- metal:
|
||||
- heavy metal
|
||||
- metalcore:
|
||||
- deathcore
|
||||
- mathcore:
|
||||
- djent
|
||||
- mexican pop
|
||||
- miami bass
|
||||
- minimal house
|
||||
- minimal techno
|
||||
- minimal wave
|
||||
- modal jazz
|
||||
- modern classical:
|
||||
- contemporary classical
|
||||
- morlam
|
||||
- morna
|
||||
- museve
|
||||
- musique concrète:
|
||||
- tape music
|
||||
- méringue:
|
||||
- merengue
|
||||
- música popular brasileira
|
||||
- música sertaneja
|
||||
- nashville sound
|
||||
- neo soul
|
||||
- neo-bop jazz
|
||||
- neo-psychedelia
|
||||
- neo-swing
|
||||
- neofolk
|
||||
- neotraditional country
|
||||
- nerdcore
|
||||
- new age:
|
||||
- new age music
|
||||
- new-age
|
||||
- new-age music
|
||||
- new wave
|
||||
- no wave
|
||||
- noise pop
|
||||
- noise rock
|
||||
- noise:
|
||||
- harsh noise
|
||||
- japanoise
|
||||
- noise music
|
||||
- northern soul
|
||||
- nu metal
|
||||
- onkyokei
|
||||
- opera
|
||||
- oratorio
|
||||
- organum
|
||||
- outlaw country
|
||||
- p-funk
|
||||
- pagode
|
||||
- palm-wine
|
||||
- piano blues
|
||||
- piedmont blues
|
||||
- pinoy pop
|
||||
- pop punk
|
||||
- pop rock
|
||||
- pop sunda
|
||||
- pop:
|
||||
- jangle pop
|
||||
- latin ballad
|
||||
- levenslied
|
||||
- louisiana swamp pop
|
||||
- motorpop
|
||||
- new romanticism
|
||||
- pop rap
|
||||
- popera
|
||||
- schlager
|
||||
- sophisti-pop
|
||||
- sunshine pop
|
||||
- traditional pop music
|
||||
- vispop
|
||||
- wonky pop
|
||||
- post-bop
|
||||
- post-disco:
|
||||
- dance-pop
|
||||
- post-hardcore
|
||||
- post-punk
|
||||
- post-punk revival
|
||||
- post-rock:
|
||||
- post-metal
|
||||
- power electronics
|
||||
- power metal
|
||||
- power noise
|
||||
- powerviolence
|
||||
- progressive country
|
||||
- progressive electronic:
|
||||
- progressive breaks
|
||||
- progressive drum & bass
|
||||
- progressive house/trance:
|
||||
- disco house
|
||||
- dream house
|
||||
- space house
|
||||
- progressive techno
|
||||
- progressive folk
|
||||
- progressive house
|
||||
- progressive metal
|
||||
- progressive rock:
|
||||
- canterbury scene
|
||||
- new prog
|
||||
- rock in opposition
|
||||
- psychedelic folk
|
||||
- psychedelic pop
|
||||
- psychedelic rock:
|
||||
- acid rock
|
||||
- freakbeat
|
||||
- raga rock
|
||||
- psychobilly
|
||||
- psychobilly
|
||||
- punk blues
|
||||
- punk jazz
|
||||
- punk:
|
||||
- anarcho punk:
|
||||
- crust punk:
|
||||
- d-beat
|
||||
- art punk
|
||||
- christian punk
|
||||
- deathrock
|
||||
- garage punk
|
||||
- skate punk
|
||||
- punta
|
||||
- punta rock
|
||||
- r&b:
|
||||
- rhythm and blues
|
||||
- ragga:
|
||||
- raggamuffin
|
||||
- ragini
|
||||
- ragtime
|
||||
- rap rock:
|
||||
- rap metal
|
||||
- rapcore
|
||||
- rasin
|
||||
- rave:
|
||||
- rave music
|
||||
- raï
|
||||
- red dirt
|
||||
- reggae:
|
||||
- 2 tone
|
||||
- reggae en español:
|
||||
- reggae 110
|
||||
- reggae bultrón
|
||||
- romantic flow
|
||||
- spanish reggae
|
||||
- reggae fusion
|
||||
- reggaeton
|
||||
- requiem
|
||||
- riot grrrl
|
||||
- rock and roll
|
||||
- rock:
|
||||
- art rock
|
||||
- beat music
|
||||
- chinese rock
|
||||
- dark cabaret
|
||||
- desert rock
|
||||
- paisley underground
|
||||
- power pop
|
||||
- visual kei:
|
||||
- nagoya kei
|
||||
- rockabilly
|
||||
- rocksteady
|
||||
- roots reggae
|
||||
- sacred music:
|
||||
- cantique
|
||||
- gregorian chant
|
||||
- sadcore
|
||||
- sakara
|
||||
- salsa
|
||||
- samba
|
||||
- samba rock
|
||||
- sawt
|
||||
- screamo
|
||||
- sega
|
||||
- seggae
|
||||
- semba
|
||||
- sertanejo
|
||||
- shoegaze
|
||||
- ska
|
||||
- ska jazz
|
||||
- ska punk:
|
||||
- ska-core
|
||||
- slowcore
|
||||
- sludge metal
|
||||
- smooth jazz
|
||||
- soca
|
||||
- soft rock
|
||||
- son
|
||||
- sonata
|
||||
- soukous
|
||||
- soul
|
||||
- soul blues
|
||||
- soul jazz
|
||||
- south and southeast asian:
|
||||
- baila
|
||||
- bhangra
|
||||
- bhojpuri
|
||||
- dangdut
|
||||
- lavani
|
||||
- southern hip hop
|
||||
- southern rock
|
||||
- space age pop
|
||||
- space disco:
|
||||
- cosmic disco
|
||||
- space rock
|
||||
- speed metal
|
||||
- speedcore
|
||||
- st. louis blues
|
||||
- stoner metal
|
||||
- stoner rock
|
||||
- straight-ahead jazz
|
||||
- sufi rock
|
||||
- sung poetry
|
||||
- surf pop
|
||||
- surf rock
|
||||
- swamp blues
|
||||
- swing
|
||||
- swing house
|
||||
- symphonic metal
|
||||
- synthcore
|
||||
- synthpop
|
||||
- synthpunk
|
||||
- taarab
|
||||
- taiwanese pop
|
||||
- tech house
|
||||
- technical death metal
|
||||
- techno-folk
|
||||
- techno:
|
||||
- free tekno
|
||||
- nortec
|
||||
- schranz
|
||||
- techno-dnb
|
||||
- tecno brega
|
||||
- toytown techno
|
||||
- technopop
|
||||
- tecnobrega
|
||||
- teen pop
|
||||
- terrorcore
|
||||
- texas blues
|
||||
- texas country
|
||||
- thai pop
|
||||
- thrash metal:
|
||||
- crossover thrash
|
||||
- groove metal
|
||||
- thrash
|
||||
- thrashcore
|
||||
- timba
|
||||
- traditional country music
|
||||
- trance:
|
||||
- acid trance
|
||||
- classic trance
|
||||
- dream trance
|
||||
- hard trance
|
||||
- progressive trance
|
||||
- psychedelic trance
|
||||
- psytrance
|
||||
- tech trance
|
||||
- uplifting trance:
|
||||
- orchestral uplifting
|
||||
- vocal trance
|
||||
- trap
|
||||
- trip-hop:
|
||||
- trip hop
|
||||
- tropicalia
|
||||
- truck-driving country
|
||||
- turkish pop
|
||||
- turntablism
|
||||
- twoubadou
|
||||
- uk garage
|
||||
- uk hard house
|
||||
- us garage
|
||||
- vaporwave
|
||||
- vocal house
|
||||
- west coast blues
|
||||
- west coast hip hop:
|
||||
- chicano rap
|
||||
- jerkin'
|
||||
- western swing
|
||||
- witch house
|
||||
- world:
|
||||
- world music
|
||||
- worldbeat
|
||||
- world fusion
|
||||
- zouglou
|
||||
- zouk
|
||||
- zouk-lambada
|
||||
- zydeco
|
|
@ -1,491 +0,0 @@
|
|||
2-step
|
||||
acapella
|
||||
acid
|
||||
acid house
|
||||
acid jazz
|
||||
acid techno
|
||||
adult contemporary
|
||||
african
|
||||
african blues
|
||||
african heavy metal
|
||||
african hip hop
|
||||
afrobeat
|
||||
aggrotech
|
||||
alternative country
|
||||
alternative metal
|
||||
alternative rock
|
||||
ambient
|
||||
ambient dub
|
||||
ambient house
|
||||
ambient space jazz
|
||||
ambient techno
|
||||
american folk revival
|
||||
americana
|
||||
anison
|
||||
anti-folk
|
||||
apala
|
||||
arab pop
|
||||
asian underground
|
||||
atlanta hip hop
|
||||
australian country music
|
||||
avant-garde
|
||||
avant-garde jazz
|
||||
axé
|
||||
bachata
|
||||
baithak gana
|
||||
bakersfield sound
|
||||
balearic beat
|
||||
ballet
|
||||
baltimore club
|
||||
barbershop
|
||||
baroque pop
|
||||
baroque
|
||||
bebop
|
||||
benga
|
||||
berlin school
|
||||
big band
|
||||
big beat
|
||||
bikutsi
|
||||
black metal
|
||||
blue-eyed soul
|
||||
bluegrass
|
||||
blues
|
||||
blues country
|
||||
blues rock
|
||||
blues shouter
|
||||
bolero
|
||||
bongo flava
|
||||
boogie
|
||||
boogie-woogie
|
||||
bossa nova
|
||||
bounce music
|
||||
brazilian
|
||||
brazilian rock
|
||||
breakbeat
|
||||
breakcore
|
||||
brega
|
||||
british blues
|
||||
british folk revival
|
||||
britpop
|
||||
bubblegum pop
|
||||
c-pop
|
||||
cajun
|
||||
calypso
|
||||
canadian blues
|
||||
cantata
|
||||
cape jazz
|
||||
celtic music
|
||||
chamber jazz
|
||||
chamber music
|
||||
chanson
|
||||
chicago blues
|
||||
chicago house
|
||||
chillwave
|
||||
chimurenga
|
||||
chiptune
|
||||
choro
|
||||
christian country music
|
||||
christian hip hop
|
||||
christian metal
|
||||
christian pop
|
||||
christian rock
|
||||
chutney
|
||||
chutney soca
|
||||
classic country
|
||||
classical crossover
|
||||
classical
|
||||
close harmony
|
||||
coldwave
|
||||
comedy
|
||||
compas
|
||||
computer music
|
||||
concerto
|
||||
contemporary folk
|
||||
contemporary r&b
|
||||
continental jazz
|
||||
cool jazz
|
||||
country
|
||||
country blues
|
||||
country pop
|
||||
country rap
|
||||
country rock
|
||||
country soul
|
||||
country-rap
|
||||
coupé-décalé
|
||||
cowpunk
|
||||
crunkcore
|
||||
cybergrind
|
||||
dance-punk
|
||||
dance-rock
|
||||
dancehall
|
||||
dansband music
|
||||
dark ambient
|
||||
dark electro
|
||||
darkwave
|
||||
death industrial
|
||||
death metal
|
||||
deconstructed club
|
||||
deep house
|
||||
deep techno
|
||||
delta blues
|
||||
detroit blues
|
||||
detroit techno
|
||||
digital hardcore
|
||||
disco
|
||||
diva house
|
||||
dixieland
|
||||
doo wop
|
||||
doom metal
|
||||
doomcore
|
||||
downtempo
|
||||
dream pop
|
||||
drone metal
|
||||
drone
|
||||
drum and bass
|
||||
dub poetry
|
||||
dub techno
|
||||
dub
|
||||
dubstep
|
||||
dubtronica
|
||||
dungeon synth
|
||||
dutch house
|
||||
east coast hip hop
|
||||
easy listening
|
||||
ebm
|
||||
edm
|
||||
electric blues
|
||||
electro
|
||||
electro house
|
||||
electro-grime
|
||||
electro-industrial
|
||||
electroacoustic
|
||||
electroclash
|
||||
electrofunk
|
||||
electronic rock
|
||||
electropop
|
||||
electropunk
|
||||
emo
|
||||
enka
|
||||
eurodance
|
||||
europop
|
||||
experimental pop
|
||||
experimental rock
|
||||
experimental
|
||||
fann at-tanbura
|
||||
field recording
|
||||
fijiri
|
||||
filmi
|
||||
folk metal
|
||||
folk punk
|
||||
folk rock
|
||||
folk
|
||||
folktronica
|
||||
footwork
|
||||
forró
|
||||
fourth world
|
||||
franco-country
|
||||
freak folk
|
||||
free jazz
|
||||
freestyle house
|
||||
freestyle rap
|
||||
freestyle
|
||||
french house
|
||||
frevo
|
||||
fuji music
|
||||
funk carioca
|
||||
funk metal
|
||||
funk
|
||||
funky house
|
||||
g-funk
|
||||
gabber
|
||||
gamelan
|
||||
gangsta rap
|
||||
garage rock
|
||||
garage
|
||||
genge
|
||||
ghetto house
|
||||
ghettotech
|
||||
glam metal
|
||||
glam rock
|
||||
glitch-hop
|
||||
glitch
|
||||
goa
|
||||
gospel blues
|
||||
goth rock
|
||||
gothic metal
|
||||
grime
|
||||
grindcore
|
||||
grunge
|
||||
gulf and western
|
||||
gypsy jazz
|
||||
happy hardcore
|
||||
hard bop
|
||||
hard rock
|
||||
hardbag
|
||||
hardcore punk
|
||||
hellbilly music
|
||||
hi-nrg
|
||||
highlife
|
||||
hill country blues
|
||||
hip house
|
||||
hip-hop
|
||||
hiplife
|
||||
hokum
|
||||
hokum blues
|
||||
hong kong english pop
|
||||
honky tonk
|
||||
horror punk
|
||||
house
|
||||
houston hip hop
|
||||
idm
|
||||
illbient
|
||||
indian pop
|
||||
indie folk
|
||||
indie pop
|
||||
indie rock
|
||||
indietronica
|
||||
industrial
|
||||
industrial dance
|
||||
industrial folk
|
||||
industrial hip hop
|
||||
industrial metal
|
||||
industrial rock
|
||||
instrumental country
|
||||
instrumental hip hop
|
||||
iranian pop
|
||||
isicathamiya
|
||||
isolationism
|
||||
italo disco
|
||||
italo house
|
||||
j-pop
|
||||
jazz blues
|
||||
jazz fusion
|
||||
jazz rock
|
||||
jazz-funk
|
||||
jazz
|
||||
jit
|
||||
jump blues
|
||||
jungle
|
||||
jùjú
|
||||
k-pop
|
||||
kansas city blues
|
||||
kansas city jazz
|
||||
kapuka
|
||||
kayōkyoku
|
||||
khaliji
|
||||
kizomba
|
||||
kosmische
|
||||
kuduro
|
||||
kwaito
|
||||
kwela
|
||||
lambada
|
||||
latin house
|
||||
latin jazz
|
||||
latin
|
||||
live coding
|
||||
liwa
|
||||
lo-fi
|
||||
louisiana blues
|
||||
lounge
|
||||
lovers rock
|
||||
lowercase
|
||||
lubbock sound
|
||||
luk thung
|
||||
makossa
|
||||
maloya
|
||||
mambo
|
||||
mandopop
|
||||
manila sound
|
||||
maracatu
|
||||
marrabenta
|
||||
martial industrial
|
||||
mass
|
||||
math rock
|
||||
mbalax
|
||||
mbaqanga
|
||||
mbube
|
||||
melodic death metal
|
||||
memphis blues
|
||||
metal
|
||||
metalcore
|
||||
mexican pop
|
||||
miami bass
|
||||
minimal house
|
||||
minimal techno
|
||||
minimal wave
|
||||
modal jazz
|
||||
modern classical
|
||||
morlam
|
||||
morna
|
||||
museve
|
||||
musique concrète
|
||||
méringue
|
||||
música popular brasileira
|
||||
música sertaneja
|
||||
nashville sound
|
||||
neo soul
|
||||
neo-bop jazz
|
||||
neo-psychedelia
|
||||
neo-swing
|
||||
neofolk
|
||||
neotraditional country
|
||||
nerdcore
|
||||
new age
|
||||
new wave
|
||||
no wave
|
||||
noise pop
|
||||
noise rock
|
||||
noise
|
||||
northern soul
|
||||
nu metal
|
||||
onkyokei
|
||||
opera
|
||||
oratorio
|
||||
organum
|
||||
outlaw country
|
||||
p-funk
|
||||
pagode
|
||||
palm-wine
|
||||
piano blues
|
||||
piedmont blues
|
||||
pinoy pop
|
||||
pop punk
|
||||
pop rock
|
||||
pop sunda
|
||||
pop
|
||||
post-bop
|
||||
post-disco
|
||||
post-hardcore
|
||||
post-punk
|
||||
post-punk revival
|
||||
post-rock
|
||||
power electronics
|
||||
power metal
|
||||
power noise
|
||||
powerviolence
|
||||
progressive country
|
||||
progressive electronic
|
||||
progressive folk
|
||||
progressive house
|
||||
progressive metal
|
||||
progressive rock
|
||||
psychedelic folk
|
||||
psychedelic pop
|
||||
psychedelic rock
|
||||
psychobilly
|
||||
psychobilly
|
||||
punk blues
|
||||
punk jazz
|
||||
punk
|
||||
punta
|
||||
punta rock
|
||||
r&b
|
||||
ragga
|
||||
ragini
|
||||
ragtime
|
||||
rap rock
|
||||
rasin
|
||||
rave
|
||||
raï
|
||||
red dirt
|
||||
reggae
|
||||
reggaeton
|
||||
requiem
|
||||
riot grrrl
|
||||
rock and roll
|
||||
rock
|
||||
rockabilly
|
||||
rocksteady
|
||||
roots reggae
|
||||
sacred music
|
||||
sadcore
|
||||
sakara
|
||||
salsa
|
||||
samba
|
||||
samba rock
|
||||
sawt
|
||||
screamo
|
||||
sega
|
||||
seggae
|
||||
semba
|
||||
sertanejo
|
||||
shoegaze
|
||||
ska
|
||||
ska jazz
|
||||
ska punk
|
||||
slowcore
|
||||
sludge metal
|
||||
smooth jazz
|
||||
soca
|
||||
soft rock
|
||||
son
|
||||
sonata
|
||||
soukous
|
||||
soul
|
||||
soul blues
|
||||
soul jazz
|
||||
south and southeast asian
|
||||
southern hip hop
|
||||
southern rock
|
||||
space age pop
|
||||
space disco
|
||||
space rock
|
||||
speed metal
|
||||
speedcore
|
||||
st. louis blues
|
||||
stoner metal
|
||||
stoner rock
|
||||
straight-ahead jazz
|
||||
sufi rock
|
||||
sung poetry
|
||||
surf pop
|
||||
surf rock
|
||||
swamp blues
|
||||
swing
|
||||
swing house
|
||||
symphonic metal
|
||||
synthcore
|
||||
synthpop
|
||||
synthpunk
|
||||
taarab
|
||||
taiwanese pop
|
||||
tech house
|
||||
technical death metal
|
||||
techno-folk
|
||||
techno
|
||||
technopop
|
||||
tecnobrega
|
||||
teen pop
|
||||
terrorcore
|
||||
texas blues
|
||||
texas country
|
||||
thai pop
|
||||
thrash metal
|
||||
thrashcore
|
||||
timba
|
||||
traditional country music
|
||||
trance
|
||||
trap
|
||||
trip-hop
|
||||
tropicalia
|
||||
truck-driving country
|
||||
turkish pop
|
||||
turntablism
|
||||
twoubadou
|
||||
uk garage
|
||||
uk hard house
|
||||
us garage
|
||||
vaporwave
|
||||
vocal house
|
||||
west coast blues
|
||||
west coast hip hop
|
||||
western swing
|
||||
witch house
|
||||
world
|
||||
worldbeat
|
||||
world fusion
|
||||
gregorian chant
|
||||
zouglou
|
||||
zouk
|
||||
zouk-lambada
|
||||
zydeco
|
|
@ -1,20 +0,0 @@
|
|||
[options]
|
||||
background = #080808
|
||||
overlay = false
|
||||
overlay_position_bottom = true
|
||||
overlay_font = monospace:12
|
||||
overlay_text_color = #c6c6c6
|
||||
overlay_background_color = #1c1c1c
|
||||
overlay_background_alpha = ff
|
||||
|
||||
[binds]
|
||||
n = next
|
||||
p = prev
|
||||
o = overlay
|
||||
<Shift+K> = zoom 5
|
||||
<Shift+J> = zoom -5
|
||||
<Shift+R> = rotate by 90
|
||||
z = flip horizontal
|
||||
<Shift+Z> = flip vertical
|
||||
y = exec wl-copy "$imv_current_file"
|
||||
Y = exec wl-copy < "$imv_current_file"
|
|
@ -1,266 +0,0 @@
|
|||
# For further information about options in this file see:
|
||||
# https://docs.mopidy.com/
|
||||
#
|
||||
# The initial commented out values reflect the defaults as of:
|
||||
# Mopidy 3.4.1
|
||||
# Mopidy-Bandcamp 1.1.5
|
||||
# Mopidy-File 3.4.1
|
||||
# Mopidy-HTTP 3.4.1
|
||||
# Mopidy-Iris 3.65.0
|
||||
# Mopidy-Local 3.2.1
|
||||
# Mopidy-M3U 3.4.1
|
||||
# Mopidy-MPD 3.3.0
|
||||
# Mopidy-MPRIS 3.0.3
|
||||
# Mopidy-Scrobbler 2.0.1
|
||||
# Mopidy-SoftwareMixer 3.4.1
|
||||
# Mopidy-SomaFM 2.0.2
|
||||
# Mopidy-Spotify 4.1.1
|
||||
# Mopidy-Stream 3.4.1
|
||||
# Mopidy-YouTube 3.5
|
||||
#
|
||||
# Available options and defaults might have changed since then,
|
||||
# run `mopidy config` to see the current effective config and
|
||||
# `mopidy --version` to check the current version.
|
||||
|
||||
[core]
|
||||
#cache_dir = $XDG_CACHE_DIR/mopidy
|
||||
#config_dir = $XDG_CONFIG_DIR/mopidy
|
||||
#data_dir = $XDG_DATA_DIR/mopidy
|
||||
#max_tracklist_length = 10000
|
||||
#restore_state = false
|
||||
|
||||
[logging]
|
||||
#verbosity = 0
|
||||
#format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n %(message)s
|
||||
#color = true
|
||||
#config_file =
|
||||
|
||||
[audio]
|
||||
#mixer = software
|
||||
#mixer_volume =
|
||||
#output = autoaudiosink
|
||||
#buffer_time =
|
||||
|
||||
[proxy]
|
||||
#scheme =
|
||||
#hostname =
|
||||
#port =
|
||||
#username =
|
||||
#password =
|
||||
|
||||
[spotify]
|
||||
enabled = false
|
||||
#username =
|
||||
#password =
|
||||
#client_id =
|
||||
#client_secret =
|
||||
#bitrate = 160
|
||||
#volume_normalization = true
|
||||
#private_session = false
|
||||
timeout = 5000
|
||||
#allow_cache = true
|
||||
#allow_network = true
|
||||
#allow_playlists = true
|
||||
#search_album_count = 20
|
||||
#search_artist_count = 10
|
||||
#search_track_count = 50
|
||||
#toplist_countries =
|
||||
|
||||
[iris]
|
||||
#enabled = true
|
||||
#country = NZ
|
||||
#locale = en_NZ
|
||||
#verify_certificates = true
|
||||
#snapcast_enabled = true
|
||||
#snapcast_host = localhost
|
||||
#snapcast_port = 1780
|
||||
#snapcast_ssl = false
|
||||
#snapcast_stream = Default
|
||||
#spotify_authorization_url = https://jamesbarnsley.co.nz/iris/auth_spotify.php
|
||||
#lastfm_authorization_url = https://jamesbarnsley.co.nz/iris/auth_lastfm.php
|
||||
#genius_authorization_url = https://jamesbarnsley.co.nz/iris/auth_genius.php
|
||||
#data_dir = $XDG_DATA_DIR/iris
|
||||
|
||||
[file]
|
||||
enabled = false
|
||||
#media_dirs =
|
||||
# $XDG_MUSIC_DIR|Music
|
||||
# ~/|Home
|
||||
#excluded_file_extensions =
|
||||
# .directory
|
||||
# .html
|
||||
# .jpeg
|
||||
# .jpg
|
||||
# .log
|
||||
# .nfo
|
||||
# .pdf
|
||||
# .png
|
||||
# .txt
|
||||
# .zip
|
||||
#show_dotfiles = false
|
||||
#follow_symlinks = false
|
||||
#metadata_timeout = 1000
|
||||
|
||||
[http]
|
||||
#enabled = true
|
||||
#hostname = 127.0.0.1
|
||||
#port = 6680
|
||||
#zeroconf = Mopidy HTTP server on $hostname
|
||||
#allowed_origins =
|
||||
#csrf_protection = true
|
||||
#default_app = mopidy
|
||||
|
||||
[m3u]
|
||||
#enabled = true
|
||||
#base_dir = $XDG_MUSIC_DIR
|
||||
#default_encoding = latin-1
|
||||
#default_extension = .m3u8
|
||||
#playlists_dir =
|
||||
|
||||
[softwaremixer]
|
||||
#enabled = true
|
||||
|
||||
[stream]
|
||||
#enabled = true
|
||||
#protocols =
|
||||
# http
|
||||
# https
|
||||
# mms
|
||||
# rtmp
|
||||
# rtmps
|
||||
# rtsp
|
||||
#metadata_blacklist =
|
||||
#timeout = 5000
|
||||
|
||||
[mpd]
|
||||
#enabled = true
|
||||
#hostname = 127.0.0.1
|
||||
#port = 6600
|
||||
#password =
|
||||
#max_connections = 20
|
||||
#connection_timeout = 60
|
||||
#zeroconf = Mopidy MPD server on $hostname
|
||||
#command_blacklist =
|
||||
# listall
|
||||
# listallinfo
|
||||
#default_playlist_scheme = m3u
|
||||
|
||||
[local]
|
||||
enabled = false
|
||||
#max_search_results = 100
|
||||
media_dir = $XDG_MUSIC_DIR
|
||||
scan_timeout = 5000
|
||||
#scan_flush_threshold = 100
|
||||
#scan_follow_symlinks = false
|
||||
#included_file_extensions =
|
||||
#excluded_file_extensions =
|
||||
# .cue
|
||||
# .directory
|
||||
# .html
|
||||
# .jpeg
|
||||
# .jpg
|
||||
# .log
|
||||
# .nfo
|
||||
# .pdf
|
||||
# .png
|
||||
# .txt
|
||||
# .zip
|
||||
#directories =
|
||||
# Albums local:directory?type=album
|
||||
# Artists local:directory?type=artist
|
||||
# Composers local:directory?type=artist&role=composer
|
||||
# Genres local:directory?type=genre
|
||||
# Performers local:directory?type=artist&role=performer
|
||||
# Release Years local:directory?type=date&format=%25Y
|
||||
# Tracks local:directory?type=track
|
||||
# Last Week's Updates local:directory?max-age=604800
|
||||
# Last Month's Updates local:directory?max-age=2592000
|
||||
#timeout = 10
|
||||
#use_artist_sortname = false
|
||||
#album_art_files =
|
||||
# *.jpg
|
||||
# *.jpeg
|
||||
# *.png
|
||||
|
||||
[subidy]
|
||||
url={{multimedia_mopidy_subidy_url}}
|
||||
username={{multimedia_mopidy_subidy_user}}
|
||||
password={{multimedia_mopidy_subidy_pass}}
|
||||
|
||||
[mpris]
|
||||
#enabled = true
|
||||
#bus_type = session
|
||||
|
||||
[scrobbler]
|
||||
#enabled = true
|
||||
#username =
|
||||
#password =
|
||||
|
||||
[somafm]
|
||||
#enabled = true
|
||||
#encoding = mp3
|
||||
#quality = fast
|
||||
dj_as_artist = false
|
||||
|
||||
[youtube]
|
||||
#enabled = true
|
||||
allow_cache = true
|
||||
#youtube_api_key =
|
||||
#search_results = 15
|
||||
#playlist_max_videos = 20
|
||||
#api_enabled = false
|
||||
#channel_id =
|
||||
#musicapi_enabled = false
|
||||
#musicapi_cookie =
|
||||
#autoplay_enabled = false
|
||||
#strict_autoplay = false
|
||||
#max_autoplay_length = 600
|
||||
#max_degrees_of_separation = 3
|
||||
youtube_dl_package = yt-dlp
|
||||
|
||||
[bandcamp]
|
||||
enabled = false
|
||||
#discover_pages = 1
|
||||
#collection_items = 50
|
||||
discover_genres =
|
||||
# All
|
||||
# Electronic
|
||||
# Rock
|
||||
# Metal
|
||||
# Alternative
|
||||
# Hip-Hop/Rap
|
||||
# Experimental
|
||||
# Punk
|
||||
# Folk
|
||||
# Pop
|
||||
# Ambient
|
||||
# Soundtrack
|
||||
# World
|
||||
# Jazz
|
||||
# Acoustic
|
||||
# Funk
|
||||
# R&B/Soul
|
||||
# Devotional
|
||||
# Classical
|
||||
# Reggae
|
||||
# Podcasts
|
||||
# Country
|
||||
# Spoken Word
|
||||
# Comedy
|
||||
# Blues
|
||||
# Kids
|
||||
# Audiobooks
|
||||
# Latin
|
||||
discover_tags =
|
||||
Outrun
|
||||
Future Funk
|
||||
Alternative Hip-Hop
|
||||
Cozy Synth
|
||||
Post Metal
|
||||
Post Punk
|
||||
# Tokyo, Japan
|
||||
#image_sizes =
|
||||
# 10
|
||||
# 5
|
||||
# 2
|
||||
#identity =
|
Binary file not shown.
Binary file not shown.
|
@ -1,268 +0,0 @@
|
|||
-- This script automatically loads playlist entries before and after the
|
||||
-- the currently played file. It does so by scanning the directory a file is
|
||||
-- located in when starting playback. It sorts the directory entries
|
||||
-- alphabetically, and adds entries before and after the current file to
|
||||
-- the internal playlist. (It stops if it would add an already existing
|
||||
-- playlist entry at the same position - this makes it "stable".)
|
||||
-- Add at most 5000 * 2 files when starting a file (before + after).
|
||||
|
||||
--[[
|
||||
To configure this script use file autoload.conf in directory script-opts (the "script-opts"
|
||||
directory must be in the mpv configuration directory, typically ~/.config/mpv/).
|
||||
|
||||
Example configuration would be:
|
||||
|
||||
disabled=no
|
||||
images=no
|
||||
videos=yes
|
||||
audio=yes
|
||||
|
||||
--]]
|
||||
|
||||
MAXENTRIES = 5000
|
||||
|
||||
local msg = require("mp.msg")
|
||||
local options = require("mp.options")
|
||||
local utils = require("mp.utils")
|
||||
|
||||
o = {
|
||||
disabled = false,
|
||||
images = true,
|
||||
videos = true,
|
||||
audio = true,
|
||||
}
|
||||
options.read_options(o)
|
||||
|
||||
function Set(t)
|
||||
local set = {}
|
||||
for _, v in pairs(t) do
|
||||
set[v] = true
|
||||
end
|
||||
return set
|
||||
end
|
||||
|
||||
function SetUnion(a, b)
|
||||
local res = {}
|
||||
for k in pairs(a) do
|
||||
res[k] = true
|
||||
end
|
||||
for k in pairs(b) do
|
||||
res[k] = true
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
EXTENSIONS_VIDEO = Set({
|
||||
"mkv",
|
||||
"avi",
|
||||
"mp4",
|
||||
"ogv",
|
||||
"webm",
|
||||
"rmvb",
|
||||
"flv",
|
||||
"wmv",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"m4v",
|
||||
"3gp",
|
||||
})
|
||||
|
||||
EXTENSIONS_AUDIO = Set({
|
||||
"mp3",
|
||||
"wav",
|
||||
"ogm",
|
||||
"flac",
|
||||
"m4a",
|
||||
"wma",
|
||||
"ogg",
|
||||
"opus",
|
||||
})
|
||||
|
||||
EXTENSIONS_IMAGES = Set({
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"png",
|
||||
"tif",
|
||||
"tiff",
|
||||
"gif",
|
||||
"webp",
|
||||
"svg",
|
||||
"bmp",
|
||||
})
|
||||
|
||||
EXTENSIONS = Set({})
|
||||
if o.videos then
|
||||
EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_VIDEO)
|
||||
end
|
||||
if o.audio then
|
||||
EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_AUDIO)
|
||||
end
|
||||
if o.images then
|
||||
EXTENSIONS = SetUnion(EXTENSIONS, EXTENSIONS_IMAGES)
|
||||
end
|
||||
|
||||
function add_files_at(index, files)
|
||||
index = index - 1
|
||||
local oldcount = mp.get_property_number("playlist-count", 1)
|
||||
for i = 1, #files do
|
||||
mp.commandv("loadfile", files[i], "append")
|
||||
mp.commandv("playlist-move", oldcount + i - 1, index + i - 1)
|
||||
end
|
||||
end
|
||||
|
||||
function get_extension(path)
|
||||
match = string.match(path, "%.([^%.]+)$")
|
||||
if match == nil then
|
||||
return "nomatch"
|
||||
else
|
||||
return match
|
||||
end
|
||||
end
|
||||
|
||||
table.filter = function(t, iter)
|
||||
for i = #t, 1, -1 do
|
||||
if not iter(t[i]) then
|
||||
table.remove(t, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- splitbynum and alnumcomp from alphanum.lua (C) Andre Bogus
|
||||
-- Released under the MIT License
|
||||
-- http://www.davekoelle.com/files/alphanum.lua
|
||||
|
||||
-- split a string into a table of number and string values
|
||||
function splitbynum(s)
|
||||
local result = {}
|
||||
for x, y in (s or ""):gmatch("(%d*)(%D*)") do
|
||||
if x ~= "" then
|
||||
table.insert(result, tonumber(x))
|
||||
end
|
||||
if y ~= "" then
|
||||
table.insert(result, y)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function clean_key(k)
|
||||
k = (" " .. k .. " "):gsub("%s+", " "):sub(2, -2):lower()
|
||||
return splitbynum(k)
|
||||
end
|
||||
|
||||
-- compare two strings
|
||||
function alnumcomp(x, y)
|
||||
local xt, yt = clean_key(x), clean_key(y)
|
||||
for i = 1, math.min(#xt, #yt) do
|
||||
local xe, ye = xt[i], yt[i]
|
||||
if type(xe) == "string" then
|
||||
ye = tostring(ye)
|
||||
elseif type(ye) == "string" then
|
||||
xe = tostring(xe)
|
||||
end
|
||||
if xe ~= ye then
|
||||
return xe < ye
|
||||
end
|
||||
end
|
||||
return #xt < #yt
|
||||
end
|
||||
|
||||
local autoloaded = nil
|
||||
|
||||
function find_and_add_entries()
|
||||
local path = mp.get_property("path", "")
|
||||
local dir, filename = utils.split_path(path)
|
||||
msg.trace(("dir: %s, filename: %s"):format(dir, filename))
|
||||
if o.disabled then
|
||||
msg.verbose("stopping: autoload disabled")
|
||||
return
|
||||
elseif #dir == 0 then
|
||||
msg.verbose("stopping: not a local path")
|
||||
return
|
||||
end
|
||||
|
||||
local pl_count = mp.get_property_number("playlist-count", 1)
|
||||
-- check if this is a manually made playlist
|
||||
if
|
||||
(pl_count > 1 and autoloaded == nil)
|
||||
or (pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil)
|
||||
then
|
||||
msg.verbose("stopping: manually made playlist")
|
||||
return
|
||||
else
|
||||
autoloaded = true
|
||||
end
|
||||
|
||||
local pl = mp.get_property_native("playlist", {})
|
||||
local pl_current = mp.get_property_number("playlist-pos-1", 1)
|
||||
msg.trace(("playlist-pos-1: %s, playlist: %s"):format(pl_current, utils.to_string(pl)))
|
||||
|
||||
local files = utils.readdir(dir, "files")
|
||||
if files == nil then
|
||||
msg.verbose("no other files in directory")
|
||||
return
|
||||
end
|
||||
table.filter(files, function(v, k)
|
||||
if string.match(v, "^%.") then
|
||||
return false
|
||||
end
|
||||
local ext = get_extension(v)
|
||||
if ext == nil then
|
||||
return false
|
||||
end
|
||||
return EXTENSIONS[string.lower(ext)]
|
||||
end)
|
||||
table.sort(files, alnumcomp)
|
||||
|
||||
if dir == "." then
|
||||
dir = ""
|
||||
end
|
||||
|
||||
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
|
||||
local current
|
||||
for i = 1, #files do
|
||||
if files[i] == filename then
|
||||
current = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if current == nil then
|
||||
return
|
||||
end
|
||||
msg.trace("current file position in files: " .. current)
|
||||
|
||||
local append = { [-1] = {}, [1] = {} }
|
||||
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
|
||||
for i = 1, MAXENTRIES do
|
||||
local file = files[current + i * direction]
|
||||
local pl_e = pl[pl_current + i * direction]
|
||||
if file == nil or file[1] == "." then
|
||||
break
|
||||
end
|
||||
|
||||
local filepath = dir .. file
|
||||
if pl_e then
|
||||
-- If there's a playlist entry, and it's the same file, stop.
|
||||
msg.trace(pl_e.filename .. " == " .. filepath .. " ?")
|
||||
if pl_e.filename == filepath then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if direction == -1 then
|
||||
if pl_current == 1 then -- never add additional entries in the middle
|
||||
msg.info("Prepending " .. file)
|
||||
table.insert(append[-1], 1, filepath)
|
||||
end
|
||||
else
|
||||
msg.info("Adding " .. file)
|
||||
table.insert(append[1], filepath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_files_at(pl_current + 1, append[1])
|
||||
add_files_at(pl_current, append[-1])
|
||||
end
|
||||
|
||||
mp.register_event("start-file", find_and_add_entries)
|
|
@ -1,37 +0,0 @@
|
|||
-- If the laptop is on battery, the profile 'lq' will be loaded; otherwise 'hq' is used
|
||||
local mp = require("mp")
|
||||
|
||||
local SHOULD_ADJUST = false
|
||||
|
||||
local lqprofile = "lowquality"
|
||||
local hqprofile = "highquality"
|
||||
|
||||
local function powerstate()
|
||||
local f = io.open("/sys/class/power_supply/AC/online")
|
||||
if f == nil then
|
||||
return
|
||||
end
|
||||
local t = f:read("*n")
|
||||
f:close()
|
||||
return t
|
||||
end
|
||||
|
||||
local function adjust()
|
||||
if not SHOULD_ADJUST then
|
||||
return
|
||||
end
|
||||
|
||||
local state = powerstate()
|
||||
-- this actually overrides automatically applied profiles
|
||||
-- like 'protocol.http'
|
||||
if state == 0 then
|
||||
mp.set_property("profile", lqprofile)
|
||||
mp.msg.info("[quality] running battery, setting low-quality options.")
|
||||
mp.osd_message("[quality] LQ")
|
||||
else
|
||||
mp.set_property("profile", hqprofile)
|
||||
mp.msg.info("[quality] running ac, setting high-quality options.")
|
||||
mp.osd_message("[quality] HQ")
|
||||
end
|
||||
end
|
||||
mp.add_hook("on_load", 1, adjust)
|
|
@ -1,83 +0,0 @@
|
|||
local mp = require("mp")
|
||||
require("mp.msg")
|
||||
|
||||
-- Copy the current time of the video to clipboard.
|
||||
|
||||
WINDOWS = 2
|
||||
UNIX = 3
|
||||
KEY_BIND = "y"
|
||||
|
||||
local function platform_type()
|
||||
local utils = require("mp.utils")
|
||||
local workdir = utils.to_string(mp.get_property_native("working-directory"))
|
||||
if string.find(workdir, "\\") then
|
||||
return WINDOWS
|
||||
else
|
||||
return UNIX
|
||||
end
|
||||
end
|
||||
|
||||
local function command_exists(cmd)
|
||||
local pipe = io.popen("type " .. cmd .. ' > /dev/null 2> /dev/null; printf "$?"', "r")
|
||||
if not pipe then
|
||||
return
|
||||
end
|
||||
local exists = pipe:read() == "0"
|
||||
pipe:close()
|
||||
return exists
|
||||
end
|
||||
|
||||
local function get_clipboard_cmd()
|
||||
if command_exists("xclip") then
|
||||
return "xclip -silent -in -selection clipboard"
|
||||
elseif command_exists("wl-copy") then
|
||||
return "wl-copy"
|
||||
elseif command_exists("pbcopy") then
|
||||
return "pbcopy"
|
||||
else
|
||||
mp.msg.error("No supported clipboard command found")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local function divmod(a, b)
|
||||
return a / b, a % b
|
||||
end
|
||||
|
||||
local function set_clipboard(text)
|
||||
if platform == WINDOWS then
|
||||
mp.commandv("run", "powershell", "set-clipboard", text)
|
||||
return true
|
||||
elseif platform == UNIX and clipboard_cmd then
|
||||
local pipe = io.popen(clipboard_cmd, "w")
|
||||
if not pipe then
|
||||
return
|
||||
end
|
||||
pipe:write(text)
|
||||
pipe:close()
|
||||
return true
|
||||
else
|
||||
mp.msg.error("Set_clipboard error")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local function copyTime()
|
||||
local time_pos = mp.get_property_number("time-pos")
|
||||
local minutes, remainder = divmod(time_pos, 60)
|
||||
local hours, minutes = divmod(minutes, 60)
|
||||
local seconds = math.floor(remainder)
|
||||
local milliseconds = math.floor((remainder - seconds) * 1000)
|
||||
local time = string.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, milliseconds)
|
||||
if set_clipboard(time) then
|
||||
mp.osd_message(string.format("[copytime] %s", time))
|
||||
else
|
||||
mp.osd_message("[copytime] failed")
|
||||
end
|
||||
end
|
||||
|
||||
platform = platform_type()
|
||||
if platform == UNIX then
|
||||
clipboard_cmd = get_clipboard_cmd()
|
||||
end
|
||||
mp.add_key_binding(KEY_BIND, "copyTime", copyTime)
|
|
@ -1,33 +0,0 @@
|
|||
-- gallery-dl_hook.lua
|
||||
--
|
||||
-- load online image galleries as playlists using gallery-dl
|
||||
-- https://github.com/mikf/gallery-dl
|
||||
--
|
||||
-- to use, prepend the gallery url with: gallery-dl://
|
||||
-- e.g.
|
||||
-- `mpv gallery-dl://https://imgur.com/....`
|
||||
|
||||
local mp = require("mp")
|
||||
local utils = require("mp.utils")
|
||||
local msg = require("mp.msg")
|
||||
|
||||
local function exec(args)
|
||||
local ret = utils.subprocess({ args = args })
|
||||
return ret.status, ret.stdout, ret
|
||||
end
|
||||
|
||||
mp.add_hook("on_load", 15, function()
|
||||
local fn = mp.get_property("stream-open-filename", "")
|
||||
if fn:find("gdl://") ~= 1 then
|
||||
msg.debug("not a gdl:// url: " .. fn)
|
||||
return
|
||||
end
|
||||
local url = string.gsub(url, "gdl://", "")
|
||||
|
||||
local es, urls, result = exec({ "gallery-dl", "-g", url })
|
||||
if (es < 0) or (urls == nil) or (urls == "") then
|
||||
msg.error("failed to get album list.")
|
||||
end
|
||||
|
||||
mp.commandv("loadlist", "memory://" .. urls)
|
||||
end)
|
File diff suppressed because it is too large
Load diff
|
@ -1,97 +0,0 @@
|
|||
-- sponsorblock_minimal.lua
|
||||
--
|
||||
-- This script skips sponsored segments of YouTube videos
|
||||
-- using data from https://github.com/ajayyy/SponsorBlock
|
||||
--
|
||||
-- original from https://codeberg.org/jouni/mpv_sponsorblock_minimal
|
||||
-- adapted for local playback skipping and some refactoring by me
|
||||
local mp = require("mp")
|
||||
|
||||
local options = {
|
||||
API = "https://sponsor.ajay.app/api/skipSegments",
|
||||
|
||||
-- Categories to fetch and skip
|
||||
categories = '"sponsor","intro","outro","interaction","selfpromo"',
|
||||
}
|
||||
|
||||
local function getranges()
|
||||
local args = {
|
||||
"curl",
|
||||
"-s",
|
||||
"-d",
|
||||
"videoID=" .. Youtube_id,
|
||||
"-d",
|
||||
"categories=[" .. options.categories .. "]",
|
||||
"-G",
|
||||
options.API,
|
||||
}
|
||||
local sponsors = mp.command_native({
|
||||
name = "subprocess",
|
||||
capture_stdout = true,
|
||||
playback_only = false,
|
||||
args = args,
|
||||
})
|
||||
|
||||
if string.match(sponsors.stdout, "%[(.-)%]") then
|
||||
Ranges = {}
|
||||
for i in string.gmatch(string.sub(sponsors.stdout, 2, -2), "%[(.-)%]") do
|
||||
local k, v = string.match(i, "(%d+.?%d*),(%d+.?%d*)")
|
||||
Ranges[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function skip_ads(_, pos)
|
||||
if pos ~= nil then
|
||||
for k, v in pairs(Ranges) do
|
||||
if tonumber(k) <= pos and tonumber(v) > pos then
|
||||
-- this message may sometimes be wrong
|
||||
-- it only seems to be a visual thing though
|
||||
mp.osd_message(
|
||||
"[sponsorblock] skipping forward " .. math.floor(tonumber(v) - mp.get_property("time-pos")) .. "s"
|
||||
)
|
||||
-- need to do the +0.01 otherwise mpv will start spamming skip sometimes
|
||||
-- example: https://www.youtube.com/watch?v=4ypMJzeNooo
|
||||
mp.set_property("time-pos", tonumber(v) + 0.01)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function file_loaded()
|
||||
local video_path = mp.get_property("path")
|
||||
local youtube_id1 = string.match(video_path, "https?://youtu%.be/([%w-_]+).*")
|
||||
local youtube_id2 = string.match(video_path, "https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*")
|
||||
local youtube_id3 = string.match(video_path, "/watch.*[?&]v=([%w-_]+).*")
|
||||
local youtube_id4 = string.match(video_path, "/embed/([%w-_]+).*")
|
||||
local localytfile = string.match(video_path, "-([%a%d%-_]+)%.[mw][kpe][v4b][m]?$")
|
||||
Youtube_id = youtube_id1 or youtube_id2 or youtube_id3 or youtube_id4 or localytfile
|
||||
if not Youtube_id or string.len(Youtube_id) < 11 then
|
||||
return
|
||||
end
|
||||
Youtube_id = string.sub(Youtube_id, 1, 11)
|
||||
|
||||
getranges()
|
||||
if Ranges then
|
||||
ON = true
|
||||
mp.add_key_binding("b", "sponsorblock", toggle)
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local function toggle()
|
||||
if ON then
|
||||
mp.unobserve_property(skip_ads)
|
||||
mp.osd_message("[sponsorblock] off")
|
||||
ON = false
|
||||
return
|
||||
end
|
||||
mp.observe_property("time-pos", "native", skip_ads)
|
||||
mp.osd_message("[sponsorblock] on")
|
||||
ON = true
|
||||
return
|
||||
end
|
||||
|
||||
mp.register_event("file-loaded", file_loaded)
|
|
@ -1,940 +0,0 @@
|
|||
-- thumbfast.lua
|
||||
--
|
||||
-- High-performance on-the-fly thumbnailer
|
||||
--
|
||||
-- Built for easy integration in third-party UIs.
|
||||
|
||||
--[[
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
]]
|
||||
|
||||
local options = {
|
||||
-- Socket path (leave empty for auto)
|
||||
socket = "",
|
||||
|
||||
-- Thumbnail path (leave empty for auto)
|
||||
thumbnail = "",
|
||||
|
||||
-- Maximum thumbnail generation size in pixels (scaled down to fit)
|
||||
-- Values are scaled when hidpi is enabled
|
||||
max_height = 200,
|
||||
max_width = 200,
|
||||
|
||||
-- Scale factor for thumbnail display size (requires mpv 0.38+)
|
||||
-- Note that this is lower quality than increasing max_height and max_width
|
||||
scale_factor = 1,
|
||||
|
||||
-- Apply tone-mapping, no to disable
|
||||
tone_mapping = "auto",
|
||||
|
||||
-- Overlay id
|
||||
overlay_id = 42,
|
||||
|
||||
-- Spawn thumbnailer on file load for faster initial thumbnails
|
||||
spawn_first = false,
|
||||
|
||||
-- Close thumbnailer process after an inactivity period in seconds, 0 to disable
|
||||
quit_after_inactivity = 0,
|
||||
|
||||
-- Enable on network playback
|
||||
network = false,
|
||||
|
||||
-- Enable on audio playback
|
||||
audio = false,
|
||||
|
||||
-- Enable hardware decoding
|
||||
hwdec = false,
|
||||
|
||||
-- Windows only: use native Windows API to write to pipe (requires LuaJIT)
|
||||
direct_io = false,
|
||||
|
||||
-- Custom path to the mpv executable
|
||||
mpv_path = "mpv"
|
||||
}
|
||||
|
||||
mp.utils = require "mp.utils"
|
||||
mp.options = require "mp.options"
|
||||
mp.options.read_options(options, "thumbfast")
|
||||
|
||||
local properties = {}
|
||||
local pre_0_30_0 = mp.command_native_async == nil
|
||||
local pre_0_33_0 = true
|
||||
|
||||
function subprocess(args, async, callback)
|
||||
callback = callback or function() end
|
||||
|
||||
if not pre_0_30_0 then
|
||||
if async then
|
||||
return mp.command_native_async({name = "subprocess", playback_only = true, args = args}, callback)
|
||||
else
|
||||
return mp.command_native({name = "subprocess", playback_only = false, capture_stdout = true, args = args})
|
||||
end
|
||||
else
|
||||
if async then
|
||||
return mp.utils.subprocess_detached({args = args}, callback)
|
||||
else
|
||||
return mp.utils.subprocess({args = args})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local winapi = {}
|
||||
if options.direct_io then
|
||||
local ffi_loaded, ffi = pcall(require, "ffi")
|
||||
if ffi_loaded then
|
||||
winapi = {
|
||||
ffi = ffi,
|
||||
C = ffi.C,
|
||||
bit = require("bit"),
|
||||
socket_wc = "",
|
||||
|
||||
-- WinAPI constants
|
||||
CP_UTF8 = 65001,
|
||||
GENERIC_WRITE = 0x40000000,
|
||||
OPEN_EXISTING = 3,
|
||||
FILE_FLAG_WRITE_THROUGH = 0x80000000,
|
||||
FILE_FLAG_NO_BUFFERING = 0x20000000,
|
||||
PIPE_NOWAIT = ffi.new("unsigned long[1]", 0x00000001),
|
||||
|
||||
INVALID_HANDLE_VALUE = ffi.cast("void*", -1),
|
||||
|
||||
-- don't care about how many bytes WriteFile wrote, so allocate something to store the result once
|
||||
_lpNumberOfBytesWritten = ffi.new("unsigned long[1]"),
|
||||
}
|
||||
-- cache flags used in run() to avoid bor() call
|
||||
winapi._createfile_pipe_flags = winapi.bit.bor(winapi.FILE_FLAG_WRITE_THROUGH, winapi.FILE_FLAG_NO_BUFFERING)
|
||||
|
||||
ffi.cdef[[
|
||||
void* __stdcall CreateFileW(const wchar_t *lpFileName, unsigned long dwDesiredAccess, unsigned long dwShareMode, void *lpSecurityAttributes, unsigned long dwCreationDisposition, unsigned long dwFlagsAndAttributes, void *hTemplateFile);
|
||||
bool __stdcall WriteFile(void *hFile, const void *lpBuffer, unsigned long nNumberOfBytesToWrite, unsigned long *lpNumberOfBytesWritten, void *lpOverlapped);
|
||||
bool __stdcall CloseHandle(void *hObject);
|
||||
bool __stdcall SetNamedPipeHandleState(void *hNamedPipe, unsigned long *lpMode, unsigned long *lpMaxCollectionCount, unsigned long *lpCollectDataTimeout);
|
||||
int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
|
||||
]]
|
||||
|
||||
winapi.MultiByteToWideChar = function(MultiByteStr)
|
||||
if MultiByteStr then
|
||||
local utf16_len = winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, MultiByteStr, -1, nil, 0)
|
||||
if utf16_len > 0 then
|
||||
local utf16_str = winapi.ffi.new("wchar_t[?]", utf16_len)
|
||||
if winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, MultiByteStr, -1, utf16_str, utf16_len) > 0 then
|
||||
return utf16_str
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
else
|
||||
options.direct_io = false
|
||||
end
|
||||
end
|
||||
|
||||
local file
|
||||
local file_bytes = 0
|
||||
local spawned = false
|
||||
local disabled = false
|
||||
local force_disabled = false
|
||||
local spawn_waiting = false
|
||||
local spawn_working = false
|
||||
local script_written = false
|
||||
|
||||
local dirty = false
|
||||
|
||||
local x, y
|
||||
local last_x, last_y
|
||||
|
||||
local last_seek_time
|
||||
|
||||
local effective_w, effective_h = options.max_width, options.max_height
|
||||
local real_w, real_h
|
||||
local last_real_w, last_real_h
|
||||
|
||||
local script_name
|
||||
|
||||
local show_thumbnail = false
|
||||
|
||||
local filters_reset = {["lavfi-crop"]=true, ["crop"]=true}
|
||||
local filters_runtime = {["hflip"]=true, ["vflip"]=true}
|
||||
local filters_all = {["hflip"]=true, ["vflip"]=true, ["lavfi-crop"]=true, ["crop"]=true}
|
||||
|
||||
local tone_mappings = {["none"]=true, ["clip"]=true, ["linear"]=true, ["gamma"]=true, ["reinhard"]=true, ["hable"]=true, ["mobius"]=true}
|
||||
local last_tone_mapping
|
||||
|
||||
local last_vf_reset = ""
|
||||
local last_vf_runtime = ""
|
||||
|
||||
local last_rotate = 0
|
||||
|
||||
local par = ""
|
||||
local last_par = ""
|
||||
|
||||
local last_crop = nil
|
||||
|
||||
local last_has_vid = 0
|
||||
local has_vid = 0
|
||||
|
||||
local file_timer
|
||||
local file_check_period = 1/60
|
||||
|
||||
local allow_fast_seek = true
|
||||
|
||||
local client_script = [=[
|
||||
#!/usr/bin/env bash
|
||||
MPV_IPC_FD=0; MPV_IPC_PATH="%s"
|
||||
trap "kill 0" EXIT
|
||||
while [[ $# -ne 0 ]]; do case $1 in --mpv-ipc-fd=*) MPV_IPC_FD=${1/--mpv-ipc-fd=/} ;; esac; shift; done
|
||||
if echo "print-text thumbfast" >&"$MPV_IPC_FD"; then echo -n > "$MPV_IPC_PATH"; tail -f "$MPV_IPC_PATH" >&"$MPV_IPC_FD" & while read -r -u "$MPV_IPC_FD" 2>/dev/null; do :; done; fi
|
||||
]=]
|
||||
|
||||
local function get_os()
|
||||
local raw_os_name = ""
|
||||
|
||||
if jit and jit.os and jit.arch then
|
||||
raw_os_name = jit.os
|
||||
else
|
||||
if package.config:sub(1,1) == "\\" then
|
||||
-- Windows
|
||||
local env_OS = os.getenv("OS")
|
||||
if env_OS then
|
||||
raw_os_name = env_OS
|
||||
end
|
||||
else
|
||||
raw_os_name = subprocess({"uname", "-s"}).stdout
|
||||
end
|
||||
end
|
||||
|
||||
raw_os_name = (raw_os_name):lower()
|
||||
|
||||
local os_patterns = {
|
||||
["windows"] = "windows",
|
||||
["linux"] = "linux",
|
||||
|
||||
["osx"] = "darwin",
|
||||
["mac"] = "darwin",
|
||||
["darwin"] = "darwin",
|
||||
|
||||
["^mingw"] = "windows",
|
||||
["^cygwin"] = "windows",
|
||||
|
||||
["bsd$"] = "darwin",
|
||||
["sunos"] = "darwin"
|
||||
}
|
||||
|
||||
-- Default to linux
|
||||
local str_os_name = "linux"
|
||||
|
||||
for pattern, name in pairs(os_patterns) do
|
||||
if raw_os_name:match(pattern) then
|
||||
str_os_name = name
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return str_os_name
|
||||
end
|
||||
|
||||
local os_name = mp.get_property("platform") or get_os()
|
||||
|
||||
local path_separator = os_name == "windows" and "\\" or "/"
|
||||
|
||||
if options.socket == "" then
|
||||
if os_name == "windows" then
|
||||
options.socket = "thumbfast"
|
||||
else
|
||||
options.socket = "/tmp/thumbfast"
|
||||
end
|
||||
end
|
||||
|
||||
if options.thumbnail == "" then
|
||||
if os_name == "windows" then
|
||||
options.thumbnail = os.getenv("TEMP").."\\thumbfast.out"
|
||||
else
|
||||
options.thumbnail = "/tmp/thumbfast.out"
|
||||
end
|
||||
end
|
||||
|
||||
local unique = mp.utils.getpid()
|
||||
|
||||
options.socket = options.socket .. unique
|
||||
options.thumbnail = options.thumbnail .. unique
|
||||
|
||||
if options.direct_io then
|
||||
if os_name == "windows" then
|
||||
winapi.socket_wc = winapi.MultiByteToWideChar("\\\\.\\pipe\\" .. options.socket)
|
||||
end
|
||||
|
||||
if winapi.socket_wc == "" then
|
||||
options.direct_io = false
|
||||
end
|
||||
end
|
||||
|
||||
options.scale_factor = math.floor(options.scale_factor)
|
||||
|
||||
local mpv_path = options.mpv_path
|
||||
|
||||
if mpv_path == "mpv" and os_name == "darwin" and unique then
|
||||
-- TODO: look into ~~osxbundle/
|
||||
mpv_path = string.gsub(subprocess({"ps", "-o", "comm=", "-p", tostring(unique)}).stdout, "[\n\r]", "")
|
||||
if mpv_path ~= "mpv" then
|
||||
mpv_path = string.gsub(mpv_path, "/mpv%-bundle$", "/mpv")
|
||||
local mpv_bin = mp.utils.file_info("/usr/local/mpv")
|
||||
if mpv_bin and mpv_bin.is_file then
|
||||
mpv_path = "/usr/local/mpv"
|
||||
else
|
||||
local mpv_app = mp.utils.file_info("/Applications/mpv.app/Contents/MacOS/mpv")
|
||||
if mpv_app and mpv_app.is_file then
|
||||
mp.msg.warn("symlink mpv to fix Dock icons: `sudo ln -s /Applications/mpv.app/Contents/MacOS/mpv /usr/local/mpv`")
|
||||
else
|
||||
mp.msg.warn("drag to your Applications folder and symlink mpv to fix Dock icons: `sudo ln -s /Applications/mpv.app/Contents/MacOS/mpv /usr/local/mpv`")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function vo_tone_mapping()
|
||||
local passes = mp.get_property_native("vo-passes")
|
||||
if passes and passes["fresh"] then
|
||||
for k, v in pairs(passes["fresh"]) do
|
||||
for k2, v2 in pairs(v) do
|
||||
if k2 == "desc" and v2 then
|
||||
local tone_mapping = string.match(v2, "([0-9a-z.-]+) tone map")
|
||||
if tone_mapping then
|
||||
return tone_mapping
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function vf_string(filters, full)
|
||||
local vf = ""
|
||||
local vf_table = properties["vf"]
|
||||
|
||||
if (properties["video-crop"] or "") ~= "" then
|
||||
vf = "lavfi-crop="..string.gsub(properties["video-crop"], "(%d*)x?(%d*)%+(%d+)%+(%d+)", "w=%1:h=%2:x=%3:y=%4")..","
|
||||
local width = properties["video-out-params"] and properties["video-out-params"]["dw"]
|
||||
local height = properties["video-out-params"] and properties["video-out-params"]["dh"]
|
||||
if width and height then
|
||||
vf = string.gsub(vf, "w=:h=:", "w="..width..":h="..height..":")
|
||||
end
|
||||
end
|
||||
|
||||
if vf_table and #vf_table > 0 then
|
||||
for i = #vf_table, 1, -1 do
|
||||
if filters[vf_table[i].name] then
|
||||
local args = ""
|
||||
for key, value in pairs(vf_table[i].params) do
|
||||
if args ~= "" then
|
||||
args = args .. ":"
|
||||
end
|
||||
args = args .. key .. "=" .. value
|
||||
end
|
||||
vf = vf .. vf_table[i].name .. "=" .. args .. ","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (full and options.tone_mapping ~= "no") or options.tone_mapping == "auto" then
|
||||
if properties["video-params"] and properties["video-params"]["primaries"] == "bt.2020" then
|
||||
local tone_mapping = options.tone_mapping
|
||||
if tone_mapping == "auto" then
|
||||
tone_mapping = last_tone_mapping or properties["tone-mapping"]
|
||||
if tone_mapping == "auto" and properties["current-vo"] == "gpu-next" then
|
||||
tone_mapping = vo_tone_mapping()
|
||||
end
|
||||
end
|
||||
if not tone_mappings[tone_mapping] then
|
||||
tone_mapping = "hable"
|
||||
end
|
||||
last_tone_mapping = tone_mapping
|
||||
vf = vf .. "zscale=transfer=linear,format=gbrpf32le,tonemap="..tone_mapping..",zscale=transfer=bt709,"
|
||||
end
|
||||
end
|
||||
|
||||
if full then
|
||||
vf = vf.."scale=w="..effective_w..":h="..effective_h..par..",pad=w="..effective_w..":h="..effective_h..":x=-1:y=-1,format=bgra"
|
||||
end
|
||||
|
||||
return vf
|
||||
end
|
||||
|
||||
local function calc_dimensions()
|
||||
local width = properties["video-out-params"] and properties["video-out-params"]["dw"]
|
||||
local height = properties["video-out-params"] and properties["video-out-params"]["dh"]
|
||||
if not width or not height then return end
|
||||
|
||||
local scale = properties["display-hidpi-scale"] or 1
|
||||
|
||||
if width / height > options.max_width / options.max_height then
|
||||
effective_w = math.floor(options.max_width * scale + 0.5)
|
||||
effective_h = math.floor(height / width * effective_w + 0.5)
|
||||
else
|
||||
effective_h = math.floor(options.max_height * scale + 0.5)
|
||||
effective_w = math.floor(width / height * effective_h + 0.5)
|
||||
end
|
||||
|
||||
local v_par = properties["video-out-params"] and properties["video-out-params"]["par"] or 1
|
||||
if v_par == 1 then
|
||||
par = ":force_original_aspect_ratio=decrease"
|
||||
else
|
||||
par = ""
|
||||
end
|
||||
end
|
||||
|
||||
local info_timer = nil
|
||||
|
||||
local function info(w, h)
|
||||
local rotate = properties["video-params"] and properties["video-params"]["rotate"]
|
||||
local image = properties["current-tracks/video"] and properties["current-tracks/video"]["image"]
|
||||
local albumart = image and properties["current-tracks/video"]["albumart"]
|
||||
|
||||
disabled = (w or 0) == 0 or (h or 0) == 0 or
|
||||
has_vid == 0 or
|
||||
(properties["demuxer-via-network"] and not options.network) or
|
||||
(albumart and not options.audio) or
|
||||
(image and not albumart) or
|
||||
force_disabled
|
||||
|
||||
if info_timer then
|
||||
info_timer:kill()
|
||||
info_timer = nil
|
||||
elseif has_vid == 0 or (rotate == nil and not disabled) then
|
||||
info_timer = mp.add_timeout(0.05, function() info(w, h) end)
|
||||
end
|
||||
|
||||
local json, err = mp.utils.format_json({width=w * options.scale_factor, height=h * options.scale_factor, scale_factor=options.scale_factor, disabled=disabled, available=true, socket=options.socket, thumbnail=options.thumbnail, overlay_id=options.overlay_id})
|
||||
if pre_0_30_0 then
|
||||
mp.command_native({"script-message", "thumbfast-info", json})
|
||||
else
|
||||
mp.command_native_async({"script-message", "thumbfast-info", json}, function() end)
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_thumbnail_files()
|
||||
if file then
|
||||
file:close()
|
||||
file = nil
|
||||
file_bytes = 0
|
||||
end
|
||||
os.remove(options.thumbnail)
|
||||
os.remove(options.thumbnail..".bgra")
|
||||
end
|
||||
|
||||
local activity_timer
|
||||
|
||||
local function spawn(time)
|
||||
if disabled then return end
|
||||
|
||||
local path = properties["path"]
|
||||
if path == nil then return end
|
||||
|
||||
if options.quit_after_inactivity > 0 then
|
||||
if show_thumbnail or activity_timer:is_enabled() then
|
||||
activity_timer:kill()
|
||||
end
|
||||
activity_timer:resume()
|
||||
end
|
||||
|
||||
local open_filename = properties["stream-open-filename"]
|
||||
local ytdl = open_filename and properties["demuxer-via-network"] and path ~= open_filename
|
||||
if ytdl then
|
||||
path = open_filename
|
||||
end
|
||||
|
||||
remove_thumbnail_files()
|
||||
|
||||
local vid = properties["vid"]
|
||||
has_vid = vid or 0
|
||||
|
||||
local args = {
|
||||
mpv_path, "--no-config", "--msg-level=all=no", "--idle", "--pause", "--keep-open=always", "--really-quiet", "--no-terminal",
|
||||
"--load-scripts=no", "--osc=no", "--ytdl=no", "--load-stats-overlay=no", "--load-osd-console=no", "--load-auto-profiles=no",
|
||||
"--edition="..(properties["edition"] or "auto"), "--vid="..(vid or "auto"), "--no-sub", "--no-audio",
|
||||
"--start="..time, allow_fast_seek and "--hr-seek=no" or "--hr-seek=yes",
|
||||
"--ytdl-format=worst", "--demuxer-readahead-secs=0", "--demuxer-max-bytes=128KiB",
|
||||
"--vd-lavc-skiploopfilter=all", "--vd-lavc-software-fallback=1", "--vd-lavc-fast", "--vd-lavc-threads=2", "--hwdec="..(options.hwdec and "auto" or "no"),
|
||||
"--vf="..vf_string(filters_all, true),
|
||||
"--sws-scaler=fast-bilinear",
|
||||
"--video-rotate="..last_rotate,
|
||||
"--ovc=rawvideo", "--of=image2", "--ofopts=update=1", "--o="..options.thumbnail
|
||||
}
|
||||
|
||||
if not pre_0_30_0 then
|
||||
table.insert(args, "--sws-allow-zimg=no")
|
||||
end
|
||||
|
||||
if os_name == "darwin" and properties["macos-app-activation-policy"] then
|
||||
table.insert(args, "--macos-app-activation-policy=accessory")
|
||||
end
|
||||
|
||||
if os_name == "windows" or pre_0_33_0 then
|
||||
table.insert(args, "--input-ipc-server="..options.socket)
|
||||
elseif not script_written then
|
||||
local client_script_path = options.socket..".run"
|
||||
local script = io.open(client_script_path, "w+")
|
||||
if script == nil then
|
||||
mp.msg.error("client script write failed")
|
||||
return
|
||||
else
|
||||
script_written = true
|
||||
script:write(string.format(client_script, options.socket))
|
||||
script:close()
|
||||
subprocess({"chmod", "+x", client_script_path}, true)
|
||||
table.insert(args, "--scripts="..client_script_path)
|
||||
end
|
||||
else
|
||||
local client_script_path = options.socket..".run"
|
||||
table.insert(args, "--scripts="..client_script_path)
|
||||
end
|
||||
|
||||
table.insert(args, "--")
|
||||
table.insert(args, path)
|
||||
|
||||
spawned = true
|
||||
spawn_waiting = true
|
||||
|
||||
subprocess(args, true,
|
||||
function(success, result)
|
||||
if spawn_waiting and (success == false or (result.status ~= 0 and result.status ~= -2)) then
|
||||
spawned = false
|
||||
spawn_waiting = false
|
||||
options.tone_mapping = "no"
|
||||
mp.msg.error("mpv subprocess create failed")
|
||||
if not spawn_working then -- notify users of required configuration
|
||||
if options.mpv_path == "mpv" then
|
||||
if properties["current-vo"] == "libmpv" then
|
||||
if options.mpv_path == mpv_path then -- attempt to locate ImPlay
|
||||
mpv_path = "ImPlay"
|
||||
spawn(time)
|
||||
else -- ImPlay not in path
|
||||
if os_name ~= "darwin" then
|
||||
force_disabled = true
|
||||
info(real_w or effective_w, real_h or effective_h)
|
||||
end
|
||||
mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
|
||||
mp.commandv("script-message-to", "implay", "show-message", "thumbfast initial setup", "Set mpv_path=PATH_TO_ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
|
||||
end
|
||||
else
|
||||
mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
|
||||
if os_name == "windows" then
|
||||
mp.commandv("script-message-to", "mpvnet", "show-text", "thumbfast: ERROR! install standalone mpv, see README", 5000, 20)
|
||||
mp.commandv("script-message", "mpv.net", "show-text", "thumbfast: ERROR! install standalone mpv, see README", 5000, 20)
|
||||
end
|
||||
end
|
||||
else
|
||||
mp.commandv("show-text", "thumbfast: ERROR! cannot create mpv subprocess", 5000)
|
||||
-- found ImPlay but not defined in config
|
||||
mp.commandv("script-message-to", "implay", "show-message", "thumbfast", "Set mpv_path=PATH_TO_ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
|
||||
end
|
||||
end
|
||||
elseif success == true and (result.status == 0 or result.status == -2) then
|
||||
if not spawn_working and properties["current-vo"] == "libmpv" and options.mpv_path ~= mpv_path then
|
||||
mp.commandv("script-message-to", "implay", "show-message", "thumbfast initial setup", "Set mpv_path=ImPlay in thumbfast config:\n" .. string.gsub(mp.command_native({"expand-path", "~~/script-opts/thumbfast.conf"}), "[/\\]", path_separator).."\nand restart ImPlay")
|
||||
end
|
||||
spawn_working = true
|
||||
spawn_waiting = false
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function run(command)
|
||||
if not spawned then return end
|
||||
|
||||
if options.direct_io then
|
||||
local hPipe = winapi.C.CreateFileW(winapi.socket_wc, winapi.GENERIC_WRITE, 0, nil, winapi.OPEN_EXISTING, winapi._createfile_pipe_flags, nil)
|
||||
if hPipe ~= winapi.INVALID_HANDLE_VALUE then
|
||||
local buf = command .. "\n"
|
||||
winapi.C.SetNamedPipeHandleState(hPipe, winapi.PIPE_NOWAIT, nil, nil)
|
||||
winapi.C.WriteFile(hPipe, buf, #buf + 1, winapi._lpNumberOfBytesWritten, nil)
|
||||
winapi.C.CloseHandle(hPipe)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
local command_n = command.."\n"
|
||||
|
||||
if os_name == "windows" then
|
||||
if file and file_bytes + #command_n >= 4096 then
|
||||
file:close()
|
||||
file = nil
|
||||
file_bytes = 0
|
||||
end
|
||||
if not file then
|
||||
file = io.open("\\\\.\\pipe\\"..options.socket, "r+b")
|
||||
end
|
||||
elseif pre_0_33_0 then
|
||||
subprocess({"/usr/bin/env", "sh", "-c", "echo '" .. command .. "' | socat - " .. options.socket})
|
||||
return
|
||||
elseif not file then
|
||||
file = io.open(options.socket, "r+")
|
||||
end
|
||||
if file then
|
||||
file_bytes = file:seek("end")
|
||||
file:write(command_n)
|
||||
file:flush()
|
||||
end
|
||||
end
|
||||
|
||||
local function draw(w, h, script)
|
||||
if not w or not show_thumbnail then return end
|
||||
if x ~= nil then
|
||||
local scale_w, scale_h = options.scale_factor ~= 1 and (w * options.scale_factor) or nil, options.scale_factor ~= 1 and (h * options.scale_factor) or nil
|
||||
if pre_0_30_0 then
|
||||
mp.command_native({"overlay-add", options.overlay_id, x, y, options.thumbnail..".bgra", 0, "bgra", w, h, (4*w), scale_w, scale_h})
|
||||
else
|
||||
mp.command_native_async({"overlay-add", options.overlay_id, x, y, options.thumbnail..".bgra", 0, "bgra", w, h, (4*w), scale_w, scale_h}, function() end)
|
||||
end
|
||||
elseif script then
|
||||
local json, err = mp.utils.format_json({width=w, height=h, scale_factor=options.scale_factor, x=x, y=y, socket=options.socket, thumbnail=options.thumbnail, overlay_id=options.overlay_id})
|
||||
mp.commandv("script-message-to", script, "thumbfast-render", json)
|
||||
end
|
||||
end
|
||||
|
||||
local function real_res(req_w, req_h, filesize)
|
||||
local count = filesize / 4
|
||||
local diff = (req_w * req_h) - count
|
||||
|
||||
if (properties["video-params"] and properties["video-params"]["rotate"] or 0) % 180 == 90 then
|
||||
req_w, req_h = req_h, req_w
|
||||
end
|
||||
|
||||
if diff == 0 then
|
||||
return req_w, req_h
|
||||
else
|
||||
local threshold = 5 -- throw out results that change too much
|
||||
local long_side, short_side = req_w, req_h
|
||||
if req_h > req_w then
|
||||
long_side, short_side = req_h, req_w
|
||||
end
|
||||
for a = short_side, short_side - threshold, -1 do
|
||||
if count % a == 0 then
|
||||
local b = count / a
|
||||
if long_side - b < threshold then
|
||||
if req_h < req_w then return b, a else return a, b end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function move_file(from, to)
|
||||
if os_name == "windows" then
|
||||
os.remove(to)
|
||||
end
|
||||
-- move the file because it can get overwritten while overlay-add is reading it, and crash the player
|
||||
os.rename(from, to)
|
||||
end
|
||||
|
||||
local function seek(fast)
|
||||
if last_seek_time then
|
||||
run("async seek " .. last_seek_time .. (fast and " absolute+keyframes" or " absolute+exact"))
|
||||
end
|
||||
end
|
||||
|
||||
local seek_period = 3/60
|
||||
local seek_period_counter = 0
|
||||
local seek_timer
|
||||
seek_timer = mp.add_periodic_timer(seek_period, function()
|
||||
if seek_period_counter == 0 then
|
||||
seek(allow_fast_seek)
|
||||
seek_period_counter = 1
|
||||
else
|
||||
if seek_period_counter == 2 then
|
||||
if allow_fast_seek then
|
||||
seek_timer:kill()
|
||||
seek()
|
||||
end
|
||||
else seek_period_counter = seek_period_counter + 1 end
|
||||
end
|
||||
end)
|
||||
seek_timer:kill()
|
||||
|
||||
local function request_seek()
|
||||
if seek_timer:is_enabled() then
|
||||
seek_period_counter = 0
|
||||
else
|
||||
seek_timer:resume()
|
||||
seek(allow_fast_seek)
|
||||
seek_period_counter = 1
|
||||
end
|
||||
end
|
||||
|
||||
local function check_new_thumb()
|
||||
-- the slave might start writing to the file after checking existance and
|
||||
-- validity but before actually moving the file, so move to a temporary
|
||||
-- location before validity check to make sure everything stays consistant
|
||||
-- and valid thumbnails don't get overwritten by invalid ones
|
||||
local tmp = options.thumbnail..".tmp"
|
||||
move_file(options.thumbnail, tmp)
|
||||
local finfo = mp.utils.file_info(tmp)
|
||||
if not finfo then return false end
|
||||
spawn_waiting = false
|
||||
local w, h = real_res(effective_w, effective_h, finfo.size)
|
||||
if w then -- only accept valid thumbnails
|
||||
move_file(tmp, options.thumbnail..".bgra")
|
||||
|
||||
real_w, real_h = w, h
|
||||
if real_w and (real_w ~= last_real_w or real_h ~= last_real_h) then
|
||||
last_real_w, last_real_h = real_w, real_h
|
||||
info(real_w, real_h)
|
||||
end
|
||||
if not show_thumbnail then
|
||||
file_timer:kill()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
file_timer = mp.add_periodic_timer(file_check_period, function()
|
||||
if check_new_thumb() then
|
||||
draw(real_w, real_h, script_name)
|
||||
end
|
||||
end)
|
||||
file_timer:kill()
|
||||
|
||||
local function clear()
|
||||
file_timer:kill()
|
||||
seek_timer:kill()
|
||||
if options.quit_after_inactivity > 0 then
|
||||
if show_thumbnail or activity_timer:is_enabled() then
|
||||
activity_timer:kill()
|
||||
end
|
||||
activity_timer:resume()
|
||||
end
|
||||
last_seek_time = nil
|
||||
show_thumbnail = false
|
||||
last_x = nil
|
||||
last_y = nil
|
||||
if script_name then return end
|
||||
if pre_0_30_0 then
|
||||
mp.command_native({"overlay-remove", options.overlay_id})
|
||||
else
|
||||
mp.command_native_async({"overlay-remove", options.overlay_id}, function() end)
|
||||
end
|
||||
end
|
||||
|
||||
local function quit()
|
||||
activity_timer:kill()
|
||||
if show_thumbnail then
|
||||
activity_timer:resume()
|
||||
return
|
||||
end
|
||||
run("quit")
|
||||
spawned = false
|
||||
real_w, real_h = nil, nil
|
||||
clear()
|
||||
end
|
||||
|
||||
activity_timer = mp.add_timeout(options.quit_after_inactivity, quit)
|
||||
activity_timer:kill()
|
||||
|
||||
local function thumb(time, r_x, r_y, script)
|
||||
if disabled then return end
|
||||
|
||||
time = tonumber(time)
|
||||
if time == nil then return end
|
||||
|
||||
if r_x == "" or r_y == "" then
|
||||
x, y = nil, nil
|
||||
else
|
||||
x, y = math.floor(r_x + 0.5), math.floor(r_y + 0.5)
|
||||
end
|
||||
|
||||
script_name = script
|
||||
if last_x ~= x or last_y ~= y or not show_thumbnail then
|
||||
show_thumbnail = true
|
||||
last_x, last_y = x, y
|
||||
draw(real_w, real_h, script)
|
||||
end
|
||||
|
||||
if options.quit_after_inactivity > 0 then
|
||||
if show_thumbnail or activity_timer:is_enabled() then
|
||||
activity_timer:kill()
|
||||
end
|
||||
activity_timer:resume()
|
||||
end
|
||||
|
||||
if time == last_seek_time then return end
|
||||
last_seek_time = time
|
||||
if not spawned then spawn(time) end
|
||||
request_seek()
|
||||
if not file_timer:is_enabled() then file_timer:resume() end
|
||||
end
|
||||
|
||||
local function watch_changes()
|
||||
if not dirty or not properties["video-out-params"] then return end
|
||||
dirty = false
|
||||
|
||||
local old_w = effective_w
|
||||
local old_h = effective_h
|
||||
|
||||
calc_dimensions()
|
||||
|
||||
local vf_reset = vf_string(filters_reset)
|
||||
local rotate = properties["video-rotate"] or 0
|
||||
|
||||
local resized = old_w ~= effective_w or
|
||||
old_h ~= effective_h or
|
||||
last_vf_reset ~= vf_reset or
|
||||
(last_rotate % 180) ~= (rotate % 180) or
|
||||
par ~= last_par or last_crop ~= properties["video-crop"]
|
||||
|
||||
if resized then
|
||||
last_rotate = rotate
|
||||
info(effective_w, effective_h)
|
||||
elseif last_has_vid ~= has_vid and has_vid ~= 0 then
|
||||
info(effective_w, effective_h)
|
||||
end
|
||||
|
||||
if spawned then
|
||||
if resized then
|
||||
-- mpv doesn't allow us to change output size
|
||||
local seek_time = last_seek_time
|
||||
run("quit")
|
||||
clear()
|
||||
spawned = false
|
||||
spawn(seek_time or mp.get_property_number("time-pos", 0))
|
||||
file_timer:resume()
|
||||
else
|
||||
if rotate ~= last_rotate then
|
||||
run("set video-rotate "..rotate)
|
||||
end
|
||||
local vf_runtime = vf_string(filters_runtime)
|
||||
if vf_runtime ~= last_vf_runtime then
|
||||
run("vf set "..vf_string(filters_all, true))
|
||||
last_vf_runtime = vf_runtime
|
||||
end
|
||||
end
|
||||
else
|
||||
last_vf_runtime = vf_string(filters_runtime)
|
||||
end
|
||||
|
||||
last_vf_reset = vf_reset
|
||||
last_rotate = rotate
|
||||
last_par = par
|
||||
last_crop = properties["video-crop"]
|
||||
last_has_vid = has_vid
|
||||
|
||||
if not spawned and not disabled and options.spawn_first and resized then
|
||||
spawn(mp.get_property_number("time-pos", 0))
|
||||
file_timer:resume()
|
||||
end
|
||||
end
|
||||
|
||||
local function update_property(name, value)
|
||||
properties[name] = value
|
||||
end
|
||||
|
||||
local function update_property_dirty(name, value)
|
||||
properties[name] = value
|
||||
dirty = true
|
||||
if name == "tone-mapping" then
|
||||
last_tone_mapping = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function update_tracklist(name, value)
|
||||
-- current-tracks shim
|
||||
for _, track in ipairs(value) do
|
||||
if track.type == "video" and track.selected then
|
||||
properties["current-tracks/video"] = track
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function sync_changes(prop, val)
|
||||
update_property(prop, val)
|
||||
if val == nil then return end
|
||||
|
||||
if type(val) == "boolean" then
|
||||
if prop == "vid" then
|
||||
has_vid = 0
|
||||
last_has_vid = 0
|
||||
info(effective_w, effective_h)
|
||||
clear()
|
||||
return
|
||||
end
|
||||
val = val and "yes" or "no"
|
||||
end
|
||||
|
||||
if prop == "vid" then
|
||||
has_vid = 1
|
||||
end
|
||||
|
||||
if not spawned then return end
|
||||
|
||||
run("set "..prop.." "..val)
|
||||
dirty = true
|
||||
end
|
||||
|
||||
local function file_load()
|
||||
clear()
|
||||
spawned = false
|
||||
real_w, real_h = nil, nil
|
||||
last_real_w, last_real_h = nil, nil
|
||||
last_tone_mapping = nil
|
||||
last_seek_time = nil
|
||||
if info_timer then
|
||||
info_timer:kill()
|
||||
info_timer = nil
|
||||
end
|
||||
|
||||
calc_dimensions()
|
||||
info(effective_w, effective_h)
|
||||
end
|
||||
|
||||
local function shutdown()
|
||||
run("quit")
|
||||
remove_thumbnail_files()
|
||||
if os_name ~= "windows" then
|
||||
os.remove(options.socket)
|
||||
os.remove(options.socket..".run")
|
||||
end
|
||||
end
|
||||
|
||||
local function on_duration(prop, val)
|
||||
allow_fast_seek = (val or 30) >= 30
|
||||
end
|
||||
|
||||
mp.observe_property("current-tracks/video", "native", function(name, value)
|
||||
if pre_0_33_0 then
|
||||
mp.unobserve_property(update_tracklist)
|
||||
pre_0_33_0 = false
|
||||
end
|
||||
update_property(name, value)
|
||||
end)
|
||||
|
||||
mp.observe_property("track-list", "native", update_tracklist)
|
||||
mp.observe_property("display-hidpi-scale", "native", update_property_dirty)
|
||||
mp.observe_property("video-out-params", "native", update_property_dirty)
|
||||
mp.observe_property("video-params", "native", update_property_dirty)
|
||||
mp.observe_property("vf", "native", update_property_dirty)
|
||||
mp.observe_property("tone-mapping", "native", update_property_dirty)
|
||||
mp.observe_property("demuxer-via-network", "native", update_property)
|
||||
mp.observe_property("stream-open-filename", "native", update_property)
|
||||
mp.observe_property("macos-app-activation-policy", "native", update_property)
|
||||
mp.observe_property("current-vo", "native", update_property)
|
||||
mp.observe_property("video-rotate", "native", update_property)
|
||||
mp.observe_property("video-crop", "native", update_property)
|
||||
mp.observe_property("path", "native", update_property)
|
||||
mp.observe_property("vid", "native", sync_changes)
|
||||
mp.observe_property("edition", "native", sync_changes)
|
||||
mp.observe_property("duration", "native", on_duration)
|
||||
|
||||
mp.register_script_message("thumb", thumb)
|
||||
mp.register_script_message("clear", clear)
|
||||
|
||||
mp.register_event("file-loaded", file_load)
|
||||
mp.register_event("shutdown", shutdown)
|
||||
|
||||
mp.register_idle(watch_changes)
|
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue