extensive update: some cleanup, todo/agenda changes, publishing system, swayfx, WIPs, etc.

This commit is contained in:
cho
2023-12-17 05:51:21 +07:00
parent 50bd201ece
commit 6c35aed2c6
53 changed files with 2108 additions and 747 deletions

View File

@ -8,3 +8,4 @@ case "$(file --dereference --brief --mime-type -- "/tmp/convert-paste-png.data")
image/png) wl-paste -t image/png > "$1" ;;
esac
rm /tmp/convert-paste-png.data

View File

@ -1,2 +1,7 @@
#!/bin/sh
setsid -f emacsclient --alternate-editor='emacs' $@ >/dev/null 2>&1
if [ -z $1 ]
then
emacsclient -nw -c --alternate-editor='emacs -nw' .
else
emacsclient -nw -c --alternate-editor='emacs -nw' "$@"
fi

View File

@ -1,2 +0,0 @@
#!/bin/sh
emacsclient -nw -c --alternate-editor='emacs -nw' $@

7
home/default/.local/bin/emo Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
if [ -z "$1" ]
then
setsid -f emacsclient . >/dev/null 2>&1 || setsid -f emacs . >/dev/null 2>&1
else
setsid -f emacsclient "$@" >/dev/null 2>&1 || setsid -f emacs "$@" >/dev/null 2>&1
fi

View File

@ -6,7 +6,9 @@ directory="$HOME/Music"
case "$file" in
*youtube.com*|*youtu.be*|*bandcamp.com*|*soundcloud.com*)
notify-send "Downloading" "$file"
cd $directory && yt-dlp --embed-metadata --embed-thumbnail -xc -f bestaudio/best --restrict-filenames "$file" && notify-send "Music added!" "$file is now saved to the music directory."
cd $directory && yt-dlp --embed-metadata --embed-thumbnail -xc -f 'bestaudio[ext=m4a]' "$file" && notify-send "Music added!" "$file is now saved to the music directory."
# --restrict-filenames
# -f bestaudio/best
;;
*mp3|*flac|*opus|*mp3?source*)
notify-send "⏳ Queuing $file..."

4
home/default/.local/bin/pind Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
[ -z "$1" ] && echo 'usage: pind <url>' && exit 1
read url < <(curl -Ls "$1" | pup 'img attr{src}')
curl -LO --no-clobber $url && echo "$url downloaded"

View File

@ -27,6 +27,7 @@ fi
if [[ -N $file ]]; then
echo "screenshot saved."
notify-send "screenshot saved." -i $file
update-recentf.py $file
exit 0
else
echo "screenshot failed."

View File

