Compare commits

...

No commits in common. "sway-systemd" and "main" have entirely different histories.

241 changed files with 5549 additions and 4791 deletions

9
.editorconfig Normal file
View file

@ -0,0 +1,9 @@
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules/

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "dotdrop"]
path = dotdrop
url = https://github.com/deadc0de6/dotdrop.git

50
.husky/pre-commit Executable file
View file

@ -0,0 +1,50 @@
#!/bin/sh
# Source husky
# shellcheck disable=SC1091
. "$(dirname -- "$0")/_/husky.sh"
echo "FunctionalHacker's dotfile pre-commit hook start"
printf "Using shell: %s \n" "$(readlink /proc/$$/exe)"
# All staged files
staged_files=$(git diff --name-only --cached --diff-filter=d)
# Run taplo on staged TOML files
staged_toml=$(echo "$staged_files" | grep '.toml$' || true)
num_staged_toml=$(echo "$staged_toml" | grep -vce '^$' || true)
if [ "$num_staged_toml" -gt 0 ]; then
printf '\nFormatting %s staged TOML files with taplo\n' "$num_staged_toml"
taplo format "$staged_toml"
printf "Re-staging\n"
git add $staged_toml
fi
# Run lua-format on staged Lua files
staged_lua=$(echo "$staged_files" | grep '.lua$' || true)
num_staged_lua=$(echo "$staged_lua" | grep -vce '^$' || true)
if [ "$num_staged_lua" -gt 0 ]; then
printf '\nFormatting %s staged Lua files with stylua\n' "$num_staged_lua"
for file in $staged_lua; do
stylua "$file"
done
printf "Re-staging\n\n"
git add $staged_lua
fi
# Run shfmt on staged shell scripts
staged_sh=$(echo "$staged_files" | grep -E '(.sh$|pre-commit)' || true)
num_staged_sh=$(echo "$staged_sh" | grep -vce '^$' || true)
if [ "$num_staged_sh" -gt 0 ]; then
printf '\nFormatting %s staged shell scripts with shfmt\n' "$num_staged_sh"
shfmt -w $staged_sh
printf "Re-staging\n\n"
git add $staged_sh
fi
# Run prettier on all other staged files
# that are supported
printf "\nRunning prettier on all supported files\n"
npx pretty-quick --staged

1
.ignore Normal file
View file

@ -0,0 +1 @@
dotdrop/

3
.prettierignore Normal file
View file

@ -0,0 +1,3 @@
package-lock.json
lazy-lock.json
dotdrop/

4
.prettierrc.toml Normal file
View file

@ -0,0 +1,4 @@
"$schema" = "https://json.schemastore.org/prettierrc.json"
trailingComma = "es5"
singleQuote = true
tabWidth = 2

21
LICENSE
View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2019 Marko Korhonen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

14
LICENSE.adoc Normal file
View file

@ -0,0 +1,14 @@
== The MIT License (MIT)
Copyright (c) {localyear} Marko Korhonen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

24
README.adoc Normal file
View file

@ -0,0 +1,24 @@
= FunctionalHacker's dotfiles
image:https://i.imgur.com/lz1Q4Zz.png?raw=true%22[screenshot of my
setup]
My personal dotfiles for my workstations, mostly for easy access for
myself but feel free to steal them for yourself!
Im using https://github.com/deadc0de6/dotdrop[dotdrop] to manage and
ease deployment of my dotfiles.
== Mirrors
This repository lives at https://git.korhonen.cc/FunctionalHacker/dotfiles[My git server],
but it is also mirrored to:
* https://gitlab.com/FunctionalHacker/dotfiles[GitLab]
* https://github.com/FunctionalHacker/dotfiles[GitHub]
* https://bitbucket.org/FunctionalHacker/dotfiles[Bitbucket]
* https://codeberg.org/FunctionalHacker/dotfiles[codeberg]
If you have any ideas for improvements, questions or anything of this
sort, you can open an issue or a pull request at my git server
(registrations open for anyone), or any of the mirrors.

View file

