From d2c331b9f036951eef062dd5141c75182375ba12 Mon Sep 17 00:00:00 2001 From: Simon Parri Date: Tue, 22 Jul 2025 00:56:22 +0200 Subject: Add current configuration --- .gitignore | 1 + .gitmodules | 27 + common.rb | 13 + common/.XCompose | 4 + common/.Xmodmap | 1 + common/.Xresources | 15 + common/.aspell.en.pws | 23 + common/.config/beets/config.yaml | 21 + .../source-registry.conf.d/00-home-src.conf | 1 + .../source-registry.conf.d/01-lab-lisp.conf | 1 + .../source-registry.conf.d/02-slynk.conf | 1 + common/.config/fontconfig/fonts.conf | 80 + common/.config/mimeapps.list | 25 + common/.config/screenkey.json | 23 + common/.config/user-dirs.dirs | 8 + common/.config/wal/templates/dark.css | 72 + common/.config/wal/templates/dunstrc | 30 + common/.config/wal/templates/gtkrc | 253 ++ common/.dotXCompose | 1 + common/.emacs.d/init.el | 4240 ++++++++++++++++++++ common/.gallery-dl.conf | 8 + common/.gitconfig | 9 + common/.irbrc | 3 + common/.keymap.xkb | 137 + .../share/applications/emacsclient-mail.desktop | 5 + .../.local/share/applications/emacsclient.desktop | 5 + common/.local/share/applications/torrent.desktop | 5 + common/.mailcap | 1 + common/.mbsyncrc | 71 + common/.mpv/mpv.conf | 4 + common/.mpv/script-opts/mfpbar.conf | 21 + common/.mpv/script-opts/subs2srs.conf | 334 ++ common/.mpv/script-opts/thumbfast.conf | 1 + common/.mpv/scripts/mfpbar.lua | 1 + common/.mpv/scripts/sponsorblock_minimal.lua | 1 + common/.mpv/scripts/subs2srs | 1 + common/.mpv/scripts/thumbfast.lua | 1 + common/.mpv/scripts/youtube-quality.lua | 1 + .../.mpv/shaders/Anime4K_AutoDownscalePre_x2.glsl | 36 + .../.mpv/shaders/Anime4K_AutoDownscalePre_x4.glsl | 36 + common/.mpv/shaders/Anime4K_Clamp_Highlights.glsl | 90 + common/.mpv/shaders/Anime4K_Darken_Fast.glsl | 216 + common/.mpv/shaders/Anime4K_Darken_HQ.glsl | 198 + common/.mpv/shaders/Anime4K_Darken_VeryFast.glsl | 218 + common/.mpv/shaders/Anime4K_Deblur_DoG.glsl | 153 + common/.mpv/shaders/Anime4K_Deblur_Original.glsl | 287 ++ .../shaders/Anime4K_Denoise_Bilateral_Mean.glsl | 67 + .../shaders/Anime4K_Denoise_Bilateral_Median.glsl | 120 + .../shaders/Anime4K_Denoise_Bilateral_Mode.glsl | 103 + common/.mpv/shaders/Anime4K_Restore_CNN_L.glsl | 429 ++ common/.mpv/shaders/Anime4K_Restore_CNN_M.glsl | 275 ++ common/.mpv/shaders/Anime4K_Restore_CNN_S.glsl | 137 + .../.mpv/shaders/Anime4K_Restore_CNN_Soft_L.glsl | 429 ++ .../.mpv/shaders/Anime4K_Restore_CNN_Soft_M.glsl | 275 ++ .../.mpv/shaders/Anime4K_Restore_CNN_Soft_S.glsl | 137 + .../.mpv/shaders/Anime4K_Restore_CNN_Soft_UL.glsl | 1704 ++++++++ .../.mpv/shaders/Anime4K_Restore_CNN_Soft_VL.glsl | 873 ++++ common/.mpv/shaders/Anime4K_Restore_CNN_UL.glsl | 1704 ++++++++ common/.mpv/shaders/Anime4K_Restore_CNN_VL.glsl | 873 ++++ common/.mpv/shaders/Anime4K_Thin_Fast.glsl | 234 ++ common/.mpv/shaders/Anime4K_Thin_HQ.glsl | 222 + common/.mpv/shaders/Anime4K_Thin_VeryFast.glsl | 236 ++ common/.mpv/shaders/Anime4K_Upscale_CNN_x2_L.glsl | 461 +++ common/.mpv/shaders/Anime4K_Upscale_CNN_x2_M.glsl | 300 ++ common/.mpv/shaders/Anime4K_Upscale_CNN_x2_S.glsl | 158 + common/.mpv/shaders/Anime4K_Upscale_CNN_x2_UL.glsl | 1702 ++++++++ common/.mpv/shaders/Anime4K_Upscale_CNN_x2_VL.glsl | 969 +++++ common/.mpv/shaders/Anime4K_Upscale_DTD_x2.glsl | 613 +++ .../shaders/Anime4K_Upscale_Deblur_DoG_x2.glsl | 158 + .../Anime4K_Upscale_Deblur_Original_x2.glsl | 277 ++ .../shaders/Anime4K_Upscale_Denoise_CNN_x2_L.glsl | 461 +++ .../shaders/Anime4K_Upscale_Denoise_CNN_x2_M.glsl | 300 ++ .../shaders/Anime4K_Upscale_Denoise_CNN_x2_S.glsl | 158 + .../shaders/Anime4K_Upscale_Denoise_CNN_x2_UL.glsl | 1702 ++++++++ .../shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl | 969 +++++ common/.mpv/shaders/Anime4K_Upscale_DoG_x2.glsl | 143 + .../.mpv/shaders/Anime4K_Upscale_Original_x2.glsl | 277 ++ common/.mrconfig | 11 + common/.msmtprc | 32 + common/.nethackrc | 13 + common/.picom.conf | 2 + common/.profile | 51 + common/.rbrc | 1 + common/.sbclrc | 63 + common/.signature | 1 + common/.themes/linea-nord-color/cinnamon | 1 + .../linea-nord-color/general/add-workspace.svg | 1 + .../general/calendar-arrow-left.svg | 1 + .../general/calendar-arrow-right.svg | 1 + .../general/checkbox-mixed-symbolic.svg | 1 + .../linea-nord-color/general/checkbox-off.svg | 1 + .../linea-nord-color/general/checkbox-symbolic.svg | 1 + .../.themes/linea-nord-color/general/checkbox.svg | 1 + .../linea-nord-color/general/close-window.svg | 1 + .../linea-nord-color/general/corner-ripple.svg | 1 + .../general/cursor-handle-symbolic.svg | 1 + .../general/dark-add-workspace.svg | 1 + .../general/dark-calendar-arrow-left.svg | 1 + .../general/dark-calendar-arrow-right.svg | 1 + .../linea-nord-color/general/dark-checkbox-off.svg | 1 + .../linea-nord-color/general/dark-checkbox.svg | 1 + .../linea-nord-color/general/dark-close-window.svg | 1 + .../general/dark-radiobutton-off.svg | 1 + .../linea-nord-color/general/dark-radiobutton.svg | 1 + .../linea-nord-color/general/dark-switch-off.svg | 1 + .../linea-nord-color/general/dark-switch-on.svg | 1 + common/.themes/linea-nord-color/general/gtk-3.css | 1 + common/.themes/linea-nord-color/general/gtk-4.css | 1 + .../linea-nord-color/general/gtk-colors.css | 1 + common/.themes/linea-nord-color/general/light.css | 1 + .../general/radio-mixed-symbolic.svg | 1 + .../linea-nord-color/general/radio-symbolic.svg | 1 + .../linea-nord-color/general/radiobutton-off.svg | 1 + .../linea-nord-color/general/radiobutton.svg | 1 + .../linea-nord-color/general/switch-off.svg | 1 + .../.themes/linea-nord-color/general/switch-on.svg | 1 + .../.themes/linea-nord-color/general/titlebar.css | 1 + .../.themes/linea-nord-color/general/widgets.css | 1 + common/.themes/linea-nord-color/gnome-shell | 1 + common/.themes/linea-nord-color/gtk-3.0 | 1 + common/.themes/linea-nord-color/gtk-4.0 | 1 + common/.themes/linea-nord-color/index.theme | 1 + common/.themes/linea-nord-color/metacity-1 | 1 + common/.themes/linea-nord-color/plank | 1 + common/.tmux.conf | 5 + common/.vimfx/config.js | 608 +++ common/.vimfx/frame.js | 24 + common/.vimfx/tabfs | 1 + common/.vimfx/userChrome.css | 64 + common/.vimfx/userContent.css | 47 + common/.vimrc | 17 + common/.xinitrc | 22 + common/.xsettingsd | 11 + common/.zprofile | 1 + common/.zshenv | 1 + common/.zshrc | 117 + common/bin/asdf-make | 3 + common/bin/bandwidthtest | 20 + common/bin/beet-import-yt | 8 + common/bin/browse-git | 19 + common/bin/dotdot | 1 + common/bin/e | 7 + common/bin/emacs-available | 2 + common/bin/jailgame | 12 + common/bin/mywal | 8 + common/bin/random-wallpaper | 72 + common/bin/rb | 14 + common/bin/red | 13 + common/bin/retheme | 16 + common/bin/say | 2 + common/bin/sbclcurse | 5 + common/bin/sudo | 4 + common/bin/urldecode | 2 + common/bin/xss | 2 + common/bin/yt-dlpm | 3 + kbd-us/.config/keymapper-keys.conf | 13 + kbd-us/.config/keymapper.conf | 64 + kbd-us/.xinitrc.pre | 6 + modules/dotdot | 1 + modules/mpv-toolbox | 1 + modules/mpv-youtube-quality | 1 + modules/mpv_sponsorblock_minimal | 1 + modules/mpvacious | 1 + modules/tabfs | 1 + modules/thumbfast | 1 + modules/wpgtk-templates | 1 + modules/xcompose | 1 + tomato.rb | 5 + tomato/.config/keymapper-keys.conf | 1 + tomato/.config/keymapper.conf | 1 + tomato/.mpv/input.conf | 10 + tomato/.profile.local | 3 + tomato/.xinitrc.post | 3 + tomato/.xinitrc.pre | 1 + 174 files changed, 24609 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 common.rb create mode 100644 common/.XCompose create mode 100644 common/.Xmodmap create mode 100644 common/.Xresources create mode 100644 common/.aspell.en.pws create mode 100644 common/.config/beets/config.yaml create mode 100644 common/.config/common-lisp/source-registry.conf.d/00-home-src.conf create mode 100644 common/.config/common-lisp/source-registry.conf.d/01-lab-lisp.conf create mode 100644 common/.config/common-lisp/source-registry.conf.d/02-slynk.conf create mode 100644 common/.config/fontconfig/fonts.conf create mode 100644 common/.config/mimeapps.list create mode 100644 common/.config/screenkey.json create mode 100644 common/.config/user-dirs.dirs create mode 100644 common/.config/wal/templates/dark.css create mode 100644 common/.config/wal/templates/dunstrc create mode 100644 common/.config/wal/templates/gtkrc create mode 120000 common/.dotXCompose create mode 100644 common/.emacs.d/init.el create mode 100644 common/.gallery-dl.conf create mode 100644 common/.gitconfig create mode 100644 common/.irbrc create mode 100644 common/.keymap.xkb create mode 100644 common/.local/share/applications/emacsclient-mail.desktop create mode 100644 common/.local/share/applications/emacsclient.desktop create mode 100644 common/.local/share/applications/torrent.desktop create mode 100644 common/.mailcap create mode 100644 common/.mbsyncrc create mode 100644 common/.mpv/mpv.conf create mode 100644 common/.mpv/script-opts/mfpbar.conf create mode 100644 common/.mpv/script-opts/subs2srs.conf create mode 100644 common/.mpv/script-opts/thumbfast.conf create mode 120000 common/.mpv/scripts/mfpbar.lua create mode 120000 common/.mpv/scripts/sponsorblock_minimal.lua create mode 120000 common/.mpv/scripts/subs2srs create mode 120000 common/.mpv/scripts/thumbfast.lua create mode 120000 common/.mpv/scripts/youtube-quality.lua create mode 100644 common/.mpv/shaders/Anime4K_AutoDownscalePre_x2.glsl create mode 100644 common/.mpv/shaders/Anime4K_AutoDownscalePre_x4.glsl create mode 100644 common/.mpv/shaders/Anime4K_Clamp_Highlights.glsl create mode 100644 common/.mpv/shaders/Anime4K_Darken_Fast.glsl create mode 100644 common/.mpv/shaders/Anime4K_Darken_HQ.glsl create mode 100644 common/.mpv/shaders/Anime4K_Darken_VeryFast.glsl create mode 100644 common/.mpv/shaders/Anime4K_Deblur_DoG.glsl create mode 100644 common/.mpv/shaders/Anime4K_Deblur_Original.glsl create mode 100644 common/.mpv/shaders/Anime4K_Denoise_Bilateral_Mean.glsl create mode 100644 common/.mpv/shaders/Anime4K_Denoise_Bilateral_Median.glsl create mode 100644 common/.mpv/shaders/Anime4K_Denoise_Bilateral_Mode.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_L.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_M.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_S.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_Soft_L.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_Soft_M.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_Soft_S.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_Soft_UL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_Soft_VL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_UL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Restore_CNN_VL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Thin_Fast.glsl create mode 100644 common/.mpv/shaders/Anime4K_Thin_HQ.glsl create mode 100644 common/.mpv/shaders/Anime4K_Thin_VeryFast.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_CNN_x2_L.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_CNN_x2_M.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_CNN_x2_S.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_CNN_x2_UL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_CNN_x2_VL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_DTD_x2.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Deblur_DoG_x2.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Deblur_Original_x2.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Denoise_CNN_x2_L.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Denoise_CNN_x2_M.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Denoise_CNN_x2_S.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Denoise_CNN_x2_UL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_DoG_x2.glsl create mode 100644 common/.mpv/shaders/Anime4K_Upscale_Original_x2.glsl create mode 100644 common/.mrconfig create mode 100644 common/.msmtprc create mode 100644 common/.nethackrc create mode 100644 common/.picom.conf create mode 100644 common/.profile create mode 100644 common/.rbrc create mode 100644 common/.sbclrc create mode 100644 common/.signature create mode 120000 common/.themes/linea-nord-color/cinnamon create mode 120000 common/.themes/linea-nord-color/general/add-workspace.svg create mode 120000 common/.themes/linea-nord-color/general/calendar-arrow-left.svg create mode 120000 common/.themes/linea-nord-color/general/calendar-arrow-right.svg create mode 120000 common/.themes/linea-nord-color/general/checkbox-mixed-symbolic.svg create mode 120000 common/.themes/linea-nord-color/general/checkbox-off.svg create mode 120000 common/.themes/linea-nord-color/general/checkbox-symbolic.svg create mode 120000 common/.themes/linea-nord-color/general/checkbox.svg create mode 120000 common/.themes/linea-nord-color/general/close-window.svg create mode 120000 common/.themes/linea-nord-color/general/corner-ripple.svg create mode 120000 common/.themes/linea-nord-color/general/cursor-handle-symbolic.svg create mode 120000 common/.themes/linea-nord-color/general/dark-add-workspace.svg create mode 120000 common/.themes/linea-nord-color/general/dark-calendar-arrow-left.svg create mode 120000 common/.themes/linea-nord-color/general/dark-calendar-arrow-right.svg create mode 120000 common/.themes/linea-nord-color/general/dark-checkbox-off.svg create mode 120000 common/.themes/linea-nord-color/general/dark-checkbox.svg create mode 120000 common/.themes/linea-nord-color/general/dark-close-window.svg create mode 120000 common/.themes/linea-nord-color/general/dark-radiobutton-off.svg create mode 120000 common/.themes/linea-nord-color/general/dark-radiobutton.svg create mode 120000 common/.themes/linea-nord-color/general/dark-switch-off.svg create mode 120000 common/.themes/linea-nord-color/general/dark-switch-on.svg create mode 120000 common/.themes/linea-nord-color/general/gtk-3.css create mode 120000 common/.themes/linea-nord-color/general/gtk-4.css create mode 120000 common/.themes/linea-nord-color/general/gtk-colors.css create mode 120000 common/.themes/linea-nord-color/general/light.css create mode 120000 common/.themes/linea-nord-color/general/radio-mixed-symbolic.svg create mode 120000 common/.themes/linea-nord-color/general/radio-symbolic.svg create mode 120000 common/.themes/linea-nord-color/general/radiobutton-off.svg create mode 120000 common/.themes/linea-nord-color/general/radiobutton.svg create mode 120000 common/.themes/linea-nord-color/general/switch-off.svg create mode 120000 common/.themes/linea-nord-color/general/switch-on.svg create mode 120000 common/.themes/linea-nord-color/general/titlebar.css create mode 120000 common/.themes/linea-nord-color/general/widgets.css create mode 120000 common/.themes/linea-nord-color/gnome-shell create mode 120000 common/.themes/linea-nord-color/gtk-3.0 create mode 120000 common/.themes/linea-nord-color/gtk-4.0 create mode 120000 common/.themes/linea-nord-color/index.theme create mode 120000 common/.themes/linea-nord-color/metacity-1 create mode 120000 common/.themes/linea-nord-color/plank create mode 100644 common/.tmux.conf create mode 100644 common/.vimfx/config.js create mode 100644 common/.vimfx/frame.js create mode 120000 common/.vimfx/tabfs create mode 100644 common/.vimfx/userChrome.css create mode 100644 common/.vimfx/userContent.css create mode 100644 common/.vimrc create mode 100644 common/.xinitrc create mode 100644 common/.xsettingsd create mode 120000 common/.zprofile create mode 100644 common/.zshenv create mode 100644 common/.zshrc create mode 100755 common/bin/asdf-make create mode 100755 common/bin/bandwidthtest create mode 100755 common/bin/beet-import-yt create mode 100755 common/bin/browse-git create mode 120000 common/bin/dotdot create mode 100755 common/bin/e create mode 100755 common/bin/emacs-available create mode 100755 common/bin/jailgame create mode 100755 common/bin/mywal create mode 100755 common/bin/random-wallpaper create mode 100755 common/bin/rb create mode 100755 common/bin/red create mode 100755 common/bin/retheme create mode 100755 common/bin/say create mode 100755 common/bin/sbclcurse create mode 100755 common/bin/sudo create mode 100755 common/bin/urldecode create mode 100755 common/bin/xss create mode 100755 common/bin/yt-dlpm create mode 100644 kbd-us/.config/keymapper-keys.conf create mode 100644 kbd-us/.config/keymapper.conf create mode 100644 kbd-us/.xinitrc.pre create mode 160000 modules/dotdot create mode 160000 modules/mpv-toolbox create mode 160000 modules/mpv-youtube-quality create mode 160000 modules/mpv_sponsorblock_minimal create mode 160000 modules/mpvacious create mode 160000 modules/tabfs create mode 160000 modules/thumbfast create mode 160000 modules/wpgtk-templates create mode 160000 modules/xcompose create mode 100644 tomato.rb create mode 120000 tomato/.config/keymapper-keys.conf create mode 120000 tomato/.config/keymapper.conf create mode 100644 tomato/.mpv/input.conf create mode 100644 tomato/.profile.local create mode 100644 tomato/.xinitrc.post create mode 120000 tomato/.xinitrc.pre diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ff62e68 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,27 @@ +[submodule "modules/xcompose"] + path = modules/xcompose + url = https://github.com/kragen/xcompose +[submodule "modules/mpv_sponsorblock_minimal"] + path = modules/mpv_sponsorblock_minimal + url = https://codeberg.org/jouni/mpv_sponsorblock_minimal +[submodule "modules/mpv-youtube-quality"] + path = modules/mpv-youtube-quality + url = https://github.com/jgreco/mpv-youtube-quality +[submodule "modules/mpv-toolbox"] + path = modules/mpv-toolbox + url = https://codeberg.org/NRK/mpv-toolbox +[submodule "modules/thumbfast"] + path = modules/thumbfast + url = https://github.com/po5/thumbfast +[submodule "modules/dotdot"] + path = modules/dotdot + url = https://ba.ln.ea.cx/src/marsironpi/dotdot +[submodule "modules/wpgtk-templates"] + path = modules/wpgtk-templates + url = https://github.com/deviantfero/wpgtk-templates +[submodule "modules/tabfs"] + path = modules/tabfs + url = https://github.com/osnr/TabFS +[submodule "modules/mpvacious"] + path = modules/mpvacious + url = https://github.com/Ajatt-Tools/mpvacious diff --git a/common.rb b/common.rb new file mode 100644 index 0000000..e5166bd --- /dev/null +++ b/common.rb @@ -0,0 +1,13 @@ +tree src: "#{dir}/common", + dst: HOME, + stops: [".config/common-lisp", + ".mpv/scripts", + *%w[cinnamon gnome-shell metacity-1 + gtk-3.0 gtk-4.0 plank] + .map {|x| ".themes/linea-nord-color/#{x}"}] +op SymLink, + to: "#{HOME}/.themes/linea-nord-color/general/dark.css", + from: "../../../.cache/wal/dark.css" +op SymLink, + to: "#{HOME}/.themes/linea-nord-color/gtk-2.0/gtkrc", + from: "../../../.cache/wal/gtkrc" diff --git a/common/.XCompose b/common/.XCompose new file mode 100644 index 0000000..62cf089 --- /dev/null +++ b/common/.XCompose @@ -0,0 +1,4 @@ +include "%L" +include "%H/.dotXCompose" + + : "’" diff --git a/common/.Xmodmap b/common/.Xmodmap new file mode 100644 index 0000000..12d10f9 --- /dev/null +++ b/common/.Xmodmap @@ -0,0 +1 @@ +remove mod1 = Meta_L Meta_R diff --git a/common/.Xresources b/common/.Xresources new file mode 100644 index 0000000..70c287a --- /dev/null +++ b/common/.Xresources @@ -0,0 +1,15 @@ +!! Let pywal do the work !! + +URxvt.font: xft:monospace:size=7,xft:Noto Color Emoji:size=10,xft:Symbola:size=10 +URxvt.scrollBar: false +URxvt.perl-ext-common: default,matcher,keyboard-select,resize-font,selection-to-clipboard +URxvt.matcher.button: 1 +URxvt.keysym.M-k: perl:matcher:list +URxvt.keysym.M-h: resize-font:smaller +URxvt.keysym.M-l: resize-font:bigger +URxvt.keysym.M-equal: resize-font:reset +URxvt.keysym.M-question: resize-font:show +URxvt.keysym.M-j: perl:keyboard-select:activate +URxvt.modifier: alt + +*.dpi: 96 diff --git a/common/.aspell.en.pws b/common/.aspell.en.pws new file mode 100644 index 0000000..5cd1d2d --- /dev/null +++ b/common/.aspell.en.pws @@ -0,0 +1,23 @@ +personal_ws-1.1 en 22 +Allenville +Arcmage +BZFlag +Babbo +Donavan +GMail +Kinkley +Krumwiede +Maurie +Moultrie +PSU +PSUs +Parri +Pinephone +RSS +Sindarin +backlight +combinator +docstrings +dotfiles +rebalance +trackpoint diff --git a/common/.config/beets/config.yaml b/common/.config/beets/config.yaml new file mode 100644 index 0000000..ca04d22 --- /dev/null +++ b/common/.config/beets/config.yaml @@ -0,0 +1,21 @@ +directory: ~/mus +library: ~/mus/beets.db +plugins: + - edit + - parentwork + - fetchart + - missing + - replaygain + +fetchart: + sources: filesystem coverart wikipedia itunes + +replaygain: + backend: ffmpeg + +paths: + genre:classical: $parent_composer/$parentwork/$album%aunique{}/$track $title + "album:The Battle for Wesnoth OST": $album/$track $title + singleton: $artist/$title + comp: compilation/$album%aunique{}/$track $title + default: $albumartist/$album%aunique{}/$track $title diff --git a/common/.config/common-lisp/source-registry.conf.d/00-home-src.conf b/common/.config/common-lisp/source-registry.conf.d/00-home-src.conf new file mode 100644 index 0000000..7e9e0a9 --- /dev/null +++ b/common/.config/common-lisp/source-registry.conf.d/00-home-src.conf @@ -0,0 +1 @@ +(:tree (:home "src/lisp/")) diff --git a/common/.config/common-lisp/source-registry.conf.d/01-lab-lisp.conf b/common/.config/common-lisp/source-registry.conf.d/01-lab-lisp.conf new file mode 100644 index 0000000..697ed82 --- /dev/null +++ b/common/.config/common-lisp/source-registry.conf.d/01-lab-lisp.conf @@ -0,0 +1 @@ +(:tree (:home "lab/lisp")) diff --git a/common/.config/common-lisp/source-registry.conf.d/02-slynk.conf b/common/.config/common-lisp/source-registry.conf.d/02-slynk.conf new file mode 100644 index 0000000..ea1e5e8 --- /dev/null +++ b/common/.config/common-lisp/source-registry.conf.d/02-slynk.conf @@ -0,0 +1 @@ +(:tree (:home ".emacs.d/elpa/")) \ No newline at end of file diff --git a/common/.config/fontconfig/fonts.conf b/common/.config/fontconfig/fonts.conf new file mode 100644 index 0000000..b7b1034 --- /dev/null +++ b/common/.config/fontconfig/fonts.conf @@ -0,0 +1,80 @@ + + + + + serif + + Iosevka Martial Etoile + Iosevka Etoile + Roboto Slab + DejaVu Serif + + + + sans-serif + + Iosevka Martial Aile + Iosevka Aile + B612 + Roboto + DejaVu Sans + + + + sans + + sans-serif + + + + monospace + + Iosevka Martial + Iosevka + B612 Mono + Hack + DejaVu Sans Mono + + + + cursive + + Elegante + serif + + + + + + ja + + + serif + + + Noto Serif CJK JP + + + + + ja + + + sans-serif + + + Noto Sans CJK JP + + + + + ja + + + monospace + + + Noto Sans Mono CJK JP + + + diff --git a/common/.config/mimeapps.list b/common/.config/mimeapps.list new file mode 100644 index 0000000..70f6cc8 --- /dev/null +++ b/common/.config/mimeapps.list @@ -0,0 +1,25 @@ +[Default Applications] +image/jpg=emacsclient.desktop; +image/png=emacsclient.desktop; + +video/mp4=emacsclient.desktop; +video/webm=emacsclient.desktop; +video/x-msvideo=emacsclient.desktop + +audio/mpeg=emacsclient.desktop; +audio/x-vorbis+ogg=emacsclient.desktop; + +text/plain=emacsclient.desktop; +text/html=firefox-esr.desktop; + +application/pdf=emacsclient.desktop; +application/epub+zip=emacsclient.desktop; + +x-scheme-handler/magnet=torrent.desktop; +application/x-bittorrent=torrent.desktop; + +x-scheme-handler/mailto=emacsclient-mail.desktop; + +x-scheme-handler/http=firefox-esr.desktop; +x-scheme-handler/https=firefox-esr.desktop; +x-scheme-handler/about=firefox-esr.desktop; diff --git a/common/.config/screenkey.json b/common/.config/screenkey.json new file mode 100644 index 0000000..d972e27 --- /dev/null +++ b/common/.config/screenkey.json @@ -0,0 +1,23 @@ +{ + "opacity": 0.4, + "mods_only": false, + "font_desc": "monspace 10", + "compr_cnt": 3, + "screen": 0, + "no_systray": false, + "bg_color": "black", + "vis_space": true, + "position": "bottom", + "key_mode": "composed", + "vis_shift": false, + "mods_mode": "normal", + "ignore": [], + "font_size": "small", + "recent_thr": 0.1, + "bak_mode": "baked", + "geometry": null, + "multiline": false, + "timeout": 1.0, + "persist": false, + "font_color": "white" +} diff --git a/common/.config/user-dirs.dirs b/common/.config/user-dirs.dirs new file mode 100644 index 0000000..51bb939 --- /dev/null +++ b/common/.config/user-dirs.dirs @@ -0,0 +1,8 @@ +XDG_DOCUMENTS_DIR="$HOME/etc" +XDG_DOWNLOAD_DIR="$HOME/tmp/dl" +XDG_MUSIC_DIR="$HOME/mus" +XDG_PICTURES_DIR="$HOME/img" +XDG_VIDEOS_DIR="$HOME/vid" +XDG_DESKTOP_DIR="$HOME" +XDG_TEMPLATES_DIR="$HOME" +XDG_PUBLICSHARE_DIR="$HOME" diff --git a/common/.config/wal/templates/dark.css b/common/.config/wal/templates/dark.css new file mode 100644 index 0000000..1d8547d --- /dev/null +++ b/common/.config/wal/templates/dark.css @@ -0,0 +1,72 @@ + +@import url("gtk-version.css"); +@import url("../general/gtk-colors.css"); +@import url("../general/widgets.css"); +@import url("../general/titlebar.css"); + +@define-color gtk_titlebar_bg_color mix(@gtk_bg_color,@gtk_fg_color,0.05); + +@define-color gtk_fg_color {color15}; +@define-color gtk_text_color @gtk_fg_color; +@define-color gtk_base_color {color0}; +@define-color gtk_bg_color mix(@gtk_base_color, @gtk_fg_color, 0.03); + +@define-color gtk_button_color mix(@gtk_bg_color, @gtk_fg_color, 0.1); +@define-color gtk_widget_color alpha(currentcolor,0.1); + +@define-color gtk_shadow alpha(black,0.3); +@define-color gtk_button_shadow alpha(@gtk_shadow,0.15); +@define-color gtk_menu_shadow alpha(@gtk_shadow,0.5); + +@define-color text_shadow_color alpha(@panel_bg,0.5); + +@define-color gtk_borders mix(@gtk_bg_color,@gtk_fg_color,0.1); +@define-color gtk_transparent_borders alpha(@gtk_fg_color,0.1); + +@define-color gtk_selected_bg_color {color4}; +@define-color gtk_selected_fg_color shade(@gtk_selected_bg_color, 0.2); + +@define-color gtk_highlight alpha(@gtk_selected_bg_color,0.6); +@define-color gtk_titlebar_highlight alpha(@gtk_selected_bg_color,0.2); + +check, +radio, +treeview.view.content-view.check:not(list), +iconview.content-view.check:not(list), +.content-view:not(list) check, +.view check:not(:checked):selected, +.view radio:not(:checked):selected, +check.view:not(treeview):not(:checked):selected, +radio.view:not(treeview):not(:checked):selected, +progressbar trough +{{background-clip: padding-box;}} +check:checked, +check:indeterminate, +radio:checked, +radio:indeterminate, +treeview.view check:checked, +treeview.view check:indeterminate, +treeview.view radio:checked, +treeview.view radio:indeterminate, +treeview.view.content-view.check:not(list):checked, +iconview.content-view.check:not(list):checked, +.content-view:not(list) check:checked, +switch, +progressbar progress, +levelbar block, +scale highlight, +button.suggested-action, +button.destructive-action +{{background-clip: border-box;}} + +.window-frame, .window-frame:backdrop {{ + box-shadow: 0 0 0 black; /* removes shadow completely */ + border-style: none; + margin: 1px; /* this retains the ability to resize with the mouse, if 1px is too narrow, set some higher values */ + border-radius: 0; +}} + +window-frame, window, headerbar, .titlebar, menubar {{ + box-shadow: none; + margin: 1px; +}} diff --git a/common/.config/wal/templates/dunstrc b/common/.config/wal/templates/dunstrc new file mode 100644 index 0000000..bcfbdb8 --- /dev/null +++ b/common/.config/wal/templates/dunstrc @@ -0,0 +1,30 @@ +[global] +follow = mouse +enable_posix_regex = true + +width = (200, 300) +offset = (20, 10) + +transparency = 20 + +gap_size = 1 + +idle_threshold = 5m + +frame_color = "{cursor}" + +[urgency_low] + background = "{background}" + foreground = "{foreground}" + timeout = 5 + +[urgency_normal] + background = "{background}" + foreground = "{foreground}" + timeout = 10 + +[urgency_critical] + background = "{background}" + foreground = "{foreground}" + frame_color = "{color4}" + timeout = 0 diff --git a/common/.config/wal/templates/gtkrc b/common/.config/wal/templates/gtkrc new file mode 100644 index 0000000..e93d5ce --- /dev/null +++ b/common/.config/wal/templates/gtkrc @@ -0,0 +1,253 @@ +gtk_color_scheme = "fg_color:{color15} +bg_color:{color0} +base_color:{color8} +text_color:{color15} +selected_bg_color:{color4} +selected_fg_color:{color0} +tooltip_bg_color:{color8} +tooltip_fg_color:{color15} +border_color:{color4}" + +style "default" +{{ + xthickness = 2 + ythickness = 2 + + GtkEntry::cursor_color = @fg_color + GtkEntry::cursor_aspect_ratio = 0.05 + + GtkRange::stepper-size = 20 + GtkScale ::slider-length = 20 + GtkScale ::trough-side-details = 0 # 0 = thin slider, >0 = thick slider + + GtkTextView::cursor_aspect_ratio = 0.1 + GtkTextView::cursor_color = @fg_color + + GtkTreeView::expander-size = 16 + + GtkWidget::focus-padding = 0 + GtkWidget::interior_focus = 2 + GtkWidget::link-color = @selected_bg_color + GtkWidget::visited-link-color = shade(0.8,@selected_bg_color) + + GtkToolbar :: shadow-type = GTK_SHADOW_NONE + GtkMenuBar :: shadow-type = GTK_SHADOW_NONE + + GtkToolbar ::internal-padding = 4 + + GtkScrollbar ::has-backward-stepper = 0 + GtkScrollbar ::has-forward-stepper = 0 + + GtkCheckButton ::indicator-size = 16 + + GtkProgressBar ::min-vertical-bar-width = 6 + GtkProgressBar ::min-horizontal-bar-height = 6 + + fg[NORMAL] = @fg_color # this is the color of borders + text[NORMAL] = @fg_color + fg[PRELIGHT] = @fg_color + text[PRELIGHT] = @fg_color + fg[ACTIVE] = @fg_color + text[ACTIVE] = @fg_color + fg[SELECTED] = @fg_color + text[SELECTED] = @fg_color + fg[INSENSITIVE] = mix(0.5, @base_color, @fg_color) + text[INSENSITIVE] = mix(0.5, @base_color, @fg_color) + + bg[NORMAL] = @bg_color + base[NORMAL] = @base_color + bg[PRELIGHT] = @bg_color + base[PRELIGHT] = @bg_color + bg[ACTIVE] = mix(0.2,@fg_color,@bg_color) + base[ACTIVE] = mix(0.1,@fg_color,@base_color) + bg[SELECTED] = @selected_bg_color + base[SELECTED] = mix(0.1,@fg_color,@base_color) + bg[INSENSITIVE] = @bg_color + base[INSENSITIVE] = @bg_color + + engine "murrine" +{{ + contrast = 0.0 + arrowstyle = 2 #to draw filled arrows. + glazestyle = 0 # 0 = flat highlight, 1 = curved highlight, 2 = concave style, 3 = top curved highlight, 4 = beryl highlight + gradient_shades = {{1.0, 1.0, 1.0, 1.0}} # default: {{1.1,1.0,1.0,1.1}} + highlight_shade = 1.0 # set highlight amount for buttons or widgets + lightborder_shade = 1.0 # sets lightborder amount for buttons or widgets + lightborderstyle = 1 # 0 = lightborder on top side, 1 = lightborder on all sides + focusstyle = 1 + reliefstyle = 0 + menustyle = 0 + menubaritemstyle = 0 # 0 = menuitem look, 1 = button look + menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped + menuitemstyle = 0 # 0 = flat, 1 = glassy, 2 = striped + progressbarstyle = 0 + border_shades = {{ 1.0, 1.0 }} # this for light borders +}} + +}} + +style "entry" +{{ + xthickness = 4 + ythickness = 4 + + engine "murrine" {{border_shades = {{ 1.5, 1.5 }}}} +}} + +style "button" +{{ + xthickness = 4 + ythickness = 4 + + engine "murrine" {{ roundness = 3 border_shades = {{ 1.5, 1.5 }} }} + + bg[NORMAL] = @bg_color + bg[PRELIGHT] = @bg_color + bg[ACTIVE] = mix(0.2, @fg_color,@bg_color) +}} + +style "radiocheck" +{{ + text[NORMAL] = @selected_fg_color # Text in window + text[PRELIGHT] = @selected_fg_color # Text on Mouseover + text[ACTIVE] = @selected_fg_color # Text on click + + bg[SELECTED] = @selected_bg_color +}} + +style "progressbar" +{{ + xthickness = 0 + ythickness = 0 + + engine "murrine" {{}} + + fg[PRELIGHT] = @selected_fg_color +}} + +style "scale" +{{ + GtkRange ::slider-width = 14 + GtkScale ::slider-length = 14 + GtkScale ::trough-side-details = 1 + + engine "murrine" {{roundness = 4 border_shades = {{ 1.5, 1.5 }}}} + + bg[NORMAL] = @base_color + bg[PRELIGHT] = @base_color +}} + +style "menubar" +{{ +}} + +style "menubaritem" +{{ + fg[NORMAL] = @fg_color +}} + +style "menu" +{{ + xthickness = 1 + ythickness = 4 + + bg[NORMAL] = @bg_color + +}} + +style "menuitem" +{{ + xthickness = 4 + ythickness = 4 + + engine "murrine" {{ contrast = 0.0}} + + bg[SELECTED] = mix(0.1,@fg_color,@bg_color) + + text[NORMAL] = @fg_color + text[PRELIGHT] = @fg_color + fg[PRELIGHT] = @fg_color +}} + +style "menu-separator" +{{ + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 1 + xthickness = 1 + ythickness = 2 + + engine "hcengine" {{ edge_thickness = 1}} + fg[NORMAL] = @border_color +}} + +style "separator" +{{ + engine "hcengine" {{ edge_thickness = 1}} + fg[NORMAL] = @border_color +}} + +style "toolbar" +{{ + +}} + +style "scrollbar" +{{ + engine "murrine" {{ border_shades = {{ 1.65, 1.65 }} gradient_shades = {{1.0, 1.0, 1.0, 1.0}} }} + bg[SELECTED] = mix(0.5,@fg_color, @base_color) +}} + +style "notebook" +{{ + xthickness = 5 + ythickness = 2 + + bg[NORMAL] = @base_color + bg[ACTIVE] = @bg_color +}} + +style "notebook_viewport" {{ + bg[NORMAL] = @base_color +}} + +style "tooltips" +{{ + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @tooltip_bg_color + fg[NORMAL] = @tooltip_fg_color +}} + +class "GtkWidget" style "default" + +class "GtkEntry" style "entry" +widget_class "*" style "button" +class "GtkRadio*" style "radiocheck" +class "GtkCheck*" style "radiocheck" +widget_class "*" style "progressbar" +class "GtkScale" style "scale" + +class "GtkFrame" style "separator" +class "GtkSeparator" style "separator" +class "GtkVSeparator" style "separator" +class "GtkHSeparator" style "separator" +class "GtkSeparatorToolItem" style "separator" + +class "GtkMenuBar" style "menubar" +widget_class "*MenuBar.*" style "menubaritem" +class "GtkMenu" style "menu" +widget_class "**" style "menuitem" +widget_class "**" style "menu-separator" + +class "GtkToolbar" style "toolbar" +class "GtkScrollbar" style "scrollbar" +widget "gtk-tooltip*" style "tooltips" + +widget_class "**" style "notebook" +widget_class "**" style "notebook" +widget_class "**" style "notebook" +widget_class "***" style "notebook_viewport" +widget_class "*" style "notebook" diff --git a/common/.dotXCompose b/common/.dotXCompose new file mode 120000 index 0000000..2ea311c --- /dev/null +++ b/common/.dotXCompose @@ -0,0 +1 @@ +../modules/xcompose/dotXCompose \ No newline at end of file diff --git a/common/.emacs.d/init.el b/common/.emacs.d/init.el new file mode 100644 index 0000000..eb18086 --- /dev/null +++ b/common/.emacs.d/init.el @@ -0,0 +1,4240 @@ +;; -*- lexical-binding: t; eval: (outline-minor-mode); outline-regexp: "^(" -*- +(setq use-package-expand-minimally t) +(use-package use-package + :demand t + :config + (setq use-package-always-defer t) + (unless (eq (car use-package-keywords) :if) + (push :if use-package-keywords))) + +(use-package cl-lib + :demand t) + +(use-package use-package-ensure + :config + (define-advice use-package-ensure-elpa (:after (name args _state &optional _no-refresh) select-package) + (dolist (ensure args) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when (consp package) + (setq package (car package))) + (when package + (cl-pushnew package package-selected-packages)))))) + +(use-package package + :demand t + :config + (setq + package-archives + '(("gnu" . "https://elpa.gnu.org/packages/") + ("nongnu" . "https://elpa.nongnu.org/nongnu/") + ("melpa" . "https://melpa.org/packages/") + ("melpa-stable" . "https://stable.melpa.org/packages/")) + package-archive-priorities + '(("gnu" . 10) + ("nongnu" . 9) + ("melpa-stable" . 5) + ("melpa" . 1)) + package-menu-hide-low-priority t)) + +(use-package anaphora + :demand t + :ensure t) + +(progn ;; groups + (defvar group--enabled-groups '()) + (defvar group--all-groups nil) + + (defun enable-group (group) + (push group group--enabled-groups)) + + (defmacro enable-groups (&rest groups) + (declare (indent 0)) + `(progn ,@(mapcar (lambda (g) `(enable-group ',g)) groups))) + + (defun enable-all-groups () + (setq group--all-groups t)) + + (defun group-enabled-p (group) + (or (memq group group--enabled-groups) + group--all-groups)) + + (defmacro if-group (groups then &rest else) + (declare (indent 2)) + (let ((groups (if (listp groups) + groups + (list groups)))) + `(if (and + ,@(mapcar (lambda (group) + `(group-enabled-p ',group)) + groups)) + ,then + ,@else))) + + (defmacro when-group (groups &rest body) + (declare (indent 1)) + `(if-group ,groups + (progn ,@body))) + + (defmacro unless-group (groups &rest body) + (declare (indent 1)) + `(if-group ,groups + nil + ,@body)) + + (defvar group-file (locate-user-emacs-file "groups.el")) + (if (file-exists-p group-file) + (load group-file) + (enable-all-groups))) + +(progn ;; host attributes + (defun has-attribute (attr) + (let ((attr + (if (stringp attr) + attr + (thread-last + (symbol-name attr) + upcase + (string-replace "-" "_"))))) + (string= (getenv attr) "1"))) + + (defmacro if-attribute (attr then &rest else) + (declare (indent 2)) + `(if (has-attribute ',attr) + ,then + ,@else)) + + (defmacro when-attribute (attr &rest body) + (declare (indent 1)) + `(if-attribute ,attr + (progn ,@body))) + + (defmacro unless-attribute (attr &rest body) + (declare (indent 1)) + `(if-attribute ,attr + nil + ,@body))) + +(use-package custom + :config + (setq + custom-safe-themes t + custom-file (locate-user-emacs-file ".custom.el"))) + +(use-package faces + :config + (add-to-list 'face-remapping-alist '(tab-bar-tab-inactive mode-line-inactive)) + + (custom-set-faces + '(default ((t (:font "monospace 7")))) + '(variable-pitch ((t (:font "sans-serif 8")))) + '(font-lock-comment-face ((t (:slant italic)))))) + +(progn ;; transparency + (defvar default-alpha 90) + (set-frame-parameter nil 'alpha-background default-alpha) + (add-to-list 'default-frame-alist `(alpha-background . ,default-alpha)) + + (defun toggle-transparency (&optional frame) + (interactive) + (let* ((current-alpha (frame-parameter nil 'alpha-background))) + (set-frame-parameter frame 'alpha-background + (if (= current-alpha default-alpha) + 100 default-alpha)))) + + (defun disable-transparency (&optional frame) + (interactive) + (set-frame-parameter frame 'alpha-background '(100 . 100))) + + (defun change-transparency (f &optional frame) + (let ((trans (frame-parameter frame 'alpha-background))) + (set-frame-parameter + nil + 'alpha-background (funcall f trans)))) + + (defun lower-transparency (arg) + (interactive "P") + (change-transparency (lambda (x) (- x (or arg 5))))) + + (defun raise-transparency (arg) + (interactive "P") + (change-transparency (lambda (x) (+ x (or arg 5)))))) + +(progn ;; useful-functions + (defun spawn-shell-cmd (name buffer command) + (declare (ignore name)) + (call-process-shell-command (concat "setsid -f " command) nil buffer)) + + (cl-defun clear-message-with-delay (&optional (delay 0.5)) + (interactive) + (run-with-timer delay nil clear-message-function)) + + (defmacro with-new-frame (&rest body) + `(progn (select-frame (make-frame)) + ,@body)) + + (defun eval-in-new-frame (form &optional lexical) + (with-new-frame (eval form lexical))) + + (defun greet (name) + "Greet NAME in a frendly, non intimidating fassion." + (interactive "sWhat's your name? ") + (message "Hello, %s, I am the Emacs Lisp interpreter." name)) + + (defun advice-clear (sym) + (advice-mapc (lambda (f &rest _) (advice-remove sym f)) sym)) + + (defun frame-menu-toolbars-on () + "Show the menu and toolbars in current frame." + (interactive) + (modify-frame-parameters + nil + '((tool-bar-lines . 1) + (menu-bar-lines . 1) + (vertical-scroll-bars) + (right-fringe . 1) (left-fringe . 1)))) + + (defun frame-menu-toolbars-off () + "Hide the menu and toolbars in current frame." + (interactive) + (modify-frame-parameters + nil + '((tool-bar-lines . 0) + (menu-bar-lines . 0) + (vertical-scroll-bars) + (right-fringe . 0) (left-fringe . 0)))) + + (defun make-scratch-buffer (name) + (interactive "sName: ") + (find-file (concat "~/tmp/" name ".scratch.org"))) + + (defun revert-all-buffers (&optional arg) + (interactive) + (let ((pattern (or arg ".*")) (c-buf (current-buffer))) + (dolist (buf (buffer-list)) + (when (and (string-match-p pattern (buffer-name buf)) + (buffer-file-name buf)) + (with-current-buffer buf + (revert-buffer 'ignore-auto 'noconfirm 'preserve-modes)))))) + + (defun do-split-window () + (interactive) + (funcall split-window-preferred-function)) + + (defun go-next-window (arg) + (interactive "p") + (cond ((cl-plusp arg) + (select-window (next-window)) + (go-next-window (1- arg))) + ((cl-minusp arg) + (select-window (previous-window)) + (go-next-window (1+ arg))))) + (defun go-previous-window (arg) + (interactive "p") + (go-next-window (* arg -1))) + (defun go-other-buffer () + (interactive) + (switch-to-buffer (other-buffer (current-buffer)) nil t)) + + (defun kill-buffer-and-maybe-window () + (interactive) + (if (not (one-window-p)) + (kill-buffer-and-window) + (kill-buffer))) + + (defun display-buffer-in-side-window-nearest (buffer alist) + (let* ((side (if (> (+ (window-left-column) + (current-column)) + (/ (frame-width) 2)) + 'right + 'left)) + (alist (cons `(side . ,side) alist))) + (display-buffer-in-side-window + buffer alist))) + + + (defun pidof (name) + (require 'proced) + (cl-find + name + (proced-filter (proced-process-attributes) + (alist-get 'user proced-filter-alist)) + :key (lambda (x) (alist-get 'args (cdr x))) + :test #'string-match-p)) + + (defun string-match-substrings (regexp string &optional start) + (declare (side-effect-free t)) + (save-match-data + (when (string-match regexp string start) + (mapcar + (lambda (x) + (if (and (car x) (cadr x)) + (substring string (car x) (cadr x)) + "")) + (seq-partition + (match-data) 2))))) + + (defun write-string (string filename &optional append mustbenew) + (with-temp-buffer + (insert string) + (write-region + (point-min) (point-max) + filename append + nil nil mustbenew))) + + (defun file-string (filename &optional beg end) + (with-temp-buffer + (insert-file-contents + filename nil beg end) + (buffer-string))) + + (defun add-hooks (hook &rest functions) + (declare (indent 1)) + (mapc + (lambda (x) + ;; A closure is a list. Ugh. + (let* ((x (ensure-list x)) + (x (if (functionp x) (list x) x))) + (apply #'add-hook hook x))) + functions)) + + (defun keymap-modify (keymap &rest definitions) + (declare (indent 1)) + (apply #'define-keymap :keymap keymap definitions)) + + (defun keymap-global-modify (&rest definitions) + (declare (indent 0)) + (apply #'define-keymap :keymap global-map definitions)) + + (defun insert-file-name (&optional absolute) + (interactive "P") + (let ((f (read-file-name "File name: "))) + (insert (if absolute f + (file-relative-name f default-directory))))) + (keymap-global-set "C-x M-f" 'insert-file-name) + + (defun fixup-typing-stats (&optional arg) + "Keyboard macro." + (interactive "p") + (kmacro-exec-ring-item '([left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left left 44 right right right right right right right right right right right right right right right 44 right right right right right right right right right right right 40 right right right right right right right right right right 41 down] 2 "%d") arg)) + + (defun fixup-writing-station (&optional arg) + "Keyboard macro." + (interactive "p") + (kmacro-exec-ring-item '([C-up right 60 115 101 99 116 105 111 110 32 105 100 61 5 62 6 60 104 50 62 5 60 47 104 50 62 13 60 112 62 6 67108896 C-down 15 60 47 115 101 99 116 105 111 110 62 1 2 24 24 134217765 91 13 60 98 62 13 33 21 67108896 24 24 24 24 134217765 93 13 60 47 98 62 13 33 21 67108896 24 24 24 24 134217765 17 10 13 60 98 114 62 17 10 13 33 C-down 14] 0 "%d") arg)) + + (defun writing-station-preproc (&optional arg) + "Keyboard macro." + (interactive "p") + (kmacro-exec-ring-item '([?\C-r ?_ right ?\C- end ?\M-w home right ?\M-c ?: ?\C-s ?\C-y ?\M-b ?\[ ?\M-f ?\] ?\C-r ?S backspace ?_ right backspace]) arg)) + + (defun zdict-open () + (interactive) + (cond + ((file-exists-p "/etc/dictionaries-common/words") + (view-file "/etc/dictionaries-common/words")) + ((file-exists-p "/usr/share/dict/words") + (view-file "/usr/share/dict/words")) + (t (message "zdict: cannot open dictionary"))) + (rename-buffer "zlastcompletion") + (bury-buffer))) + +(progn ;; pair-inserters + (defvar-keymap insert-pair-map) + (defmacro define-pair-inserter (name delim1 &optional delim2) + (let ((name (intern (format "insert-%s" name)))) + `(progn + (defun ,name (arg) + (interactive "P") + (insert-pair (or arg 1) ,delim1 ,(or delim2 delim1))) + ,@(mapcar (lambda (pfx) + `(keymap-set insert-pair-map + ,(format "%s%c" pfx delim1) ',name)) + '("" "M-"))))) + (define-pair-inserter parens ?\( ?\)) + (define-pair-inserter brackets ?\[ ?\]) + (define-pair-inserter braces ?\{ ?\}) + (define-pair-inserter angle-brackets ?< ?>) + (define-pair-inserter double-quotes ?\") + (define-pair-inserter single-quotes ?\') + (define-pair-inserter back-quotes ?\`) + + (keymap-global-set "M-(" insert-pair-map)) + +(progn ;; hyper-key + (define-prefix-command 'h-x-prefix) + (keymap-global-modify + "H-x" 'h-x-prefix + "H-" 'backward-sexp + "H-" 'forward-sexp + "H-" 'backward-up-list + "H-" 'down-list + "H-f" 'insert-file-name)) + +(progn ;; alt-key + (setq x-meta-keysym 'meta) + (setq x-alt-keysym 'alt) + (when-group alt-key + (cl-psetq + x-alt-keysym x-meta-keysym + x-meta-keysym x-alt-keysym))) + +;; (progn ;; swap-ctrl +;; (setq x-ctrl-keysym 'ctrl) +;; (cl-psetq +;; x-alt-keysym x-ctrl-keysym +;; x-ctrl-keysym x-alt-keysym)) + +(progn ;; ham + (defvar ham-callsign-history nil) + (defun ham-lookup-callsign (call) + (interactive + (list + (cond + ((and (not current-prefix-arg) + (word-at-point)) + (word-at-point)) + ((region-active-p) + (buffer-substring-no-properties (region-beginning) (region-end))) + (t (read-string "Callsign: " nil 'ham-callsign-history))))) + (browse-url (format "https://www.ae7q.com/query/data/CallHistory.php?CALL=%s" (upcase call)))) + + (define-prefix-command 'ham-prefix) + (keymap-global-set "H-x H-h" 'ham-prefix) + (keymap-global-set "H-x H-h c" 'ham-lookup-callsign)) + +(use-package emacs + :load-path "lisp/" + :config + (setq enable-recursive-minibuffers t) + (minibuffer-depth-indicate-mode) + + (setq + scroll-conservatively 999 + scroll-preserve-screen-position t + next-screen-context-lines 0 + + auto-revert-avoid-polling t + + disabled-command-function nil + + ediff-window-setup-function 'ediff-setup-windows-plain + ediff-split-window-function 'split-window-sensibly + + diff-font-lock-prettify t + + set-mark-command-repeat-pop t + + fortune-dir "/usr/share/games/fortunes" + fortune-file (expand-file-name "linuxcookie" fortune-dir) + + initial-scratch-message nil + + save-interprogram-paste-before-kill t + + visible-bell t + + what-cursor-show-names t + + windmove-create-window t + + tab-always-indent 'complete + + goto-line-history-local t + + repeat-keep-prefix t + + desktop-load-locked-desktop 'check-pid + + completion-styles '(basic flex partial-completion initials) + completion-ignore-case t + read-file-name-completion-ignore-case t + read-buffer-completion-ignore-case t + bookmark-completion-ignore-case t + + window-sides-slots '(4 4 4 4) + display-buffer-alist + (cl-flet ((match-modes + (&rest modes) + (lambda (buf _) + (with-current-buffer buf + (not (seq-every-p + #'null + (mapcar #'derived-mode-p modes))))))) + `((,(rx bol (| "*Help*" "*Man" "*info" "*Shortdoc")) + (display-buffer-reuse-mode-window + (lambda (buffer alist) + (if (> (frame-width) 255) + (display-buffer-in-side-window-nearest buffer alist) + (display-buffer-in-side-window buffer alist)))) + (side . left) (slot . -4) + (window-width . 81) + (mode help-mode Man-mode Info-mode)) + (,(rx bol (| "*compilation*" "*Compile-Log*" "*grep*" "*Occur*" "*Locate*") eol) + display-buffer-in-side-window-nearest + (window-width . 0.33)) + (,(rx (| "*Backtrace*" "*Warnings*" "*Messages*")) + display-buffer-in-side-window + (side . bottom) (slot . 4) + (window-height . 0.33)) + (,(match-modes 'magit-mode) + display-buffer-in-side-window-nearest + (window-width . 100)) + (,(rx bol "*sly-mrepl") + display-buffer-same-window) + (,(rx bol "*Dired-sidebar*" eol) + display-buffer-in-side-window + (side . left) (slot . 4) + (window-width . 30)) + (,(rx bol (or "*Org Agenda*" ) eol) + display-buffer-reuse-mode-window + (mode org-agenda-mode)) + (,(rx bol (or "*Org Select*" "*Org Attach*" " *Agenda Commands*") eol) + display-buffer-in-side-window + (side . bottom) (slot . 4) + (window-height . fit-window-to-buffer)) + (,(rx bol "*Org QL View: ") + display-buffer-in-side-window-nearest + (slot . 1)))) + display-buffer-base-action '(display-buffer-same-window)) + (setq-default fill-column 78) + + (keymap-global-set "C-x M-s" 'window-toggle-side-windows) + + (keymap-global-set " " 'ibuffer) + (keymap-global-modify + "M-s M-g" 'rgrep + "M-s M-l" 'locate + "M-s M-f" 'find-dired) + + (keymap-global-modify + "C-(" 'backward-paragraph + "C-)" 'forward-paragraph) + + (add-hook 'before-save-hook 'delete-trailing-whitespace) + + (modify-all-frames-parameters + '((tool-bar-lines . 0) + (menu-bar-lines . 0) + (vertical-scroll-bars) + (right-fringe . 0) (left-fringe . 0))) + + (blink-cursor-mode 0) + (global-hi-lock-mode) + (minibuffer-electric-default-mode) + (column-number-mode) + (show-paren-mode) + (electric-pair-mode) + (repeat-mode) + (url-handler-mode) + (size-indication-mode) + (when (fboundp #'editorconfig-mode) + (editorconfig-mode)) + (zdict-open) + (switch-to-buffer "*scratch*")) + +(use-package project + :config + (define-advice project-try-vc (:around (oldf &rest args) ignore-home) + (require 'tramp) + (let ((pr (apply oldf args))) + (cond + ((not pr) nil) + ((file-equal-p + (project-root pr) + (tramp-handle-expand-file-name + (concat + (or (file-remote-p default-directory) + "") + "~/"))) + nil) + (t pr)))) + (setq project-vc-extra-root-markers '(".projectile" ".project"))) + +(use-package diminish + :ensure t) + +(use-package meow + :config + (apply #'meow-leader-define-key + (mapcar (lambda (n) + (cons (number-to-string n) + 'meow-digit-argument)) + (number-sequence 0 9))) + (apply + #'meow-normal-define-key + (mapcar + (lambda (x) (cons (car x) (cadr x))) + (seq-partition + `(,@(apply #'append + (mapcar (lambda (n) + `(,(number-to-string n) + ,(intern (format "meow-expand-%d" n)))) + (number-sequence 0 9))) + "-" negative-argument + ,@(apply + #'append + (apply + #'append + (mapcar (lambda (x) + (list `(,(car x) ,(intern (format "meow-%s" (cadr x)))) + `(,(upcase (car x)) + ,(intern (format "meow-%s-expand" (cadr x)))))) + '(("n" next) + ("p" prev) + ("b" left) + ("f" right))))) + "a" meow-append + "A" meow-open-below + "c" meow-change + "d" meow-delete + "D" meow-backward-delete + "e" meow-next-word + "E" meow-next-symbol + "g" meow-cancel-selection + "G" meow-grab + "h" meow-mark-word + "H" meow-mark-symbol + "i" meow-insert + "I" meow-open-above + "j" meow-find + "J" meow-join + "k" meow-kill + "m" meow-back-word + "M" meow-back-symbol + "o" meow-block + "O" meow-to-block + "q" meow-quit + "r" meow-replace + "R" meow-swap-grab + "s" meow-search + "t" meow-till + "u" meow-undo + "U" meow-undo-in-selection + "v" meow-visit + "w" meow-save + "x" meow-delete + "X" meow-backward-delete + "y" meow-yank + "Y" meow-sync-grab + "z" meow-pop-selection + ";" meow-reverse + "l" meow-line + "\"" meow-goto-line + "," meow-inner-of-thing + "." meow-bounds-of-thing + "[" meow-beginning-of-thing + "]" meow-end-of-thing + "<" beginning-of-buffer + ">" end-of-buffer + "{" backward-paragraph + "}" forward-paragraph + "'" avy-goto-char) + 2)))) + +(use-package server + :demand t + :config + (unless (server-running-p server-name) + (server-start)) + (setenv "EDITOR" "emacsclient")) + +(use-package el-patch + :demand t + :ensure t + :config + (unless (eq (car use-package-keywords) :if) + (push :if use-package-keywords))) + +(use-package window + :config/el-patch + (defun split-window-sensibly (&optional window) + "Split WINDOW in a way suitable for `display-buffer'. +WINDOW defaults to the currently selected window. +If `split-height-threshold' specifies an integer, WINDOW is at +least `split-height-threshold' lines tall and can be split +vertically, split WINDOW into two windows one above the other and +return the lower window. Otherwise, if `split-width-threshold' +specifies an integer, WINDOW is at least `split-width-threshold' +columns wide and can be split horizontally, split WINDOW into two +windows side by side and return the window on the right. If this +can't be done either and WINDOW is the only window on its frame, +try to split WINDOW vertically disregarding any value specified +by `split-height-threshold'. If that succeeds, return the lower +window. Return nil otherwise. + +By default `display-buffer' routines call this function to split +the largest or least recently used window. To change the default +customize the option `split-window-preferred-function'. + +You can enforce this function to not split WINDOW horizontally, +by setting (or binding) the variable `split-width-threshold' to +nil. If, in addition, you set `split-height-threshold' to zero, +chances increase that this function does split WINDOW vertically. + +In order to not split WINDOW vertically, set (or bind) the +variable `split-height-threshold' to nil. Additionally, you can +set `split-width-threshold' to zero to make a horizontal split +more likely to occur. + +Have a look at the function `window-splittable-p' if you want to +know how `split-window-sensibly' determines whether WINDOW can be +split." + (let ((window (or window (selected-window)))) + (or (and (window-splittable-p window (el-patch-add t)) + ;; Split window horizontally. + (with-selected-window window + ((el-patch-swap + split-window-below + split-window-right)))) + (and (window-splittable-p window (el-patch-remove t)) + ;; Split window vertically. + (with-selected-window window + ((el-patch-swap + split-window-right + split-window-below)))) + (and + ;; If WINDOW is the only usable window on its frame (it is + ;; the only one or, not being the only one, all the other + ;; ones are dedicated) and is not the minibuffer window, try + ;; to split it vertically disregarding the value of + ;; `split-height-threshold'. + (let ((frame (window-frame window))) + (or + (eq window (frame-root-window frame)) + (catch 'done + (walk-window-tree (lambda (w) + (unless (or (eq w window) + (window-dedicated-p w)) + (throw 'done nil))) + frame nil 'nomini) + t))) + (not (window-minibuffer-p window)) + (let ((split-height-threshold 0)) + (when (window-splittable-p window) + (with-selected-window window + (split-window-below))))))))) + +(use-package info + :init + (defun my/view-org-as-info () + (interactive) + (let* ((base (file-name-concat + temporary-file-directory + (make-temp-name "org-info"))) + (texi (file-name-with-extension base "texi")) + (info (file-name-with-extension base "info")) + (title (if (buffer-file-name) + (file-name-nondirectory (buffer-file-name)) + (buffer-name)))) + (org-export-to-file 'texinfo texi + nil nil nil nil `(:title ,title) + #'org-texinfo-compile) + (info info (format "*info for %s*" (buffer-name (current-buffer)))) + (delete-file texi) + (delete-file info))) + + (defun my/view-md-as-info () + (interactive) + (let ((b (get-buffer-create + (concat (buffer-name) "(org)")))) + (call-process-region + nil nil + "pandoc" nil b nil + "-f" "markdown" "-t" "org") + (with-current-buffer b + (my/view-org-as-info)) + (kill-buffer b))) + + (defun my/view-file-as-info () + (interactive) + (let* ((ff + (mapcar + (lambda (x) (intern (format "my/view-%s-as-info" x))) + `(,@(when (buffer-file-name) `(,(file-name-extension (buffer-file-name)))) + ,@(when-let ((ext (cdr (last (split-string (buffer-name) "\\."))))) + `(,ext)) + ,major-mode))) + (f (seq-find #'functionp ff))) + (if f (funcall f) + (user-error "Don't know how to view file as info")))) + + :config + (custom-set-faces + '(Info-quoted ((t (:inherit font-lock-string-face)))) + '(info-title-4 ((t (:inherit variable-pitch))))) + + (add-hook 'Info-mode-hook 'variable-pitch-mode)) + +(use-package shr + :config + (setq shr-width 80 + shr-fill-text nil) + (when (display-graphic-p) + (setq shr-bullet "• "))) + +(use-package eww-lnum + :ensure t) + +(use-package eww + :config + (keymap-set eww-mode-map "f" 'eww-lnum-follow)) + +(use-package elpher + :ensure t + :config + (custom-set-faces + '(elpher-gemini-preformatted ((t (:inherit (fixed-pitch)))))) + (add-hook 'elpher-mode-hook 'variable-pitch-mode)) + +(use-package browse-url + :config + (setq + browse-url-firefox-program (or (executable-find "firefox-esr") + (executable-find "firefox")) + browse-url-browser-function #'browse-url-firefox)) + +(use-package browser-hist + :ensure t + :config + (setq browser-hist-default-browser 'firefox + browser-hist-db-paths '((firefox . "$HOME/.mozilla/firefox/main/places.sqlite")))) + +(when-group org ;; org packages + (use-package org-present + :ensure t) + (use-package org-real + :ensure t)) + +(use-package org + :if (group-enabled-p 'org) + :init + (defun my/org-procrastinate () + (interactive) + (org-with-point-at (org-find-exact-headline-in-buffer + "Procrastination" + (find-file-noselect (expand-file-name "_.org" org-directory))) + (org-clock-in))) + + (defun my/org-clock-nag-procrastination () + (require 'org-clock) + (when (and (org-clocking-p) + (equal org-clock-heading "Procrastination")) + (org-notify "What are you doing? What should you be doing?" t))) + (run-at-time t 150 #'my/org-clock-nag-procrastination) + + (defun my/consult-org-heading () + (interactive) + (let ((files (org-agenda-files)) + (consult-after-jump-hook nil)) + (consult-org-heading + nil + (cond + ((and buffer-file-name + (derived-mode-p 'org-mode)) + (if (member buffer-file-name files) + files + (cons buffer-file-name files))) + ((derived-mode-p 'org-mode) + nil) + (t 'agenda))))) + + (define-prefix-command 'org-prefix) + (define-prefix-command 'org-clock-prefix) + + (keymap-global-modify + "H-o" 'org-prefix + "C-x M-o" 'org-prefix) + + (keymap-modify org-prefix + "a" 'org-agenda + "c" 'org-capture + "b" 'org-switchb + "p" 'my/org-procrastinate + "o" 'my/consult-org-heading + "l" 'org-clock-prefix) + (keymap-modify org-clock-prefix + "i" 'org-clock-in + "o" 'org-clock-out + "x" 'org-clock-in-last + "e" 'org-clock-modify-effort-estimate + "j" 'org-clock-goto + "q" 'org-clock-cancel) + + :config + (require 'xdg) + + (setq + org-todo-keywords + '((sequence "TODO(t)" "PROG(p)" "DONE(d)") + (type "WAIT(w)" "|") + (type "PROJ(j)" "|")) + + org-priority-highest 1 + org-priority-default 3 + org-priority-lowest 5 + org-priority-start-cycle-with-default nil + + org-use-fast-todo-selection 'expert + org-log-into-drawer t + + org-refile-use-outline-path t + org-refile-targets '((nil . (:maxlevel . 9))) + + org-modules + '(org-habit org-tempo ol-info ol-man ol-gnus ox-beamer) + + org-startup-folded t + org-hide-leading-stars t + org-startup-indented t + org-src-window-setup 'current-window + org-ellipsis "…" + org-hide-emphasis-markers t + org-pretty-entities t + + org-tags-column 0 + org-catch-invisible-edits 'show + org-image-actual-width 500 + org-display-remote-inline-images 'cache + org-preview-latex-default-process 'dvisvgm + org-preview-latex-image-directory + (file-name-concat + (or (xdg-cache-home) + user-emacs-directory) + "ltximg/") + org-show-notification-handler "notify-send" + org-timestamp-custom-formats '("%B %d, %Y" . "%B %d, %Y at %H:%M") + + org-enforce-todo-dependencies t + org-enforce-todo-checkbox-dependencies t + org-clock-out-remove-zero-time-clocks t + org-tags-exclude-from-inheritance '("ATTACH")) + + (setf (plist-get org-format-latex-options :background) "Transparent") + + (add-hook 'org-mode-hook 'variable-pitch-mode) + + (custom-set-faces + '(org-code ((t (:inherit (font-lock-function-name-face fixed-pitch))))) + '(org-block ((t (:inherit fixed-pitch)))) + '(org-meta-line ((t (:inherit fixed-pitch)))) + '(org-indent ((t (:inherit (org-hide fixed-pitch))))) + '(org-ellipsis ((t (:underline nil :foreground "#454d4f")))) + '(org-checkbox ((t (:inherit fixed-pitch)))) + '(org-table ((t (:inherit fixed-pitch))))) + + (keymap-modify org-mode-map + "C-c b" 'org-switchb + "C-'" nil) + + (define-advice org-get-category (:around (oldf &optional pos _) use-parent) + (or + (save-excursion + (when (org-up-heading-safe) + (org-no-properties + (org-sort-remove-invisible + (org-get-heading t t t t))))) + (funcall oldf pos _))) + + (defun revert-org-buffers () + (interactive) + (save-some-buffers nil (lambda () (eq major-mode 'org-mode))) + (revert-all-buffers "\\.org$"))) + +(use-package org-superstar + :if (group-enabled-p 'org) + :ensure t + :init + (add-hook 'org-mode-hook 'org-superstar-mode) + :config + (setq + org-superstar-special-todo-items t + + org-superstar-todo-bullet-alist + '(("TODO" . (?☐ ?*)) + ("PROG" . (?☒ ?*)) + ("DONE" . (?☑ ?*)) + ("PROJ" . (?☐ ?*)) + ("WAIT" . (?⌚ ?*))) + + org-superstar-headline-bullets-list + '((?◉ ?*) (?○ ?*) (?● ?*) (?◈ ?*) (?◇ ?*)) + + org-superstar-item-bullet-alist + '((?* . ?⦿) (?+ . ?•) (?- . ?⁃)))) + +(use-package calfw + :ensure t) + +(use-package calfw-org + :ensure t + :commands cfw:open-org-calendar) + +(use-package org-capture + :if (group-enabled-p 'org) + :config + (defun my/org-agenda-capture-day () + (with-current-buffer org-agenda-buffer + (format-time-string + "<%Y-%m-%d %a>" + (org-time-from-absolute (org-get-at-bol 'day))))) + + (defun my/org-capture-date-tag () + (format-time-string "date%%%Y_%m_%d")) + + (setq + org-capture-templates + (cl-flet + ((tmpl (pre &optional post) + (format "* %s\n%s" + pre + (if post post ""))) + (loc (loc) + (cdr + (assoc + loc + '((calendar . (file+olp "_.org" "Calendar")) + (todos . (file+olp "_.org" "TODOs")))))) + (linked ( + unkey undesc + ankey andesc + type loc + tmpl &optional antmpl) + (list + (list unkey undesc type loc + tmpl) + (list ankey andesc type loc + (or antmpl + (concat tmpl "\n%a")))))) + `(,@(linked + "a" "Add appointment" + "A" "Add linked appointment" + 'entry + (loc 'calendar) + (tmpl "%^{Name}" "%^{at}t")) + ("c" "Add appointment for this day (calfw)" + entry + ,(loc 'calendar) + ,(tmpl "%^{Name}" "%(cfw:org-capture-day)")) + ("p" "Add appointment for this day (agenda)" + entry + ,(loc 'calendar) + ,(tmpl "%^{Name}" "%(my/org-agenda-capture-day)")) + ,@(linked + "t" "Add TODO" + "T" "Add linked TODO" + 'entry + (loc 'todos) + (tmpl "TODO %^{Name} :@review:")))) + org-capture-templates-contexts + '(("p" ((in-mode . "org-agenda-mode"))) + ("c" ((in-mode . "cfw:calendar-mode"))) + ("p" "c" ((in-mode . "cfw:calendar-mode")))))) + +(use-package org-urgency + :if (group-enabled-p 'org) + :ensure t + :vc (:url "https://ba.ln.ea.cx/src/marsironpi/emacs/org-urgency") + :config + + (setq + org-urgency-functions + (org-urgency-list + '((tag? "@review" 1000) + (state? "PROG" 2) + (state? "WAIT" -10) + (priority 5) + (near-deadline 4) + (timestamped-today? 110) + (random 2))))) + +(use-package org-agenda + :if (group-enabled-p 'org) + :config + (defvar my/org-today nil) + + (define-advice org-today (:filter-return (val) my/org-today) + (if my/org-today + my/org-today + val)) + + (defun my/org-visit-day (&optional day) + (interactive + (list (time-to-days + (encode-time + (org-parse-time-string + (org-read-date)))))) + (let ((today + (let ((my/org-today nil)) + (org-today)))) + (setq my/org-today + (unless (equal day today) + day)))) + + (defun my/org-agenda-visit-day (&optional arg) + (interactive "P" org-agenda-mode) + (call-interactively #'my/org-visit-day) + (org-agenda-redo-all arg)) + + (defun my/org-agenda-include-tag () + (interactive nil org-agenda-mode) + (org-agenda-filter-by-tag '(16))) + + (defun my/org-agenda-skip-if-sub-todos () + (let* ((end (save-excursion + (org-end-of-subtree t) + )) + (end (max end (org-entry-end-position)))) + (save-match-data + (when (save-excursion + (goto-char (1- (org-entry-end-position))) + (re-search-forward + (rx-to-string `(and "* " (or ,@org-not-done-keywords))) + end 'noerror)) + (org-entry-end-position))))) + + (defun my/org-agenda-skip-if-only-timestamped () + (when (and (org-entry-is-todo-p) + (not (or (org-get-scheduled-time (point)) + (org-get-deadline-time (point))))) + (org-entry-end-position))) + + (setq + org-agenda-files + (list + (file-name-concat org-directory "_.org")) + org-agenda-include-diary t + org-agenda-time-grid nil + org-agenda-persistent-marks t + org-agenda-window-setup 'current-window + + org-agenda-prefix-format + '((agenda . " %-50:c%?-12t% s") + (todo . " %-50:c") + (tags . " %-50:c") + (search . " %-50:c")) + + org-agenda-span 31 + org-agenda-start-on-weekday nil + + org-agenda-skip-deadline-if-done t + org-agenda-skip-scheduled-if-done t + org-agenda-skip-timestamp-if-done t + + org-agenda-cmp-user-defined #'org-urgency-compare + org-agenda-sorting-strategy + '((agenda . (user-defined-down)) + (todo . (user-defined-down)) + (search . (category-keep))) + + org-agenda-custom-commands + '(("n" "Agenda and TODO list" + ((alltodo "") + (agenda "" + ((org-agenda-skip-function + #'my/org-agenda-skip-if-only-timestamped) + (org-deadline-warning-days 0)))) + ((org-agenda-skip-function #'my/org-agenda-skip-if-sub-todos) + (org-agenda-max-entries 7) + (org-agenda-span 15))) + ("L" "Shortened TODO list" + ((alltodo "")) + ((org-agenda-skip-function #'my/org-agenda-skip-if-sub-todos) + (org-agenda-max-entries 7))) + ("l" "TODO list" + ((alltodo "")) + ((org-agenda-skip-function #'my/org-agenda-skip-if-sub-todos)))) + + org-agenda-exporter-settings + '((htmlize-hyperlink-style + (format " +body { + background-image: url(\"img\"); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 100vh; +} +pre { + background-color: %scc; + padding: 1em; + padding-bottom: 5em; + margin: 5em; + margin-top: 20vh; + overflow: hidden; + border-radius: 0.7em; +} +span { background-color: initial !important } +" (face-background 'default) (face-background 'default))) + (org-agenda-tags-column -100))) + + (add-hook + 'org-agenda-mode-hook + (lambda () + (when (not text-scale-mode) + (text-scale-set 1)))) + + (keymap-modify org-agenda-mode-map + "M-u" 'rename-uniquely + "\\" 'my/org-agenda-include-tag + "`" 'my/org-agenda-visit-day) + + :config/el-patch + (defun org-agenda-filter-make-matcher (filter type &optional expand) + "Create the form that tests a line for agenda filter. +Optional argument EXPAND can be used for the TYPE tag and will +expand the tags in the FILTER if any of the tags in FILTER are +grouptags." + (let ((multi-pos-cats + (and (eq type 'category) + (string-match-p "\\+.*\\+" + (mapconcat (lambda (cat) (substring cat 0 1)) + filter "")))) + f f1) + (cond + ;; Tag filter + ((eq type 'tag) + (setq filter + (delete-dups + (append (assoc-default 'tag org-agenda-filters-preset) + filter))) + (dolist (x filter) + (let ((op (string-to-char x))) + (if expand (setq x (org-agenda-filter-expand-tags (list x) t)) + (setq x (list x))) + (setq f1 (org-agenda-filter-make-matcher-tag-exp x op)) + (push f1 f)))) + ;; Category filter + ((eq type 'category) + (setq filter + (delete-dups + (append (assoc-default 'category org-agenda-filters-preset) + filter))) + (dolist (x filter) + (if (equal "-" (substring x 0 1)) + (setq f1 (list 'not (list 'equal (substring x 1) 'cat))) + (setq f1 (list 'equal (substring x 1) 'cat))) + (push f1 f))) + ;; Regexp filter + ((eq type 'regexp) + (setq filter + (delete-dups + (append (assoc-default 'regexp org-agenda-filters-preset) + filter))) + (dolist (x filter) + (if (equal "-" (substring x 0 1)) + (setq f1 (list 'not (list 'string-match (substring x 1) 'txt))) + (setq f1 (list 'string-match (substring x 1) 'txt))) + (push f1 f))) + ;; Effort filter + ((eq type 'effort) + (setq filter + (delete-dups + (append (assoc-default 'effort org-agenda-filters-preset) + filter))) + (dolist (x filter) + (push (org-agenda-filter-effort-form x) f)))) + (cons (if (el-patch-swap multi-pos-cats + (or multi-pos-cats + (eq type 'tag))) + 'or 'and) + (nreverse f))))) + +(use-package org-clock + :config + (define-advice org-clock-select-task (:around (oldf &rest args) use-consult) + (require 'consult) + (if consult-mode + (save-window-excursion + (save-excursion + (my/consult-org-heading))) + (apply oldf args)))) + +(use-package org-refile + :config + (define-advice org-refile-get-location (:around (oldf &rest args) use-consult) + (require 'consult) + (if consult-mode + (org-with-point-at (my/consult-org-heading) + (list + (or (elt (org-heading-components) 4) "") + buffer-file-name + nil + (save-restriction + (widen) + (org-narrow-to-subtree) + (point-max) + (point)))) + (apply oldf args)))) + +(use-package holidays + :config + (setq + calendar-christian-all-holidays-flag t + calendar-holidays + (append holiday-general-holidays + holiday-local-holidays + holiday-other-holidays + holiday-christian-holidays + holiday-solar-holidays))) + +(use-package org-habit + :config + (setq org-habit-graph-column 70) + (custom-set-faces + '(org-habit-clear-face ((t (:background "blue")))) + '(org-habit-clear-future-face ((t (:background "midnightblue")))) + '(org-habit-ready-face ((t (:background "forestgreen")))) + '(org-habit-ready-future-face ((t (:background "darkgreen")))) + '(org-habit-alert-face ((t (:background "gold")))) + '(org-habit-alert-future-face ((t (:background "darkgoldenrod")))) + '(org-habit-overdue-face ((t (:background "firebrick")))) + '(org-habit-overdue-future-face ((t (:background "darkred")))))) + +(use-package org-num + :if (group-enabled-p 'org) + :config + (defun my/org-num-format (nums) + (concat (number-to-string (car (last nums))) " ")) + (setq + org-num-skip-unnumbered t + org-num-format-function #'my/org-num-format)) + +(use-package ol + :if (group-enabled-p 'org) + :init + (keymap-modify org-prefix + "H-o" 'org-open-at-point-global + "H-s" 'org-store-link + "H-l" 'org-insert-link-global)) + +(use-package org-ctags + :if (group-enabled-p 'org) + :init + (setq + org-ctags-open-link-functions nil)) + +(use-package citeproc + :if (group-enabled-p 'org) + :ensure t) + +(use-package oc + :if (group-enabled-p 'org) + :config + (mapc #'require + '(oc-csl + oc-natbib))) + +(use-package ob + :if (group-enabled-p '(programming org)) + :config + (mapc + #'require + '(ob-ruby + ob-js + ob-C + ob-shell + ob-lilypond + ob-lisp + ob-haskell + ob-plantuml + ob-lisp + ob-scheme)) + (setq + org-plantuml-exec-mode 'plantuml + org-babel-lisp-eval-fn #'sly-eval) + + :config/el-patch + (defun org-babel-confirm-evaluate (info) + "Confirm evaluation of the code block INFO. + +This query can also be suppressed by setting the value of +`org-confirm-babel-evaluate' to nil, in which case all future +interactive code block evaluations will proceed without any +confirmation from the user. + +Note disabling confirmation may result in accidental evaluation +of potentially harmful code. + +The variable `org-babel-confirm-evaluate-answer-no' is used by +the async export process, which requires a non-interactive +environment, to override this check." + (let* ((evalp (org-babel-check-confirm-evaluate info)) + (lang (nth 0 info)) + (name (nth 4 info)) + (name-string (if name (format " (%s) " name) " "))) + (pcase evalp + (`nil nil) + (`t t) + (`query (or + (and (not (bound-and-true-p + org-babel-confirm-evaluate-answer-no)) + ((el-patch-swap yes-or-no-p y-or-n-p) + (format "Evaluate this %s code block%son your system? " + lang name-string))) + (progn + (message "Evaluation of this %s code block%sis aborted." + lang name-string) + nil))) + (x (error "Unexpected value `%s' from `org-babel-check-confirm-evaluate'" x)))))) + +(use-package ox + :if (group-enabled-p 'org) + :config + (require 'ox-html) + (org-export-define-derived-backend 'html-simple 'html + :translate-alist + ;; markup + '((bold . org-html-simple-bold) + (code . org-html-simple-code) + (italic . org-html-simple-italic) + (subscript . org-html-simple-subscript) + (superscript . org-html-simple-superscript) + (strike-through . org-html-simple-strike-through) + (underline . org-html-simple-underline) + (verbatim . org-html-simple-verbatim) + + ;; misc + (horizontal-rule . org-html-simple-horizontal-rule) + (line-break . org-html-simple-line-break) + (timestamp . org-html-simple-timestamp) + + ;; blocks + (example-block . org-html-simple-example-block) + (item . org-html-simple-item) + (paragraph . org-html-simple-paragraph) + (plain-list . org-html-simple-plain-list) + (quote-block . org-html-simple-quote-block) + (special-block . org-html-simple-special-block) + (src-block . org-html-simple-src-block) + (verse-block . org-html-simple-verse-block) + + ;; table + (table . org-html-simple-table) + (table-row . org-html-simple-table-row) + (cell . org-html-simple-table-cell) + + ;; structural + (headline . org-html-simple-headline) + (inner-template . (lambda (a &rest _) a)) + (plain-text . org-html-simple-plain-text) + (section . org-html-simple-section) + (template . org-html-simple-template)) + + :options-alist + '((:html-simple-title-suffix "HTML_TITLE_SUFFIX" nil nil) + (:html-simple-preamble "HTML_SIMPLE_PREAMBLE" nil nil) + (:html-simple-postamble "HTML_SIMPLE_POSTAMBLE" nil nil)) + + :menu-entry + '(?H "Export to simple HTML" + ((?H "As HTML buffer" org-html-simple-export-as-html) + (?h "As HTML file" org-html-simple-export-to-html) + (?o "As HTML file and open" + (lambda (a s v b) + (if a (org-html-simple-export-to-html t s v b) + (org-open-file (org-html-simple-export-to-html nil s v b)))))))) + + (cl-macrolet + ((defsimple (name &rest body) + `(defun ,(intern (format "org-html-simple-%s" name)) (el contents info) + ,@body)) + (deftag (name tag form &key nl) + (let ((nl (if nl "\n" ""))) + `(defsimple ,name + (let ((val (org-html-encode-plain-text + (or (org-element-property :value el) ""))) + (cnt contents)) + (format ,(format "<%s>%s%%s" tag nl tag) ,form)))))) + + ;; markup + (deftag bold "strong" cnt) + (deftag code "code" val) + (deftag italic "em" cnt) + (deftag subscript "sub" cnt) + (deftag superscript "sup" cnt) + (deftag strike-through "s" cnt) + (deftag underline "u" cnt) + (deftag verbatim "var" val) + + ;; misc + (defsimple line-break "
\n") + + (defsimple horizontal-rule "
\n") + + (defun org-html-simple--format-timestamp (el) + (cl-flet ((p (prop) + (org-element-property prop el))) + (format + "%04d-%02d-%02d%s" + (p :year-start) + (p :month-start) + (p :day-start) + (if (p :hour-start) + (format + "T%02d:%02d" + (p :hour-start) + (p :minute-start)) + "")))) + (defsimple timestamp + (let* ((org-display-custom-times t) + (value (org-html-simple--format-timestamp el)) + (text (replace-regexp-in-string + (rx (or "<" ">" "[" "]")) + "" + (org-timestamp-translate el)))) + (format "" + value text))) + + ;; blocks + (deftag example "samp" + (thread-last cnt + (replace-regexp-in-string "\n" "
\n") + (replace-regexp-in-string "
\n\\'" "")) + :nl t) + + (defsimple item + (let* ((list (org-export-get-parent el)) + (type (cl-case (org-element-property :type list) + (descriptive "dt") + (otherwise "li"))) + (checkbox (if (org-element-property :checkbox el) + (format " " + (if (eq (org-element-property :checkbox el) 'on) + " checked" "")) + "")) + (text (if (string= type "dt") + (concat (org-export-data (org-element-property :tag el) info) "\n
" contents) + contents))) + (format "<%s>%s%s" type checkbox (or text "")))) + + (defsimple paragraph + (cond + ((eq (org-element-type (org-export-get-parent el)) 'item) + contents) + ((org-html-standalone-image-p el info) + (format "
\n%s
\n%s\n
\n
\n" + contents + (org-export-data (org-export-get-caption el) info))) + (t (format "

\n%s" contents)))) + + (defsimple plain-list + (let ((type (cl-case (org-element-property :type el) + (descriptive "dl") + (ordered "ol") + (unordered "ul") + (otherwise "ul")))) + (format "<%s>\n%s" type contents type))) + + (deftag quote-block "blockquote" cnt :nl t) + + (defsimple special-block + (let ((tag (org-element-property :type el))) + (format "<%s>\n%s" tag (or contents "") tag))) + + (deftag src-block "pre" val :nl t) + + (deftag verse-block "blockquote" + (thread-last cnt + (replace-regexp-in-string "\n" "
\n") + (replace-regexp-in-string "
\n\\'" "\n")) + :nl t) + + ;; table + (defsimple cell + (let ((row (org-export-get-parent el)) + (table (org-export-get-parent-table el))) + (cond + ((and (org-export-table-has-header-p el info) + (= 1 (org-export-table-row-group row info))) + (concat "" contents)) + (t (concat "" contents))))) + + (defsimple table-row + (when (eq (org-element-property :type el) 'standard) + (let ((starts-group (org-export-table-row-starts-rowgroup-p el info)) + (group (org-export-table-row-group el info))) + (concat + (when starts-group + (if (= group 1) + "\n\n" + "\n")) + "" contents "\n")))) + + (defsimple table + (let ((caption + (when (org-export-get-caption el) + (org-export-data (org-export-get-caption el) info))) + (colgroups + (mapconcat + (lambda (cell) + (let ((alignment (org-export-table-cell-alignment + cell info))) + (concat + ;; Begin a colgroup? + (when (org-export-table-cell-starts-colgroup-p + cell info) + "\n\n") + ;; Add a column. Also specify its alignment. + (format "" alignment) + ;; End a colgroup? + (when (org-export-table-cell-ends-colgroup-p + cell info) + "\n")))) + (org-html-table-first-row-data-cells el info) "\n"))) + (concat + "" + (when (and + caption + (not (string-empty-p (org-trim caption)))) + (format "\n\n" caption)) + colgroups + "\n" + contents + "
%s
"))) + + ;; structural + (defsimple headline + (let* ((level + (org-export-get-relative-level el info)) + (pre-newline + (not + (and (= level 1) + (org-export-first-sibling-p el info)))) + (type + (number-to-string (min 6 level))) + (todo-keyword + (org-element-property :todo-keyword el)) + (todo + (and todo-keyword + (concat "" + todo-keyword " "))) + (priority-level + (org-element-property :priority el)) + (priority + (and priority-level (concat "" priority-level " "))) + (title + (org-export-data (org-element-property :title el) info))) + (format "%s%s%s%s\n%s" + (if pre-newline "\n" "") + type + (or todo "") + (or priority "") + (or title "") + type + (or contents "")))) + + (defsimple section (or contents "")) + + (defun org-html-simple-plain-text (contents info) + (org-html-encode-plain-text contents)) + + (defun org-html-simple-template (contents info) + (concat "\n" + "" + (org-export-data (plist-get info :title) info) + (plist-get info :html-simple-title-suffix) + "\n\n" + (let ((h (plist-get info :html-simple-preamble))) + (if (functionp h) + (funcall h contents info) + h)) + contents + (let ((h (plist-get info :html-simple-postamble))) + (if (functionp h) + (funcall h contents info) + h))))) + + (defun org-html-simple-export-as-html (&optional async subtreep visible-only body-only ext-plist) + (interactive) + (org-export-to-buffer 'html-simple "*Org HTML-Simple Export*" + async subtreep visible-only body-only ext-plist + ;; FIXME: Find out why `set-auto-mode' doesn't work + (lambda () (mhtml-mode)))) + + (defun org-html-simple-export-to-html (&optional async subtreep visible-only body-only ext-plist) + (interactive) + (let* ((extension (concat + (when (> (length org-html-extension) 0) ".") + (or (plist-get ext-plist :html-extension) + org-html-extension + "html"))) + (file (org-export-output-file-name extension subtreep)) + (org-export-coding-system org-html-coding-system)) + (org-export-to-file 'html-simple file + async subtreep visible-only body-only ext-plist))) + + (defun org-html-simple-publish-to-html (plist filename pub-dir) + (require 'ox-publish) + (org-publish-org-to 'html-simple filename + (concat (when (> (length org-html-extension) 0) ".") + (or (plist-get plist :html-extension) + org-html-extension + "html")) + plist pub-dir))) + +(use-package ox-publish + :if (group-enabled-p 'org) + :config + (defun my/org-html-site-preamble (c info) + (format + " + + +

+

%s

%s +
+" + (org-export-data (plist-get info :title) info) + (if-let ((title (plist-get info :subtitle))) + (format "\n

%s

\n" title) + ""))) + + (defun my/org-html-site-postamble (c info) + (let* ((file (plist-get info :input-file)) + (date (org-timestamp-from-time + (org-publish-find-date file info)))) + (if (equal + (file-name-nondirectory file) + (plist-get info :sitemap-filename)) + "
\n
\n" + (format + " + + + +" + (plist-get info :postamble-time-prefix) + (org-html-simple-timestamp date nil nil))))) + + (defun my/org-publish-sitemap-entry (entry _style project) + (format "[[file:%s][%s]]" + (file-name-sans-extension entry) + (org-publish-find-title entry project))) + + (defun my/org-publish-blog-post-entry (entry _style project) + (format "[[file:%s][%s - %s]]" + (file-name-sans-extension entry) + (replace-regexp-in-string + "[a-z]+\\'" "" + (file-name-base entry)) + (org-publish-find-title entry project))) + + (defun my/org-publish-org-project (name &rest opts) + (cons + name + (org-combine-plists + '( + :recursive t + :publishing-function org-html-simple-publish-to-html + :html-simple-preamble my/org-html-site-preamble + :html-simple-postamble my/org-html-site-postamble + :html-simple-title-suffix " - Home on the Web" + :auto-sitemap t + :sitemap-filename "_.org" + :sitemap-style list + :sitemap-sort-files chronologically + :sitemap-format-entry my/org-publish-sitemap-entry) + opts))) + + (setq + org-publish-project-alist + `(,(my/org-publish-org-project + "www/log" + :base-directory "~/www/simon/src/log" + :publishing-directory "~/www/simon/www/log" + :sitemap-title "Blog" + :sitemap-format-entry #'my/org-publish-blog-post-entry + :postamble-time-prefix "Published on") + ,(my/org-publish-org-project + "www/doc" + :base-directory "~/www/simon/src/doc" + :publishing-directory "~/www/simon/www/doc" + :sitemap-title "Articles" + :postamble-time-prefix "Last updated on") + ,(my/org-publish-org-project + "k12/11/wri/a" + :base-directory "~/k12/11/wri/a" + :publishing-directory "~/www/simon/www/k12/11/wri/a" + :sitemap-title "Writings" + :html-simple-title-suffix " - Simon's K12" + :postamble-time-prefix "Last updated on") + ("k12/css" + :base-directory "~/k12" + :publishing-directory "~/www/simon/www/k12" + :base-extension "css" + :recursive t + :publishing-function org-publish-attachment) + ("k12" + :components ("k12/11/wri/a" "k12/css")) + ,(my/org-publish-org-project + "www/misc" + :base-directory "~/www/simon/src" + :publishing-directory "~/www/simon/www" + :html-simple-postamble "\n" + :auto-sitemap nil) + ("www/rest" + :base-directory "~/www/simon/src" + :publishing-directory "~/www/simon/www" + :recursive t + :publishing-function org-publish-attachment + :base-extension any + :exclude ,(rx (or ".org" "~") string-end)) + ("www" + :components ("www/rest" "www/misc" "www/log" "www/doc"))) + org-publish-use-timestamps-flag nil)) + +(use-package ox-latex + :if (group-enabled-p 'org) + :config + (setf + (alist-get "leaflet" org-latex-classes nil nil #'equal) + '("\\documentclass[11pt,notumble]{leaflet}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + + (alist-get "letter" org-latex-classes nil nil #'equal) + '("\\documentclass[11pt]{letter}" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) + +(use-package gnuplot + :ensure t + :if (group-enabled-p 'org)) + +(use-package outline + :init + (add-to-list 'desktop-locals-to-save 'outline-regexp) + :config + (setq outline-minor-mode-cycle t) + + (defun outline-guess-regexp () + (interactive) + (setq-local outline-regexp + (concat "[ \t]*\\(" + (regexp-quote comment-start) + "\\)+ *[*]+"))) + + (defun my/outline-minor-mode-hook () + (when (derived-mode-p 'prog-mode) + (outline-guess-regexp))) + + (add-hook 'outline-minor-mode-hook 'my/outline-minor-mode-hook)) + +(use-package tex-mode + :config + (setq + tex-indent-basic 0 + LaTeX-indent-level 0)) + +(when-group tex + (use-package auctex + :ensure t) + (use-package cdlatex + :ensure t + :config + (setq cdlatex-takeover-subsuperscript nil)) + + (with-eval-after-load 'org + (keymap-set org-mode-map "C-c d" 'org-cdlatex-mode) + (keymap-modify org-cdlatex-mode-map + "_" nil + "^" nil)) + + ;; from https://karthinks.com/software/scaling-latex-previews-in-emacs + (defun my/text-scale-adjust-latex-previews () + "Adjust the size of latex preview fragments when changing the +buffer's text scale." + (pcase major-mode + ('latex-mode + (dolist (ov (overlays-in (point-min) (point-max))) + (if (eq (overlay-get ov 'category) + 'preview-overlay) + (my/text-scale--resize-fragment ov)))) + ('org-mode + (dolist (ov (overlays-in (point-min) (point-max))) + (if (eq (overlay-get ov 'org-overlay-type) + 'org-latex-overlay) + (my/text-scale--resize-fragment ov)))))) + + (defun my/text-scale--resize-fragment (ov) + (overlay-put + ov 'display + (cons 'image + (plist-put + (cdr (overlay-get ov 'display)) + :scale (+ 1.0 (* 0.25 text-scale-mode-amount)))))) + + (add-hook 'text-scale-mode-hook + 'my/text-scale-adjust-latex-previews)) + +(use-package auth-source-pass + :init + (auth-source-pass-enable)) + +(use-package pinentry + :init + (when (fboundp 'pinentry-start) + (pinentry-start t))) + +(use-package mm-decode + :if (executable-find "w3m") + :config + (setq mm-text-html-renderer 'gnus-w3m)) + +(use-package sendmail + :if (group-enabled-p 'mail) + :init + (setq + mail-default-directory "~/mail" + send-mail-function 'sendmail-send-it + sendmail-program (executable-find "msmtp") + mail-specify-envelope-from t + mail-envelope-from 'header)) + +(use-package message + :if (group-enabled-p 'mail) + :init + (setq + message-directory mail-default-directory + message-alternative-emails + (rx (or "simonparri@ganzeria.com" + "simon@zoar.cx" + "marsironpi@ba.ln.ea.cx" + "2025sparri@sullivan.k12.il.us"))) + :config + (add-hooks 'message-mode-hook + 'electric-indent-mode)) + +(use-package gnus + :if (group-enabled-p 'mail) + :init + (setq + gnus-directory "~/.news/") + :config + (setq + gnus-select-method '(nnnil "") + gnus-secondary-select-methods + (cl-flet ((maildir (name) + `(nnmaildir + ,(format "%s" name) + (directory ,(format "~/mail/%s" name)) + (gnus-search-engine gnus-search-mu)))) + `(,@(mapcar #'maildir + '(ganzeria + ba.ln.ea.cx + sullivan-schools)) + (nntp "news.gwene.org") + (nntp "news.eternal-september.org" + (nntp-authinfo-user "MarsIronPI") + (nntp-authinfo-force t)))) + + gnus-search-mu-remove-prefix (expand-file-name "~/mail") + + gnus-plugged nil + gnus-message-archive-method nil + gnus-activate-level 3 + + gnus-summary-line-format "%U%O %6i %4t %(%16&user-date; %-30,30f %B%S%)\n" + gnus-summary-dummy-line-format gnus-summary-line-format + gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M")) + gnus-sum-thread-tree-false-root "" + gnus-sum-thread-tree-indent " " + gnus-sum-thread-tree-leaf-with-other "├► " + gnus-sum-thread-tree-root "" + gnus-sum-thread-tree-single-leaf "╰► " + gnus-sum-thread-tree-vertical "│" + + gnus-summary-thread-gathering-function + 'gnus-gather-threads-by-references + gnus-summary-make-false-root 'dummy + gnus-thread-sort-functions '(gnus-thread-sort-by-date + gnus-thread-sort-by-score) + gnus-refer-thread-use-search t + gnus-simplify-subject-functions + '(gnus-simplify-subject-re gnus-simplify-whitespace) + + nntp-connection-timeout 10 + gnus-agent-auto-agentize-methods '(nntp) + gnus-agent-queue-mail nil + + gnus-score-thread-simplify t + gnus-use-adaptive-scoring t + gnus-decay-scores "\\.ADAPT\\'" + gnus-score-decay-constant 1 + gnus-default-adaptive-score-alist + '((gnus-killed-mark (subject -10)) + (gnus-catchup-mark (subject -2)))) + + (add-hooks 'gnus-group-mode-hook + 'gnus-topic-mode) + + (add-hooks 'gnus-article-mode-hook + 'variable-pitch-mode)) + +(use-package message + :if (executable-find "mu") + :if (group-enabled-p 'mail) + :config + ;; based on `org-contacts-message-complete-function' + (defun mu-cfind-completion-function () + (when (mail-abbrev-in-expansion-header-p) + (let ((beg + (save-match-data + (save-excursion + (re-search-backward "[\n:,][ \t]*") + (goto-char (match-end 0)) + (point)))) + (end (point))) + (list beg + end + (completion-table-dynamic + (lambda (string) + (thread-last + (shell-quote-argument string) + (format "mu cfind --format=json %s") + shell-command-to-string + json-parse-string + (mapcar (lambda (h) (gethash "display" h)))))) + :exclusive 'no)))) + (add-hook + 'message-mode-hook + (lambda () + (add-hook 'completion-at-point-functions + 'mu-cfind-completion-function + nil t)))) + +(use-package jabber + :ensure t + :init + (keymap-set ctl-x-map "C-j" #'dired-jump) + (keymap-global-set "H-c" jabber-global-keymap) + :config + (defun my/jabber-jabber-activity-show-p (jid) + (and (jabber-activity-show-p-default jid) + (not (member jid (mapcar #'car *jabber-active-groupchats*))))) + + (setq jabber-activity-show-p #'my/jabber-jabber-activity-show-p + jabber-alert-muc-hooks '(jabber-muc-scroll) + jabber-muc-decorate-presence-patterns + '(("^.+ has left the chatroom$" . nil) + ("^.+ enters the room (.+)$" . nil) + ("." . jabber-muc-presence-dim)) + + jabber-account-list '(("marsironpi@ba.ln.ea.cx")))) + +(use-package proced + :config + (setq-default proced-auto-update-flag t)) + +(use-package piper + :vc (:url "https://gitlab.com/howardabrams/emacs-piper")) + +(use-package dired-subtree + :ensure t) +(use-package dired + :config + (require 'em-ls) + (eshell-ls-enable-in-dired) + + (setq + eshell-ls-use-in-dired t + dired-dwim-target t + dired-mark-region t) + + (defun dired-do-async-command-silent (command) + "Run a shell command COMMAND like dired-do-async-shell-command, but without an output buffer. +Only works on a single file." + (interactive `(,(read-shell-command (format "& on %s: " (car (dired-get-marked-files t)))))) + (let ((cmd (concat command " \"" (car (dired-get-marked-files)) "\""))) + (spawn-shell-cmd cmd nil cmd))) + + (keymap-modify dired-mode-map + "C-c &" 'dired-do-async-command-silent + "C-c l" 'bongo-dired-library-mode + "C-c m" 'bongo-dired-play-line + "TAB" 'dired-subtree-cycle) + + (defvar dired-id3--hist () + "History for dired-id3") + (defun dired-id3 (file) + (interactive + (list (or (car (dired-get-marked-files t)) + (expand-file-name (read-file-name "MP3 File: "))))) + (if (executable-find "mid3v2") + (let ((command "mid3v2")) + (mapc (lambda (lst) + (let* ((name (car lst)) + (option (cadr lst)) + (value (read-string (concat name ": ") nil dired-id3--hist))) + (if (not (string= value "")) + (setq command (concat command " " option " " (shell-quote-argument value)))))) + '(("Title" "-t") + ("Artist" "-a") + ("Album" "-A") + ("Comment" "-c") + ("Genre" "-g") + ("Year" "-y") + ("Track" "-T"))) + (shell-command (concat command " " file))) + (message "Unable to run. Install mid3v2 and try again.")))) + +(progn ;; dired-sidebar + (defvar dired-sidebar-name "*Dired-sidebar*") + + (defun dired-sidebar (&optional dir) + (interactive + (list (when current-prefix-arg + (dired-read-dir-and-switches "")))) + (aif (get-buffer-window dired-sidebar-name) + (quit-window nil it) + (awhen (get-buffer dired-sidebar-name) + (kill-buffer it)) + (let ((buf (dired-noselect (or dir default-directory)))) + (with-current-buffer buf + (rename-buffer dired-sidebar-name) + (dired-hide-details-mode) + (display-buffer buf))))) + + (keymap-global-set "C-x M-d" 'dired-sidebar)) + +(use-package image + :config + (setq image-transform-smoothing t)) + +(use-package image-dired + :init + (defvar dired-wallpapers-directory + "~/img/wallpapers/") + (defun dired-wallpapers () + (interactive) + (require 'image-dired) + (awhen (get-buffer "*wallpapers*") (kill-buffer it)) + (awhen (get-file-buffer dired-wallpapers-directory) + (with-current-buffer it + (revert-buffer nil t))) + (let ((image-dired-show-all-from-dir-max-files + most-positive-fixnum) + (display-buffer-overriding-action + '(display-buffer-no-window + (allow-no-window . t))) + (image-dired-thumbnail-buffer "*wallpapers*")) + (with-current-buffer (image-dired dired-wallpapers-directory) + (let ((display-buffer-overriding-action '(nil))) + (display-buffer (current-buffer)))))) + + :config + (awhen (executable-find "xdg-open") + (setq image-dired-external-viewer it)) + + (defun my/image-dired-display-thumbnail-original-image (&optional arg) + (interactive "P") + (if-let ((file (image-dired-file-name-at-point))) + (progn + (find-file file) + (if arg + (image-transform-original) + (image-transform-fit-both))) + (if (not (string-equal major-mode "image-dired-thumbnail-mode")) + (user-error "Not in image-dired-thumbnail-mode") + (when (not file) + (user-error "No original file name found"))))) + + (keymap-modify image-dired-thumbnail-mode-map + "n" 'image-dired-next-line + "p" 'image-dired-previous-line + "f" 'image-dired-forward-image + "b" 'image-dired-backward-image + " " + 'my/image-dired-display-thumbnail-original-image)) + +(use-package wallpaper + :config + (defvar my/wallpaper-light nil) + (defun my/set-wallpaper (file) + (call-process-shell-command + (concat "mywal -s " + (when my/wallpaper-light "-l ") + "-i " (expand-file-name file)))) + (setq wallpaper-set-function #'my/set-wallpaper) + (define-advice wallpaper-set (:around (oldf file) pass-prefix-arg) + (let ((my/wallpaper-light (equal current-prefix-arg '(4)))) + (funcall oldf file)))) + +(use-package wgrep + :ensure t + :config + (setq wgrep-auto-save-buffer t)) + +(use-package calendar + :config + (setq + calendar-latitude 39.598 + calendar-longitude -88.610 + calendar-location-name "Sullivan, IL") + (calendar-set-date-style 'iso)) + +(use-package calc + :config + (setq + calc-make-windows-dedicated t + calc-symbolic-mode t + calc-angle-mode 'rad + calc-language 'big + calc-prefer-frac t)) + +(use-package tab-bar + :config + (setq + tab-bar-tab-hints t + tab-bar-new-tab-to 'rightmost + tab-bar-auto-width-max nil + tab-bar-close-button-show nil + tab-bar-format '(tab-bar-format-tabs tab-bar-separator)) + (tab-bar-history-mode)) + +(use-package hide-mode-line + :ensure t) + +(use-package hippie-exp + :config + (setq + hippie-expand-try-functions-list + '(try-expand-dabbrev-visible + try-expand-dabbrev + try-expand-dabbrev-all-buffers + try-complete-file-name-partially + try-complete-file-name + try-expand-dabbrev-from-kill + try-expand-whole-kill + try-expand-line + try-expand-line-all-buffers + try-expand-all-abbrevs + try-complete-lisp-symbol-partially + try-complete-lisp-symbol)) + ;; (keymap-global-set " " hippie-expand) + ) + +(use-package special + :config + (keymap-modify special-mode-map + "o" 'other-window + "O" (lambda () (interactive) (other-window -1)) + "'" 'avy-goto-char)) + +(use-package conf-space + :mode "\\.htaccess\\'") + +(use-package visual-fill + :ensure t) + +(use-package visual-fill-column + :ensure t + :config + (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)) + +(use-package adaptive-wrap + :ensure t + :config + (define-advice adaptive-wrap-prefix-function (:after (beg end) org-indent) + (when org-indent-mode + (org-indent-refresh-maybe beg end t)))) + +(use-package text-mode + :config + (add-hooks 'text-mode-hook + 'visual-line-mode + 'visual-fill-column-mode + 'adaptive-wrap-prefix-mode + 'flyspell-mode + 'electric-quote-local-mode)) + +(use-package ispell + :init + (defun dict-lang-it () + "Change the current ispell dictionary to italiano." + (interactive) + (ispell-change-dictionary "italiano")) + + (defun dict-lang-enus () + "Change the ispell dictionary to en_us." + (interactive) + (ispell-change-dictionary "en_US"))) + +(use-package flyspell + :config + (setq flyspell-check-changes t)) + +(use-package vertico-posframe + :ensure t + :config + (keymap-unset vertico-multiform-map "M-p") + (keymap-set vertico-multiform-map "M-P" + #'vertico-multiform-posframe)) +(use-package vertico + :demand t + :ensure t + :config + (mapc + #'require + '(vertico-repeat + vertico-directory + vertico-multiform + vertico-posframe)) + (setq + vertico-count 5 + vertico-cycle t + vertico-posframe-poshandler + #'posframe-poshandler-frame-bottom-center + vertico-multiform-commands 'nil) + + (keymap-modify vertico-map + "RET" 'vertico-directory-enter + "DEL" 'vertico-directory-delete-char + "M-g" 'vertico-multiform-grid + "C-c b" 'embark-become + "H-b" 'embark-become) + + (keymap-global-set "H-r" 'vertico-repeat) + + (add-hook 'rfn-eshadow-update-overlay-hook 'vertico-directory-tidy) + (add-hook 'minibuffer-setup-hook 'vertico-repeat-save) + + (vertico-mode) + (vertico-multiform-mode) + (when (display-graphic-p) + (vertico-posframe-mode))) + +(use-package consult + :demand t + :ensure t + :config + (setq + consult-buffer-sources + (delq 'consult--source-bookmark consult-buffer-sources) + + consult-preview-excluded-buffers '(major-mode . exwm-mode) + + xref-show-xrefs-function 'consult-xref + xref-show-definitions-function 'consult-xref) + + (defvar-keymap consult-mode-map + " " 'consult-buffer + " " 'consult-buffer-other-window + " " 'consult-buffer-other-window + + " " 'consult-yank-pop + + " " 'consult-imenu + " " 'consult-locate + " " 'consult-find + + " " 'consult-keep-lines + + " " 'consult-goto-line + + " " 'consult-complex-command + + " " 'consult-history + " " 'consult-history + + "C-x r C-c" 'consult-register + "C-x r C-f" 'consult-register-load + "C-x r C-t" 'consult-register-store + + "C-x M-@" 'consult-global-mark + + "H-d c" 'consult-compile-error + "H-d f" 'consult-flymake) + + (if (executable-find "rg") + (keymap-set consult-mode-map " " 'consult-ripgrep) + (keymap-set consult-mode-map " " 'consult-grep)) + + (keymap-global-set "M-g M-i" 'consult-imenu-multi) + + (define-minor-mode consult-mode + "Enable consult keybindings." + :lighter "" + :keymap consult-mode-map + :interactive t + :global t) + + (consult-mode)) + + +(use-package consult-dir + :ensure t + :init + (keymap-global-set "H-j" 'consult-dir) + (keymap-global-set "H-J" 'consult-dir-jump-file)) +(use-package marginalia + :demand t + :ensure t + :config + (setq + marginalia-align 'right + marginalia-field-width 100) + (marginalia-mode)) + +(use-package embark + :demand t + :ensure t + :config + (setq + embark-prompter 'embark-keymap-prompter + embark-quit-after-action nil + embark-verbose-indicator-display-action + '(display-buffer-in-side-window + (side . bottom) (window-height . fit-window-to-buffer))) + + (defun my/embark-act-and-quit (&optional arg) + (interactive "P") + (let ((embark-quit-after-action t)) + (embark-act arg))) + (keymap-global-modify + "H-e" 'embark-act + "H-a" 'my/embark-act-and-quit + "H-t" 'embark-export)) + +(use-package embark-consult + :demand t + :ensure t + :config + (add-hook 'embark-after-export-hook 'consult-preview-at-point-mode)) + +(use-package company + :config + (define-advice company-mode (:around (&rest _) disable-company) + nil)) + +(use-package cape + :ensure t) +(use-package corfu + :ensure t + :demand t + :config + (defun corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + (corfu-mode))) + (add-hook 'minibuffer-setup-hook 'corfu-enable-in-minibuffer) + + (keymap-set corfu-map "M-'" 'corfu-quick-jump) + + (global-corfu-mode)) + +(use-package face-remap + :config + (diminish 'buffer-face-mode)) + +(use-package pcmpl-args + :ensure t) +(use-package eshell + :init + (defun eshell-at-home (&optional arg) + (interactive "P") + (let ((default-directory "~/")) + (eshell arg))) + + (setq + eshell-banner-message "" + eshell-show-lisp-completions t + eshell-hist-ignoredups t + eshell-status-in-mode-line t + eshell-default-target-is-dot t + eshell-visual-options nil + eshell-visual-subcommands nil + eshell-visual-commands nil + eshell-history-size 5000 + eshell-history-append t + eshell-modules-list + '( + eshell-alias eshell-banner eshell-basic + eshell-cmpl eshell-dirs eshell-elecslash + eshell-extpipe eshell-glob eshell-hist + eshell-ls eshell-pred eshell-prompt + eshell-script eshell-term eshell-unix)) + (setenv "PAGER" "cat") + (setenv "EDITOR" "emacsclient") + + :config + (defun eshell-get-last-output () + (buffer-substring + (eshell-beginning-of-output) + (eshell-end-of-output))) + + (defvar-local eshell-output-history []) + (defun eshell-save-output () + (setq eshell-output-history + (vconcat eshell-output-history + `[,(eshell-get-last-output)]))) + + (defun eshell-get-output-from-buffer (n &optional buffer) + (let ((buffer + (or (and buffer (get-buffer buffer)) + (get-buffer + (concat "*eshell*" + (if (equal buffer "0") "" + (format "<%s>" buffer)))) + (current-buffer)))) + (with-current-buffer buffer + (elt eshell-output-history n)))) + + (defun my/eshell-face (str) + (propertize + str + 'font-lock-face 'eshell-prompt)) + + (defun my/vc-dirty-p (&optional dir) + (let ((dir + (if (and + (not dir) + (project-current)) + (project-root (project-current)) + dir))) + (when dir + (thread-last + (directory-files dir) + (mapcar #'vc-state) + (seq-some + (lambda (x) + (not (member x '(nil up-to-date))))))))) + + (defun my/eshell-vcs-status (&optional dir) + (if-let* ((dir (or dir (eshell/pwd))) + (prj (project-current nil dir)) + (dir (project-root prj)) + (vc (vc-responsible-backend dir))) + (let* ((dirty + (if (my/vc-dirty-p dir) + "*" "")) + (vc-name (if (eq vc 'Git) + "" + (downcase (symbol-name vc)))) + (vc-branch (when (eq vc 'Git) + (let ((default-directory dir)) + (require 'magit) + (or (magit-get-current-tag) + (magit-get-current-branch))))) + (vc-branch (aif vc-branch + (concat + (propertize + "on " + 'font-lock-face 'shadow) + (my/eshell-face it)) + ""))) + (format "(%s%s%s)" + (my/eshell-face vc-name) + vc-branch + (my/eshell-face dirty))) + "")) + + (defvar-local eshell-prompt-number 0) + (defun my/eshell-prompt () + (prog1 + (concat + (propertize + (let ((vc (my/eshell-vcs-status))) + (format "%s %s %s%s%s" + (propertize + (format "%s" eshell-prompt-number) + 'font-lock-face 'shadow) + (my/eshell-face (abbreviate-file-name (eshell/pwd))) + vc (if (equal vc "") "" " ") + (my/eshell-face (if (= (user-uid) 0) "#" "$")))) + 'read-only t) + " ") + (cl-incf eshell-prompt-number))) + + (setq + eshell-prompt-function #'my/eshell-prompt + eshell-highlight-prompt nil) + + (define-advice eshell-next-prompt (:around (oldf &rest args) assume-highlighted) + (let ((eshell-highlight-prompt t)) + (apply oldf args))) + + (define-advice eshell-fix-bad-commands (:around (&rest ignore) disable) + nil) + + (defun eshell-read-aliases-list () + (setq eshell-command-aliases-list + '(("la" "ls -a $*") + ("ll" "ls -l $*") + ("lla" "ls -al $*") + ("l" "ls $*") + ("rtv" "rtv --enable-media $*") + ("dquilt" "quilt --quiltrc=~/.quiltrc-dpkg $*") + ("gaac" "git annex autocommit -a $*") + ("gaag" "git annex get --auto $*") + ("gasy" "git annex sync $*") + ("gaas" "git annex autosync $*") + ("gage" "git annex get $*") + ("ip-u" "ip-update basil") + + ("-" "cd -") + ("e" "find-file $1")))) + (eshell-read-aliases-list) + (defun eshell-write-aliases-list () + nil) + (defalias 'eshell/date nil) + + (define-advice eshell-ls-decorated-name (:filter-return (val) add-link) + (require 'tramp) + (if (eq insert-func #'eshell-buffered-print) + (let ((fname (tramp-handle-expand-file-name val))) + (propertize + val + 'button t + 'follow-link t + 'category t + 'keymap button-map + 'action (lambda (&rest _) + (find-file fname)))) + val)) + + (defun eshell/from (&rest args) + (eshell-eval-using-options + "from" args + `((?h "help" nil nil "output this help screen") + (?b "buffer" t buffer "use a different Eshell buffer") + :usage "[OPTIONS] N + +Output the command output from the Nth command from the desired +Eshell buffer.") + (cl-destructuring-bind (n) args + (setq n (string-to-number n)) + (cl-assert (numberp n) nil + "from: argument must be a number: %s" + (car args)) + (eshell-get-output-from-buffer n buffer)))) + (put 'eshell/from 'eshell-no-numeric-conversions t) + + (defun eshell/ssh (&rest args) + (throw + 'eshell-replace-command + (if (or eshell-in-pipeline-p + (not (= (length args) 1))) + (eshell-parse-command "*ssh" args) + (eshell-parse-command + "cd" (list (concat "/ssh:" (car args) ":~/")))))) + (put 'eshell/ssh 'eshell-no-numeric-conversions t) + + (defun eshell/mpc (&rest args) + (if args + (throw + 'eshell-replace-command + (eshell-parse-command "*mpc" args)) + (progn (mpc) nil))) + + (add-to-list 'eshell-complex-commands "ssh") + (add-to-list 'eshell-complex-commands "mpc") + + (defun my/eshell-remove-trailing-space (beg end) + (replace-regexp-in-region " +\\'" "" beg end)) + + (defun my/eshell-clear () + (interactive) + (let ((eshell-buffer-maximum-lines 0)) + (save-excursion + (eshell-truncate-buffer)))) + + (defun my/eshell-cd () + (interactive) + (eshell/cd (read-directory-name "Change directory: " nil nil t)) + (let (beg end) + (save-excursion + (eshell-bol) + (setq beg (point)) + (end-of-line) + (setq end (point))) + (let ((cur (buffer-substring beg end))) + (delete-region beg end) + (eshell-send-input) + (insert cur)))) + + (defun my/eshell-mode-hook () + (add-hook 'eshell-expand-input-functions + 'my/eshell-remove-trailing-space + nil t) + (add-hook 'eshell-post-command-hook + 'eshell-save-output + 99 t)) + + (add-hook 'eshell-mode-hook 'my/eshell-mode-hook) + + :config/el-patch + (defun eshell (&optional arg) + "Create an interactive Eshell buffer. +Start a new Eshell session, or switch to an already active +session. Return the buffer selected (or created). + +With a nonnumeric prefix arg, create a new session. + +With a numeric prefix arg (as in `\\[universal-argument] 42 \\[eshell]'), switch +to the session with that number, or create it if it doesn't +already exist. + +The buffer name used for Eshell sessions is determined by the +value of `eshell-buffer-name', which see. + +Eshell is a shell-like command interpreter. For more +information on Eshell, see Info node `(eshell)Top'." + (interactive "P") + (cl-assert eshell-buffer-name) + (let ((buf (cond ((numberp arg) + (get-buffer-create (format "%s<%d>" + eshell-buffer-name + arg))) + (arg + ((el-patch-swap generate-new-buffer get-buffer-create) + eshell-buffer-name)) + (t + ((el-patch-swap get-buffer-create generate-new-buffer) + eshell-buffer-name))))) + (cl-assert (and buf (buffer-live-p buf))) + (with-suppressed-warnings + ((obsolete display-comint-buffer-action)) + (pop-to-buffer buf display-comint-buffer-action)) + (unless (derived-mode-p 'eshell-mode) + (eshell-mode)) + buf))) + +(use-package em-ls + :config + (setq eshell-ls-date-format "%Y-%m-%d %H:%M") + :config/el-patch + (defun eshell-ls-file (fileinfo &optional size-width copy-fileinfo) + "Output FILEINFO in long format. +FILEINFO may be a string, or a cons cell whose car is the +filename and whose cdr is the list of file attributes." + (if (not (cdr fileinfo)) + (funcall error-func (format "%s: No such file or directory\n" + (car fileinfo))) + (setq fileinfo + (eshell-ls-annotate (if copy-fileinfo + (cons (car fileinfo) + (cdr fileinfo)) + fileinfo))) + (let ((file (car fileinfo)) + (attrs (cdr fileinfo))) + (if (not (eq listing-style 'long-listing)) + (if show-size + (funcall insert-func (eshell-ls-size-string attrs size-width) + " " file "\n") + (funcall insert-func file "\n")) + (let ((line + (concat + (if show-size + (concat (eshell-ls-size-string attrs size-width) " ")) + (format + (if numeric-uid-gid + "%s%4d %-8s %-8s " + "%s%4d %-14s %-8s ") + (or (file-attribute-modes attrs) "??????????") + (or (file-attribute-link-number attrs) 0) + (or (let ((user (file-attribute-user-id attrs))) + (and (stringp user) + (eshell-substring user 14))) + (file-attribute-user-id attrs) + "") + (or (let ((group (file-attribute-group-id attrs))) + (and (stringp group) + (eshell-substring group 8))) + (file-attribute-group-id attrs) + "")) + (let* ((str (eshell-ls-printable-size (file-attribute-size attrs))) + (len (length str))) + ;; Let file sizes shorter than 9 align neatly. + (if (< len (or size-width 8)) + (concat (make-string (- (or size-width 8) len) ? ) str) + str)) + " " (format-time-string + (el-patch-swap + (concat + eshell-ls-date-format " " + (if (= (decoded-time-year (decode-time)) + (decoded-time-year + (decode-time + (nth (cond ;; What /is/ this stupid thing? + ((eq sort-method 'by-atime) 4) ;; Who ever asked for /this/ + ((eq sort-method 'by-ctime) 6) ;; insane, broken behavior? + (t 5)) + attrs)))) + "%H:%M" + " %Y")) + eshell-ls-date-format) + (nth (cond + ((eq sort-method 'by-atime) 4) + ((eq sort-method 'by-ctime) 6) + (t 5)) attrs)) " "))) + (funcall insert-func line file "\n")))))) + + (defun eshell-ls--insert-directory + (orig-fun file switches &optional wildcard full-directory-p) + "Insert directory listing for FILE, formatted according to SWITCHES. +Leaves point after the inserted text. +SWITCHES may be a string of options, or a list of strings. +Optional third arg WILDCARD means treat FILE as shell wildcard. +Optional fourth arg FULL-DIRECTORY-P means file is a directory and +switches do not contain `d', so that a full listing is expected. + +This version of the function uses `eshell/ls'. If any of the switches +passed are not recognized, the operating system's version will be used +instead." + (el-patch-add (defvar insert-func)) + (if (not eshell-ls-use-in-dired) + (funcall orig-fun file switches wildcard full-directory-p) + (let ((handler (find-file-name-handler file 'insert-directory))) + (if handler + (funcall handler 'insert-directory file switches + wildcard full-directory-p) + (if (stringp switches) + (setq switches (split-string switches))) + (let (eshell-current-handles + eshell-current-subjob-p + font-lock-mode) + ;; use the fancy highlighting in `eshell-ls' rather than font-lock + (when eshell-ls-use-colors + (el-patch-remove (font-lock-mode -1)) + (setq font-lock-defaults nil)) + (require 'em-glob) + (let* ((insert-func 'insert) + (error-func 'insert) + (eshell-error-if-no-glob t) + (target ; Expand the shell wildcards if any. + (if (and (atom file) + (string-match "[[?*]" file) + (not (file-exists-p file))) + (mapcar #'file-relative-name (eshell-extended-glob file)) + (file-relative-name file))) + (switches + (append eshell-ls-dired-initial-args + (and (or (consp dired-directory) wildcard) (list "-d")) + switches))) + (eshell-do-ls (nconc switches (list target)))))))))) + +(use-package esh-mode + :config + (keymap-modify eshell-mode-map + "C-l" 'my/eshell-clear + "C-c d" 'my/eshell-cd + "C-c C-f" 'insert-file-name)) + +(use-package esh-var + :config + (setf (alist-get "$" eshell-variable-aliases-list + nil nil #'equal) + ;; Don't ask, it works. + '((lambda (indices) + (let ((v eshell-output-history)) + (cond + (indices (eshell-apply-indices v indices)) + (t (elt v (1- (length v)))))))))) + +(use-package fish-completion + :if (executable-find "fish") + :ensure t + :config + (setq fish-completion-fallback-on-bash-p t) + (add-hook 'eshell-mode 'fish-completion-mode)) + +(use-package bash-completion + :disabled t + :if (and (executable-find "bash") + (not (executable-find "fish"))) + :ensure t + :init + (defun my/eshell-add-bash-completion-function () + (add-hook 'completion-at-point-functions + 'bash-completion-dynamic-complete-nocomint + nil t)) + + (unless (package-installed-p 'fish-completion) + (add-hook 'eshell-mode-hook 'my/eshell-add-bash-completion-function))) + +(use-package eat + :ensure t + :init + (with-eval-after-load 'eshell + (eat-eshell-mode)) + :config + (defun my/eat-kill-after-exit (proc) + (kill-buffer (process-buffer proc))) + + (add-hook 'eat-exit-hook 'my/eat-kill-after-exit)) + + +(use-package pdf-tools + :if (locate-library "pdf-view") + :autoload pdf-view-mode + :load-path ("~/lab/emacs/pdf-view-reader") + :init + (add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode)) + + ;; (pdf-view-desktop-setup) + :config + + (keymap-modify pdf-view-mode-map + "M-g M-g" #'pdf-view-goto-page + "M-g g" #'pdf-view-goto-page + "d" #'pdf-view-book + "o" #'pdf-view-offset-mode + "O" #'pdf-view-offset-set)) + +(use-package nov + :if (group-enabled-p 'media) + :ensure t + :init + (add-to-list 'auto-mode-alist '("\\.epub3?\\'" . nov-mode)) + :config + (setq nov-save-place-file nil) + (add-hooks 'nov-mode-hook + 'visual-line-mode + 'visual-fill-column-mode)) + + +(progn ;; pulseaudio + (defun pulseaudio--list-type (type) + (thread-last + (shell-command-to-string (concat "pactl list short " (symbol-name type))) + (string-chop-newline) + (string-lines) + (mapcar #'string-chop-newline) + (mapcar + (lambda (s) + (cadr (string-match-substrings "^[0-9]+\t\\(.+?\\)\t.*$" s)))))) + + (defun pulseaudio--sinks () + (pulseaudio--list-type 'sinks)) + + (defun pulseaudio--sources () + (pulseaudio--list-type 'sources)) + + (defvar pulseaudio--sink-history ()) + (defun pulseaudio--read-sink (&optional prompt) + (completing-read + (or prompt "Sink: ") + (pulseaudio--sinks) + nil t nil + 'pulseaudio--sink-history)) + + (defun pulseaudio-set-default-sink (sink) + (interactive (list (pulseaudio--read-sink))) + (call-process-shell-command + (concat + "pactl set-default-sink " + (shell-quote-argument sink)))) + + (defun pulseaudio-add-remote-sink (host) + (interactive "sHost: ") + (call-process-shell-command + (concat + "pactl load-module module-tunnel-sink server=" + (shell-quote-argument host)))) + + (defun pulseaudio-remove-remote-sink () + (interactive) + (call-process-shell-command + "pactl unload-module module-tunnel-sink")) + + (defun pulseaudio-mute (&optional arg) + (interactive) + (let ((state + (cl-case arg + (mute "1") + (unmute "0") + (otherwise "toggle")))) + (call-process-shell-command + (concat "pactl set-sink-mute @DEFAULT_SINK@ " state)))) + + (defun pulseaudio-change-sink (amt &optional sink) + (interactive "P") + (call-process-shell-command + (concat + "pactl set-sink-volume @DEFAULT_SINK@ " + (format "%s%s%%" + (if (cl-plusp amt) + "+" "") + amt)))) + + (defvar pulseaudio-default-amt 5) + + (defun pulseaudio-sink-raise (&optional amt) + (interactive "P") + (pulseaudio-change-sink + (or amt pulseaudio-default-amt))) + + (defun pulseaudio-sink-lower (&optional amt) + (interactive "P") + (pulseaudio-change-sink + (- (or amt pulseaudio-default-amt))))) + +(use-package bongo + :ensure t + :commands (bongo-dired-library-mode + bongo-dired-play-line + bongo-pause/resume + bongo-stop + bongo-next + bongo-previous) + :config + (require 'xdg) + + (setq + bongo-mpv-extra-arguments () + bongo-default-directory + (concat (or (xdg-user-dir "MUSIC") + (expand-file-name "~/mus")) + "/") + bongo-field-separator " — " + bongo-display-track-icons nil + bongo-insert-album-covers t + bongo-mark-played-tracks t + bongo-prefer-library-buffers nil + bongo-custom-backend-matchers + '((mpv . ((local-file "file:" "http:" "https:" "ftp:") "opus" "m4a")) + (mpv . ("https:" . t)))) + + (defun my/bongo-switch-buffers (&optional prompt) + (interactive "P") + (let ((dir (if prompt + (read-directory-name + "Library directory: " + bongo-default-directory) + bongo-default-directory))) + (with-current-buffer (dired-noselect dir) + (bongo-dired-library-mode) + (display-buffer (current-buffer))))) + + (keymap-modify bongo-playlist-mode-map + " " 'my/bongo-switch-buffers) + + :config/el-patch + (defun bongo-compose-remote-option (socket-file) + "Get the command line argument for starting mpv's remote interface at SOCKET-FILE." + (when (equal bongo-mpv-remote-option 'unknown) + (setq bongo-mpv-remote-option (bongo--mpv-get-remote-option))) + (el-patch-swap + (list bongo-mpv-remote-option socket-file) + (list (format "%s=%s" bongo-mpv-remote-option socket-file))))) + +(use-package yeetube + :config + (require 'xdg) + (setq yeetube-results-limit 30 + yeetube-download-directory (xdg-user-dir "DOWNLOAD"))) + +(use-package goggles + :diminish + :demand t + :ensure t + :config + (define-globalized-minor-mode global-goggles-mode + goggles-mode goggles-mode) + (global-goggles-mode)) + +(use-package avy + :ensure t + :init + (keymap-global-modify + "C-'" 'avy-goto-char + "H-'" 'avy-goto-char) + + :config + ;; Much from https://karthinks.com/software/avy-can-do-anything/ + + (defun avy-action-embark (pt) + (unwind-protect + (save-excursion + (goto-char pt) + (embark-act)) + (select-window + (cdr (ring-ref avy-ring 0)))) + t) + + (defun avy-action-mark-to-char (pt) + (activate-mark) + (goto-char pt)) + + (defun avy-action-recenter (pt) + (save-excursion + (goto-char pt) + (recenter nil t)) + t) + (defun avy-action-recenter-to-top (pt) + (save-excursion + (goto-char pt) + (recenter 0 t)) + t) + (defun avy-action-recenter-to-bottom (pt) + (save-excursion + (goto-char pt) + (recenter -1 t)) + t) + + (setf (alist-get ?e avy-dispatch-alist) + 'avy-action-embark + + (alist-get ? avy-dispatch-alist) + 'avy-action-mark-to-char + + (alist-get ? avy-dispatch-alist) + 'avy-action-recenter + (alist-get ?r avy-dispatch-alist) + 'avy-action-recenter-to-top + (alist-get ?R avy-dispatch-alist) + 'avy-action-recenter-to-bottom)) + +(use-package ace-window + :ensure t + :init + (keymap-global-set "C-x o" 'ace-window) + :config + (setq + aw-keys + (seq-remove (lambda (x) + (memq x '( + ?x ?m ?M ?c ?j ?n + ?u ?e ?F ?v ?b ?o ?T))) + (number-sequence ?a ?z)) + aw-scope 'frame) + (add-to-list 'aw-ignored-buffers "*Embark Actions*")) + +(use-package golden-ratio + :ensure t + :config + (setq + golden-ratio-extra-commands + '(windmove-left + windmove-right + windmove-down + windmove-up + ace-window + go-next-window + go-previous-window)) + + :config/el-patch + (defun golden-ratio (&optional arg) + "Resizes current window to the golden-ratio's size specs." + (interactive "p") + (unless (or (el-patch-remove (and (not golden-ratio-mode) (null arg))) + (window-minibuffer-p) + (one-window-p) + (golden-ratio-exclude-major-mode-p) + (member (buffer-name) + golden-ratio-exclude-buffer-names) + (and golden-ratio-exclude-buffer-regexp + (loop for r in golden-ratio-exclude-buffer-regexp + thereis (string-match r (buffer-name)))) + (and golden-ratio-inhibit-functions + (loop for fun in golden-ratio-inhibit-functions + thereis (funcall fun)))) + (let ((dims (golden-ratio--dimensions)) + (golden-ratio-mode nil)) + ;; Always disable `golden-ratio-mode' to avoid + ;; infinite loop in `balance-windows'. + (let (window-configuration-change-hook) + (balance-windows) + (golden-ratio--resize-window dims) + (when golden-ratio-recenter + (scroll-right) (recenter))) + (run-hooks 'window-configuration-change-hook))))) + +(use-package isearch + :config + (setq isearch-allow-motion t) + (keymap-modify isearch-mode-map + " " 'avy-isearch + " " 'isearch-query-replace + " " 'isearch-query-replace-regexp)) + +(use-package anzu + :demand t + :ensure t + :diminish + :init + (global-anzu-mode) + (defvar-keymap anzu-replace-mode-map + " " 'anzu-query-replace + " " 'anzu-query-replace-regexp + " " 'anzu-isearch-query-replace + " " 'anzu-isearch-query-replace-regexp) + (define-minor-mode anzu-replace-mode + "Rebind query-replace and friends to anzu equivalents." + :lighter "" + :keymap anzu-replace-mode-map + :interactive t + :global t) + (anzu-replace-mode)) + +(use-package expand-region + :ensure t + :init + (keymap-global-set "C-=" 'er/expand-region)) + +(use-package hydra + :ensure t) + +(progn ;; hydra-modes + (defhydra hydra-modes (global-map "H-m") + "Modes" + ("s" electric-pair-mode "Electric Pair Mode") + ("f" flymake-mode "Flymake") + ("o" outline-minor-mode "Outline") + ("(" puni-mode "Puni") + ("v" view-mode "View Mode") + ("F" which-function-mode "Which-Function Mode") + ("m" minimap-mode "Minimap") + ("V" variable-pitch-mode "Variable Pitch Mode") + ("M" hide-mode-line-mode "Toggle Mode Line") + ("T" toggle-transparency "Toggle transparency") + ("W" global-subword-mode "Subword mode") + ("d" eldoc-mode "ElDoc mode") + ("w" visual-fill-column-mode "Visual Fill Column") + ("$" global-show-trailing-whitespace-mode "Show trailing whitespace"))) + +(use-package multiple-cursors + :ensure t + :init + (keymap-global-set "C-;" 'mc/mark-all-dwim) + (defhydra hydra-multiple-cursors (global-map "H-;") + ("l" mc/edit-lines "Beginning of lines") + ("L" mc/edit-ends-of-lines "Ends of lines") + ("n" mc/mark-next-like-this "Mark next") + ("N" mc/unmark-next-like-this "Unmark next") + ("p" mc/mark-previous-like-this "Mark previous") + ("P" mc/unmark-previous-like-this "Unmark previous") + ("m" mc/mark-more-like-this-extended "Mark more") + ("a" mc/mark-all-dwim "Mark all (dwim)") + ("A" mc/insert-letters "Insert letters") + ("!" mc/insert-numbers "Insert numbers") + ("|" mc/vertical-align "Align cursors")) + :config + (mapc (lambda (h) + (let ((cmd (intern + (format "hydra-multiple-cursors/%s" + (cadr h))))) + (cl-pushnew cmd mc/cmds-to-run-once))) + hydra-multiple-cursors/heads)) + +(use-package prog-mode + :config + (defun my/beginning-point-toplevel-sexp () + (save-excursion + (condition-case err + (progn + (while (progn + (backward-up-list) + t))) + (scan-error (point))))) + + (defun my/ending-point-toplevel-sexp () + (save-excursion + (goto-char (my/beginning-point-toplevel-sexp)) + (if (bound-and-true-p puni-mode) + (puni-forward-sexp) + (forward-sexp)) + (point))) + + (defun my/indent-toplevel-sexp () + (interactive) + (indent-region + (my/beginning-point-toplevel-sexp) + (my/ending-point-toplevel-sexp))) + + (when (version< emacs-version "30.0") + (keymap-set prog-mode-map "M-q" 'my/indent-toplevel-sexp)) + + (define-advice insert-pair (:after (&rest _) indent-sexp-when-prog) + (when (derived-mode-p 'prog-mode) + (if (version< emacs-version "30.0") + (my/indent-toplevel-sexp) + (prog-fill-reindent-defun)))) + + (add-hooks 'prog-mode-hook + (lambda () (indent-tabs-mode -1)) + 'hs-minor-mode)) + +(use-package puni + :if (group-enabled-p 'programming) + :ensure t + :demand t + :init + (add-hook 'prog-mode-hook 'puni-mode) + :config + (setf (alist-get 'puni-mode minor-mode-alist) + '(" Puni")) + + (keymap-modify puni-mode-map + "M-s" 'puni-splice + "M-?" 'puni-convolute + "M-r" 'puni-raise + "M-R" 'move-to-window-line-top-bottom + "M-J" 'puni-split + "M-" 'puni-barf-forward + "C-M-" 'puni-slurp-backward + "M-" 'puni-slurp-forward + "C-M-" 'puni-barf-backward + "M-S" search-map + "M-(" nil + "M-)" nil) + + (mapc (lambda (sym) + (advice-add sym :after #'my/indent-toplevel-sexp)) + '(puni-splice puni-raise puni-convolute puni-kill-line))) + +(use-package hideshow + :config + (keymap-modify hs-minor-mode-map + "H-i i" 'hs-toggle-hiding + "H-i s" 'hs-show-all + "H-i h" 'hs-hide-all + "H-i l" 'hs-hide-level)) + +(use-package sgml-mode + :config + (setq sgml-basic-offset 0)) + +(use-package css-mode + :config + (setq css-indent-offset 2)) + +(require 'sgml-mode) +(use-package mhtml-mode + :config + (require 'ruby-mode) + (defconst mhtml--ruby-submode + (mhtml--construct-submode 'ruby-mode + :name "Ruby" + :end-tag "" + :syntax-table ruby-mode-syntax-table + :propertize #'ruby-syntax-propertize + :keymap ruby-mode-map)) + :config/el-patch + (defvar mhtml--syntax-propertize + (syntax-propertize-rules + ("" + (0 (ignore + (goto-char (match-end 0)) + ;; Don't apply in a comment. + (unless (syntax-ppss-context (syntax-ppss)) + (mhtml--syntax-propertize-submode mhtml--css-submode end))))) + (el-patch-add + ("