@ -1,43 +0,0 @@
#!/bin/sh
bmdirs="${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs"
bmfiles="${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-files"
# Output locations. Unactivated progs should go to /dev/null.
shell_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc"
zsh_named_dirs="${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc"
lf_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/lf/shortcutrc"
vim_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/nvim/shortcuts.vim"
ranger_shortcuts="/dev/null"
qute_shortcuts="/dev/null"
fish_shortcuts="/dev/null"
vifm_shortcuts="/dev/null"
# Remove, prepare files
rm -f "$lf_shortcuts" "$ranger_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" 2>/dev/null
printf "# vim: filetype=sh\\n" > "$fish_shortcuts"
printf "# vim: filetype=sh\\nalias " > "$shell_shortcuts"
printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts"
# Format the `directories` file in the correct syntax and sent it to all three configs.
eval "echo \"$(cat "$bmdirs")\"" | \
awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
printf(\"%s=\42cd %s && ls -a\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
printf(\"abbr %s \42cd %s; and ls -a\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ;
printf(\"map g%s :cd %s<CR>\nmap t%s <tab>:cd %s<CR><tab>\nmap M%s <tab>:cd %s<CR><tab>:mo<CR>\nmap Y%s <tab>:cd %s<CR><tab>:co<CR> \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ;
printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ;
printf(\"map g%s cd %s\nmap t%s tab_new %s\nmap m%s shell mv -v %%s %s\nmap Y%s shell cp -rv %%s %s \n\",\$1,\$2,\$1,\$2, \$1, \$2, \$1, \$2) >> \"$ranger_shortcuts\" ;
printf(\"map C%s cd \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" }"
# Format the `files` file in the correct syntax and sent it to both configs.
eval "echo \"$(cat "$bmfiles")\"" | \
awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
printf(\"%s=\42\$EDITOR %s\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
printf(\"abbr %s \42\$EDITOR %s\42 \n\",\$1,\$2) >> \"$fish_shortcuts\" ;
printf(\"map %s :e %s<CR> \n\",\$1,\$2) >> \"$vifm_shortcuts\" ;
printf(\"map %s shell \$EDITOR %s \n\",\$1,\$2) >> \"$ranger_shortcuts\" ;
printf(\"map E%s \$\$EDITOR \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" }"

View File

@ -0,0 +1,293 @@
#!/usr/bin/env bash
# https://gitlab.com/wef/dotfiles/-/blob/master/bin/sway-select-window
# shellcheck disable=SC2034
TIME_STAMP="20230129.084152"
# Copyright (C) 2019-2023 Bob Hepple <bob dot hepple at gmail dot com>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# CUSTOMISE HERE IF YOU'RE NOT GETTING ALL YOUR ICONS:
# This array contains my most commonly used apps on f34, cached here
# for speed. If they don't work for you, you can either just remove
# these entries and rely on on-the-fly lookup of icons (which may be
# slow). Or, for speedier operation, you can:
# 1. get all your common apps running
# 2. remove the entries in the array
# 3. run the script from the CLI
# 4. copy-paste the list of "[app]=icon" lines into the array
# Also, if all else fails, you can hardcode your app here:
declare -A icons=(
[floating-kitty]=/usr/share/icons/hicolor/256x256/apps/kitty.png
[kitty]=/usr/share/icons/hicolor/256x256/apps/kitty.png
[foot]=/usr/share/icons/hicolor/48x48/apps/foot.png
[emacs]=/usr/share/icons/breeze/apps/48/emacs.svg
[firefox]=/usr/share/icons/hicolor/48x48/apps/firefox.png
[mythfrontend]=/usr/share/pixmaps/mythfrontend.png
[kitty]=/usr/share/icons/hicolor/256x256/apps/kitty.png
[Gdcalc]=/usr/share/pixmaps/HP-16C-48.xpm
[pavucontrol]=/usr/share/icons/gnome/48x48/apps/multimedia-volume-control.png
[pulseeffects]=/usr/share/icons/hicolor/scalable/apps/pulseeffects.svg
[blueman-manager]=/usr/share/icons/hicolor/scalable/apps/blueman.svg
[gnome-system-monitor]=/usr/share/icons/hicolor/scalable/apps/org.gnome.SystemMonitor.svg
[gnome-disks]=/usr/share/icons/hicolor/scalable/apps/org.gnome.DiskUtility.svg
[org.gnome.Weather]=/usr/share/icons/hicolor/scalable/apps/org.gnome.Weather.svg
[xfce4-appfinder]=/usr/share/icons/hicolor/scalable/apps/org.xfce.appfinder.svg
[LibreWolf]=/var/lib/flatpak/exports/share/icons/hicolor/128x128/apps/io.gitlab.librewolf-community.png
[firefox]=/var/lib/flatpak/exports/share/icons/hicolor/128x128/apps/org.mozilla.firefox.png
)
KEYBOARD_DEVICE="/dev/input/event4"
verbose=""
PROG=$( basename "$0" )
case "$1" in
-h|--help)
echo "Usage: $PROG"
echo
echo "show running programs and select one to display (uses wofi)."
echo "If evtest(1) is installed and sudo is available then you can press"
echo "Shift-Enter to move the window here rather than move to"
echo "the windows workspace. You may need to change KEYBOARD_DEVICE above."
exit 0
;;
-v|--verbose)
verbose="set"
shift
;;
esac
jq_get_windows='
# descend to workspace or scratchpad
.nodes[].nodes[]
# save workspace name as .w
| {"w": .name} + (
if (.nodes|length) > 0 then # workspace
[recurse(.nodes[])]
else # scratchpad
[]
end
+ .floating_nodes
| .[]
# select nodes with no children (windows)
| select(.nodes==[])
)'
jq_windows_to_tsv='
[
(.id | tostring),
# remove markup and index from workspace name, replace scratch with "[S]"
(.w | gsub("<[^>]*>|:$"; "") | sub("__i3_scratch"; "[S]")),
# get app name (or window class if xwayland)
(.app_id // .window_properties.class),
(.name),
(.pid)
]
| @tsv'
get_fs_win_in_ws() {
id="${1:?}"
swaymsg -t get_tree |
jq -e -r --argjson id "$id" "
[ $jq_get_windows ]
| (.[]|select(.id == \$id)) as \$selected_workspace
| .[]
| select( .w == \$selected_workspace.w and .fullscreen_mode == 1 )
| $jq_windows_to_tsv
"
}
get_hardcoded_icon() {
icon="${icons[$1]}"
echo "$icon"
}
get_desktop() {
app="$1"
p="/usr/share/applications"
# fast and easy cases first:
for prefix in "" org.kde. org.gnome. org.freedesktop.; do
d="$p/$prefix$app.desktop"
[[ -r "$d" ]] && echo "$d" && return
done
# maybe lowercase
for prefix in "" org.kde. org.gnome. org.freedesktop.; do
d="$p/$prefix${app,,}.desktop"
[[ -r "$d" ]] && echo "$d" && return
done
# this is fairly reliable but slow:
# look for a .desktop file with Exec=$app eg
# gnome-disks (but exclude gnome-disk-image-writer.desktop)
# gnome-font-viewer
GREP='egrep -r'
type rg &>/dev/null && GREP=rg
d=$( $GREP -il "^exec=$app( %u)*[[:space:]]*$" $p | head -n 1)
[[ -r "$d" ]] && echo "$d" && return
# desperation - weird apps like com.github.wwmm.pulseeffects.desktop!!
# shellcheck disable=SC2012
d=$( ls "$p/"*".$app.desktop" 2>/dev/null | head -n 1 )
[[ -r "$d" ]] && echo "$d" && return
}
get_icon() {
icon_locations=(
icons/hicolor/scalable/apps
icons/hicolor/48x48/apps
icons/hicolor/128x128/apps
icons/hicolor/256x256/apps
icons/gnome/48x48/apps
icons/gnome/48x48/devices
pixmaps
)
app="$1"
icon=$( get_hardcoded_icon "$app_name" )
[[ "$icon" && -r "$icon" ]] && echo "$icon" && return
# let's go poke in the .desktop files:
icon_name=""
dt=$( get_desktop "$app" )
# sometimes we get the 'class' rather than the exe - so try this:
[[ "$dt" ]] || {
app=$( tr '\0' '\n' < "/proc/$pid/cmdline" | head -n 1 )
dt=$( get_desktop "$( basename "$app" )" )
}
[[ "$dt" ]] && {
icon_name=$( awk -v IGNORECASE="set" -F"=" '/^icon/ {print $2}' "$dt" )
[[ "$icon_name" ]] && {
for d in "${icon_locations[@]}"; do
for s in .svg .png ""; do
icon=/usr/share/$d/$icon_name$s
[[ -r $icon ]] && echo "$icon" && return
done
done
}
}
# desperation street:
icon=$( find /usr/share/icons /usr/share/pixmaps | grep -E -i "/$app.(png|svg)" | head -n 1 )
[[ "$icon" && -r "$icon" ]] && echo "$icon" && return
# failed:
#echo "/usr/share/icons/Adwaita/32x32/status/image-missing-symbolic.symbolic.png"
echo "$HOME/.local/share/icons/img-missing-sym.png"
}
focus_window() {
id="${1}"
ws_name="${2}"
app_name="${3}"
win_title="${4}"
[[ "$verbose" ]] && printf "focusing window (in workspace %s): [%s] (%s) \`%s\`\n" "$ws_name" "$id" "$app_name" "$win_title" >&2
# look for fullscreen among other windows in selected window's workspace
if fs_win_tsv="$( get_fs_win_in_ws "$id" )" ; then
read -r win_id ws_name app_name win_title <<<"$fs_win_tsv"
if [ "$win_id" != "$id" ] ; then
[[ "$verbose" ]] && printf 'found fullscreen window in target workspace (%s): [%s] (%s) "%s"\n' "$ws_name" "$win_id" "$app_name" "$win_title" >&2
swaymsg "[con_id=$win_id] fullscreen disable"
fi
fi
swaymsg "[con_id=$id]" focus
}
id_fmt='<span stretch="ultracondensed" size="xx-small">%s</span>'
ws_fmt='<span size="small">%s</span>'
app_fmt='<span weight="bold">%s</span>'
title_fmt='<span style="italic">%s</span>'
#id_fmt='%s'
#ws_fmt='%s'
#app_fmt='%s'
#title_fmt='%s'
# allow Alt+Tab etc to not be caught by sway:
trap 'swaymsg "mode default"' EXIT
swaymsg "mode passthrough"
swaymsg -t get_tree |
# get list of windows as tab-separated columns
jq -r "$jq_get_windows | $jq_windows_to_tsv" |
# align columns w/ spaces (keep tab as separator)
column -s $'\t' -o $'\t' -t |
# pango format the window list
while IFS=$'\t' read -r win_id ws_name app_name win_title pid; do
shopt -s extglob
app_name="${app_name%%*( )}"
icon=$( get_icon "$app_name" "$pid" )
[[ "$verbose" ]] && printf "[%s]=>%s\n" "$app_name" "$icon" >&2
# shellcheck disable=SC2059
# hide win_id for now
#win_id=""
# simplify ws_name instead of Scratch
#(( ${#ws_name} > 8 )) && ws_name="${ws_name:0:1}"
printf "img:$icon:text:${id_fmt}\t${ws_fmt}\t${app_fmt}\t${title_fmt}\n" \
"$win_id" \
"$ws_name" \
"$app_name" \
"$win_title"
done |
# sort by workspace name and then app_name:
sort -k2 -k3 |
# defeat the initial cache in order to preserve the order:
wofi -m --cache-file=/dev/null --insensitive --allow-images --show dmenu --prompt='Focus a window' | {
FS=$'\t' read -r win_id ws_name app_name win_title
# printf "win_id='$win_id' ws_name='$ws_name' app_name='$app_name' win_title='$win_title'" >&2
# use evtest (if installed) to detect the state of the left shift
# key and if it's 'down' then move the window here rather than move
# to the window's workspace. Should be safe if evtest or sudo are
# not available.
## i've disabled this
type evtest && sudo evtest --query $KEYBOARD_DEVICE EV_KEY KEY_LEFTSHIFT
SHIFT_STATE=$?
if [[ "$win_id" ]]; then
if (( SHIFT_STATE == 10 )); then
# bring the window here
swaymsg "[con_id=$win_id] move window to workspace current, focus"
else
focus_window "$win_id" "$ws_name" "$app_name" "$win_title"
fi
fi
}
exit 0
# this is the example documented in 'man 7 wofi' but it doesn't understand the scratchpad:
swaymsg -t get_tree |
jq -r '.nodes[].nodes[] | if .nodes then [recurse(.nodes[])] else [] end + .floating_nodes | .[] | select(.nodes==[]) | ((.id | tostring) + " " + .name)' |
wofi --show dmenu | {
read -r id name
swaymsg "[con_id=$id]" focus
}
# Local Variables:
# mode: shell-script
# time-stamp-pattern: "4/TIME_STAMP=\"%:y%02m%02d.%02H%02M%02S\""
# eval: (add-hook 'before-save-hook 'time-stamp)
# End:

View File

@ -7,7 +7,8 @@ case "$(readlink -f /sbin/init)" in
*) ctl='loginctl' ;;
esac
case "$(printf "🔒 lock\n🚪 leave $WM\n♻ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥 shutdown\n💤 sleep\n📺 display off\n set background\n start idle\n kill swayidle\n fcitx5\n kill fcitx5\n start emacs daemon\n kill emacs daemon\n restart emacs daemon" | rofi -dmenu -i -l 16 -p 'action')" in
#case "$(printf "🔒 lock\n🚪 leave $WM\n♻ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥 shutdown\n💤 sleep\n📺 display off\n set background\n start idle\n kill swayidle\n fcitx5\n kill fcitx5\n start emacs daemon\n kill emacs daemon\n restart emacs daemon" | rofi -dmenu -i -l 16 -p 'action')" in
case "$(printf "🔒 lock\n🚪 leave $WM\n♻ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥 shutdown\n💤 sleep\n📺 display off\n set background\n start idle\n kill swayidle\n fcitx5\n kill fcitx5\n start emacs daemon\n kill emacs daemon\n restart emacs daemon" | wofi -L 17 --cache-file=/dev/null --show=dmenu -i -p 'action')" in
'🔒 lock')
setsid -f swaylock
setsid -f sleep 2 && swayidle -w timeout 1 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on" && kill $#'
@ -24,6 +25,9 @@ case "$(printf "🔒 lock\n🚪 leave $WM\n♻ renew $WM\n🐻 hibernate\n
' kill swayidle') killall swayidle && notify-send 'idle killed.';;
' fcitx5') fcitx5 ;;
' kill fcitx5') killall fcitx5 ;;
#' start emacs daemon') emacs --daemon && emacsclient -c ;;
#' kill emacs daemon') emacsclient -e '(kill-emacs)' ;;
#' restart emacs daemon') emacsclient -e '(kill-emacs)' ; emacs --daemon && emacsclient -c ;;
' start emacs daemon') emacs --daemon && notify-send 'emacs daemon started' ;;
' kill emacs daemon') emacsclient -e '(kill-emacs)' && notify-send 'emacs daemon killed' ;;
' restart emacs daemon') emacsclient -e '(kill-emacs)' && notify-send 'emacs daemon killed' ; emacs --daemon && notify-send 'emacs daemon started' ;;

View File

@ -0,0 +1,13 @@
#!/usr/bin/python3
import gi, sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, GLib
rec_mgr = Gtk.RecentManager.get_default()
for arg in sys.argv[1:]:
rec_mgr.add_item(Gio.File.new_for_path(arg).get_uri())
GLib.idle_add(Gtk.main_quit)
Gtk.main()