@ -1,16 +0,0 @@
# FunctionalHacker's dotfiles
![screenshot of my setup](https://i.imgur.com/lz1Q4Zz.png?raw=true")
My personal dotfiles for my workstations, mostly for easy access for myself
but feel free to steal them for yourself!
I'm using [dotdrop](https://github.com/deadc0de6/dotdrop) to manage and ease deployment of my dotfiles.
## Mirrors
This repository lives at [My git server](https://git.korhonen.cc/FunctionalHacker/dotfiles), but it is also mirrored to:
- [GitLab](https://gitlab.com/FunctionalHacker/dotfiles)
- [GitHub](https://github.com/FunctionalHacker/dotfiles)
- [Bitbucket](https://bitbucket.org/FunctionalHacker/dotfiles)
- [codeberg](https://codeberg.org/FunctionalHacker/dotfiles)
If you have any ideas for improvements, questions or anything of this sort, you can open an issue or a pull request in either my git server (registrations open for anyone), or any of the mirrors.

239
config-root.toml Normal file
View file

@ -0,0 +1,239 @@
[config]
backup = true
banner = true
create = true
dotpath = "root"
ignoreempty = false
keepdot = true
link_dotfile_default = "nolink"
link_on_import = "nolink"
longkey = false
showdiff = false
workdir = "~/.config/sdotdrop"
[dotfiles."f_60-uinput-permissions.rules"]
dst = "/etc/udev/rules.d/60-uinput-permissions.rules"
src = "etc/udev/rules.d/60-uinput-permissions.rules"
[dotfiles."f_yubikey_udev.rules"]
dst = "/etc/udev/rules.d/20-yubikey.rules"
src = "etc/udev/rules.d/20-yubikey.rules"
[dotfiles.d_bin]
dst = "/usr/local/bin"
src = "usr/local/bin"
[dotfiles.d_network]
src = "etc/systemd/network"
dst = "/etc/systemd/network"
[dotfiles."f_networkd.conf"]
src = "etc/systemd/networkd.conf"
dst = "/etc/systemd/networkd.conf"
[dotfiles."f_99-sysctl.conf"]
dst = "/etc/sysctl.d/99-sysctl.conf"
src = "etc/sysctl.d/99-sysctl.conf"
[dotfiles."f_adb.service"]
dst = "/etc/systemd/system/adb.service"
src = "etc/systemd/system/adb.service"
[dotfiles."f_clamd.conf"]
dst = "/etc/clamav/clamd.conf"
src = "etc/clamav/clamd.conf"
[dotfiles.f_cryptissue]
dst = "/etc/cryptissue"
src = "etc/cryptissue"
[dotfiles."f_detected.sh"]
dst = "/etc/clamav/detected.sh"
src = "etc/clamav/detected.sh"
[dotfiles."f_freetype2.sh"]
dst = "/etc/profile.d/freetype2.sh"
src = "etc/profile.d/freetype2.sh"
[dotfiles."f_fonts.conf"]
dst = "/etc/fonts/local.conf"
src = "etc/fonts/local.conf"
[dotfiles."f_locale.conf"]
dst = "/etc/locale.conf"
src = "etc/locale.conf"
[dotfiles."f_locale.gen"]
dst = "/etc/locale.gen"
src = "etc/locale.gen"
[dotfiles."f_logind.conf"]
dst = "/etc/systemd/logind.conf"
src = "etc/systemd/logind.conf"
[dotfiles."f_bluetooth.conf"]
dst = "/etc/bluetooth/main.conf"
src = "etc/bluetooth/main.conf"
[dotfiles."f_pacman.conf"]
dst = "/etc/pacman.conf"
src = "etc/pacman.conf"
[dotfiles.f_pacman_zsh_hook]
dst = "/etc/pacman.d/hooks/zsh.hook"
src = "etc/pacman.d/hooks/zsh.hook"
[dotfiles."f_plymouthd.conf"]
src = "etc/plymouth/plymouthd.conf"
dst = "/etc/plymouth/plymouthd.conf"
[dotfiles.f_sshd_config]
dst = "/etc/ssh/sshd_config"
src = "etc/ssh/sshd_config"
[dotfiles."f_welcomemessage.conf"]
dst = "/etc/welcomemessage.conf"
src = "etc/welcomemessage.conf"
[dotfiles."f_99-conbee-usb-serial.rules"]
src = "etc/udev/rules.d/99-conbee-usb-serial.rules"
dst = "/etc/udev/rules.d/99-conbee-usb-serial.rules"
[dotfiles."f_99-lowbat.rules"]
src = "etc/udev/rules.d/99-lowbat.rules"
dst = "/etc/udev/rules.d/99-lowbat.rules"
[dotfiles."f_sleep.conf"]
src = "etc/systemd/sleep.conf"
dst = "/etc/systemd/sleep.conf"
[dotfiles.f_fstab]
src = "etc/fstab"
dst = "/etc/fstab"
[dotfiles.f_ignore]
src = ".ignore"
dst = "/.ignore"
[dotfiles."f_mkinitcpio.conf"]
src = "etc/mkinitcpio.conf"
dst = "/etc/mkinitcpio.conf"
[dotfiles."f_vconsole.conf"]
src = "etc/vconsole.conf"
dst = "/etc/vconsole.conf"
[dotfiles."f_20-quiet-printk.conf"]
src = "etc/sysctl.d/20-quiet-printk.conf"
dst = "/etc/sysctl.d/20-quiet-printk.conf"
[dotfiles."f_system.conf"]
src = "etc/systemd/system.conf"
dst = "/etc/systemd/system.conf"
[dotfiles.f_cpupower]
src = "etc/default/cpupower"
dst = "/etc/default/cpupower"
[dotfiles."f_pacserve.service.conf"]
src = "etc/pacserve/pacserve.service.conf"
dst = "/etc/pacserve/pacserve.service.conf"
[dotfiles."f_mkinitcpio_linux.preset"]
src = "etc/mkinitcpio.d/linux.preset"
dst = "/etc/mkinitcpio.d/linux.preset"
[dotfiles."f_mkinitcpio_linux-cachyos.preset"]
src = "etc/mkinitcpio.d/linux-cachyos.preset"
dst = "/etc/mkinitcpio.d/linux-cachyos.preset"
[dotfiles.f_cmdline]
src = "etc/kernel/cmdline"
dst = "/etc/kernel/cmdline"
[dotfiles."f_timesyncd.conf"]
src = "etc/systemd/timesyncd.conf"
dst = "/etc/systemd/timesyncd.conf"
[dotfiles.f_sudoers_pacman]
src = "etc/sudoers.d/pacman"
dst = "/etc/sudoers.d/pacman"
[dotfiles."f_doas.conf"]
src = "etc/doas.conf"
dst = "/etc/doas.conf"
[dotfiles."f_flexo.toml"]
src = "etc/flexo/flexo.toml"
dst = "/etc/flexo/flexo.toml"
[profiles.Locale]
dotfiles = ["f_locale.conf", "f_locale.gen"]
[profiles.Pacman]
dotfiles = [
"f_pacman.conf",
"f_pacman_zsh_hook",
"f_pacserve.service.conf",
"f_sudoers_pacman",
]
[profiles.Mirkwood]
dotfiles = [
"d_bin",
"f_20-quiet-printk.conf",
"f_60-uinput-permissions.rules",
"f_99-lowbat.rules",
"f_adb.service",
"f_bluetooth.conf",
"f_cmdline",
"f_cpupower",
"f_cryptissue",
"f_doas.conf",
"f_fonts.conf",
"f_freetype2.sh",
"f_ignore",
"f_logind.conf",
"f_mkinitcpio.conf",
"f_mkinitcpio_linux.preset",
"f_mkinitcpio_linux-cachyos.preset",
"f_plymouthd.conf",
"f_sshd_config",
"f_system.conf",
"f_timesyncd.conf",
"f_welcomemessage.conf",
"f_flexo.toml",
]
include = ["Locale", "Pacman"]
[profiles.Moria]
include = ["Locale", "Pacman"]
dotfiles = [
"f_99-sysctl.conf",
"f_cmdline",
"f_cpupower",
"f_doas.conf",
"f_adb.service",
"f_mkinitcpio.conf",
"f_mkinitcpio_linux.preset",
"f_mkinitcpio_linux-cachyos.preset",
"f_plymouthd.conf",
"f_sshd_config",
"f_flexo.toml",
]
[profiles.Tirion]
dotfiles = ["f_doas.conf", "f_ignore", "f_sshd_config"]
[profiles.Gondor]
include = ["Locale", "Pacman"]
dotfiles = ["f_doas.conf", "f_sshd_config"]
[profiles.localhost]
include = ["Locale"]
[profiles.Edoras]
include = ["Pacman"]
[profiles.mko-laptop]
dotfiles = ["f_cpupower", "f_doas.conf", "f_timesyncd.conf"]

View file

@ -1,161 +0,0 @@
config:
backup: true
banner: true
create: true
dotpath: root
ignoreempty: false
keepdot: true
link_dotfile_default: nolink
link_on_import: nolink
longkey: false
showdiff: false
workdir: ~/.config/sdotdrop
dotfiles:
f_60-uinput-permissions.rules:
dst: /etc/udev/rules.d/60-uinput-permissions.rules
src: etc/udev/rules.d/60-uinput-permissions.rules
d_bin:
dst: /usr/local/bin
src: usr/local/bin
d_network:
src: etc/systemd/network
dst: /etc/systemd/network
f_networkd.conf:
src: etc/systemd/networkd.conf
dst: /etc/systemd/networkd.conf
f_99-sysctl.conf:
dst: /etc/sysctl.d/99-sysctl.conf
src: etc/sysctl.d/99-sysctl.conf
f_adb.service:
dst: /etc/systemd/system/adb.service
src: etc/systemd/system/adb.service
f_clamd.conf:
dst: /etc/clamav/clamd.conf
src: etc/clamav/clamd.conf
f_cryptissue:
dst: /etc/cryptissue
src: etc/cryptissue
f_detected.sh:
dst: /etc/clamav/detected.sh
src: etc/clamav/detected.sh
f_freetype2.sh:
dst: /etc/profile.d/freetype2.sh
src: etc/profile.d/freetype2.sh
f_fonts.conf:
dst: /etc/fonts/local.conf
src: etc/fonts/local.conf
f_locale.conf:
dst: /etc/locale.conf
src: etc/locale.conf
f_locale.gen:
dst: /etc/locale.gen
src: etc/locale.gen
f_logind.conf:
dst: /etc/systemd/logind.conf
src: etc/systemd/logind.conf
f_bluetooth.conf:
dst: /etc/bluetooth/main.conf
src: etc/bluetooth/main.conf
f_pacman.conf:
dst: /etc/pacman.conf
src: etc/pacman.conf
f_sshd_config:
dst: /etc/ssh/sshd_config
src: etc/ssh/sshd_config
f_welcomemessage.conf:
dst: /etc/welcomemessage.conf
src: etc/welcomemessage.conf
f_getty.conf:
src: etc/systemd/system/getty@tty1.service.d/override.conf
dst: /etc/systemd/system/getty@tty1.service.d/override.conf
f_99-conbee-usb-serial.rules:
src: etc/udev/rules.d/99-conbee-usb-serial.rules
dst: /etc/udev/rules.d/99-conbee-usb-serial.rules
f_99-lowbat.rules:
src: etc/udev/rules.d/99-lowbat.rules
dst: /etc/udev/rules.d/99-lowbat.rules
f_sleep.conf:
src: etc/systemd/sleep.conf
dst: /etc/systemd/sleep.conf
f_fstab:
src: etc/fstab
dst: /etc/fstab
f_ignore:
src: .ignore
dst: /.ignore
f_mkinitcpio.conf:
src: etc/mkinitcpio.conf
dst: /etc/mkinitcpio.conf
f_vconsole.conf:
src: etc/vconsole.conf
dst: /etc/vconsole.conf
f_20-quiet-printk.conf:
src: etc/sysctl.d/20-quiet-printk.conf
dst: /etc/sysctl.d/20-quiet-printk.conf
f_system.conf:
src: etc/systemd/system.conf
dst: /etc/systemd/system.conf
f_cpupower:
src: etc/default/cpupower
dst: /etc/default/cpupower
f_pacserve.service.conf:
src: etc/pacserve/pacserve.service.conf
dst: /etc/pacserve/pacserve.service.conf
profiles:
Network:
dotfiles:
- d_network
- f_networkd.conf
Locale:
dotfiles:
- f_locale.conf
- f_locale.gen
Pacman:
dotfiles:
- f_pacman.conf
- f_pacserve.service.conf
Mirkwood:
dotfiles:
- f_getty.conf
- f_cryptissue
- f_welcomemessage.conf
- d_bin
- f_adb.service
- f_bluetooth.conf
- f_sshd_config
- f_logind.conf
- f_60-uinput-permissions.rules
- f_freetype2.sh
- f_fonts.conf
- f_99-lowbat.rules
- f_ignore
- f_mkinitcpio.conf
- f_vconsole.conf
- f_20-quiet-printk.conf
- f_system.conf
- f_cpupower
include:
- Locale
- Pacman
- Network
Moria:
include:
- Locale
- Pacman
- Network
dotfiles:
- f_sshd_config
- f_99-sysctl.conf
- f_cpupower
Gondor:
include:
- Locale
- Pacman
dotfiles:
- f_sshd_config
localhost:
include:
- Locale
Edoras:
include:
- Pacman

263
config.toml Normal file
View file

@ -0,0 +1,263 @@
#:schema ../../dotdrop-config-schema.json
[actions]
dconf-load = "dconf load / < ~/.config/dconf.ini"
kanagawa-compile = "vim +KanagawaCompile +qa"
[config]
backup = true
banner = true
create = true
dotpath = "home"
ignoreempty = false
keepdot = true
link_dotfile_default = "nolink"
link_on_import = "nolink"
longkey = false
showdiff = false
workdir = "~/.config/dotdrop"
[dotfiles.d_systemd]
dst = "~/.config/systemd/user"
src = ".config/systemd/user"
[dotfiles.d_mpv]
dst = "~/.config/mpv"
src = ".config/mpv"
[dotfiles.d_nvim]
dst = "~/.config/nvim"
src = ".config/nvim"
actions = ["kanagawa-compile"]
instignore = ["*-lock.json"]
[dotfiles."f_abcde.conf"]
dst = "~/.abcde.conf"
src = ".abcde.conf"
[dotfiles.d_ssh]
dst = "~/.ssh"
src = ".ssh"
[dotfiles.f_beets_config]
dst = "~/.config/beets/config.yaml"
src = ".config/beets/config.yaml"
[dotfiles.f_beets_whitelist]
dst = "~/.config/beets/whitelist"
src = ".config/beets/whitelist"
[dotfiles.f_gitconfig]
dst = "~/.config/git/config"
src = ".config/git/config"
[dotfiles.f_librewolf_overrides]
dst = "~/.librewolf/librewolf.overrides.cfg"
src = ".librewolf/librewolf.overrides.cfg"
[dotfiles."f_makepkg.conf"]
dst = "~/.config/pacman/makepkg.conf"
src = ".config/pacman/makepkg.conf"
[dotfiles."f_mpd.conf"]
dst = "~/.config/mpd/mpd.conf"
src = ".config/mpd/mpd.conf"
[dotfiles."f_mpdris2.conf"]
dst = "~/.config/mpDris2/mpDris2.conf"
src = ".config/mpDris2/mpDris2.conf"
[dotfiles.f_ncmpcpp_bindings]
dst = "~/.config/ncmpcpp/bindings"
src = ".config/ncmpcpp/bindings"
[dotfiles."f_ranger.conf"]
dst = "~/.config/ranger/rc.conf"
src = ".config/ranger/rc.conf"
[dotfiles."f_ranger_commands.py"]
dst = "~/.config/ranger/commands.py"
src = ".config/ranger/commands.py"
[dotfiles."f_ssh.conf"]
dst = "~/.ssh/config"
src = ".ssh/config"
[dotfiles.f_zprofile]
dst = "~/.zprofile"
src = ".zprofile"
[dotfiles.f_zshrc]
dst = "~/.zshrc"
src = ".zshrc"
[dotfiles.d_zsh]
src = ".config/zsh"
dst = "~/.config/zsh"
[dotfiles."f_fonts.conf"]
src = ".config/fontconfig/fonts.conf"
dst = "~/.config/fontconfig/fonts.conf"
[dotfiles.f_ignore]
src = ".ignore"
dst = "~/.ignore"
[dotfiles."f_ncmpcpp.conf"]
src = ".config/ncmpcpp/config"
dst = "~/.config/ncmpcpp/config"
[dotfiles.f_hushlogin]
src = ".hushlogin"
dst = "~/.hushlogin"
[dotfiles."f_paru.conf"]
src = ".config/paru/paru.conf"
dst = "~/.config/paru/paru.conf"
[dotfiles."f_foot.ini"]
src = ".config/foot/foot.ini"
dst = "~/.config/foot/foot.ini"
[dotfiles."f_gpg-agent.conf"]
src = ".gnupg/gpg-agent.conf"
dst = "~/.gnupg/gpg-agent.conf"
chmod = "600"
[dotfiles."f_gpg.conf"]
src = ".gnupg/gpg.conf"
dst = "~/.gnupg/gpg.conf"
[dotfiles."f_gpg_scdaemon.conf"]
src = ".gnupg/scdaemon.conf"
dst = "~/.gnupg/scdaemon.conf"
[dotfiles."f_electron-flags.conf"]
src = ".config/electron-flags.conf"
dst = "~/.config/electron-flags.conf"
[dotfiles."f_electron12-flags.conf"]
src = ".config/electron12-flags.conf"
dst = "~/.config/electron12-flags.conf"
[dotfiles.f_pam_environment]
src = ".pam_environment"
dst = "~/.pam_environment"
[dotfiles."f_dconf.ini"]
src = ".config/dconf.ini"
dst = "~/.config/dconf.ini"
actions = ["dconf-load"]
[dotfiles."f_docker-config.json"]
src = ".docker/config.json"
dst = "~/.docker/config.json"
chmod = "600"
[dotfiles.f_npmrc]
src = ".npmrc"
dst = "~/.npmrc"
chmod = "600"
[dotfiles.f_zellij]
src = ".config/zellij/config.kdl"
dst = "~/.config/zellij/config.kdl"
[profiles.pacman]
dotfiles = ["f_makepkg.conf", "f_paru.conf"]
[profiles.terminal]
dotfiles = [
"d_nvim",
"d_ssh",
"d_zsh",
"f_gitconfig",
"f_hushlogin",
"f_ignore",
"f_ranger.conf",
"f_ranger_commands.py",
"f_zellij",
"f_zshrc",
"f_npmrc",
]
[profiles.media]
dotfiles = [
"d_mpv",
"f_abcde.conf",
"f_beets_config",
"f_beets_whitelist",
"f_mpd.conf",
"f_mpdris2.conf",
"f_ncmpcpp.conf",
"f_ncmpcpp_bindings",
]
[profiles.gpg]
dotfiles = [
"f_gpg-agent.conf",
"f_gpg.conf",
"f_gpg_scdaemon.conf",
"f_pam_environment",
]
[profiles.Mirkwood]
include = ["pacman", "terminal", "media", "gpg"]
dotfiles = [
"f_librewolf_overrides",
"f_dconf.ini",
"f_docker-config.json",
"f_fonts.conf",
"f_foot.ini",
]
[profiles.Mirkwood.variables]
wayland = true
[profiles.Moria]
include = ["pacman", "terminal", "media", "gpg"]
dotfiles = [
"f_librewolf_overrides",
"f_dconf.ini",
"f_zprofile",
"f_fonts.conf",
"d_systemd",
]
[profiles.Moria.variables]
wayland = true
[profiles.Tirion]
include = ["terminal", "gpg"]
[profiles.Gondor]
include = ["pacman", "terminal"]
[profiles.mko-laptop]
include = ["terminal", "media", "gpg"]
dotfiles = ["f_librewolf_overrides", "f_dconf.ini", "d_systemd"]
[profiles.mko-laptop.variables]
wayland = true
scale_factor = 1.25
[profiles.Isengard]
include = ["terminal"]
[profiles.Isengard.variables]
distro_id = "termux"
[profiles.Edoras]
include = ["terminal"]
[profiles.TakamakiPC]
include = ["terminal"]
[profiles.TakamakiPC.variables]
wayland = false
[profiles.localhost]
include = ["terminal"]
[profiles.ViiruJaTeippi]
include = ["terminal"]

View file

@ -1,257 +0,0 @@
actions:
vim-plug: nvim +PlugInstall +qall
config:
backup: true
banner: true
create: true
dotpath: home
ignoreempty: false
keepdot: true
link_dotfile_default: nolink
link_on_import: nolink
longkey: false
showdiff: false
workdir: ~/.config/dotdrop
dotfiles:
d_systemd:
dst: ~/.config/systemd/user
src: .config/systemd/user
d_mpv:
dst: ~/.config/mpv
src: .config/mpv
d_neomutt:
dst: ~/.config/neomutt
src: .config/neomutt
d_imapnotify:
dst: ~/.config/imapnotify
src: .config/imapnotify
f_init.vim:
dst: ~/.config/nvim/init.vim
src: .config/nvim/init.vim
d_nvim_config:
actions:
- vim-plug
dst: ~/.config/nvim/conf.d
src: .config/nvim/conf.d
f_user-dirs.dirs:
dst: ~/.config/user-dirs.dirs
src: .config/user-dirs.dirs
f_coc-settings.json:
dst: ~/.config/nvim/coc-settings.json
src: .config/nvim/coc-settings.json
d_sway:
dst: ~/.config/sway
src: .config/sway
d_waybar:
dst: ~/.config/waybar
src: .config/waybar
d_wofi:
src: .config/wofi
dst: ~/.config/wofi
f_abcde.conf:
dst: ~/.abcde.conf
src: .abcde.conf
f_mbsyncrc:
dst: ~/.mbsyncrc
src: .mbsyncrc
f_alacritty.yml:
dst: ~/.config/alacritty/alacritty.yml
src: .config/alacritty/alacritty.yml
f_authorized_keys:
dst: ~/.ssh/authorized_keys
src: .ssh/authorized_keys
f_beets_config:
dst: ~/.config/beets/config.yaml
src: .config/beets/config.yaml
f_beets_whitelist:
dst: ~/.config/beets/whitelist
src: .config/beets/whitelist
f_bspwmrc:
dst: ~/.config/bspwm/bspwmrc
src: .config/bspwm/bspwmrc
f_gitconfig:
dst: ~/.gitconfig
src: .gitconfig
f_libra_config:
dst: ~/.config/libra/config.toml
src: .config/libra/config.toml
f_mailcap:
dst: ~/.mailcap
src: .mailcap
f_makepkg.conf:
dst: ~/.config/pacman/makepkg.conf
src: .config/pacman/makepkg.conf
f_mako_config:
dst: ~/.config/mako/config
src: .config/mako/config
f_mimeo_associations.txt:
dst: ~/.config/mimeo/associations.txt
src: .config/mimeo/associations.txt
f_mpd.conf:
dst: ~/.config/mpd/mpd.conf
src: .config/mpd/mpd.conf
f_mpdris2.conf:
dst: ~/.config/mpDris2/mpDris2.conf
src: .config/mpDris2/mpDris2.conf
f_mpdscribble.conf:
dst: ~/.mpdscribble/mpdscribble.conf
src: .mpdscribble/mpdscribble.conf
f_ncmpcpp_bindings:
dst: ~/.config/ncmpcpp/bindings
src: .config/ncmpcpp/bindings
f_ranger.conf:
dst: ~/.config/ranger/rc.conf
src: .config/ranger/rc.conf
f_ranger_commands.py:
dst: ~/.config/ranger/commands.py
src: .config/ranger/commands.py
f_redshift.conf:
dst: ~/.config/redshift/redshift.conf
src: .config/redshift/redshift.conf
f_rtv.cfg:
dst: ~/.config/rtv/rtv.cfg
src: .config/rtv/rtv.cfg
f_ssh.conf:
dst: ~/.ssh/config
src: .ssh/config
f_steam-native.desktop:
dst: ~/.local/share/applications/steam-native.desktop
src: .local/share/applications/steam-native.desktop
f_tdesktop_lang.strings:
dst: ~/.config/telegram-desktop/lang.strings
src: .config/telegram-desktop/lang.strings
f_tmux.conf:
dst: ~/.tmux.conf
src: .tmux.conf
f_youtube-dl_config:
dst: ~/.config/youtube-dl/config
src: .config/youtube-dl/config
f_zathurarc:
dst: ~/.config/zathura/zathurarc
src: .config/zathura/zathurarc
f_zshrc:
dst: ~/.zshrc
src: .zshrc
d_zsh:
src: .config/zsh
dst: ~/.config/zsh
f_fonts.conf:
src: .config/fontconfig/fonts.conf
dst: ~/.config/fontconfig/fonts.conf
f_ripgrep_ignore:
src: .ignore
dst: ~/.ignore
f_nvimpager:
src: .config/nvimpager/init.vim
dst: ~/.config/nvimpager/init.vim
f_ncmpcpp.conf:
src: .config/ncmpcpp/config
dst: ~/.config/ncmpcpp/config
f_hushlogin:
src: .hushlogin
dst: ~/.hushlogin
f_paru.conf:
src: .config/paru/paru.conf
dst: ~/.config/paru/paru.conf
f_msmtp_config:
src: .config/msmtp/config
dst: ~/.config/msmtp/config
f_foot.ini:
src: .config/foot/foot.ini
dst: ~/.config/foot/foot.ini
profiles:
base:
dotfiles:
- d_systemd
terminal:
dotfiles:
- f_nvimpager
- f_hushlogin
- f_ripgrep_ignore
- f_ranger_commands.py
- f_rtv.cfg
- f_mailcap
- d_zsh
- f_zshrc
- f_tmux.conf
- f_ranger.conf
- f_ssh.conf
- f_authorized_keys
- d_nvim_config
- f_init.vim
- f_coc-settings.json
- f_gitconfig
- f_alacritty.yml
email:
dotfiles:
- d_neomutt
- d_imapnotify
- f_mbsyncrc
- f_msmtp_config
media:
dotfiles:
- f_beets_config
- f_beets_whitelist
- f_abcde.conf
- d_mpv
- f_youtube-dl_config
- f_mpd.conf
- f_ncmpcpp_bindings
- f_ncmpcpp.conf
- f_libra_config
- f_mpdscribble.conf
- f_mpdris2.conf
sway:
dotfiles:
- d_sway
- d_waybar
- d_wofi
- f_mako_config
- f_redshift.conf
- f_zathurarc
- f_mimeo_associations.txt
- f_tdesktop_lang.strings
- f_fonts.conf
Pacman:
dotfiles:
- f_makepkg.conf
- f_paru.conf
Mirkwood:
include:
- base
- terminal
- email
- media
- sway
- Pacman
dotfiles:
- f_paru.conf
- f_user-dirs.dirs
- f_gitconfig
- f_foot.ini
Moria:
include:
- terminal
- media
- Pacman
Gondor:
include:
- terminal
- Pacman
mko-laptop:
include:
- terminal
Edoras:
include:
- terminal
- Pacman
TakamakiPC:
include:
- terminal
- Pacman
localhost:
include:
- terminal
ViiruJaTeippi:
include:
- terminal

View file

@ -1,73 +0,0 @@
#!/bin/zsh
# This is a script that should be ran once
# on a new system. Dotdrop will take it from there.
# It is higly tailored to my own needs and
# you (the random person on the internet) should probably not run it
export DOTREPO="$HOME/git/dotfiles"
DISTRO="$(lsb_release -ds | sed 's/"//g')"
PKGLIST="python-ruamel-yaml python-magic-git python-jinja python-docopt"
if [ -d $DOTREPO ]; then
print "Dotfile repository already exists, exiting..."
exit 1
fi
if [ "$DISTRO" -ne "Arch Linux" ]; then
print "Not running on Arch Linux"
print "Other distros not supported, exiting..."
exit 1
fi
# install neovim if not installed
if ! [ -x "$(command -v nvim)" ]; then
read -p "Install neovim? [Y/n] " -i "y" INVIM
if [ "$(tr '[:upper:]' ':lower:' $INVIM)" -eq "y" ]; then
print "Installing neovim"
PKGLIST=$PKGLIST + " neovim neovim-dropin"
fi
fi
# install zsh if not installed
if ! [ -x "$(command -v zsh)" ]; then
read -p "Install zsh? [Y/n] " -i "y" IZSH
if [ "$(tr '[:upper:]' ':lower:' $INVIM)" -eq "y" ]; then
print "Installing zsh"
PKGLIST=$PKGLIST + " zsh"
fi
fi
# install paru if not installed
if ! [ -x "$(command -v paru)" ]; then
read -p "Install paru? [Y/n] " -i "y" IYAY
if [ "$(tr '[:upper:]' ':lower:' $IYAY)" -eq "y" ]; then
print "Installing paru"
sudo pacman -Syu --needed --noconfirm git wget base-devel
cd
wget https://aur.archlinux.org/cgit/aur.git/snapshot/paru-bin.tar.gz
tar xfv paru-bin.tar.gz
cd paru-bin
makepkg -si --noconfirm
cd ..
rm -r paru*
fi
fi
if [ $PKGLIST -ne "" ]
if ! [ -x "$(command -v paru)" ]; then
print "Can't continue without paru"
paru -S $PKGLIST
fi
fi
mkdir ~/git
git clone https://git.korhonen.cc/ReekyMarko/dotfiles.git $DOTREPO
cd ~/git/dotfiles
git submodule init
git submodule update
$DOTREPO/dotdrop.sh --cfg=$DOTREPO/config-home.yaml install
chsh -s /bin/zsh
zsh -c "source ~/.zshrc; sdotdrop install"

1
docker/.gitignore vendored
View file

@ -1 +1,2 @@
*/.env
*/DISABLED

View file

@ -1,20 +0,0 @@
version: "2"
services:
openldap:
container_name: openldap
image: osixia/openldap:stable
environment:
- TZ=Europe/Helsinki
- LDAP_ORGANIZATION="Korhonen"
- LDAP_DOMAIN="korhonen.cc"
- LDAP_ADMIN_PASSWORD="${LDAP_ADMIN_PASSWORD}"
hostname: ldap.korhonen.cc
ports:
- 389:389
- 636:636
restart: unless-stopped
volumes:
- /docker/auth/openldap/ldap:/var/lib/ldap
- /docker/auth/openldap/slapd.d:/etc/ldap/slapd.d
- /etc/localtime:/etc/localtime:ro

View file

@ -0,0 +1,78 @@
[volumes]
redis = {}
media = {}
custom_templates = {}
geoip = {}
backups = {}
[services.redis]
image = "redis:alpine"
container_name = "authentik-redis"
networks = ["authentik"]
restart = "unless-stopped"
volumes = ["redis:/data"]
[services.redis.healthcheck]
test = ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period = "20s"
interval = "30s"
retries = 5
timeout = "3s"
[services.server]
image = "ghcr.io/goauthentik/server"
container_name = "authentik"
restart = "unless-stopped"
command = "server"
volumes = [
"media:/media",
"custom_templates:/templates",
"geoip:/geoip",
]
env_file = [".env"]
networks = ["authentik", "postgres", "proxy"]
[services.worker]
image = "ghcr.io/goauthentik/server"
container_name = "authentik-worker"
restart = "unless-stopped"
command = "worker"
user = "root"
volumes = [
"backups:/backups",
"custom_templates:/templates",
"geoip:/geoip",
"media:/media",
"/var/run/docker.sock:/var/run/docker.sock",
]
env_file = [".env"]
networks = ["authentik", "postgres"]
[services.geoipupdate]
image = "maxmindinc/geoipupdate"
container_name = "authentik-geoipupdate"
restart = "unless-stopped"
networks = ["authentik"]
volumes = ["geoip:/usr/share/GeoIP"]
env_file = [".env"]
[services.geoipupdate.environment]
GEOIPUPDATE_EDITION_IDS = "GeoLite2-City"
GEOIPUPDATE_FREQUENCY = "8"
[services.whoami-test]
image = "traefik/whoami"
container_name = "whoami-test"
restart = "unless-stopped"
security_opt = ["no-new-privileges:true"]
networks = ["proxy"]
environment = ["TZ"]
[networks.authentik]
external = true
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -0,0 +1,36 @@
[volumes.caddy_data]
external = true
[volumes.caddy_config]
external = true
[volumes.caddy_wkd]
external = true
[volumes.homeautomation_hass]
external = true
[services.backup]
image = "offen/docker-volume-backup:v2"
container_name = "volume-backup"
environment = [
"AWS_ENDPOINT",
"AWS_S3_BUCKET_NAME",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"GPG_PASSPHRASE",
"EMAIL_SMTP_HOST",
"EMAIL_SMTP_PASSWORD",
"EMAIL_SMTP_USERNAME",
"EMAIL_SMTP_PORT",
"BACKUP_COMPRESSION=zst",
"BACKUP_RETENTION_DAYS=7",
]
volumes = [
"/var/run/docker.sock:/var/run/docker.sock:ro",
"/etc/localtime:/etc/localtime:ro",
"caddy_data:/backup/caddy_data:ro",
"caddy_config:/backup/caddy_config:ro",
"caddy_wkd:/backup/caddy_wkd:ro",
"homeautomation_hass:/backup/homeautomation_hass:ro",
]

203
docker/caddy/Caddyfile Normal file
View file

@ -0,0 +1,203 @@
korhonen.cc, *.korhonen.cc {
tls {$CLOUDFLARE_EMAIL} {
dns cloudflare {$CLOUDFLARE_API_TOKEN}
resolvers 1.1.1.1
}
encode zstd gzip
@static {
file
path *.ico *.css *.js *.gif *.webp *.avif *.jpg *.jpeg *.png *.svg *.woff *.woff2 *.pdf *.webmanifest
}
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
}
@homepage-www-redir host www.korhonen.cc
handle @homepage-www-redir {
redir https://korhonen.cc
}
@homepage host korhonen.cc
handle @homepage {
# Redirect finnish WIP
# @redirFinnish {
# header Accept-Language *fi-FI*
# not path *.js *.css *.png *.jpg *.jpeg *.svg
# not path /en* /fi*
# }
# redir @redirFinnish /fi{uri}
#
# uri strip_prefix /en
header @static Cache-Control max-age=5184000
root * /var/www/korhonen.cc
file_server
}
@wkd host openpgpkey.korhonen.cc
handle @wkd {
root * /var/www/wkd
file_server browse
header Access-Control-Allow-Origin "*"
}
@index host index.korhonen.cc
handle @index {
root * /var/www/index.korhonen.cc
file_server browse
}
@home-assistant host home.korhonen.cc
handle @home-assistant {
reverse_proxy home-assistant:8123
}
@authentik host sso.korhonen.cc
handle @authentik {
reverse_proxy authentik:9000
}
@forgejo host git.korhonen.cc
handle @forgejo {
rewrite /user/login /user/oauth2/authentik
reverse_proxy forgejo:3000
}
@woodpecker host ci.korhonen.cc
handle @woodpecker {
reverse_proxy woodpecker:8000
}
@searx host search.korhonen.cc
handle @searx {
reverse_proxy searx:8080
}
@freshrss host rss.korhonen.cc
handle @freshrss {
reverse_proxy freshrss
}
@jellyfin host jellyfin.korhonen.cc
handle @jellyfin {
reverse_proxy jellyfin:8096
}
@pihole host pihole.korhonen.cc
handle @pihole {
reverse_proxy pihole
}
@umami host umami.korhonen.cc
handle @umami {
reverse_proxy umami:3000
rewrite /ua9quuaW.js /script.js
}
@nextcloud host cloud.korhonen.cc
handle @nextcloud {
# Redirect login page to Authentik
redir /login /apps/sociallogin/custom_oidc/korhonen-sso 301
# .htaccess / data / config / ... shouldn't be accessible from outside
@forbidden {
path /.htaccess
path /data/*
path /config/*
path /db_structure
path /.xml
path /README
path /3rdparty/*
path /lib/*
path /templates/*
path /occ
path /console.php
}
handle @forbidden {
respond 404
}
redir /.well-known/carddav /remote.php/dav 301
redir /.well-known/caldav /remote.php/dav 301
root * /var/www/nextcloud
php_fastcgi nextcloud:9000 {
root /var/www/html
# Tells nextcloud to remove /index.php from URLs in links
env front_controller_active true
}
file_server
}
@tvheadend host tvheadend.korhonen.cc
handle @tvheadend {
reverse_proxy tvheadend:9981
}
@collabora host collabora.korhonen.cc
handle @collabora {
reverse_proxy collabora:9980
}
@grafana host grafana.korhonen.cc
handle @grafana {
reverse_proxy grafana:3000
}
@drop host drop.korhonen.cc
handle @drop {
reverse_proxy drop:3000
}
handle {
respond "404 Not Found" 404
}
handle_errors {
@homepage_404 {
expression {http.error.status_code} == 404
host korhonen.cc
}
handle @homepage_404 {
root * /var/www/korhonen.cc
rewrite * /404.html
file_server
}
respond "{err.status_code} {err.status_text}"
}
}
korhonen.social, *.korhonen.social {
tls {$CLOUDFLARE_EMAIL} {
dns cloudflare {$CLOUDFLARE_API_TOKEN}
resolvers 1.1.1.1
}
encode zstd gzip
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
}
@firefish-www-redir host www.korhonen.social
handle @firefish-www-redir {
redir https://korhonen.social
}
@firefish host korhonen.social
handle @firefish {
reverse_proxy firefish:3000
}
handle {
respond "404 Not Found" 404
}
handle_errors {
respond "{err.status_code} {err.status_text}"
}
}

View file

@ -0,0 +1,29 @@
[volumes]
data = {}
config = {}
wkd = {}
korhonen_cc = {}
[volumes.nextcloud_config]
external = true
[services.caddy]
image = "git.korhonen.cc/functionalhacker/caddy"
container_name = "caddy"
restart = "unless-stopped"
ports = ["80:80", "443:443/tcp", "443:443/udp"]
networks = ["proxy"]
volumes = [
"./Caddyfile:/etc/caddy/Caddyfile",
"data:/data",
"config:/config",
"wkd:/var/www/wkd",
"korhonen_cc:/var/www/korhonen.cc",
"nextcloud_config:/var/www/nextcloud",
"/var/www/index.korhonen.cc:/var/www/index.korhonen.cc",
]
environment = ["CLOUDFLARE_EMAIL", "CLOUDFLARE_API_TOKEN", "ACME_AGREE=true"]
cap_add = ["NET_ADMIN"]
[networks.proxy]
external = true

View file

@ -0,0 +1,8 @@
[services.cloudflare-ddns]
image = "timothyjmiller/cloudflare-ddns"
container_name = "cloudflare-ddns"
security_opt = ["no-new-privileges:true"]
network_mode = "host"
environment = ["PUID=1000", "PGID=1000"]
volumes = ["/mnt/Storage/docker/ddns/config.json:/config.json"]
restart = "unless-stopped"

View file

@ -0,0 +1,9 @@
[services.drop]
image = "lscr.io/linuxserver/pairdrop"
container_name = "drop"
restart = "unless-stopped"
networks = ["proxy"]
environment = ["TZ=Europe/Helsinki"]
[networks.proxy]
external = true

View file

@ -0,0 +1,41 @@
[volumes]
files = {}
config = {}
redis = {}
db = {}
[services.firefish]
image = "registry.firefish.dev/firefish/firefish"
container_name = "firefish"
restart = "unless-stopped"
depends_on = ["redis"]
ports = ["3084:3000"]
networks = ["firefish", "proxy"]
environment = { NODE_ENV = "production" }
volumes = ["files:/firefish/files", "config:/firefish/.config:ro"]
[services.redis]
image = "redis"
container_name = "redis-firefish"
restart = "unless-stopped"
networks = ["firefish"]
volumes = ["redis:/data"]
[services.db]
image = "groonga/pgroonga:3.1.8-alpine-16-slim"
container_name = "firefish-db"
restart = "unless-stopped"
networks = ["firefish"]
volumes = ["db:/var/lib/postgresql/data"]
[services.db.healthcheck]
test = "pg_isready --user=\"firefish\" --dbname=\"firefish\""
interval = "5s"
timeout = "5s"
retries = 5
[networks.firefish]
internal = true
[networks.proxy]
external = true

View file

@ -0,0 +1,32 @@
[volumes]
data = {}
runner = {}
[services.forgejo]
image = "git.korhonen.cc/functionalhacker/forgejo-asciidoc"
container_name = "forgejo"
environment = ["TZ=Europe/Helsinki", "USER_UID=1000", "USER_GID=1000"]
restart = "unless-stopped"
networks = ["postgres", "proxy"]
ports = ["22:22"]
volumes = ["data:/data", "/etc/localtime:/etc/localtime:ro"]
[services.runner]
image = "code.forgejo.org/forgejo/runner:3.4.1"
container_name = "forgejo-runner"
user = "root:root"
volumes = [
"runner:/data",
"./runner.yaml:/data/config.yaml",
"/var/run/docker.sock:/var/run/docker.sock",
"/etc/localtime:/etc/localtime:ro",
]
environment = ["SOCKFILE=/var/run/docker.sock"]
restart = "unless-stopped"
command = "forgejo-runner daemon -c /data/config.yaml"
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -0,0 +1,34 @@
log:
level: info
runner:
file: .runner
capacity: 2
env_file: .env
timeout: 3h
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
labels:
- 'docker:docker://git.korhonen.cc/functionalhacker/ubuntu-act:22.04'
cache:
enabled: true
dir: ''
host: ''
port: 0
external_server: ''
container:
network: ''
enable_ipv6: false
privileged: false
options:
workdir_parent:
valid_volumes:
- 'caddy_korhonen_cc'
docker_host: ''
force_pull: false
host:
workdir_parent:

View file

@ -0,0 +1,19 @@
[volumes]
config = {}
[services.freshrss]
image = "linuxserver/freshrss"
container_name = "freshrss"
restart = "unless-stopped"
networks = ["freshrss", "postgres", "proxy"]
environment = ["PUID=1000", "PGID=985", "TZ=Europe/Helsinki"]
volumes = ["config:/config", "/etc/localtime:/etc/localtime:ro"]
[networks.freshrss]
external = false
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -1,96 +0,0 @@
version: "2.1"
services:
freshrss:
image: linuxserver/freshrss
container_name: freshrss
restart: unless-stopped
networks:
- freshrss
- postgres
- proxy
environment:
- PUID=1000
- PGID=985
- TZ=Europe/Helsinki
depends_on:
- spotifeed
- bibliogram
volumes:
- /docker/freshrss/freshrss:/config
- /etc/localtime:/etc/localtime:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.freshrss-redirect.entrypoints=http"
- "traefik.http.routers.freshrss-redirect.rule=Host(`rss.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.freshrss-redirect.middlewares=http2https"
- "traefik.http.routers.freshrss.entrypoints=https"
- "traefik.http.routers.freshrss.rule=Host(`rss.korhonen.cc`)"
- "traefik.http.routers.freshrss.tls=true"
- "traefik.http.routers.freshrss.tls.certresolver=http"
- "traefik.http.routers.freshrss.service=freshrss"
- "traefik.docker.network=proxy"
- "traefik.http.services.freshrss.loadbalancer.server.port=80"
spotifeed:
build: ./spotifeed
image: spotifeed
container_name: spotifeed
environment:
- SPOTIFY_CLIENT_ID=${SPOTIFY_CLIENT_ID}
- SPOTIFY_CLIENT_SECRET=${SPOTIFY_CLIENT_SECRET}
restart: unless-stopped
networks:
- freshrss
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.spotifeed-redirect.entrypoints=http"
- "traefik.http.routers.spotifeed-redirect.rule=Host(`spotifeed.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.spotifeed-redirect.middlewares=http2https"
- "traefik.http.routers.spotifeed.entrypoints=https"
- "traefik.http.routers.spotifeed.rule=Host(`spotifeed.korhonen.cc`)"
- "traefik.http.routers.spotifeed.tls=true"
- "traefik.http.routers.spotifeed.tls.certresolver=http"
- "traefik.http.routers.spotifeed.service=spotifeed"
- "traefik.docker.network=proxy"
- "traefik.http.services.spotifeed.loadbalancer.server.port=8083"
bibliogram:
image: cloudrac3r/bibliogram
container_name: bibliogram
restart: unless-stopped
volumes:
- /docker/freshrss/bibliogram/db:/app/db
- /docker/freshrss/bibliogram/config.js:/app/config.js
networks:
- freshrss
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.bibliogram-redirect.entrypoints=http"
- "traefik.http.routers.bibliogram-redirect.rule=Host(`bibliogram.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.bibliogram-redirect.middlewares=http2https"
- "traefik.http.routers.bibliogram.entrypoints=https"
- "traefik.http.routers.bibliogram.rule=Host(`bibliogram.korhonen.cc`)"
- "traefik.http.routers.bibliogram.tls=true"
- "traefik.http.routers.bibliogram.tls.certresolver=http"
- "traefik.http.routers.bibliogram.service=bibliogram"
- "traefik.docker.network=proxy"
- "traefik.http.services.bibliogram.loadbalancer.server.port=10407"
networks:
freshrss:
external: false
postgres:
external: true
proxy:
external: true

View file

@ -1,9 +0,0 @@
FROM ruby:2.7.2
RUN git clone https://github.com/timdorr/spotifeed
WORKDIR /spotifeed
RUN bundle install
EXPOSE 8083
RUN apt-get update
RUN apt-get upgrade
RUN apt-get install redis-server -y
CMD puma -p 8083 & redis-server

View file

@ -1,41 +0,0 @@
version: "2"
services:
gitea:
container_name: gitea
image: gitea/gitea:1
environment:
- TZ=Europe/Helsinki
- USER_UID=1000
- USER_GID=1000
restart: unless-stopped
networks:
- postgres
- proxy
ports:
- "3000:3000"
- "222:22"
volumes:
- /docker/gitea:/data
- /etc/localtime:/etc/localtime:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea-redirect.entrypoints=http"
- "traefik.http.routers.gitea-redirect.rule=Host(`git.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.gitea-redirect.middlewares=http2https"
- "traefik.http.routers.gitea.entrypoints=https"
- "traefik.http.routers.gitea.rule=Host(`git.korhonen.cc`)"
- "traefik.http.routers.gitea.tls=true"
- "traefik.http.routers.gitea.tls.certresolver=http"
- "traefik.http.routers.gitea.service=gitea"
- "traefik.docker.network=proxy"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
networks:
postgres:
external: true
proxy:
external: true

View file

@ -0,0 +1,20 @@
[volumes]
config = {}
data = {}
[services.headscale]
image = "headscale/headscale:0"
container_name = "headscale"
volumes = ["config:/etc/headscale", "data:/var/lib/headscale"]
ports = ["3478:3478/udp"]
command = "headscale serve"
restart = "unless-stopped"
networks = ["postgres"]
[services.headscale-ui]
image = "ghcr.io/gurucomputing/headscale-ui"
container_name = "headscale-ui"
restart = "unless-stopped"
[networks.postgres]
external = true

View file

@ -0,0 +1,111 @@
[volumes]
hass = {}
mosquitto = {}
piper_english = {}
whisper_english = {}
openwakeword_english = {}
[services.home-assistant]
container_name = "home-assistant"
image = "homeassistant/home-assistant"
restart = "unless-stopped"
environment = ["TZ=Europe/Helsinki"]
devices = ["/dev/ttyACM0"]
volumes = ["hass:/config", "/etc/localtime:/etc/localtime:ro"]
networks = ["homeautomation", "postgres", "proxy"]
ports = ["8123:8123", "8300:8300"]
extra_hosts = ["host.docker.internal:host-gateway"]
[services.mosquitto]
container_name = "mosquitto"
image = "eclipse-mosquitto"
restart = "unless-stopped"
environment = ["TZ=Europe/Helsinki"]
networks = ["homeautomation"]
ports = ["1883:1883", "8866:8866"]
volumes = ["mosquitto:/mosquitto", "/etc/localtime:/etc/localtime:ro"]
[services.piper_english]
container_name = "piper_english"
image = "rhasspy/wyoming-piper"
restart = "unless-stopped"
environment = ["TZ=Europe/Helsinki"]
ports = ["10200:10200"]
networks = ["homeautomation"]
command = ["--voice", "en_US-hfc_male-medium"]
volumes = ["piper_english:/data", "/etc/localtime:/etc/localtime:ro"]
[services.whisper_english]
container_name = "whisper_english"
image = "rhasspy/wyoming-whisper"
restart = "unless-stopped"
environment = ["TZ=Europe/Helsinki"]
ports = ["10300:10300"]
networks = ["homeautomation"]
depends_on = ["home-assistant"]
command = ["--model", "tiny-int8", "--language", "en"]
volumes = ["whisper_english:/data", "/etc/localtime:/etc/localtime:ro"]
[services.openwakeword_english]
container_name = "openwakeword_english"
image = "rhasspy/wyoming-openwakeword"
restart = "unless-stopped"
environment = ["TZ=Europe/Helsinki"]
networks = ["homeautomation"]
command = ["--preload-model", "ok_nabu"]
depends_on = ["home-assistant"]
volumes = ["openwakeword_english:/data", "/etc/localtime:/etc/localtime:ro"]
[services.microphone]
build = "https://github.com/rhasspy/wyoming-mic-external.git"
image = "rhasspy/wyoming-mic-external"
container_name = "microphone"
restart = "unless-stopped"
devices = ["/dev/snd:/dev/snd"]
ports = ["10600:10600"]
group_add = ["audio"]
networks = ["homeautomation"]
command = ["--device", "plughw:CARD=USB,DEV=0", "--debug"]
volumes = ["/etc/localtime:/etc/localtime:ro"]
[services.speaker]
build = "https://github.com/rhasspy/wyoming-snd-external.git"
image = "rhasspy/wyoming-snd-external"
container_name = "speaker"
restart = "unless-stopped"
devices = ["/dev/snd:/dev/snd"]
ports = ["10601:10601"]
group_add = ["audio"]
networks = ["homeautomation"]
command = ["--device", "iec958:CARD=USB,DEV=0", "--debug"]
volumes = ["/etc/localtime:/etc/localtime:ro"]
[services.satellite]
build = "https://github.com/rhasspy/wyoming-satellite.git"
image = "rhasspy/wyoming-satellite"
container_name = "satellite"
restart = "unless-stopped"
ports = ["10700:10700"]
networks = ["homeautomation"]
depends_on = ["speaker", "microphone", "whisper_english"]
command = [
"--name",
"ha-server-satellite",
"--mic-uri",
"tcp://microphone:10600",
"--snd-uri",
"tcp://speaker:10601",
"--wake-uri",
"tcp://openwakeword_english:10400",
"--debug",
]
volumes = ["/etc/localtime:/etc/localtime:ro"]
[networks.homeautomation]
external = false
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -1,136 +0,0 @@
version: "3"
services:
home-assistant:
container_name: home-assistant
image: homeassistant/home-assistant
environment:
- TZ=Europe/Helsinki
devices:
- /dev/ttyACM0
volumes:
- /docker/homeautomation/home-assistant:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
networks:
- homeautomation
- postgres
- proxy
ports:
- "8123:8123"
depends_on:
- mosquitto
labels:
- "traefik.enable=true"
- "traefik.http.routers.home-assistant-redirect.entrypoints=http"
- "traefik.http.routers.home-assistant-redirect.rule=Host(`home.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.home-assistant-redirect.middlewares=http2https"
- "traefik.http.routers.home-assistant.entrypoints=https"
- "traefik.http.routers.home-assistant.rule=Host(`home.korhonen.cc`)"
- "traefik.http.routers.home-assistant.tls=true"
- "traefik.http.routers.home-assistant.tls.certresolver=http"
- "traefik.http.routers.home-assistant.service=home-assistant"
- "traefik.docker.network=proxy"
- "traefik.http.services.home-assistant.loadbalancer.server.port=8123"
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto
environment:
- TZ=Europe/Helsinki
ports:
- "1883:1883"
networks:
- homeautomation
volumes:
- /docker/homeautomation/mosquitto:/mosquitto
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
rhasspy:
container_name: rhasspy
image: rhasspy/rhasspy
command: --profile en --user-profiles /profiles
volumes:
- /docker/homeautomation/rhasspy:/profiles
environment:
- TZ=Europe/Helsinki
ports:
- "12101:12101"
networks:
- homeautomation
restart: unless-stopped
depends_on:
- home-assistant
devices:
- "/dev/snd:/dev/snd"
node-red:
container_name: node-red
image: nodered/node-red
environment:
- TZ=Europe/Helsinki
- proxy
ports:
- "1880:1880"
networks:
- homeautomation
volumes:
- /docker/homeautomation/node-red:/data
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
depends_on:
- home-assistant
labels:
- "traefik.enable=true"
- "traefik.http.routers.node-red-redirect.entrypoints=http"
- "traefik.http.routers.node-red-redirect.rule=Host(`node.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.node-red-redirect.middlewares=http2https"
- "traefik.http.routers.node-red.entrypoints=https"
- "traefik.http.routers.node-red.rule=Host(`node.korhonen.cc`)"
- "traefik.http.routers.node-red.tls=true"
- "traefik.http.routers.node-red.tls.certresolver=http"
- "traefik.http.routers.node-red.service=node-red"
- "traefik.docker.network=proxy"
- "traefik.http.services.node-red.loadbalancer.server.port=1880"
gotify:
image: gotify/server
container_name: gotify
volumes:
- /docker/homeautomation/gotify:/app/data
environment:
- GOTIFY_DATABASE_DIALECT=postgres
- GOTIFY_DATABASE_CONNECTION="host=postgres port=5432 user=gotify dbname=gotify password=${GOTIFY_PGPASS} sslmode=disable"
networks:
- proxy
- postgres
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.gotify-redirect.entrypoints=http"
- "traefik.http.routers.gotify-redirect.rule=Host(`gotify.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.gotify-redirect.middlewares=http2https"
- "traefik.http.routers.gotify.entrypoints=https"
- "traefik.http.routers.gotify.rule=Host(`gotify.korhonen.cc`)"
- "traefik.http.routers.gotify.tls=true"
- "traefik.http.routers.gotify.tls.certresolver=http"
- "traefik.http.routers.gotify.service=gotify"
- "traefik.docker.network=proxy"
- "traefik.http.services.gotify.loadbalancer.server.port=80"
networks:
homeautomation:
external: false
postgres:
external: true
proxy:
external: true

View file

@ -1,33 +0,0 @@
version: "3"
services:
nginx:
image: fraoustin/fancyindex
container_name: index.korhonen.cc
environment:
- DISABLE_AUTH=true
- CONTAINER_TIMEZONE="Europe/Helsinki"
volumes:
- /docker/index.korhonen.cc:/share
networks:
- proxy
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.index-redirect.entrypoints=http"
- "traefik.http.routers.index-redirect.rule=Host(`index.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.index-redirect.middlewares=http2https"
- "traefik.http.routers.index.entrypoints=https"
- "traefik.http.routers.index.rule=Host(`index.korhonen.cc`)"
- "traefik.http.routers.index.tls=true"
- "traefik.http.routers.index.tls.certresolver=http"
- "traefik.http.routers.index.service=index"
- "traefik.docker.network=proxy"
- "traefik.http.services.index.loadbalancer.server.port=80"
networks:
proxy:
external: true

View file

@ -0,0 +1,34 @@
[volumes]
config = {}
cache = {}
[volumes.media]
external = true
[volumes.nextcloud_data]
external = true
[services.jellyfin]
image = "jellyfin/jellyfin"
container_name = "jellyfin"
environment = ["TZ=Europe/Helsinki"]
ports = ["8096:8096"]
networks = ["proxy", "authentik"]
restart = "unless-stopped"
volumes = [
"config:/config",
"cache:/cache",
"media:/media",
"nextcloud_data:/nextcloud_data",
"/etc/localtime:/etc/localtime:ro",
]
devices = [
"/dev/dri/renderD128:/dev/dri/renderD128",
"/dev/dri/card0:/dev/dri/card0",
]
[networks.proxy]
external = true
[networks.authentik]
external = true

View file

@ -1,40 +0,0 @@
version: "2.3"
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
environment:
- TZ=Europe/Helsinki
- NVIDIA_DRIVER_CAPABILITIES=all
- NVIDIA_VISIBLE_DEVICES=all
ports:
- "8096:8096"
networks:
- proxy
restart: unless-stopped
volumes:
- /docker/jellyfin/config:/config
- /docker/jellyfin/cache:/cache
- /mnt/Storage/Media:/media
- /etc/localtime:/etc/localtime:ro
devices:
- /dev/dri:/dev/dri
labels:
- "traefik.enable=true"
- "traefik.http.routers.jellyfin-redirect.entrypoints=http"
- "traefik.http.routers.jellyfin-redirect.rule=Host(`jellyfin.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.jellyfin-redirect.middlewares=http2https"
- "traefik.http.routers.jellyfin.entrypoints=https"
- "traefik.http.routers.jellyfin.rule=Host(`jellyfin.korhonen.cc`)"
- "traefik.http.routers.jellyfin.tls=true"
- "traefik.http.routers.jellyfin.tls.certresolver=http"
- "traefik.http.routers.jellyfin.service=jellyfin"
- "traefik.docker.network=proxy"
- "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
networks:
proxy:
external: true

View file

@ -0,0 +1,10 @@
[volumes]
config = {}
[services.mumble]
container_name = "mumble"
image = "phlak/mumble"
environment = ["TZ=Europe/Helsinki"]
network_mode = "host"
volumes = ["config:/etc/mumble", "/etc/localtime:/etc/localtime:ro"]
restart = "unless-stopped"

View file

@ -1,14 +0,0 @@
version: "3"
services:
mumble:
container_name: mumble
image: phlak/mumble
user: "1000:985"
environment:
- TZ=Europe/Helsinki
network_mode: host
volumes:
- /docker/mumble:/etc/mumble
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped

1
docker/nextcloud/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.env

View file

@ -0,0 +1,84 @@
[volumes.nextcloud_config]
external = true
[volumes.nextcloud_data]
external = true
[services.nextcloud]
image = "nextcloud:fpm-alpine"
container_name = "nextcloud"
restart = "unless-stopped"
networks = ["nextcloud", "postgres", "proxy"]
volumes = [
"nextcloud_config:/var/www/html",
"nextcloud_data:/var/www/html/data",
"/etc/localtime:/etc/localtime:ro",
]
environment = [
"REDIS_HOST=redis",
"REDIS_HOST_PASSWORD=123",
"TRUSTED_PROXIES=caddy",
"NEXTCLOUD_TRUSTED_DOMAINS=cloud.korhonen.cc",
"OVERWRITEHOST=cloud.korhonen.cc",
"OVERWRITEPROTOCOL=https",
]
depends_on = ["redis"]
[services.nextcloud.labels]
"ofelia.enabled" = true
"ofelia.job-exec.nextcloud.schedule" = "0 */5 * * * *"
"ofelia.job-exec.nextcloud.command" = "php /var/www/html/cron.php"
"ofelia.job-exec.nextcloud.user" = "www-data"
"ofelia.smtp-host" = "${SMTP_HOST}"
"ofelia.smtp-port" = "${SMTP_PORT}"
"ofelia.smtp-user" = "${SMTP_USER}"
"ofelia.smtp-password" = "${SMTP_PASSWORD}"
"ofelia.email-to" = "${EMAIL_TO}"
"ofelia.email-from" = "${EMAIL_FROM}"
"ofelia.mail-only-on-error" = true
[services.redis]
image = "redis:alpine"
container_name = "redis-nextcloud"
networks = ["nextcloud"]
restart = "unless-stopped"
command = "redis-server --requirepass 123"
[services.coturn]
image = "instrumentisto/coturn"
container_name = "coturn"
restart = "unless-stopped"
env_file = ".env"
ports = ["3478:3478/tcp", "3478:3478/udp", "49160-49200:49160-49200/udp"]
networks = ["nextcloud"]
command = [
"-n",
"--log-file=stdout",
"--min-port=49160",
"--max-port=49200",
"--realm=cloud.korhonen.cc",
"--use-auth-secret",
"--static-auth-secret=${STATIC_AUTH_SECRET}",
]
[services.collabora]
image = "collabora/code"
container_name = "collabora"
restart = "unless-stopped"
env_file = ".env"
environment = [
"username=${COLLABORA_USERNAME}",
"password=${COLLABORA_PASSWORD}",
"domain=cloud.korhonen.cc",
'extra_params=--o:ssl.enable=false --o:ssl.termination=true',
]
networks = ["proxy"]
[networks.nextcloud]
external = false
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -1,66 +0,0 @@
version: "3"
services:
nextcloud:
image: nextcloud:apache
container_name: nextcloud
restart: always
ports:
- "1869:80"
networks:
- nextcloud
- postgres
- proxy
volumes:
- /docker/nextcloud:/var/www/html
- /mnt/Storage/Nextcloud:/var/www/html/data
- /mnt/Storage/Syncthing:/Syncthing
- /mnt/Storage/Media/Music:/Music
- /etc/localtime:/etc/localtime:ro
environment:
- TZ=Europe/Helsinki
- REDIS_HOST=redis
- REDIS_HOST_PASSWORD=123
depends_on:
- redis
labels:
- "traefik.enable=true"
- "traefik.http.routers.nextcloud-redirect.entrypoints=http"
- "traefik.http.routers.nextcloud-redirect.rule=Host(`cloud.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.nextcloud-redirect.middlewares=http2https"
- "traefik.http.routers.nextcloud.entrypoints=https"
- "traefik.http.routers.nextcloud.rule=Host(`cloud.korhonen.cc`)"
- "traefik.http.routers.nextcloud.tls=true"
- "traefik.http.routers.nextcloud.tls.certresolver=http"
- "traefik.http.routers.nextcloud.service=nextcloud"
- "traefik.docker.network=proxy"
- "traefik.http.services.nextcloud.loadbalancer.server.port=80"
redis:
image: redis:alpine
container_name: redis
networks:
- nextcloud
restart: always
command: redis-server --requirepass 123
cron:
image: nextcloud:apache
container_name: cron
restart: always
volumes:
- /docker/nextcloud:/var/www/html
entrypoint: /cron.sh
depends_on:
- redis
networks:
nextcloud:
external: false
postgres:
external: true
proxy:
external: true

View file

@ -0,0 +1,9 @@
[services.ofelia]
image = "mcuadros/ofelia"
container_name = "ofelia"
restart = "unless-stopped"
volumes = [
"/etc/localtime:/etc/localtime:ro",
"/var/run/docker.sock:/var/run/docker.sock:ro",
]
command = "daemon --docker"

View file

@ -0,0 +1,23 @@
[volumes]
config = {}
dnsmasq = {}
[services.pihole]
container_name = "pihole"
image = "pihole/pihole"
ports = ["53:53/tcp", "53:53/udp", "67:67/udp", "8069:80/tcp"]
networks = ["proxy"]
volumes = [
"config:/etc/pihole/",
"dnsmasq:/etc/dnsmasq.d/",
]
dns = ["127.0.0.1", "1.1.1.1"]
cap_add = ["NET_ADMIN"]
restart = "unless-stopped"
[services.pihole.environment]
TZ = "Europe/Helsinki"
WEBPASSWORD = "${WEBPASSWORD}"
[networks.proxy]
external = true

View file

@ -1,46 +0,0 @@
version: "3"
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
ports:
- "53:53/tcp"
- "53:53/udp"
- "67:67/udp"
- "8069:80/tcp"
networks:
- proxy
environment:
TZ: "Europe/Helsinki"
WEBPASSWORD: "${WEBPASSWORD}"
volumes:
- "/docker/pihole/pihole:/etc/pihole/"
- "/docker/pihole/dnsmasq:/etc/dnsmasq.d/"
dns:
- 127.0.0.1
- 1.1.1.1
# Recommended but not required (DHCP needs NET_ADMIN)
# https://github.com/pihole/docker-pihole#note-on-capabilities
cap_add:
- NET_ADMIN
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.pihole-redirect.entrypoints=http"
- "traefik.http.routers.pihole-redirect.rule=Host(`pihole.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.pihole-redirect.middlewares=http2https"
- "traefik.http.routers.pihole.entrypoints=https"
- "traefik.http.routers.pihole.rule=Host(`pihole.korhonen.cc`)"
- "traefik.http.routers.pihole.tls=true"
- "traefik.http.routers.pihole.tls.certresolver=http"
- "traefik.http.routers.pihole.service=pihole"
- "traefik.docker.network=proxy"
- "traefik.http.services.pihole.loadbalancer.server.port=80"
networks:
proxy:
external: true

View file

@ -1,33 +0,0 @@
version: '3'
services:
portainer:
image: portainer/portainer-ce
container_name: portainer
environment:
- TZ=Europe/Helsinki
restart: unless-stopped
networks:
- proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /docker/portainer:/data
- /etc/localtime:/etc/localtime:ro
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.portainer-redirect.entrypoints=http'
- 'traefik.http.routers.portainer-redirect.rule=Host(`portainer.korhonen.cc`)'
- 'traefik.http.middlewares.http2https.redirectscheme.scheme=https'
- 'traefik.http.routers.portainer-redirect.middlewares=http2https'
- 'traefik.http.routers.portainer.entrypoints=https'
- 'traefik.http.routers.portainer.rule=Host(`portainer.korhonen.cc`)'
- 'traefik.http.routers.portainer.tls=true'
- 'traefik.http.routers.portainer.tls.certresolver=http'
- 'traefik.http.routers.portainer.service=portainer'
- 'traefik.docker.network=proxy'
- 'traefik.http.services.portainer.loadbalancer.server.port=9000'
networks:
proxy:
external: true

View file

@ -0,0 +1,17 @@
[volumes]
data = {}
[services.postgres]
container_name = "postgres"
image = "postgres:16"
environment = ["TZ=Europe/Helsinki"]
ports = ["127.0.0.1:5432:5432"]
networks = ["postgres"]
volumes = [
"data:/var/lib/postgresql/data",
"/etc/localtime:/etc/localtime:ro",
]
restart = "unless-stopped"
[networks.postgres]
external = true

View file

@ -1,20 +0,0 @@
version: "3"
services:
postgres:
container_name: postgres
image: postgres:13
environment:
- TZ=Europe/Helsinki
- POSTGRES_PASSWORD=12345
ports:
- 5432:5432
networks:
- postgres
volumes:
- /docker/postgres:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
networks:
postgres:
external: true

View file

@ -0,0 +1,37 @@
[volumes]
config = {}
[services.searx]
container_name = "searx"
image = "searxng/searxng"
restart = "unless-stopped"
networks = ["searx", "proxy"]
volumes = [
"config:/etc/searxng",
#"/docker/searx/logo.png:/usr/local/searxng/searx/static/themes/simple/img/searxng.png:ro"
]
environment = ["SEARXNG_BASE_URL=https://search.korhonen.cc/"]
cap_drop = ["ALL"]
cap_add = ["CHOWN", "SETGID", "SETUID", "DAC_OVERRIDE"]
[services.searx.logging]
driver = "json-file"
[services.searx.logging.options]
max-size = "1m"
max-file = "1"
[services.redis]
container_name = "redis-searx"
image = "redis:alpine"
command = "redis-server --save \"\" --appendonly \"no\""
networks = ["searx"]
tmpfs = ["/var/lib/redis"]
cap_drop = ["ALL"]
cap_add = ["SETGID", "SETUID", "DAC_OVERRIDE"]
[networks.searx.ipam]
driver = "default"
[networks.proxy]
external = true

View file

@ -0,0 +1,27 @@
[services.grafana]
image = "grafana/grafana"
container_name = "grafana"
volumes = ["grafana:/var/lib/grafana"]
networks = ["stats", "proxy"]
user = "1000:984"
env_file = [".env"]
environment = [
"GF_AUTH_GENERIC_OAUTH_CLIENT_ID",
"GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET",
"GF_AUTH_GENERIC_OAUTH_ENABLED=true",
"GF_AUTH_GENERIC_OAUTH_NAME=authentik",
"GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email",
"GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://sso.korhonen.cc/application/o/authorize/",
"GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://sso.korhonen.cc/application/o/token/",
"GF_AUTH_GENERIC_OAUTH_API_URL=https://sso.korhonen.cc/application/o/userinfo/",
"GF_AUTH_SIGNOUT_REDIRECT_URL=https://sso.korhonen.cc/application/o/grafana/end-session/",
"GF_AUTH_OAUTH_AUTO_LOGIN=true",
"GF_SERVER_ROOT_URL=https://grafana.korhonen.cc",
"GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(groups[*], 'Administrators') && 'Admin' || 'Viewer'",
]
[networks.stats]
external = false
[networks.proxy]
external = true

View file

@ -0,0 +1,9 @@
[services]
[services.tftp]
container_name = "tftp"
image = "pghalliday/tftp"
environment = ["TZ=Europe/Helsinki"]
restart = "unless-stopped"
ports = ["69:69/udp"]
volumes = ["/etc/localtime:/etc/localtime:ro", "/docker/tftp:/var/tftpboot"]

View file

@ -1,53 +0,0 @@
version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
ports:
- '80:80'
- '443:443'
environment:
- TZ=Europe/Helsinki
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /docker/træfik/træfik/traefik.yml:/traefik.yml:ro
- /docker/træfik/træfik/dashboard-users:/dashboard-users:ro
- /docker/træfik/træfik/acme.json:/acme.json
- /docker/træfik/træfik/log:/var/log
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.redirect.entrypoints=http'
- 'traefik.http.routers.redirect.rule=Host(`traefik.korhonen.cc`)'
- 'traefik.http.middlewares.http2https.redirectscheme.scheme=https'
- 'traefik.http.routers.redirect.middlewares=http2https'
- 'traefik.http.routers.dashboard.entrypoints=https'
- 'traefik.http.routers.dashboard.rule=Host(`traefik.korhonen.cc`)'
- 'traefik.http.middlewares.dashboard-auth.basicauth.usersfile=/dashboard-users'
- 'traefik.http.routers.dashboard.middlewares=dashboard-auth'
- 'traefik.http.routers.dashboard.tls=true'
- 'traefik.http.routers.dashboard.tls.certresolver=http'
- 'traefik.http.routers.dashboard.service=api@internal'
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
network_mode: "host"
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- /docker/træfik/træfik/log:/var/log/træfik:ro
- /docker/træfik/fail2ban:/data
networks:
proxy:
external: true

View file

@ -0,0 +1,21 @@
[volumes]
config = {}
picons = {}
[services.tvheadend]
image = "linuxserver/tvheadend"
container_name = "tvheadend"
environment = ["TZ=Europe/Helsinki", "PUID=1000", "PGID=985"]
volumes = [
"config:/config",
"picons:/picons",
"/mnt/Storage/Media/PVR:/recordings",
"/etc/localtime:/etc/localtime:ro",
]
ports = ["9981:9981", "9982:9982"]
devices = ["/dev/dvb:/dev/dvb"]
restart = "unless-stopped"
networks = ["proxy"]
[networks.proxy]
external = true

View file

@ -1,42 +0,0 @@
version: "2"
services:
tvheadend:
image: linuxserver/tvheadend
container_name: tvheadend
environment:
- TZ=Europe/Helsinki
- PUID=1000
- PGID=985
volumes:
- /docker/tvheadend:/config
- /mnt/Storage/Media/PVR:/recordings
- /mnt/Storage/picons:/picons
- /etc/localtime:/etc/localtime:ro
ports:
- 9981:9981
- 9982:9982
devices:
- /dev/dri:/dev/dri #hardware acceleration
- /dev/dvb:/dev/dvb #tuner card
restart: unless-stopped
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.tvheadend-redirect.entrypoints=http"
- "traefik.http.routers.tvheadend-redirect.rule=Host(`tvheadend.korhonen.cc`)"
- "traefik.http.middlewares.http2https.redirectscheme.scheme=https"
- "traefik.http.routers.tvheadend-redirect.middlewares=http2https"
- "traefik.http.routers.tvheadend.entrypoints=https"
- "traefik.http.routers.tvheadend.rule=Host(`tvheadend.korhonen.cc`)"
- "traefik.http.routers.tvheadend.tls=true"
- "traefik.http.routers.tvheadend.tls.certresolver=http"
- "traefik.http.routers.tvheadend.service=tvheadend"
- "traefik.docker.network=proxy"
- "traefik.http.services.tvheadend.loadbalancer.server.port=9981"
networks:
proxy:
external: true

View file

@ -0,0 +1,20 @@
[services.umami]
image = "ghcr.io/umami-software/umami:postgresql-latest"
container_name = "umami"
restart = "unless-stopped"
networks = ["postgres", "proxy"]
env_file = ".env"
[services.umami.environment]
DATABASE_URL = "postgresql://umami:${POSTGRES_PASS}@postgres:5432/umami"
HASH_SALT = "${HASH_SALT}"
[services.umami.logging.options]
max-size = "10m"
max-file = "10"
[networks.postgres]
external = true
[networks.proxy]
external = true

View file

@ -0,0 +1,19 @@
[services.watchtower]
image = "containrrr/watchtower"
container_name = "watchtower"
restart = "unless-stopped"
environment = [
"WATCHTOWER_CLEANUP=true",
"WATCHTOWER_NOTIFICATION_EMAIL_FROM=watchtower@korhonen.cc",
"WATCHTOWER_NOTIFICATION_EMAIL_TO=admin@korhonen.cc",
"WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.migadu.com",
"WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587",
"WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER}",
"WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD}",
"WATCHTOWER_NOTIFICATION_EMAIL_DELAY=30",
"WATCHTOWER_NOTIFICATIONS=email",
]
volumes = [
"/var/run/docker.sock:/var/run/docker.sock",
"/etc/localtime:/etc/localtime:ro",
]

View file

@ -1,22 +0,0 @@
version: "2.1"
services:
wireguard:
image: linuxserver/wireguard
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- TZ=Europe/Helsinki
- PEERS=4
- SERVERURL=korhonen.cc
- SERVERPORT=48574
- INTERNAL_SUBNET=10.200.200.0/24
volumes:
- /docker/wireguard:/config
- /lib/modules:/lib/modules
ports:
- 48574:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped

@ -1 +0,0 @@
Subproject commit 9ae90d51095b7fe9b26350c8dd33902e862466a5

View file

@ -1,37 +0,0 @@
#!/usr/bin/env bash
# author: deadc0de6 (https://github.com/deadc0de6)
# Copyright (c) 2017, deadc0de6
# check for readlink/realpath presence
# https://github.com/deadc0de6/dotdrop/issues/6
rl="readlink -f"
if ! ${rl} "${0}" >/dev/null 2>&1; then
rl="realpath"
if ! hash ${rl}; then
echo "\"${rl}\" not found!" && exit 1
fi
fi
# setup variables
args=("$@")
cur=$(dirname "$(${rl} "${0}")")
opwd=$(pwd)
cfg="${cur}/config.yaml"
sub="dotdrop"
# pivot
cd "${cur}" || { echo "Directory \"${cur}\" doesn't exist, aborting." && exit 1; }
# init/update the submodule
if [ "${DOTDROP_AUTOUPDATE-yes}" = yes ] ; then
git submodule update --init --recursive
git submodule update --remote dotdrop
fi
# launch dotdrop
PYTHONPATH=dotdrop python3 -m dotdrop.dotdrop "${args[@]}"
ret="$?"
# pivot back
cd "${opwd}" || { echo "Directory \"${opwd}\" doesn't exist, aborting." && exit 1; }
# exit with dotdrop exit code
exit ${ret}

View file

@ -1,12 +0,0 @@
#/bin/bash
# vim:ft=sh
sudo efibootmgr \
--disk /dev/sda \
--part 1 \
--create \
--quiet \
--remove-dups \
--label "Arch Linux" \
--loader /vmlinuz-linux \
--unicode 'initrd=\amd-ucode.img initrd=\initramfs-linux.img cryptdevice=UUID=19fa8fab-c5fe-454a-9a17-b7185ce975ea:cryptroot:allow-discards root=/dev/mapper/cryptroot rootflags=subvol=root resume=/dev/mapper/cryptroot resume_offset=10530935 rw quiet splash vga=current idle=nomwait cpuidle.governor=teo'

View file

@ -1,12 +0,0 @@
#!/bin/bash
# vim:ft=sh
sudo efibootmgr \
--disk /dev/sda \
--part 1 \
--create \
--quiet \
--remove-dups \
--label "Arch Linux LTS" \
--loader /vmlinuz-linux-lts \
--unicode 'initrd=\amd-ucode.img initrd=\initramfs-linux-lts.img cryptdevice=UUID=19fa8fab-c5fe-454a-9a17-b7185ce975ea:cryptroot:allow-discards root=/dev/mapper/cryptroot rootflags=subvol=root resume=/dev/mapper/cryptroot resume_offset=10530935 rw quiet splash vga=current idle=nomwait cpuidle.governor=teo'

View file

@ -1,14 +0,0 @@
#!/bin/bash
# remove old entries
for bootentry in $(efibootmgr | head -n 3 | tail -n 1 | cut -d' ' -f2- | sed 's/,/\n/g'); do
sudo efibootmgr -qBb $bootentry
done
# add all entries back
for bootscript in *.efi; do
./$bootscript
done
# set bootorder
sudo efibootmgr --bootorder 0000,0001

View file

@ -1,4 +1,5 @@
window:
opacity: 1.0
dimensions:
columns: 0
lines: 0
@ -29,42 +30,40 @@ font:
colors:
# Default colors
primary:
background: "0x282c34"
foreground: "0xabb2bf"
background: '0x282c34'
foreground: '0xabb2bf'
# Cursor colors
cursor:
text: "0x282c34"
cursor: "0xabb2bf"
text: '0x282c34'
cursor: '0xabb2bf'
# Normal colors
normal:
black: "0x282c34"
red: "0xe06c75"
green: "0x98c379"
yellow: "0xe5c07b"
blue: "0x61afef"
magenta: "0xc678dd"
cyan: "0x56b6c2"
white: "0xabb2bf"
black: '0x282c34'
red: '0xe06c75'
green: '0x98c379'
yellow: '0xe5c07b'
blue: '0x61afef'
magenta: '0xc678dd'
cyan: '0x56b6c2'
white: '0xabb2bf'
# Bright colors
bright:
black: "0x3e4452"
red: "0xbe5046"
green: "0x98c379"
yellow: "0xd19a66"
blue: "0x61afef"
magenta: "0xc678dd"
cyan: "0x56b6c2"
white: "0x5c6370"
black: '0x3e4452'
red: '0xbe5046'
green: '0x98c379'
yellow: '0xd19a66'
blue: '0x61afef'
magenta: '0xc678dd'
cyan: '0x56b6c2'
white: '0x5c6370'
bell:
animation: EaseOutExpo
duration: 0
color: "#ffffff"
background_opacity: 1.0
color: '#ffffff'
mouse_bindings:
- { mouse: Middle, action: PasteSelection }
@ -73,8 +72,6 @@ mouse:
double_click: { threshold: 300 }
triple_click: { threshold: 300 }
hide_when_typing: false
url:
modifiers: None
selection:
semantic_escape_chars: ',│`|:"'' ()[]{}<>'

0
home/.config/asd Normal file
View file

View file

@ -1,34 +1,31 @@
directory: ~/music
library: ~/music/beets.db
plugins:
- acousticbrainz
- check
- edit
- fetchart
- follow
- fuzzy
- info
- lastgenre
- lyrics
- mbcollection
- mpdupdate
- play
- replaygain
- thumbnails
- web
directory: ~/Music
library: ~/Music/beets.db
plugins:
- edit
- fetchart
- fuzzy
- info
- lastgenre
- lyrics
# - mbcollection
- mpdupdate
- play
- replaygain
- thumbnails
- web
import:
copy: no
move: yes
link: no
write: yes
copy: yes
lastgenre:
whitelist: ~/.config/beets/whitelist
lyrics:
fallback: ''
play:
command: mpv
command: mpv --no-vid --no-resume-playback
mpd:
host: localhost
port: 6600
host: localhost
port: 6600
password: "{{@@ env['PASS_MPD_ADMIN'] @@}}"
follow:
email: reekymarko@reekynet.com
password: "{{@@ env['PASS_MUSPY'] @@}}"
@ -37,9 +34,6 @@ follow:
replaygain:
backend: gstreamer
auto: yes
musicbrainz:
user: ReekyMarko
pass: "{{@@ env['PASS_MUSICBRAINZ'] @@}}"
mbcollection:
auto: "yes"
collection: "a4955b5c-db7f-4e27-9887-f77f820bad34"
#mbcollection:
# auto: 'yes'
# collection: 'a4955b5c-db7f-4e27-9887-f77f820bad34'

88
home/.config/dconf.ini Normal file
View file

@ -0,0 +1,88 @@
[io/github/celluloid-player/celluloid]
dark-theme-enable=false
mpv-config-enable=true
mpv-config-file='file:///home/{{@@ env['USER'] @@}}/.config/mpv/mpv.conf'
mpv-input-config-enable=true
mpv-input-config-file='file:///home/{{@@ env['USER'] @@}}/.config/mpv/input.conf'
settings-migrated=true
[org/gnome/Connections]
first-run=false
[org/gnome/shell/weather]
automatic-location=false
locations=[<(uint32 2, <('Lappeenranta', 'EFLP', false, [(1.0654507804726074, 0.49128594181309354)], @a(dd) [])>)>]
[org/gnome/Weather]
locations=[<(uint32 2, <('Lappeenranta', 'EFLP', false, [(1.0654507804726074, 0.49128594181309354)], @a(dd) [])>)>]
[org/gnome/shell/world-clocks]
locations=[<(uint32 2, <('Bangkok', 'VTBD', true, [(0.24289166005364171, 1.7558012275062955)], [(0.23998277214922031, 1.754346792280731)])>)>]
[org/gnome/clocks]
world-clocks=[{'location': <(uint32 2, <('Bangkok', 'VTBD', true, [(0.24289166005364171, 1.7558012275062955)], [(0.23998277214922031, 1.754346792280731)])>)>}]
[org/gnome/desktop/a11y/mouse]
dwell-click-enabled=false
dwell-threshold=10
dwell-time=1.2
secondary-click-enabled=true
secondary-click-time=1.2
[org/gnome/desktop/calendar]
show-weekdate=true
[org/gnome/desktop/input-sources]
show-all-sources=true
sources=[('xkb', 'eu'), ('xkb', 'fi')]
xkb-options=['lv3:ralt_switch']
[org/gnome/desktop/peripherals/touchpad]
tap-to-click=true
two-finger-scrolling-enabled=true
[org/gnome/desktop/privacy]
disable-microphone=false
old-files-age=uint32 14
recent-files-max-age=-1
remove-old-temp-files=true
remove-old-trash-files=true
[org/gnome/desktop/wm/keybindings]
close=['<Super>w']
move-to-workspace-down=['<Shift><Super>j']
move-to-workspace-left=['<Shift><Super>h']
move-to-workspace-right=['<Shift><Super>l']
move-to-workspace-up=['<Shift><Super>k']
switch-to-workspace-down=['<Super>j']
switch-to-workspace-left=['<Super>h']
switch-to-workspace-right=['<Super>l']
switch-to-workspace-up=['<Super>k']
toggle-fullscreen=@as []
toggle-maximized=['<Super>f']
[org/gnome/settings-daemon/plugins/media-keys]
custom-keybindings=['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']
screensaver=['<Super>BackSpace']
www=['<Super>b']
volume-step=1
[org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0]
binding='<Super>Return'
command='kgx'
name='Open terminal'
[org/gnome/file-roller/dialogs/new]
default-extension='.tar.zst'
[org/gnome/software]
check-timestamp=int64 1667730233
download-updates=true
download-updates-notify=true
first-run=false
[org/gnome/system/location]
enabled=true
[org/gnome/tweaks]
show-extensions-notice=false

View file

@ -0,0 +1,2 @@
--enable-features=UseOzonePlatform
--ozone-platform=wayland

View file

@ -0,0 +1,2 @@
--enable-features=UseOzonePlatform
--ozone-platform=wayland

View file

@ -1,26 +1,22 @@
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<alias>
<family>sans-serif</family>
<prefer>
<family>Overpass</family>
</prefer>
</alias>
<alias>
<family>serif</family>
<prefer>
<family>Overpass</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Hack Nerd Font Mono</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Overpass</family>
</prefer>
</alias>
<alias>
<family>serif</family>
<prefer>
<family>Overpass</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>Hack Nerd Font Mono</family>
</prefer>
</alias>
</fontconfig>

View file

@ -0,0 +1,45 @@
pad=10x0
dpi-aware=yes
[scrollback]
lines=1000
[cursor]
blink=yes
[mouse]
hide-when-typing=yes
[colors]
foreground = 545464
background = f2ecbc
selection-foreground = 43436c
selection-background = c9cbd1
regular0 = 1F1F28
regular1 = c84053
regular2 = 6f894e
regular3 = 77713f
regular4 = 4d699b
regular5 = b35b79
regular6 = 597b75
regular7 = 545464
bright0 = 8a8980
bright1 = d7474b
bright2 = 6e915f
bright3 = 836f4a
bright4 = 6693bf
bright5 = 624c83
bright6 = 5e857a
bright7 = 43436c
16 = cc6d00
17 = e82424
[csd]
color = fff2ecbc
button-color = ff545464
hide-when-maximized = yes

View file

@ -1,4 +1,5 @@
pad=20x20
pad=10x0
dpi-aware=yes
[scrollback]
lines=1000
@ -10,21 +11,34 @@ blink=yes
hide-when-typing=yes
[colors]
background=282c34
foreground=abb2bf
regular0=282c34
regular1=e06c75
regular2=98c379
regular3=e5c07b
regular4=61afef
regular5=c678dd
regular6=56b6c2
regular7=abb2bf
bright0=3e4452
bright1=be5046
bright2=98c379
bright3=d19a66
bright4=61afef
bright5=c678dd
bright6=56b6c2
bright7=5c6370
foreground = dcd7ba
background = 1f1f28
selection-foreground = c8c093
selection-background = 2d4f67
regular0 = 090618
regular1 = c34043
regular2 = 76946a
regular3 = c0a36e
regular4 = 7e9cd8
regular5 = 957fb8
regular6 = 6a9589
regular7 = c8c093
bright0 = 727169
bright1 = e82424
bright2 = 98bb6c
bright3 = e6c384
bright4 = 7fb4ca
bright5 = 938aa9
bright6 = 7aa89f
bright7 = dcd7ba
16 = ffa066
17 = ff5d62
[csd]
color = ff1f1f28
button-color = ffdcd7ba
hide-when-maximized = yes

59
home/.config/git/config Normal file
View file

@ -0,0 +1,59 @@
[user]
{%@@ if profile == "mko-laptop" @@%}
email = marko.korhonen@rossum.fi
{%@@ else @@%}
email = marko@korhonen.cc
{%@@ endif @@%}
name = Marko Korhonen
signingkey = F2B9F713E7ED627336DD85E444FA3F28CD931BB0
[commit]
signoff = true
gpgsign = true
[tag]
gpgSign = true
signoff = true
[format]
signoff = true
[merge]
prompt = false
conflictstyle = diff3
tool = nvim
[mergetool]
keepBackup = false
prompt = false
[mergetool "nvim"]
cmd = nvim +DiffviewOpen
[pull]
rebase = merges
[alias]
mergetest = !git switch test && git pull && git merge --no-ff -m \"Merge $1 features to test\" $1
upstream = !git push -u origin HEAD
sync = !git pull && git push
recommit = !git commit -eF $(git rev-parse --git-dir)/COMMIT_EDITMSG
[color]
pager = no
[init]
defaultBranch = main
[credential]
helper = cache --timeout=600
helper = !pass-git-helper $@
[rerere]
enabled = true
[submodule]
recurse = true
[push]
recurseSubmodules = check

View file

@ -1,3 +1,4 @@
VteTerminal, vte-terminal {
padding: 40px;
VteTerminal,
vte-terminal {
padding: 40px;
}

View file

@ -1,19 +1,19 @@
var child_process = require("child_process");
var child_process = require('child_process');
function getStdout(cmd) {
var stdout = child_process.execSync(cmd);
return stdout.toString().trim();
}
exports.host = "imap.migadu.com";
exports.host = 'imap.migadu.com';
exports.port = 993;
exports.tls = true;
exports.tlsOptions = {
rejectUnauthorized: true,
};
exports.username = "admin@korhonen.cc";
exports.username = 'admin@korhonen.cc';
exports.password = "{{@@ env['PASS_EMAIL_ADMIN'] @@}}";
exports.onNewMail = "mbsync admin@korhonen.cc";
exports.onNewMail = 'mbsync admin@korhonen.cc';
exports.onNewMailPost =
"~/git/dotfiles/scripts/mail/notify-new-mail.sh admin@korhonen.cc";
exports.boxes = ["INBOX"];
'~/git/dotfiles/scripts/mail/notify-new-mail.sh admin@korhonen.cc';
exports.boxes = ['INBOX'];

View file

@ -1,19 +1,19 @@
var child_process = require("child_process");
var child_process = require('child_process');
function getStdout(cmd) {
var stdout = child_process.execSync(cmd);
return stdout.toString().trim();
}
exports.host = "imap.migadu.com";
exports.host = 'imap.migadu.com';
exports.port = 993;
exports.tls = true;
exports.tlsOptions = {
rejectUnauthorized: true,
};
exports.username = "functionalhacker@korhonen.cc";
exports.username = 'functionalhacker@korhonen.cc';
exports.password = "{{@@ env['PASS_EMAIL_HACKER'] @@}}";
exports.onNewMail = "mbsync functionalhacker@korhonen.cc";
exports.onNewMail = 'mbsync functionalhacker@korhonen.cc';
exports.onNewMailPost =
"~/git/dotfiles/scripts/mail/notify-new-mail.sh functionalhacker@korhonen.cc";
exports.boxes = ["INBOX"];
'~/git/dotfiles/scripts/mail/notify-new-mail.sh functionalhacker@korhonen.cc';
exports.boxes = ['INBOX'];

View file

@ -1,19 +1,19 @@
var child_process = require("child_process");
var child_process = require('child_process');
function getStdout(cmd) {
var stdout = child_process.execSync(cmd);
return stdout.toString().trim();
}
exports.host = "imap.migadu.com";
exports.host = 'imap.migadu.com';
exports.port = 993;
exports.tls = true;
exports.tlsOptions = {
rejectUnauthorized: true,
};
exports.username = "marko@korhonen.cc";
exports.username = 'marko@korhonen.cc';
exports.password = "{{@@ env['PASS_EMAIL_MARKO'] @@}}";
exports.onNewMail = "mbsync marko@korhonen.cc";
exports.onNewMail = 'mbsync marko@korhonen.cc';
exports.onNewMailPost =
"~/git/dotfiles/scripts/mail/notify-new-mail.sh marko@korhonen.cc";
exports.boxes = ["INBOX"];
'~/git/dotfiles/scripts/mail/notify-new-mail.sh marko@korhonen.cc';
exports.boxes = ['INBOX'];

View file

@ -1,7 +1,12 @@
background-color=#282828
text-color=#EBDBB2
border-color=#D65D0E
background-color=#1E1D2F
text-color=#D9E0EE
border-color=#96CDFB
progress-color=over #302D41
icons=1
default-timeout=5000
max-visible=6
layer=overlay
[urgency=high]
border-color=#F8BD96

View file

@ -17,7 +17,10 @@ mpvqueue %U
^https?://(?:[a-z0-9\-]+\.)+[a-z]{2,6}(?:/[^/#?]+)+\.(?:mp4|mkv|webm|avi|3gp|gif|gifv)
mpvqueue %U
^https://www.facebook.com/watch/?v=.*
^https?://www.facebook.com/watch/?v=.*
mpvqueue %U
^https?://www.facebook.com/.*/videos/.*
mpvqueue %U
^https://fb.watch/.*
@ -31,11 +34,8 @@ mpvqueue %U
mpvqueue %U
^https?://v.redd.it/.*
imgurviewer %U
^https?://(www.)?imgur.com/a/
imgurviewer %U
^https?://(www.)?imgur.com/gallery/
mpvqueue %U
^https?://areena.yle.fi.*
imageviewer %U
^https?://(?:[a-z0-9\-]+\.)+[a-z]{2,6}(?:/[^/#?]+)+\.(?:jpg|jpeg|png|svg)
@ -48,6 +48,3 @@ alacritty -e rtv "%U"
alacritty -e rtv "%U"
^https?://redd.it.*
mpv "$(yle-dl --showurl %U)"
^https?://areena.yle.fi.*

View file

@ -1,25 +1,24 @@
music_directory "~/music"
playlist_directory "~/music/Playlists"
db_file "~/.mpd/database"
log_file "~/.mpd/log"
pid_file "~/.mpd/pid"
state_file "~/.mpd/state"
sticker_file "~/.mpd/sticker.sql"
music_directory "~/Music"
playlist_directory "~/Music/Playlists"
db_file "~/.mpd/database"
log_file "~/.mpd/log"
state_file "~/.mpd/state"
sticker_file "~/.mpd/sticker.sql"
replaygain "track"
replaygain "track"
default_permissions "read"
password "{{@@ env['PASS_MPD'] @@}}@read,add,control"
password "{{@@ env['PASS_MPD_ADMIN'] @@}}@read,add,control,admin"
default_permissions "read,add,control"
password "{{@@ env['PASS_MPD'] @@}}@read,add,control"
password "{{@@ env['PASS_MPD_ADMIN'] @@}}@read,add,control,admin"
audio_output {
type "fifo"
name "Visualizer"
path "/tmp/mpd.fifo"
format "44100:16:2"
type "fifo"
name "Visualizer"
path "/tmp/mpd.fifo"
format "44100:16:2"
}
audio_output {
type "pulse"
name "MPD PulseAudio"
type "pipewire"
name "MPD PipeWire"
}

View file

@ -22,3 +22,5 @@ MUTE cycle ao-mute
= add audio-delay 0.100
- add audio-delay -0.100
s playlist-shuffle

View file

@ -7,10 +7,8 @@ vo=gpu
hwdec=vaapi
hwdec-codecs=all
{%@@ if profile == "Mirkwood" @@%}
{%@@ if wayland @@%}
gpu-context=wayland
{%@@ elif profile == "Rivendell" @@%}
ao=alsa
{%@@ endif @@%}
#############
@ -27,8 +25,12 @@ replaygain=track
# Start ipc server
input-ipc-server=/tmp/mpvsocket
# set youtube-dl max res to 1080
# set youtube-dl max res
{%@@ if profile == "Moria" @@%}
ytdl-format=bestvideo[height<=2160]+bestaudio/best[height<=2160]
{%@@ else @@%}
ytdl-format=bestvideo[height<=1080]+bestaudio/best[height<=1080]
{%@@ endif @@%}
# continue watching
save-position-on-quit
@ -72,7 +74,7 @@ osd-bar-w=60 # width of " " "
osd-shadow-color="#11000000"
osd-fractions
# Protocol specific configuration
# Protocol specific configuration
[protocol.https]
cache=yes
user-agent='Mozilla/5.0 (X11; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0'
@ -104,8 +106,4 @@ ytdl-format="bestvideo[height<=2160]+bestaudio/best[height<=2160]"
[best]
ytdl-format="bestvideo+bestaudio"
# Vulkan hwdec profile
[vulkan]
gpu-api=vulkan
gpu-context=waylandvk
hwdec=vaapi-copy
script-opts-append=ytdl_hook-ytdl_path=yt-dlp

View file

@ -0,0 +1,76 @@
-- Copied from https://github.com/pekkarr/mpv-yledl
-- Copyright 2021 Pekka Ristola
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
local msg = require 'mp.msg'
local utils = require 'mp.utils'
local function add_series(data)
local playlist = { "#EXTM3U" }
for _, episode in pairs(data) do
table.insert(playlist, episode["webpage"])
end
mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))
end
local function add_single_video(data)
local flavors = data["flavors"]
table.sort(flavors, function(a, b) return a["bitrate"] > b["bitrate"] end)
local best = flavors[1]
mp.set_property("stream-open-filename", best["url"])
mp.set_property("file-local-options/force-media-title", data["title"])
for _, sub in ipairs(data["subtitles"]) do
local lang = sub["language"]
msg.verbose("Adding subtitles for " .. lang)
mp.commandv("sub-add", sub["url"], "auto", sub["category"], lang)
end
end
mp.add_hook("on_load", 9, function()
msg.verbose('yle-dl hook')
local url = mp.get_property("stream-open-filename", "")
if (url:find("https?://%a+%.yle%.fi/") == 1) or (url:find("https?://yle%.fi/") == 1) then
local start_time = os.clock()
local command = { "yle-dl", "--showmetadata", url }
msg.debug("Running: " .. table.concat(command, ' '))
local ret = mp.command_native({name = "subprocess",
args = command,
capture_stdout = true,
capture_stderr = false})
if ret.killed_by_us then
return
end
if (ret.status < 0) or (ret.stdout == nil) or (ret.stdout == "") then
msg.error("yle-dl failed to parse url")
return
end
local json, err = utils.parse_json(ret.stdout)
if (json == nil) then
msg.error("failed to parse JSON: " .. err)
return
end
msg.verbose("yle-dl succeeded")
msg.debug("running yle-dl took " .. os.clock() - start_time .. " seconds")
if #json == 1 then
add_single_video(json[1])
else
add_series(json)
end
else
msg.verbose('not an areena url')
end
end)

View file

@ -1,99 +0,0 @@
SPACE repeatable playlist-next
alt+SPACE repeatable playlist-prev
UP ignore
DOWN ignore
LEFT repeatable playlist-prev
RIGHT repeatable playlist-next
# simple reminder of default bindings
#1 add contrast -1
#2 add contrast 1
#3 add brightness -1
#4 add brightness 1
#5 add gamma -1
#6 add gamma 1
#7 add saturation -1
#8 add saturation 1
# mouse-centric bindings
MBTN_RIGHT script-binding image_viewer/drag-to-pan
MBTN_LEFT script-binding image_viewer/pan-follows-cursor
WHEEL_UP script-message cursor-centric-zoom 0.1
WHEEL_DOWN script-message cursor-centric-zoom -0.1
# panning with the keyboard:
# pan-image takes the following arguments
# pan-image AXIS AMOUNT ZOOM_INVARIANT IMAGE_CONSTRAINED
# ^ ^ ^
# x or y | |
# | |
# if yes, will pan by the same if yes, stops panning if the image
# amount regardless of zoom would go outside of the window
ctrl+down repeatable script-message pan-image y -0.1 yes yes
ctrl+up repeatable script-message pan-image y +0.1 yes yes
ctrl+right repeatable script-message pan-image x -0.1 yes yes
ctrl+left repeatable script-message pan-image x +0.1 yes yes
# now with more precision
alt+down repeatable script-message pan-image y -0.01 yes yes
alt+up repeatable script-message pan-image y +0.01 yes yes
alt+right repeatable script-message pan-image x -0.01 yes yes
alt+left repeatable script-message pan-image x +0.01 yes yes
# replace at will with h,j,k,l if you prefer vim-style bindings
# on a trackpad you may want to use these
#WHEEL_UP repeatable script-message pan-image y -0.02 yes yes
#WHEEL_DOWN repeatable script-message pan-image y +0.02 yes yes
#WHEEL_LEFT repeatable script-message pan-image x -0.02 yes yes
#WHEEL_RIGHT repeatable script-message pan-image x +0.02 yes yes
# align the border of the image to the border of the window
# align-border takes the following arguments:
# align-border ALIGN_X ALIGN_Y
# any value for ALIGN_* is accepted, -1 and 1 map to the border of the window
ctrl+shift+right script-message align-border -1 ""
ctrl+shift+left script-message align-border 1 ""
ctrl+shift+down script-message align-border "" -1
ctrl+shift+up script-message align-border "" 1
# reset the image
ctrl+0 no-osd set video-pan-x 0; no-osd set video-pan-y 0; no-osd set video-zoom 0
+ add video-zoom 0.5
- add video-zoom -0.5; script-message reset-pan-if-visible
= no-osd set video-zoom 0; script-message reset-pan-if-visible
# sxiv compatibility
w no-osd set video-unscaled yes; keypress =
e no-osd set video-unscaled no; keypress =
h no-osd vf toggle hflip; show-text "Horizontal flip"
v no-osd vf toggle vflip; show-text "Vertical flip"
r script-message rotate-video 90; show-text "Clockwise rotation"
R script-message rotate-video -90; show-text "Counter-clockwise rotation"
alt+r no-osd set video-rotate 0; show-text "Reset rotation"
d script-message ruler
# Toggling between pixel-exact reproduction and interpolation
a cycle-values scale nearest ewa_lanczossharp
# Toggle color management on or off
c cycle icc-profile-auto
# Screenshot of the window output
S screenshot window
# Toggle aspect ratio information on and off
A cycle-values video-aspect "-1" "no"
p script-message force-print-filename
# ADVANCED: you can define bindings that belong to a "section" (named "image-viewer" here) like so:
#alt+SPACE {image-viewer} repeatable playlist-prev
#SPACE {image-viewer} repeatable playlist-next
# to load them conditionally with a command. See scripts-opts/image_viewer.conf for how you can do this

View file

@ -1,46 +0,0 @@
## IMAGE
# classic opengl-hq parameter, change at will
scale=spline36
cscale=spline36
dscale=mitchell
dither-depth=auto
correct-downscaling
sigmoid-upscaling
# debanding seems rarely useful with images
#deband
## MISC
mute=yes
# the osc is mostly useful for videos
osc=no
# don't try to autoload subtitles or audio files
sub-auto=no
audio-file-auto=no
# get rid of the useless V: 00:00:00 / 00:00:00 line
term-status-msg=
# replace mpv with mvi in the window title
title="${?media-title:${media-title}}${!media-title:No file} - mvi"
# don't slideshow by default
image-display-duration=inf
# loop files in case of webms or gifs
loop-file=inf
# and loop the whole playlist
loop-playlist=inf
# you need this if you plan to use drag-to-pan or pan-follows-cursor with MOUSE_LEFT
window-dragging=no
#according to haasn, aspect ratio info for PNG and JPG is "universally bust"
[extension.png]
video-aspect=no
[extension.jpg]
video-aspect=no
[extension.jpeg]
profile=extension.jpg
[silent]
msg-level=all=no

View file

@ -1,78 +0,0 @@
## MISC
# size of the margins with pan-follows-cursor
pan_follows_cursor_margin=50
# whether pan-follows-cursor should pan when the entire image is visible
pan_follows_cursor_move_if_full_view=no
## STATUS LINE
# whether to show a status line
status_line_enabled=yes
# its position, possible values: (bottom|top)_(left|right)
status_line_position=bottom_left
# its font size
status_line_size=36
# the text to be expanded
# see property expansion: https://mpv.io/manual/master/#property-expansion
# \N can be used for line breaks
# you can also use ass tags, see here: http://docs.aegisub.org/3.2/ASS_Tags/
status_line=${filename} [${playlist-pos-1}/${playlist-count}]
## MINIMAP
# whether to show a minimap
minimap_enabled=yes
# the position of the center of the minimap, in percentage of the window (x, y)
minimap_center=92,92
# the scale of the minimap (i.e. the view rectangle is scale / 100 times the size of the window)
minimap_scale=12
# the cutoff size of the minimap (i.e. the image rectangle is clipped if it falls outside of the this zone)
minimap_max_size=16,16
# opacity of the "image" (from 00=opaque to FF=transparent)
minimap_image_opacity=88
# color of the "image" (#BBGGRR where each component rages from 00 to FF)
minimap_image_color=BBBBBB
# opacity of the "view"
minimap_view_opacity=BB
minimap_view_color=222222
# whether the view should be drawn above the image
minimap_view_above_image=yes
# whether to show the minimap if the current image is fully visible
minimap_hide_when_full_image_in_view=yes
## RULER
# whether to show the length of the lines between the two points
ruler_show_distance=yes
# whether to show the coordinates of the two points
ruler_show_coordinates=yes
# the coordinate space of the text shown. Can be "image", "window", "both"
ruler_coordinates_space=image
# can be "degrees", "radians", "both", or "no"
ruler_show_angles=degrees
ruler_line_width=2
ruler_dots_radius=3
ruler_font_size=36
# ranges from 00 (black) to FF (white)
ruler_line_color=33
# bindings used to set points. The binding to trigger ruler mode can also be used. Comma-separated list
ruler_confirm_bindings=MBTN_LEFT,ENTER
# bindings used to set points. The binding to trigger ruler mode can also be used. Comma-separated list
ruler_exit_bindings=ESC
# if yes, the first point will be immediately set at the cursor position when calling 'ruler'
ruler_set_first_point_on_begin=no
# if yes, the ruler overlay will be immediately cleared when setting the second point
ruler_clear_on_second_point_set=no
## HOOKS
# commands to execute when a file detected as an image (1 frame, no audio) is loaded or unloaded
# an image was loaded, and the previous file was not an image (or there was no previous file)
command_on_first_image_loaded=
# an image was loaded (regardless of what the previous file was)
command_on_image_loaded=
# a non-image was loaded, and the previous file was an image
command_on_non_image_loaded=
# the purpose of these "hooks" is to let you change bindings, profiles, reset properties...
# see https://mpv.io/manual/master/#list-of-input-commands for general command information
# note that there is no such thing as "unloading a profile", to emulate this you must create an opposite profile and load that
# example possible values:
#command_on_first_image_loaded=apply-profile image; enable-section image-viewer; script-message enable-status-line
#command_on_image_loaded=no-osd set video-pan-x 0; script-message align-border "" -1
#command_on_non_image_loaded=disable-section image-viewer; no-osd set video-pan-x 0; no-osd set video-pan-y 0; no-osd set video-zoom 0; script-message disable-status-line

View file

@ -1,953 +0,0 @@
local opts = {
pan_follows_cursor_margin = 50,
pan_follows_cursor_move_if_full_view = false,
status_line_enabled = false,
status_line_position = "bottom_left",
status_line_size = 36,
status_line = "${filename} [${playlist-pos-1}/${playlist-count}]",
minimap_enabled = true,
minimap_center = "92,92",
minimap_scale = 12,
minimap_max_size = "16,16",
minimap_image_opacity = "88",
minimap_image_color = "BBBBBB",
minimap_view_opacity = "BB",
minimap_view_color = "222222",
minimap_view_above_image = true,
minimap_hide_when_full_image_in_view = true,
ruler_show_distance=true,
ruler_show_coordinates=true,
ruler_coordinates_space="both",
ruler_show_angles="degrees",
ruler_line_width=2,
ruler_dots_radius=3,
ruler_font_size=36,
ruler_line_color="33",
ruler_confirm_bindings="MBTN_LEFT,ENTER",
ruler_exit_bindings="ESC",
ruler_set_first_point_on_begin=false,
ruler_clear_on_second_point_set=false,
command_on_first_image_loaded="",
command_on_image_loaded="",
command_on_non_image_loaded="",
}
(require 'mp.options').read_options(opts)
function split(input)
local ret = {}
for str in string.gmatch(input, "([^,]+)") do
ret[#ret + 1] = str
end
return ret
end
function str_to_num(array)
local ret = {}
for _, v in ipairs(array) do
ret[#ret + 1] = tonumber(v)
end
return ret
end
opts.minimap_center=str_to_num(split(opts.minimap_center))
opts.minimap_max_size=str_to_num(split(opts.minimap_max_size))
opts.ruler_confirm_bindings=split(opts.ruler_confirm_bindings)
opts.ruler_exit_bindings=split(opts.ruler_exit_bindings)
function clamp(value, low, high)
if value <= low then
return low
elseif value >= high then
return high
else
return value
end
end
local msg = require 'mp.msg'
local assdraw = require 'mp.assdraw'
local ass = { -- shared ass state
status_line = "",
minimap = "",
ruler = "",
}
local cleanup = nil -- function set up by drag-to-pan/pan-follows cursor and must be called to clean lingering state
local mouse_move_callbacks = {} -- functions that are called when mouse_move is triggered
function add_mouse_move_callback(key, func)
if #mouse_move_callbacks == 0 then
mp.add_forced_key_binding("mouse_move", "image-viewer-internal", function()
for _, func in pairs(mouse_move_callbacks) do
func()
end
end)
end
mouse_move_callbacks[key] = func
end
function remove_mouse_move_callback(key)
mouse_move_callbacks[key] = nil
for _,_ in pairs(mouse_move_callbacks) do
return
end
mp.remove_key_binding("image-viewer-internal")
end
video_dimensions_stale = true
function get_video_dimensions()
-- this function is very much ripped from video/out/aspect.c in mpv's source
if not video_dimensions_stale then return _video_dimensions end
local video_params = mp.get_property_native("video-out-params")
if not video_params then
_video_dimensions = nil
return nil
end
if not _timestamp then _timestamp = 0 end
_timestamp = _timestamp + 1
_video_dimensions = {
timestamp = _timestamp,
top_left = {x = 0, y = 0},
bottom_right = {x = 0, y = 0},
size = {w = 0, h = 0},
ratios = {w = 0, h = 0}, -- by how much the original video got scaled
}
local keep_aspect = mp.get_property_bool("keepaspect")
local w = video_params["w"]
local h = video_params["h"]
local dw = video_params["dw"]
local dh = video_params["dh"]
if mp.get_property_number("video-rotate") % 180 == 90 then
w, h = h,w
dw, dh = dh, dw
end
local window_w, window_h = mp.get_osd_size()
if keep_aspect then
local unscaled = mp.get_property_native("video-unscaled")
local panscan = mp.get_property_number("panscan")
local fwidth = window_w
local fheight = math.floor(window_w / dw * dh)
if fheight > window_h or fheight < h then
local tmpw = math.floor(window_h / dh * dw)
if tmpw <= window_w then
fheight = window_h
fwidth = tmpw
end
end
local vo_panscan_area = window_h - fheight
local f_w = fwidth / fheight
local f_h = 1
if vo_panscan_area == 0 then
vo_panscan_area = window_h - fwidth
f_w = 1
f_h = fheight / fwidth
end
if unscaled or unscaled == "downscale-big" then
vo_panscan_area = 0
if unscaled or (dw <= window_w and dh <= window_h) then
fwidth = dw
fheight = dh
end
end
local scaled_width = fwidth + math.floor(vo_panscan_area * panscan * f_w)
local scaled_height = fheight + math.floor(vo_panscan_area * panscan * f_h)
local split_scaling = function (dst_size, scaled_src_size, zoom, align, pan)
scaled_src_size = math.floor(scaled_src_size * 2 ^ zoom)
align = (align + 1) / 2
local dst_start = math.floor((dst_size - scaled_src_size) * align + pan * scaled_src_size)
if dst_start < 0 then
--account for C int cast truncating as opposed to flooring
dst_start = dst_start + 1
end
local dst_end = dst_start + scaled_src_size;
if dst_start >= dst_end then
dst_start = 0
dst_end = 1
end
return dst_start, dst_end
end
local zoom = mp.get_property_number("video-zoom")
local align_x = mp.get_property_number("video-align-x")
local pan_x = mp.get_property_number("video-pan-x")
_video_dimensions.top_left.x, _video_dimensions.bottom_right.x = split_scaling(window_w, scaled_width, zoom, align_x, pan_x)
local align_y = mp.get_property_number("video-align-y")
local pan_y = mp.get_property_number("video-pan-y")
_video_dimensions.top_left.y, _video_dimensions.bottom_right.y = split_scaling(window_h, scaled_height, zoom, align_y, pan_y)
else
_video_dimensions.top_left.x = 0
_video_dimensions.bottom_right.x = window_w
_video_dimensions.top_left.y = 0
_video_dimensions.bottom_right.y = window_h
end
_video_dimensions.size.w = _video_dimensions.bottom_right.x - _video_dimensions.top_left.x
_video_dimensions.size.h = _video_dimensions.bottom_right.y - _video_dimensions.top_left.y
_video_dimensions.ratios.w = _video_dimensions.size.w / w
_video_dimensions.ratios.h = _video_dimensions.size.h / h
video_dimensions_stale = false
return _video_dimensions
end
for _, p in ipairs({
"keepaspect",
"video-out-params",
"video-unscaled",
"panscan",
"video-zoom",
"video-align-x",
"video-pan-x",
"video-align-y",
"video-pan-y",
"osd-width",
"osd-height",
}) do
mp.observe_property(p, "native", function() video_dimensions_stale = true end)
end
function drag_to_pan_handler(table)
if cleanup then
cleanup()
cleanup = nil
end
if table["event"] == "down" then
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local mouse_pos_origin, video_pan_origin = {}, {}
local moved = false
mouse_pos_origin.x, mouse_pos_origin.y = mp.get_mouse_pos()
video_pan_origin.x = mp.get_property("video-pan-x")
video_pan_origin.y = mp.get_property("video-pan-y")
local idle = function()
if moved then
local mX, mY = mp.get_mouse_pos()
local pX = video_pan_origin.x + (mX - mouse_pos_origin.x) / video_dimensions.size.w
local pY = video_pan_origin.y + (mY - mouse_pos_origin.y) / video_dimensions.size.h
mp.command("no-osd set video-pan-x " .. clamp(pX, -3, 3) .. "; no-osd set video-pan-y " .. clamp(pY, -3, 3))
moved = false
end
end
mp.register_idle(idle)
add_mouse_move_callback("drag-to-pan", function() moved = true end)
cleanup = function()
remove_mouse_move_callback("drag-to-pan")
mp.unregister_idle(idle)
end
end
end
function pan_follows_cursor_handler(table)
if cleanup then
cleanup()
cleanup = nil
end
if table["event"] == "down" then
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local window_w, window_h = mp.get_osd_size()
local moved = true
local idle = function()
if moved then
local mX, mY = mp.get_mouse_pos()
local x = math.min(1, math.max(- 2 * mX / window_w + 1, -1))
local y = math.min(1, math.max(- 2 * mY / window_h + 1, -1))
local command = ""
local margin, move_full = opts.pan_follows_cursor_margin, opts.pan_follows_cursor_move_if_full_view
if (not move_full and window_w < video_dimensions.size.w) then
command = command .. "no-osd set video-pan-x " .. clamp(x * (video_dimensions.size.w - window_w + 2 * margin) / (2 * video_dimensions.size.w), -3, 3) .. ";"
elseif mp.get_property_number("video-pan-x") ~= 0 then
command = command .. "no-osd set video-pan-x " .. "0;"
end
if (not move_full and window_h < video_dimensions.size.h) then
command = command .. "no-osd set video-pan-y " .. clamp(y * (video_dimensions.size.h - window_h + 2 * margin) / (2 * video_dimensions.size.h), -3, 3) .. ";"
elseif mp.get_property_number("video-pan-y") ~= 0 then
command = command .. "no-osd set video-pan-y " .. "0;"
end
if command ~= "" then
mp.command(command)
end
moved = false
end
end
mp.register_idle(idle)
add_mouse_move_callback("pan-follows-cursor", function() moved = true end)
cleanup = function()
remove_mouse_move_callback("pan-follows-cursor")
mp.unregister_idle(idle)
end
end
end
function cursor_centric_zoom_handler(amt)
local zoom_inc = tonumber(amt)
if not zoom_inc or zoom_inc == 0 then return end
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local mouse_pos_origin, video_pan_origin = {}, {}
mouse_pos_origin.x, mouse_pos_origin.y = mp.get_mouse_pos()
video_pan_origin.x = mp.get_property("video-pan-x")
video_pan_origin.y = mp.get_property("video-pan-y")
local zoom_origin = mp.get_property("video-zoom")
-- how far the cursor is form the middle of the video (in percentage)
local rx = (video_dimensions.top_left.x + video_dimensions.size.w / 2 - mouse_pos_origin.x) / (video_dimensions.size.w / 2)
local ry = (video_dimensions.top_left.y + video_dimensions.size.h / 2 - mouse_pos_origin.y) / (video_dimensions.size.h / 2)
-- the size in pixels of the (in|de)crement
local diffHeight = (2 ^ zoom_inc - 1) * video_dimensions.size.h
local diffWidth = (2 ^ zoom_inc - 1) * video_dimensions.size.w
local newPanX = (video_pan_origin.x * video_dimensions.size.w + rx * diffWidth / 2) / (video_dimensions.size.w + diffWidth)
local newPanY = (video_pan_origin.y * video_dimensions.size.h + ry * diffHeight / 2) / (video_dimensions.size.h + diffHeight)
mp.command("no-osd set video-zoom " .. zoom_origin + zoom_inc .. "; no-osd set video-pan-x " .. clamp(newPanX, -3, 3) .. "; no-osd set video-pan-y " .. clamp(newPanY, -3, 3))
end
function align_border(x, y)
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local window_w, window_h = mp.get_osd_size()
local x, y = tonumber(x), tonumber(y)
local command = ""
if x then
command = command .. "no-osd set video-pan-x " .. clamp(x * (video_dimensions.size.w - window_w) / (2 * video_dimensions.size.w), -3, 3) .. ";"
end
if y then
command = command .. "no-osd set video-pan-y " .. clamp(y * (video_dimensions.size.h - window_h) / (2 * video_dimensions.size.h), -3, 3) .. ";"
end
if command ~= "" then
mp.command(command)
end
end
function pan_image(axis, amount, zoom_invariant, image_constrained)
amount = tonumber(amount)
if not amount or amount == 0 or axis ~= "x" and axis ~= "y" then return end
if zoom_invariant == "yes" then
amount = amount / 2 ^ mp.get_property_number("video-zoom")
end
local prop = "video-pan-" .. axis
local old_pan = mp.get_property_number(prop)
if image_constrained == "yes" then
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local measure = axis == "x" and "w" or "h"
local window = {}
window.w, window.h = mp.get_osd_size()
local pixels_moved = amount * video_dimensions.size[measure]
-- should somehow refactor this
if pixels_moved > 0 then
if window[measure] > video_dimensions.size[measure] then
if video_dimensions.bottom_right[axis] >= window[measure] then return end
if video_dimensions.bottom_right[axis] + pixels_moved > window[measure] then
amount = (window[measure] - video_dimensions.bottom_right[axis]) / video_dimensions.size[measure]
end
else
if video_dimensions.top_left[axis] >= 0 then return end
if video_dimensions.top_left[axis] + pixels_moved > 0 then
amount = (0 - video_dimensions.top_left[axis]) / video_dimensions.size[measure]
end
end
else
if window[measure] > video_dimensions.size[measure] then
if video_dimensions.top_left[axis] <= 0 then return end
if video_dimensions.top_left[axis] + pixels_moved < 0 then
amount = (0 - video_dimensions.top_left[axis]) / video_dimensions.size[measure]
end
else
if video_dimensions.bottom_right[axis] <= window[measure] then return end
if video_dimensions.bottom_right[axis] + pixels_moved < window[measure] then
amount = (window[measure] - video_dimensions.bottom_right[axis]) / video_dimensions.size[measure]
end
end
end
end
mp.set_property_number(prop, old_pan + amount)
end
function rotate_video(amt)
local rot = mp.get_property_number("video-rotate")
rot = (rot + amt) % 360
mp.set_property_number("video-rotate", rot)
end
function reset_pan_if_visible()
local video_dimensions = get_video_dimensions()
if not video_dimensions then return end
local window_w, window_h = mp.get_osd_size()
local command = ""
if (window_w >= video_dimensions.size.w) then
command = command .. "no-osd set video-pan-x 0" .. ";"
end
if (window_h >= video_dimensions.size.h) then
command = command .. "no-osd set video-pan-y 0" .. ";"
end
if command ~= "" then
mp.command(command)
end
end
function force_print_filename()
mp.set_property("msg-level", "cplayer=info")
mp.commandv("print-text", mp.get_property("path"))
mp.set_property("msg-level", "all=no")
end
function draw_ass()
local ww, wh = mp.get_osd_size()
local merge = function(a, b)
return b ~= "" and (a .. "\n" .. b) or a
end
mp.set_osd_ass(ww, wh, merge(merge(ass.status_line, ass.minimap), ass.ruler))
end
local status_line_enabled = false
local status_line_stale = true
function mark_status_line_stale()
status_line_stale = true
end
function refresh_status_line()
if not status_line_stale then return end
status_line_stale = false
local path = mp.get_property("path")
if path == nil or path == "" then
ass.status_line = ""
draw_ass()
return
end
local expanded = mp.command_native({ "expand-text", opts.status_line })
if not expanded then
msg.warn("Error expanding status line")
ass.status_line = ""
draw_ass()
return
end
local w,h = mp.get_osd_size()
local an, x, y
local margin = 10
if opts.status_line_position == "top_left" then
x = margin
y = margin
an = 7
elseif opts.status_line_position == "top_right" then
x = w-margin
y = margin
an = 9
elseif opts.status_line_position == "bottom_right" then
x = w-margin
y = h-margin
an = 3
else
x = margin
y = h-margin
an = 1
end
local a = assdraw:ass_new()
a:new_event()
a:an(an)
a:pos(x,y)
a:append("{\\fs".. opts.status_line_size.. "}{\\bord1.0}")
a:append(expanded)
ass.status_line = a.text
draw_ass()
end
function enable_status_line()
if status_line_enabled then return end
status_line_enabled = true
local start = 0
while true do
local s, e, cap = string.find(opts.status_line, "%${[?!]?([%l%d-/]*)", start)
if not s then break end
mp.observe_property(cap, nil, mark_status_line_stale)
start = e
end
mp.observe_property("path", nil, mark_status_line_stale)
mp.observe_property("osd-width", nil, mark_status_line_stale)
mp.observe_property("osd-height", nil, mark_status_line_stale)
mp.register_idle(refresh_status_line)
mark_status_line_stale()
end
function disable_status_line()
if not status_line_enabled then return end
status_line_enabled = false
mp.unobserve_property(mark_status_line_stale)
mp.unregister_idle(refresh_status_line)
ass.status_line = ""
draw_ass()
end
if opts.status_line_enabled then
enable_status_line()
end
if opts.command_on_image_loaded ~= "" or opts.command_on_non_image_loaded ~= "" then
local was_image = false
local frame_count = nil
local audio_tracks = nil
local out_params_ready = nil
local path = nil
function state_changed()
function set_image(is_image)
if is_image and not was_image and opts.command_on_first_image_loaded ~= "" then
mp.command(opts.command_on_first_image_loaded)
end
if is_image and opts.command_on_image_loaded ~= "" then
mp.command(opts.command_on_image_loaded)
end
if not is_image and was_image and opts.command_on_non_image_loaded ~= "" then
mp.command(opts.command_on_non_image_loaded)
end
was_image = is_image
end
-- only do things when state is consistent
if path ~= nil and audio_tracks ~= nil then
if frame_count == nil and audio_tracks > 0 then
set_image(false)
elseif out_params_ready and frame_count ~= nil then
-- png have 0 frames, jpg 1 ¯\_(ツ)_/¯
set_image((frame_count == 0 or frame_count == 1) and audio_tracks == 0)
end
end
end
mp.observe_property("video-out-params/par", "number", function(_, val)
out_params_ready = (val ~= nil and val > 0)
state_changed()
end)
mp.observe_property("estimated-frame-count", "number", function(_, val)
frame_count = val
state_changed()
end)
mp.observe_property("path", "string", function(_, val)
if not val or val == "" then
path = nil
else
path = val
end
state_changed()
end)
mp.register_event("tracks-changed", function()
audio_tracks = 0
local tracks = 0
for _, track in ipairs(mp.get_property_native("track-list")) do
tracks = tracks + 1
if track.type == "audio" then
audio_tracks = audio_tracks + 1
end
end
if tracks == 0 then
audio_tracks = nil
end
state_changed()
end)
end
function refresh_minimap()
local dim = get_video_dimensions()
if not dim then
ass.minimap = ""
draw_ass()
return
end
if _minimap_old_timestamp and dim.timestamp == _minimap_old_timestamp then return end
_minimap_old_timestamp = dim.timestamp
local ww, wh = mp.get_osd_size()
if opts.minimap_hide_when_full_image_in_view then
if dim.top_left.x >= 0 and
dim.top_left.y >= 0 and
dim.bottom_right.x <= ww and
dim.bottom_right.y <= wh
then
ass.minimap = ""
draw_ass()
return
end
end
local center = {
x=opts.minimap_center[1]/100*ww,
y=opts.minimap_center[2]/100*wh
}
local cutoff = {
x=opts.minimap_max_size[1]/100*ww/2,
y=opts.minimap_max_size[2]/100*wh/2
}
local a = assdraw.ass_new()
local draw = function(x, y, w, h, opacity, color)
a:new_event()
a:pos(center.x, center.y)
a:append("{\\bord0}")
a:append("{\\shad0}")
a:append("{\\c&" .. color .. "&}")
a:append("{\\2a&HFF}")
a:append("{\\3a&HFF}")
a:append("{\\4a&HFF}")
a:append("{\\1a&H" .. opacity .. "}")
w=w/2
h=h/2
a:draw_start()
local rounded = {true,true,true,true} -- tl, tr, br, bl
local x0,y0,x1,y1 = x-w, y-h, x+w, y+h
if x0 < -cutoff.x then
x0 = -cutoff.x
rounded[4] = false
rounded[1] = false
end
if y0 < -cutoff.y then
y0 = -cutoff.y
rounded[1] = false
rounded[2] = false
end
if x1 > cutoff.x then
x1 = cutoff.x
rounded[2] = false
rounded[3] = false
end
if y1 > cutoff.y then
y1 = cutoff.y
rounded[3] = false
rounded[4] = false
end
local r = 3
local c = 0.551915024494 * r
if rounded[0] then
a:move_to(x0 + r, y0)
else
a:move_to(x0,y0)
end
if rounded[1] then
a:line_to(x1 - r, y0)
a:bezier_curve(x1 - r + c, y0, x1, y0 + r - c, x1, y0 + r)
else
a:line_to(x1, y0)
end
if rounded[2] then
a:line_to(x1, y1 - r)
a:bezier_curve(x1, y1 - r + c, x1 - r + c, y1, x1 - r, y1)
else
a:line_to(x1, y1)
end
if rounded[3] then
a:line_to(x0 + r, y1)
a:bezier_curve(x0 + r - c, y1, x0, y1 - r + c, x0, y1 - r)
else
a:line_to(x0, y1)
end
if rounded[4] then
a:line_to(x0, y0 + r)
a:bezier_curve(x0, y0 + r - c, x0 + r - c, y0, x0 + r, y0)
else
a:line_to(x0, y0)
end
a:draw_stop()
end
local image = function()
draw((dim.top_left.x + dim.size.w/2 - ww/2) / opts.minimap_scale,
(dim.top_left.y + dim.size.h/2 - wh/2) / opts.minimap_scale,
dim.size.w / opts.minimap_scale,
dim.size.h / opts.minimap_scale,
opts.minimap_image_opacity,
opts.minimap_image_color)
end
local view = function()
draw(0,
0,
ww / opts.minimap_scale,
wh / opts.minimap_scale,
opts.minimap_view_opacity,
opts.minimap_view_color)
end
if opts.minimap_view_above_image then
image()
view()
else
view()
image()
end
ass.minimap = a.text
draw_ass()
end
local minimap_enabled = false
function enable_minimap()
if minimap_enabled then return end
minimap_enabled = true
mp.register_idle(refresh_minimap)
end
function disable_minimap()
if not minimap_enabled then return end
minimap_enabled = false
ass.minimap = a.text
draw_ass()
mp.unregister_idle(refresh_minimap)
end
if opts.minimap_enabled then
enable_minimap()
end
local ruler_state = 0 -- {0,1,2,3} = {inactive,setting first point,setting second point,done}
local ruler_first_point = nil -- in video space coordinates
local ruler_second_point = nil -- in video space coordinates
function cursor_video_space()
local dim = get_video_dimensions()
if not dim then return nil end
local mx, my = mp.get_mouse_pos()
local ret = {}
ret.x = (mx - dim.top_left.x) / dim.ratios.w
ret.y = (my - dim.top_left.y) / dim.ratios.h
return ret
end
function video_space_to_screen(point)
local dim = get_video_dimensions()
if not dim then return nil end
local ret = {}
ret.x = point.x * dim.ratios.w + dim.top_left.x
ret.y = point.y * dim.ratios.h + dim.top_left.y
return ret
end
function refresh_ruler()
local dim = get_video_dimensions()
if not dim then
ass.ruler = ""
draw_ass()
return
end
local line_start = {}
local line_end = {}
if ruler_second_point then
line_start.image = ruler_first_point
line_start.screen = video_space_to_screen(ruler_first_point)
line_end.image = ruler_second_point
line_end.screen = video_space_to_screen(ruler_second_point)
elseif ruler_first_point then
line_start.image = ruler_first_point
line_start.screen = video_space_to_screen(ruler_first_point)
line_end.image = cursor_video_space()
line_end.screen = {}
line_end.screen.x, line_end.screen.y = mp.get_mouse_pos()
else
local mx, my = mp.get_mouse_pos()
line_start.image = cursor_video_space()
line_start.screen = {}
line_start.screen.x, line_start.screen.y = mp.get_mouse_pos()
line_end = line_start
end
local distinct = (math.abs(line_start.screen.x - line_end.screen.x) >= 1
or math.abs(line_start.screen.y - line_end.screen.y) >= 1)
local a = assdraw:ass_new()
local draw_setup = function(bord)
a:new_event()
a:pos(0,0)
a:append("{\\bord" .. bord .. "}")
a:append("{\\shad0}")
local r = opts.ruler_line_color
a:append("{\\3c&H".. r .. r .. r .. "&}")
a:append("{\\1a&HFF}")
a:append("{\\2a&HFF}")
a:append("{\\3a&H00}")
a:append("{\\4a&HFF}")
a:draw_start()
end
local dot = function(pos, size)
draw_setup(size)
a:move_to(pos.x, pos.y-0.5)
a:line_to(pos.x, pos.y+0.5)
end
local line = function(from, to, size)
draw_setup(size)
a:move_to(from.x, from.y)
a:line_to(to.x, to.y)
end
if distinct then
dot(line_start.screen, opts.ruler_dots_radius)
line(line_start.screen, line_end.screen, opts.ruler_line_width)
dot(line_end.screen, opts.ruler_dots_radius)
else
dot(line_start.screen, opts.ruler_dots_radius)
end
local line_info = function()
if not opts.ruler_show_distance then return end
a:new_event()
a:append("{\\fs36}{\\bord1}")
a:pos((line_start.screen.x + line_end.screen.x) / 2, (line_start.screen.y + line_end.screen.y) / 2)
local an = 1
if line_start.image.x < line_end.image.x then an = an + 2 end
if line_start.image.y < line_end.image.y then an = an + 6 end
a:an(an)
local image = math.sqrt(math.pow(line_start.image.x - line_end.image.x, 2) + math.pow(line_start.image.y - line_end.image.y, 2))
local screen = math.sqrt(math.pow(line_start.screen.x - line_end.screen.x, 2) + math.pow(line_start.screen.y - line_end.screen.y, 2))
if opts.ruler_coordinates_space == "both" then
a:append(string.format("image: %.1f\\Nscreen: %.1f", image, screen))
elseif opts.ruler_coordinates_space == "image" then
a:append(string.format("%.1f", image))
elseif opts.ruler_coordinates_space == "window" then
a:append(string.format("%.1f", screen))
end
end
local dot_info = function(pos, opposite)
if not opts.ruler_show_coordinates then return end
a:new_event()
a:append("{\\fs" .. opts.ruler_font_size .."}{\\bord1}")
a:pos(pos.screen.x, pos.screen.y)
local an
if distinct then
an = 1
if line_start.image.x > line_end.image.x then an = an + 2 end
if line_start.image.y < line_end.image.y then an = an + 6 end
else
an = 7
end
if opposite then
an = 9 + 1 - an
end
a:an(an)
if opts.ruler_coordinates_space == "both" then
a:append(string.format("image: %.1f, %.1f\\Nscreen: %i, %i",
pos.image.x, pos.image.y, pos.screen.x, pos.screen.y))
elseif opts.ruler_coordinates_space == "image" then
a:append(string.format("%.1f, %.1f", pos.image.x, pos.image.y))
elseif opts.ruler_coordinates_space == "window" then
a:append(string.format("%i, %i", pos.screen.x, pos.screen.y))
end
end
dot_info(line_start, true)
if distinct then
line_info()
dot_info(line_end, false)
end
if distinct and opts.ruler_show_angles ~= "no" then
local dist = 50
local pos_from_angle = function(mult, angle)
return {
x = line_start.screen.x + mult * dist * math.cos(angle),
y = line_start.screen.y + mult * dist * math.sin(angle)
}
end
local extended = {x=line_start.screen.x, y=line_start.screen.y}
if line_end.screen.x > line_start.screen.x then
extended.x = extended.x + dist
else
extended.x = extended.x - dist
end
line(line_start.screen, extended, math.max(0, opts.ruler_line_width-0.5))
local angle = math.atan(math.abs(line_start.image.y - line_end.image.y) / math.abs(line_start.image.x - line_end.image.x))
local fix_angle
local an
if line_end.image.y < line_start.image.y and line_end.image.x > line_start.image.x then
-- upper-right
an = 4
fix_angle = function(angle) return - angle end
elseif line_end.image.y < line_start.image.y then
-- upper-left
an = 6
fix_angle = function(angle) return math.pi + angle end
elseif line_end.image.x < line_start.image.x then
-- bottom-left
an = 6
fix_angle = function(angle) return math.pi - angle end
else
-- bottom-right
an = 4
fix_angle = function(angle) return angle end
end
-- should implement this https://math.stackexchange.com/questions/873224/calculate-control-points-of-cubic-bezier-curve-approximating-a-part-of-a-circle
local cp1 = pos_from_angle(1, fix_angle(angle*1/4))
local cp2 = pos_from_angle(1, fix_angle(angle*3/4))
local p2 = pos_from_angle(1, fix_angle(angle))
a:bezier_curve(cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y)
a:new_event()
a:append("{\\fs" .. opts.ruler_font_size .."}{\\bord1}")
local text_pos = pos_from_angle(1.1, fix_angle(angle*2/3)) -- you'd think /2 would make more sense, but *2/3 looks better
a:pos(text_pos.x, text_pos.y)
a:an(an)
if opts.ruler_show_angles == "both" then
a:append(string.format("%.2f\\N%.1f°", angle, angle / math.pi * 180))
elseif opts.ruler_show_angles == "degrees" then
a:append(string.format("%.1f°", angle / math.pi * 180))
elseif opts.ruler_show_angles == "radians" then
a:append(string.format("%.2f", angle))
end
end
ass.ruler = a.text
draw_ass()
end
function ruler_next()
if ruler_state == 0 then
mp.register_idle(refresh_ruler)
add_mouse_move_callback("ruler", function() end) -- only used to get an idle event on mouse move
for _,key in ipairs(opts.ruler_confirm_bindings) do
mp.add_forced_key_binding(key, "ruler-next-" .. key, ruler_next)
end
for _,key in ipairs(opts.ruler_exit_bindings) do
mp.add_forced_key_binding(key, "ruler-stop-" .. key, ruler_stop)
end
ruler_state = 1
if opts.ruler_set_first_point_on_begin then
ruler_next()
end
elseif ruler_state == 1 then
ruler_first_point = cursor_video_space()
ruler_state = 2
elseif ruler_state == 2 then
ruler_state = 3
ruler_second_point = cursor_video_space()
if opts.ruler_clear_on_second_point_set then
ruler_next()
end
else
ruler_stop()
end
end
function ruler_stop()
if ruler_state == 0 then return end
mp.unregister_idle(refresh_ruler)
for _,key in ipairs(opts.ruler_confirm_bindings) do
mp.remove_key_binding("ruler-next-" .. key)
end
for _,key in ipairs(opts.ruler_exit_bindings) do
mp.remove_key_binding("ruler-stop-" .. key)
end
remove_mouse_move_callback("ruler")
ruler_state = 0
ruler_first_point = nil
ruler_second_point = nil
ass.ruler = ""
draw_ass()
end
mp.add_key_binding(nil, "drag-to-pan", drag_to_pan_handler, {complex = true})
mp.add_key_binding(nil, "pan-follows-cursor", pan_follows_cursor_handler, {complex = true})
mp.add_key_binding(nil, "cursor-centric-zoom", cursor_centric_zoom_handler)
mp.add_key_binding(nil, "align-border", align_border)
mp.add_key_binding(nil, "pan-image", pan_image)
mp.add_key_binding(nil, "rotate-video", rotate_video)
mp.add_key_binding(nil, "reset-pan-if-visible", reset_pan_if_visible)
mp.add_key_binding(nil, "force-print-filename", force_print_filename)
mp.add_key_binding(nil, "ruler", ruler_next)
mp.add_key_binding(nil, "enable-status-line", enable_status_line)
mp.add_key_binding(nil, "disable-status-line", disable_status_line)
mp.add_key_binding(nil, "toggle-status-line", function() if status_line_enabled then disable_status_line() else enable_status_line() end end)
mp.add_key_binding(nil, "enable-minimap", enable_minimap)
mp.add_key_binding(nil, "disable-minimap", disable_minimap)
mp.add_key_binding(nil, "toggle-minimap", function() if minimap_enabled then disable_minimap() else enable_minimap() end end)

View file

@ -0,0 +1,16 @@
= FunctionalHacker's NeoVim configuration
This is my personal NeoVim configuration I use for all text editing in my free
time and at my day job. I mostly code in Java, TypeScript and ReactJS, with
a bit of Rust and Python once in a blue moon.
The configuration is quite minimal but still fully featured. Some highlights
include
* LSP support with neovim's built in LSP client
** LSP servers are easily installed and auto-configured with Mason
* Treesitter
** Code folding
** Code highlighting
** Text objects
* Lazy plugin manager for fast startup times

View file

@ -1,33 +0,0 @@
{
"python.jediEnabled": false,
"suggest.noselect": false,
"suggest.echodocSupport": true,
"suggest.maxCompleteItemCount": 20,
"coc.preferences.formatOnSaveFiletypes": [],
"prettier.singleQuote": false,
"diagnostic.errorSign": "•",
"diagnostic.warningSign": "•",
"diagnostic.infoSign": "•",
"suggest.snippetIndicator": "~",
"rust-analyzer.serverPath": "/usr/bin/rust-analyzer",
"languageserver": {
"bash": {
"command": "bash-language-server",
"args": ["start"],
"filetypes": ["sh"],
"ignoredRootPaths": ["~"]
},
"xml": {
"command": "xml-language-server",
"args": ["start"],
"filetypes": ["xml"],
"ignoredRootPaths": ["~"]
}
},
"markdownlint.config": {
"rules": {
"default": true,
"line_length": false
}
}
}

View file

@ -1,96 +0,0 @@
" Auto-install vim-plug
if empty(glob('~/.config/nvim/autoload/plug.vim'))
silent !curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
autocmd VimEnter * PlugInstall
endif
" Set coc extensions
let g:coc_global_extensions = [
\ 'coc-tsserver',
\ 'coc-html',
\ 'coc-tsserver',
\ 'coc-json',
\ 'coc-yaml',
\ 'coc-texlab',
\ 'coc-prettier',
\ 'coc-python',
\ 'coc-emmet',
\ 'coc-rust-analyzer',
\ 'coc-markdownlint',
\ 'coc-snippets',
\ 'coc-java',
\ 'coc-flutter'
\ ]
call plug#begin()
" statusline/tabline
Plug 'vim-airline/vim-airline'
" Make editing passwords safer
Plug 'https://git.zx2c4.com/password-store', { 'rtp': 'contrib/vim/redact_pass.vim' }
" Colorize color words
Plug 'norcalli/nvim-colorizer.lua'
" NeoVim in Firefox
Plug 'glacambre/firenvim', { 'do': { _ -> firenvim#install(0) } }
" Spelling
Plug 'vim-scripts/Vimchant'
" Pandoc plugins
Plug 'vim-pandoc/vim-pandoc'
Plug 'conornewton/vim-pandoc-markdown-preview'
" Fuzzy finder
Plug 'junegunn/fzf'
Plug 'junegunn/fzf.vim'
" Language syntax pack
Plug 'sheerun/vim-polyglot'
" Read editorconfig settings
Plug 'editorconfig/editorconfig-vim'
" Make directory if it doesn't exist
Plug 'pbrisbin/vim-mkdir'
" Tree explorer
Plug 'scrooloose/nerdtree'
" Moar snippets
Plug 'honza/vim-snippets'
" Filetype icons
Plug 'ryanoasis/vim-devicons'
" Surround stuff with brackets and quotes
Plug 'tpope/vim-surround'
" Do stuff as sudo
Plug 'lambdalisue/suda.vim'
" Conguer of Completion
Plug 'neoclide/coc.nvim', {'do': './install.sh nightly'}
" VimL source for CoC
Plug 'Shougo/neco-vim'
Plug 'neoclide/coc-neco'
" Git plugin
Plug 'jreybert/vimagit'
" Git diff in gutter
Plug 'airblade/vim-gitgutter'
" Gpg support
Plug 'jamessan/vim-gnupg'
" Colorscheme
Plug 'joshdick/onedark.vim'
" Latex plugin
Plug 'lervag/vimtex'
call plug#end()

View file

@ -1,46 +0,0 @@
" Set colorscheme
colorscheme onedark
" Floating window transparency
set winblend=10
" Enable italics
let g:onedark_terminal_italics=1
" Disable built-in statusline because airline shows it
set noshowmode
" Airline
set laststatus=2
set encoding=utf-8
let g:airline#extensions#tabline#enabled = 1
let g:airline_powerline_fonts = 1
let g:airline_section_warning = ''
let g:airline_section_error = ''
let g:airline_theme='onedark'
" True color support
set termguicolors
" Line numbering
set relativenumber
set number
" Always show signcolumn
set signcolumn=yes
" Autoindent and syntax highlight
set autoindent
set smartindent
syntax on
filetype on
filetype plugin indent on
set tabstop=4
set shiftwidth=4
" Make gutter and cursorline bg transparent
highlight CursorLineNr guibg=transparent
highlight SignColumn guibg=transparent
" Don't wrap in the middle of words
set linebreak

View file

@ -1,39 +0,0 @@
" Change leader to space
nnoremap <SPACE> <Nop>
let mapleader = ' '
" Toggle nerdtree
map <silent> <C-t> :NERDTreeToggle<CR>
" Markdown preview
nmap <C-s> <Plug>MarkdownPreview
nmap <M-s> <Plug>MarkdownPreviewStop
nmap <C-p> <Plug>MarkdownPreviewToggle
set splitbelow
set splitright
" Move between buffers
nnoremap <C-N> :bn<CR>
nnoremap <C-B> :bp<CR>
" Move between splits
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>
nnoremap <C-H> <C-W><C-H>
" Enable mouse
set mouse=a
" Toggle equalalways
function ToggleEqual ()
:set equalalways!
:set equalalways!
endfunction
nnoremap <leader>= :call ToggleEqual()<CR>
" Navigate display lines insted of physical lines
nnoremap j gj
nnoremap k gk

View file

@ -1,129 +0,0 @@
" Enable symbol highlight
autocmd CursorHold * silent call CocActionAsync('highlight')
" If hidden is not set, TextEdit might fail.
set hidden
" Some servers have issues with backup files, see #649
set nobackup
set nowritebackup
" Better display for messages
set cmdheight=2
" Smaller updatetime for CursorHold & CursorHoldI
set updatetime=300
" Don't give |ins-completion-menu| messages.
set shortmess+=c
" Use tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
" Use <cr> to confirm snippet
inoremap <silent><expr> <cr> pumvisible() ? coc#_select_confirm() :
\"\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()
" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
" Coc only does snippet and additional edit on confirm.
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
" Use `[c` and `]c` to navigate diagnostics
nmap <silent> [c <Plug>(coc-diagnostic-prev)
nmap <silent> ]c <Plug>(coc-diagnostic-next)
" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
" Use K to show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
else
call CocAction('doHover')
endif
endfunction
" Highlight symbol under cursor on CursorHold
autocmd CursorHold * silent call CocActionAsync('highlight')
" Remap for rename current word
nmap <leader>rn <Plug>(coc-rename)
" Remap for format selected region
xmap <leader>f <Plug>(coc-format-selected)
nmap <leader>f <Plug>(coc-format-selected)
augroup mygroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end
" Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
xmap <leader>a <Plug>(coc-codeaction-selected)
nmap <leader>a <Plug>(coc-codeaction-selected)
" Remap for do codeAction of current line
nmap <leader>ac <Plug>(coc-codeaction)
" Fix autofix problem of current line
nmap <leader>qf <Plug>(coc-fix-current)
" Use `:Format` to format current buffer
command! -nargs=0 Format :call CocAction('format')
" Use `:Fold` to fold current buffer
command! -nargs=? Fold :call CocAction('fold', <f-args>)
" Add diagnostic info for https://github.com/itchyny/lightline.vim
let g:lightline = {
\ 'colorscheme': 'wombat',
\ 'active': {
\ 'left': [ [ 'mode', 'paste' ],
\ [ 'cocstatus', 'readonly', 'filename', 'modified' ] ]
\ },
\ 'component_function': {
\ 'cocstatus': 'coc#status'
\ },
\ }
" Using CocList
" Show all diagnostics
nnoremap <silent> <space>a :<C-u>CocList diagnostics<cr>
" Manage extensions
nnoremap <silent> <space>e :<C-u>CocList extensions<cr>
" Show commands
nnoremap <silent> <space>c :<C-u>CocList commands<cr>
" Find symbol of current document
nnoremap <silent> <space>o :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent> <space>s :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent> <space>j :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent> <space>k :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent> <space>p :<C-u>CocListResume<CR>

View file

@ -1,12 +0,0 @@
" LaTex settings
let g:vimtex_view_method='zathura'
let g:Tex_DefaultTargetFormat='pdf'
let g:Tex_MultipleCompileFormats='pdf, aux'
let g:vimtex_compiler_progname='nvr'
" YAML settings
au! BufNewFile,BufReadPost *.{yaml,yml} set filetype=yaml foldmethod=indent
autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab
" Run rustfmt on save
let g:rustfmt_autosave = 1

View file

@ -1,41 +0,0 @@
" Enable python support
let g:python3_host_prog='/usr/bin/python3'
let pyxversion=3
" LaTex fallback flavor
let g:tex_flavor = 'latex'
" Use suda by default
let g:suda_smart_edit = 1
" Remap exit terminal mode to esc
au TermOpen * tnoremap <buffer> <Esc> <c-\><c-n>
" Use system clipboard
set clipboard=unnamedplus
" Remove extra line
set cmdheight=1
" Disable auto commenting
set formatoptions-=cro
" Set pandoc preview program
let g:pandoc_preview_pdf_cmd = "zathura"
" Case insensitive search
set ignorecase
set smartcase
" Nerdtree settings
let NERDTreeMinimalUI = 1 "remove press ? for help"
let NERDTreeAutoDeleteBuffer = 1 " delete buffer when file is deleted
let NERDTreeQuitOnOpen = 1 " close nerdtree when opening file
let NERDTreeDirArrows = 1
" Firenvim filetypes
au BufEnter github.com_*.txt set filetype=markdown
au BufEnter gitlab.com_*.txt set filetype=markdown
au BufEnter git.reekynet.com_*.txt set filetype=markdown
au BufEnter www.reddit.com_*.txt set filetype=markdown
au BufEnter node.reekynet.com_*.txt set filetype=json

View file

@ -1,43 +0,0 @@
" FZF in floating window
autocmd! FileType fzf
autocmd FileType fzf call SetFZFoptions()
function SetFZFoptions()
set noshowmode noruler nonumber norelativenumber
tunmap <buffer> <Esc>
endfunction
let g:fzf_layout = { 'window': 'call FloatingFZF()' }
function! FloatingFZF()
let buf = nvim_create_buf(v:false, v:true)
call setbufvar(buf, '&signcolumn', 'no')
let width = float2nr(&columns * 0.8)
let height = float2nr(&lines * 0.6)
let horizontal = 1
let vertical = 1
let opts = {
\ 'relative': 'editor',
\ 'row': (&lines - height) / 2,
\ 'col': (&columns - width) / 2,
\ 'width': width,
\ 'height': height,
\ 'style': 'minimal'
\ }
call nvim_open_win(buf, v:true, opts)
endfunction
" Looks
"let $FZF_DEFAULT_OPTS=' --color=dark --color=fg:15,bg:-1,hl:1,fg+:#ffffff,bg+:0,hl+:1 --color=info:0,prompt:0,pointer:12,marker:4,spinner:11,header:-1 --layout=reverse --margin=1,4'
" ripgrep custom settings
command! -bang -nargs=* Rg
\ call fzf#vim#grep('rg --column --line-number --no-heading --color=always --smart-case '
\ . (len(<q-args>) > 0 ? <q-args> : '""'), 0,
\ fzf#vim#with_preview({'options': ['--delimiter=:', '--nth=2..', '--layout=reverse', '--info=inline']}), <bang>0)
" Keybinds
nmap <C-f> :Files<CR>
nmap <C-g> :Rg<CR>

View file

@ -0,0 +1,111 @@
local nvim_local_dir = vim.fn.expand("~/.local/share/nvim")
local mason_packages = nvim_local_dir .. "/mason/packages"
local lombok_jar = mason_packages .. "/jdtls/lombok.jar"
local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t")
local workspace_dir = nvim_local_dir .. "/jdtls-workspaces/" .. project_name
local lsp_utils = require("lsp_utils")
local jvm = "/usr/lib/jvm"
local java_version = 21
require("jdtls").start_or_attach({
cmd = {
jvm .. "/java-" .. java_version .. "-openjdk-amd64/bin/java",
"-Declipse.application=org.eclipse.jdt.ls.core.id1",
"-Dosgi.bundles.defaultStartLevel=4",
"-Declipse.product=org.eclipse.jdt.ls.core.product",
"-Dlog.protocol=true",
"-Dlog.level=ALL",
"-Xms1g",
"--add-modules=ALL-SYSTEM",
"--add-opens",
"java.base/java.util=ALL-UNNAMED",
"--add-opens",
"java.base/java.lang=ALL-UNNAMED",
"-javaagent:" .. lombok_jar,
"-jar",
vim.fn.glob(mason_packages .. "/jdtls/plugins/org.eclipse.equinox.launcher_*.jar"),
"-configuration",
nvim_local_dir .. "/mason/packages/jdtls/config_linux",
"-data",
workspace_dir,
},
settings = {
java = {
signatureHelp = { enabled = true },
autobuild = { enabled = false },
configuration = {
runtimes = {
{
name = "JavaSE-1.8",
path = jvm .. "/java-8-openjdk-amd64/",
},
{
name = "JavaSE-11",
path = jvm .. "/java-11-openjdk-amd64/",
},
{
name = "JavaSE-17",
path = jvm .. "/java-17-openjdk-amd64/",
},
{
name = "JavaSE-21",
path = jvm .. "/java-21-openjdk-amd64/",
},
},
},
},
},
completion = { favoriteStaticMembers = { "java.text.MessageFormat.format" } },
handlers = {
["language/status"] = function() end,
},
init_options = {
bundles = {
vim.fn.glob(mason_packages .. "/java-debug-adapter/extension/server/com.microsoft.java.debug.plugin-*.jar"),
},
},
capabilities = lsp_utils.get_capabilities(),
on_attach = lsp_utils.map_keys,
})
function RunJava()
local function show_output(output)
vim.cmd("split")
vim.cmd("enew")
vim.fn.append(0, output)
--vim.cmd("1d") -- Remove the empty first line
vim.bo[0].modifiable = false
end
local filename = vim.fn.expand("%") -- Get the current file name
local class_name = vim.fn.fnamemodify(filename, ":r") -- Extract the class name
local compile_cmd = "javac " .. filename
local run_cmd = "java " .. class_name
-- Create a temporary file to capture the compile output
local temp_file = vim.fn.tempname()
-- Run the compilation command and save the output to the temporary file
local compile_exit_code = vim.fn.system(compile_cmd .. " > " .. temp_file .. " 2>&1")
-- Check the exit code of the compile command
if compile_exit_code == 0 then
-- Compilation was successful, run the Java program
show_output(vim.fn.systemlist(run_cmd))
else
-- Compilation failed, display the error output from the temporary file
show_output(vim.fn.readfile(temp_file))
end
-- Clean up the temporary file and class file
vim.fn.delete(temp_file)
vim.fn.delete(vim.fn.expand("%:p:h") .. "/" .. class_name .. ".class")
end
-- Define a VimScript command to execute the Lua function
vim.api.nvim_exec(
[[
command! RunJava lua RunJava()
]],
false
)

View file

@ -0,0 +1,27 @@
-- Install lazy if it's not yet installed
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("settings")
require("neovide")
require("highlight_yank")
require("lazy").setup({
spec = { import = "plugins" },
lockfile = "~/git/dotfiles/home/.config/nvim/lazy-lock.json",
performance = {
disabled_plugins = { "netrwPlugin" },
},
defaults = {
-- version = "*", -- Disabled for now
},
})

View file

@ -1,3 +0,0 @@
for f in split(glob('~/.config/nvim/conf.d/*.vim'), '\n')
exe 'source' f
endfor

View file

@ -0,0 +1,68 @@
{
"LuaSnip": { "branch": "master", "commit": "b152822e1a4bafb6bdf11a16cc26525cbd95ee00" },
"alpha-nvim": { "branch": "main", "commit": "41283fb402713fc8b327e60907f74e46166f4cfd" },
"auto-dark-mode.nvim": { "branch": "master", "commit": "e328dc463d238cb7d690fb4daf068eba732a5a14" },
"bufferline.nvim": { "branch": "main", "commit": "73540cb95f8d95aa1af3ed57713c6720c78af915" },
"cder.nvim": { "branch": "main", "commit": "07c9e3e8324ee7c3ffde493c1612aca0be5255d0" },
"cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
"cmp-cmdline": { "branch": "main", "commit": "d250c63aa13ead745e3a40f61fdd3470efde3923" },
"cmp-git": { "branch": "main", "commit": "b9603f18496bc3ca07e6bd474607081af709e750" },
"cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" },
"cmp-nvim-lua": { "branch": "main", "commit": "f12408bdb54c39c23e67cab726264c10db33ada8" },
"cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
"cmp-spell": { "branch": "master", "commit": "694a4e50809d6d645c1ea29015dad0c293f019d6" },
"cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
"confirm-quit.nvim": { "branch": "main", "commit": "f15f6d728d385a3d2efa22098e9a45b8a2b20144" },
"copilot-cmp": { "branch": "master", "commit": "72fbaa03695779f8349be3ac54fa8bd77eed3ee3" },
"copilot.lua": { "branch": "master", "commit": "f7612f5af4a7d7615babf43ab1e67a2d790c13a6" },
"diffview.nvim": { "branch": "main", "commit": "3dc498c9777fe79156f3d32dddd483b8b3dbd95f" },
"dropbar.nvim": { "branch": "master", "commit": "3dd8edba9f9eeb129db269dd57ef6c0427b7ad9d" },
"firenvim": { "branch": "master", "commit": "fc72687977e1c34259c42f0e408655cf2638760d" },
"friendly-snippets": { "branch": "main", "commit": "3e9a3f5a0cfcef1741e352c37bda4e82e5eb846a" },
"gitsigns.nvim": { "branch": "main", "commit": "805610a9393fa231f2c2b49cb521bfa413fadb3d" },
"indent-blankline.nvim": { "branch": "master", "commit": "3d08501caef2329aba5121b753e903904088f7e6" },
"kanagawa.nvim": { "branch": "master", "commit": "860e4f80df71221d18bf2cd9ef1deb4d364274d2" },
"lazy.nvim": { "branch": "main", "commit": "e44636a43376e8a1e851958f7e9cbe996751d59f" },
"lualine.nvim": { "branch": "master", "commit": "0a5a66803c7407767b799067986b4dc3036e1983" },
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
"mason-extra-cmds": { "branch": "main", "commit": "4d987485b4435bca6d2da735247482f40f839d6b" },
"mason-lock.nvim": { "branch": "main", "commit": "2f18cab30f3d621002c58c725d9319a1563414e5" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "9ae570e206360e47d30b4c35a4550c165f4ea7b7" },
"mason.nvim": { "branch": "main", "commit": "1b3d60405d1d720b2c4927f19672e9479703b00f" },
"mini.nvim": { "branch": "main", "commit": "c333187fcc76d7e772dac32c2a440a949fe34be4" },
"neodev.nvim": { "branch": "main", "commit": "ce9a2e8eaba5649b553529c5498acb43a6c317cd" },
"neoformat": { "branch": "master", "commit": "4372abb846f43ec121df40e620682c985ebc8286" },
"noice.nvim": { "branch": "main", "commit": "09102ca2e9a3e9302119fdaf7a059a034e4a626d" },
"nui.nvim": { "branch": "main", "commit": "a3597dc88b53489d3fddbddbbd13787355253bb0" },
"nvim-asciidoc-preview": { "branch": "main", "commit": "e354bd84fed978e31501396aea6154bd97087e07" },
"nvim-autopairs": { "branch": "master", "commit": "14e97371b2aab6ee70054c1070a123dfaa3e217e" },
"nvim-cmp": { "branch": "main", "commit": "24122371810089d390847d8ba66325c1f1aa64c0" },
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
"nvim-dap": { "branch": "master", "commit": "615a1b2046e1eaf7995e0ba8e8a65f344201349d" },
"nvim-dap-ui": { "branch": "master", "commit": "5934302d63d1ede12c0b22b6f23518bb183fc972" },
"nvim-jdtls": { "branch": "master", "commit": "8eb5f0dbe6e126b392ddcaf45893358619893e45" },
"nvim-lsp-file-operations": { "branch": "master", "commit": "223aca86b737dc66e9c51ebcda8788a8d9cc6cf2" },
"nvim-lspconfig": { "branch": "master", "commit": "94513a5b246cf32a8f87ca714af50911df63351c" },
"nvim-nio": { "branch": "master", "commit": "8765cbc4d0c629c8158a5341e1b4305fd93c3a90" },
"nvim-notify": { "branch": "master", "commit": "5371f4bfc1f6d3adf4fe9d62cd3a9d44356bfd15" },
"nvim-tree.lua": { "branch": "master", "commit": "78c4c083ed5d47e7fab7627d78ce33d3bcfb88f0" },
"nvim-treesitter": { "branch": "master", "commit": "d5a1c2b0c8ec5bb377a41c1c414b315d6b3e9432" },
"nvim-treesitter-textobjects": { "branch": "master", "commit": "dfa4178c0cadb44f687603d72ad0908474c28dd9" },
"nvim-ts-autotag": { "branch": "main", "commit": "531f48334c422222aebc888fd36e7d109cb354cd" },
"nvim-ufo": { "branch": "main", "commit": "a5390706f510d39951dd581f6d2a972741b3fa26" },
"nvim-web-devicons": { "branch": "master", "commit": "5b9067899ee6a2538891573500e8fd6ff008440f" },
"password-store": { "branch": "master", "commit": "b5e965a838bb68c1227caa2cdd874ba496f10149" },
"plenary.nvim": { "branch": "master", "commit": "08e301982b9a057110ede7a735dd1b5285eb341f" },
"project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" },
"promise-async": { "branch": "main", "commit": "93540c168c5ed2b030ec3e6c40ab8bbb85e36355" },
"statuscol.nvim": { "branch": "main", "commit": "483b9a596dfd63d541db1aa51ee6ee9a1441c4cc" },
"suda.vim": { "branch": "master", "commit": "b97fab52f9cdeabe2bbb5eb98d82356899f30829" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "9ef21b2e6bb6ebeaf349a0781745549bbb870d27" },
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
"telescope.nvim": { "branch": "master", "commit": "02a60a83961cf9c80e471599171982a31d1cc853" },
"vim-asciidoctor": { "branch": "master", "commit": "f553311b5db03440eb8d7035434d0405e4a2c559" },
"vim-caddyfile": { "branch": "master", "commit": "24fe0720551883e407cb70ae1d7c03f162d1d5a0" },
"vim-fugitive": { "branch": "master", "commit": "ce882460cf3db12e99f8bf579cbf99e331f6dd4f" },
"vim-gnupg": { "branch": "main", "commit": "f9b608f29003dfde6450931dc0f495a912973a88" },
"which-key.nvim": { "branch": "main", "commit": "4433e5ec9a507e5097571ed55c02ea9658fb268a" }
}

Some files were not shown because too many files have changed in this diff Show more