Compare commits

...

12 Commits

22 changed files with 1325 additions and 108 deletions

View File

@ -18,6 +18,7 @@ env:
TERM: xterm-256color TERM: xterm-256color
window: window:
opacity: 0.9
# Window dimensions (changes require restart) # Window dimensions (changes require restart)
# #
# Specified in number of columns/lines, not pixels. # Specified in number of columns/lines, not pixels.
@ -245,7 +246,6 @@ font:
# Window opacity as a floating point number from `0.0` to `1.0`. # Window opacity as a floating point number from `0.0` to `1.0`.
# The value `0.0` is completely transparent and `1.0` is opaque. # The value `0.0` is completely transparent and `1.0` is opaque.
#background_opacity: 1.0 #background_opacity: 1.0
background_opacity: 0.9
#selection: #selection:
# This string contains all characters that are used as separators for "semantic words" in Alacritty. # This string contains all characters that are used as separators for "semantic words" in Alacritty.
@ -285,7 +285,7 @@ background_opacity: 0.9
# - (Linux/BSD) user login shell # - (Linux/BSD) user login shell
# - (Windows) powershell # - (Windows) powershell
shell: shell:
program: /usr/bin/zsh program: zsh
# args: # args:
# - --login # - --login
# Startup directory # Startup directory

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
#xset r rate 400 100 #xset r rate 400 100
##emacs -fs & ##emacs -fs &
rm -rf ~/.cache/fontconfig rm -rf ~/.cache/fontconfig
@ -23,7 +23,6 @@ source ~/.fehbg
#(sleep 1 && keynav)& #(sleep 1 && keynav)&
# warped > keynav # warped > keynav
(sleep 1 && warpd)& (sleep 1 && warpd)&
(sleep 0 && ~/bin/keyboard ) &
killall wired killall wired
(sleep 1 && wired ) & (sleep 1 && wired ) &
#(sleep 3 && optimus-manager-qt) & #(sleep 3 && optimus-manager-qt) &
@ -33,8 +32,10 @@ killall wired
(sleep 6 && bspc rule -r KeePassXC ) & (sleep 6 && bspc rule -r KeePassXC ) &
(sleep 5 && syncthing -no-browser) & (sleep 5 && syncthing -no-browser) &
(sleep 100 && nextcloud --background) &
#(sleep 5 && thunderbird ) & #(sleep 5 && thunderbird ) &
(sleep 7 && bspc rule -r Thunderbird ) & #(sleep 7 && bspc rule -r Thunderbird ) &
# Kill all davail instances before launching a single one # Kill all davail instances before launching a single one
kill $(pgrep --full "davmail") kill $(pgrep --full "davmail")
@ -54,9 +55,20 @@ killall goimapnotify
#done #done
~/bin/run_goimapnotify.sh & ~/bin/run_goimapnotify.sh &
## Keyboard
# ibus-daemon &
# uim-toolbar-gtk3-systray & #uim Japanses Input
# Japanses Input
#(sleep 1 && fcitx -d ) &
(sleep 0 && ~/bin/keyboard ) &
## Audio
(sleep 0 && dbus-run-session pipewire ) &
(sleep 2 && dbus-run-session pipewire-pulse ) &
(sleep 2 && dbus-run-session wireplumber ) &
#(sleep 2 && polkit-dumb-agent) &
#ibus-daemon &
#uim-toolbar-gtk3-systray & #uim Japanses Input
#if bspwm #if bspwm

View File

@ -1,14 +1,35 @@
#!/bin/bash #!/bin/bash
PYTORCH_NO_CUDA_MEMORY_CACHING=1
[ -z "$2" ] && echo "usage: input.mp4 output.mp4" [ -z "$2" ] && echo "usage: input.mp4 output.mp4"
[ -z "$2" ] && exit [ -z "$2" ] && exit
VIDEO="$1" VIDEO="$1"
VIDEO_OUTPUT="$2" VIDEO_OUTPUT="$2"
TMP_RAW_AUDIO=$(mktemp --suffix ".mp3") mkdir -p ~/tmp/demusicify
TMP_VOCALS_DIR=$(mktemp --directory) echo "Created ~/tmp/demusicify"
TMP_VOCALS=$(mktemp --suffix ".mp3")
echo "Using ~/tmp/demusicify as a temp directory"
TMP_RAW_AUDIO=$(mktemp -p ~/tmp/demusicify --suffix ".mp3")
TMP_VOCALS_DIR=$(mktemp -p ~/tmp/demusicify --directory)
TMP_VOCALS=$(mktemp -p ~/tmp/demusicify --suffix ".mp3")
function cleanup () {
read -p "Do you want to cleanup? y/n" -n 1 -r
echo # (optional) move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
echo "Cleaning up!"
rm "$TMP_RAW_AUDIO"
rm "$TMP_VOCALS"
rm -rf "$TMP_VOCALS_DIR"
fi
}
trap cleanup EXIT
# Extract Audio from Video # Extract Audio from Video
ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y
@ -16,7 +37,7 @@ ffmpeg -i "$VIDEO" -vn "$TMP_RAW_AUDIO" -y
# move to a tmp file, becuase demucs creates a lot of garbage # move to a tmp file, becuase demucs creates a lot of garbage
pushd "$TMP_VOCALS_DIR" || exit pushd "$TMP_VOCALS_DIR" || exit
demucs --two-stems=vocals --segment 10 "$TMP_RAW_AUDIO" demucs --two-stems=vocals --segment 15 "$TMP_RAW_AUDIO"
cp ./separated/*/*/vocals.wav "$TMP_VOCALS" cp ./separated/*/*/vocals.wav "$TMP_VOCALS"
@ -29,8 +50,3 @@ ffmpeg \
-c:v copy \ -c:v copy \
-map 0 -map 1:a \ -map 0 -map 1:a \
-y "$VIDEO_OUTPUT" -y "$VIDEO_OUTPUT"
rm "$TMP_RAW_AUDIO"
rm "$TMP_VOCALS"
rm -rf "$TMP_VOCALS_DIR"

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
setxkbmap -option ctrl:swapcaps setxkbmap -option ctrl:swapcaps
setxkbmap -option altwin:swap_lalt_lwin setxkbmap -option altwin:swap_lalt_lwin
setxkbmap -model pc105 -layout us,ar -variant ,qwerty -option grp:shifts_toggle setxkbmap -model pc105 -layout us,ar -variant ,qwerty -option grp:shifts_toggle

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
DEVICE_BUS_ID=$(lspci | grep "VGA compatible controller: NVIDIA" | awk '{print $1}') DEVICE_BUS_ID=$(lspci | grep "VGA compatible controller: NVIDIA" | awk '{print $1}')

7
bin/bin/nvidia-offload Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
export __NV_PRIME_RENDER_OFFLOAD=1
export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0
export __GLX_VENDOR_LIBRARY_NAME=nvidia
export __VK_LAYER_NV_optimus=NVIDIA_only
exec "$@"

View File

@ -0,0 +1,836 @@
"""
This script is intended to be called from OBS Studio. Provides
mouse-based zoom and tracking for desktop/monitor/window/game sources.
For more information please visit:
https://github.com/tryptech/obs-zoom-and-follow
"""
description = (
"Crops and resizes a source to simulate a zoomed in tracked to"\
" the mouse.\n\n"
+ "Set activation hotkey in Settings.\n\n"
+ "Active Border enables lazy/smooth tracking; border size"\
"calculated as percent of smallest dimension. "
+ "Border of 50% keeps mouse locked in the center of the zoom"\
" frame\n\n"
+ "By tryptech (@yo_tryptech / tryptech#1112)\n\n"
+ "v2022.09.26"
)
import obspython as obs
import pywinctl as pwc # version >=0.0.38
from platform import system
from math import sqrt
from json import load, loads
c = pwc.getMousePos
get_position = lambda: [c().x, c().y]
zoom_id_tog = None
follow_id_tog = None
new_source = True
ZOOM_NAME_TOG = "zoom.toggle"
FOLLOW_NAME_TOG = "follow.toggle"
ZOOM_DESC_TOG = "Enable/Disable Mouse Zoom"
FOLLOW_DESC_TOG = "Enable/Disable Mouse Follow"
USE_MANUAL_MONITOR_SIZE = "Manual Monitor Size"
# -------------------------------------------------------------------
class CursorWindow:
flag = lock = track = update = True
zi_timer = zo_timer = 0
windows = window_titles = monitor = window = window_handle \
= window_name = ''
monitors = pwc.getAllScreens()
monitors_key = list(dict.keys(monitors))
monitor_override = manual_offset = monitor_size_override = False
monitor_override_id = ''
source_w = source_h = source_x = source_y = zoom_x = zoom_y \
= source_x_override = source_y_override = 0
refresh_rate = int(obs.obs_get_frame_interval_ns()/1000000)
source_name = source_type = ''
zoom_w = 1280
zoom_h = 720
active_border = 0.15
max_speed = 160
smooth = 1.0
zoom_time = 300
def update_sources(self):
"""
Update the list of Windows and Monitors from PyWinCtl
"""
self.windows = pwc.getAllWindows()
self.monitors = pwc.getAllScreens()
self.monitors_key = list(dict.keys(self.monitors))
def update_window_dim(self, window):
"""
Update the stored window dimensions to those of the selected
window
:param window: Window with new dimensions
"""
print("Updating stored dimensions to match current dimensions")
if window != None:
# FIXME: on macos get window bounds results in an error and
# does not work
# NSInternalInconsistencyException - NSWindow drag regions
# should only be invalidated on the Main Thread!
window_dim = window.getClientFrame()
if (self.source_w != window_dim.right - window_dim.left
or self.source_h != window_dim.bottom - window_dim.top
or self.source_x != window_dim.left
or self.source_y != window_dim.top):
print("OLD")
print("Width, Height, X, Y")
print(f"{self.source_w}, {self.source_h}, {self.source_x},"\
f" {self.source_y}")
self.source_w = window_dim.right - window_dim.left
self.source_h = window_dim.bottom - window_dim.top
self.source_x = window_dim.left
self.source_y = window_dim.top
print("NEW")
print("Width, Height, X, Y")
print(f"{self.source_w}, {self.source_h}, {self.source_x},"\
f" {self.source_y}")
else:
print("Dimensions did not change")
def update_monitor_dim(self, monitor):
"""
Update the stored dimensions based on the selected monitor
:param monitor: Single monitor as returned from the PyWinCtl
Monitor function getAllScreens()
"""
if self.monitor_size_override:
print("Manual monitor size enabled")
print("Dimensions set to:")
print("Width, Height, X, Y")
self.source_x = monitor['pos'].x
self.source_y = monitor['pos'].y
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
{self.source_y}")
else:
print(f"Updating stored dimensions to match monitor's dimensions | {monitor}")
if (self.source_w != monitor['size'].width
or self.source_h != monitor['size'].height
or self.source_x != monitor['pos'].x
or self.source_y != monitor['pos'].y):
print("OLD")
print("Width, Height, X, Y")
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
{self.source_y}")
self.source_w = monitor['size'].width
self.source_h = monitor['size'].height
self.source_x = monitor['pos'].x
self.source_y = monitor['pos'].y
print("NEW")
print("Width, Height, X, Y")
print(f"{self.source_w}, {self.source_h}, {self.source_x}, \
{self.source_y}")
else:
print("Dimensions did not change")
def window_capture_mac(self, data):
"""
Window capture for macOS
macos uses an exclusive property 'window_name' pywinctl does not
report application windows correctly for macos yet, so we must
capture based on the actual window name and not based on the
application like we do for windows.
"""
self.window_name = data.get('window_name')
def monitor_capture_mac(self, data):
"""
The 'display' property is an index value and not the true
monitor id. It is only returned when there is more than one
monitor on your system. We will assume that the order of the
monitors returned from pywinctl are in the same order that OBS
is assigning the display index value.
"""
monitor_index = data.get('display', 0)
print(f"Retrieving monitor {monitor_index}")
for monitor in self.monitors.items():
if (monitor['id'] == monitor_index):
print(f"Found monitor {monitor['id']} | {monitor}")
self.update_monitor_dim(monitor)
def window_capture_gen(self, data):
"""
TODO: More Linux testing, specifically with handles Windows
capture for Windows and Linux. In Windows, application data is
stored as "Title:WindowClass:Executable"
"""
try:
# Assuming the OBS data is formatted correctly, we should
# be able to identify the window
# If New Source/Init
# If Handle Exists
# Else
if new_source:
# If new source selected / OBS initialize
# Build window, window_handle, and
# window_name
print("New Source")
print("Retrieving target window info from OBS")
self.window_name = data['window'].split(":")[0]
print(f"Searching for: {self.window_name}")
for w in self.windows:
if w.title == self.window_name:
window_match = w
self.window_handle = w.getHandle()
new_source = False
print(f"Window Match: {window_match.title}")
print("Window Match Handle:"\
f" {str(self.window_handle)}")
if self.window_handle != '':
# If window handle is already stored
# Get window based on handle
# Check if name needs changing
print(f"Handle exists: {str(self.window_handle)}")
handle_match = False
for w in self.windows:
if w.getHandle() == self.window_handle:
handle_match = True
print(f"Found Handle: {str(w.getHandle())} | {self.window}")
window_match = w
if window_match.title != self.window:
print("Changing target title")
print(f"Old Title: {self.window_name}")
self.window_name = w.title
print(f"New Title: {self.window_name}")
if handle_match == False:
# TODO: If the handle no longer exists,
# eg. Window or App closed
raise
else:
print("I don't know how it gets here.")
window_match = None
# TODO:
except:
print(f"Source {self.source_name} has changed." \
" Select new source window")
window_match = None
return window_match
def monitor_capture_gen(self, data):
"""
If monitor override, update with monitor override
Else if no monitor ID, monitor does not exist
Else search for the monitor and update
"""
monitor_id = data.get('monitor', None)
if len(self.monitors.items()) == 1:
print("Only one monitor detected. Forcing override.")
for monitor in self.monitors.items():
self.update_monitor_dim(monitor[1])
elif self.monitor_override is True:
print(f"Monitor Override: {self.monitor_override}")
for monitor in self.monitors.items():
if monitor[0] == self.monitors_key[
self.monitor_override_id]:
self.update_monitor_dim(monitor[1])
elif monitor_id == None:
print(f"Key 'monitor' does not exist in {data}")
else:
print(f"Searching for monitor {monitor_id}")
for monitor in self.monitors.items():
if (monitor[1]['id'] == monitor_id):
print(f"Found monitor {monitor[1]['id']} | {monitor}")
self.update_monitor_dim(monitor[1])
def update_source_size(self):
"""
Adjusts the source size variables based on the source given
"""
global new_source
try:
# Try to pull the data for the source object
# OBS stores the monitor index/window target in the
# window/game/display sources settings
# Info is stored in a JSON format
source = obs.obs_get_source_by_name(self.source_name)
source_settings = obs.obs_source_get_settings(source)
data = loads(obs.obs_data_get_json(source_settings))
except:
# If it cannot be pulled, it is likely one of the following:
# The source no longer exists
# The source's name has changed
# OBS does not have the sources loaded yet when launching
# the script on start
print("Source '" + self.source_name + "' not found.")
if len(self.window_name) == 0:
# OBS does not have the sources loaded yet when
# launching the script on start
self.source_name = ''
print(obs.obs_get_source_by_name(self.source_name))
else:
# If the source data is pulled, it exists. Therefore other
# information must also exists. Source Type is pulled to
# determine if the source is a display, game, or window
print(f"Source loaded successfully: {self.source_type}")
self.source_type = obs.obs_source_get_id(source)
print(f"Source Type: f{self.source_type}")
if (self.source_type in { 'window_capture','game_capture' }):
window_match = ''
if 'window_name' in data:
self.window_capture_mac(data)
elif 'window' in data:
window_match = self.window_capture_gen(data)
if window_match is not None:
print("Proceeding to resize")
self.window = pwc.getWindowsWithTitle(self.window_name)[0]
self.update_window_dim(self.window)
elif (self.source_type == 'monitor_capture'):
self.monitor_capture_gen(data)
elif (self.source_type == 'display_capture'):
self.monitor_capture_mac(data)
if (self.manual_offset
or self.monitor_size_override):
self.source_x += self.source_x_override
self.source_y += self.source_y_override
def resetZI(self):
"""
Reset the zoom-in timer
"""
self.zi_timer = 0
def resetZO(self):
"""
Reset the zoom-out timer
"""
self.zo_timer = 0
def cubic_in_out(self, p):
"""
Cubic in/out easing function. Accelerates until halfway, then
decelerates.
:param p: Linear temporal percent progress through easing from
0 to 1
:return: Adjusted percent progress
"""
if p < 0.5:
return 4 * p * p * p
else:
f = (2 * p) - 2
return 0.5 * f * f * f + 1
def check_offset(self, arg1, arg2, smooth):
"""
Checks if a given value is offset from pivot value and provides
an adjustment towards the pivot based on a smoothing factor
:param arg1: Pivot value
:param arg2: Checked value
:param smooth: Smoothing factor; larger values adjusts more
smoothly
:return: Adjustment value
"""
result = round((arg1 - arg2) / smooth + 1)
return int(result)
def follow(self, mousePos):
"""
Updates the position of the zoom window.
:param mousePos: [x,y] position of the mouse on the canvas of
all connected displays
:return: If the zoom window was moved
"""
track = False
if ((mousePos[0] - (self.source_x + self.source_w) < 1)
and (mousePos[0] - self.source_x > -1)):
if ((mousePos[1] - (self.source_y + self.source_h) < 1)
and (mousePos[1] - self.source_y > -1)):
track = True
if not track:
return track
move = False
# Find shortest dimension (usually height)
borderScale = min(self.zoom_w, self.zoom_h)
# Get active zone edges
zoom_edge_left = ( self.zoom_x
+ int(self.active_border * borderScale))
zoom_edge_right = ( self.zoom_x
+ self.zoom_w
- int(self.active_border * borderScale))
zoom_edge_top = ( self.zoom_y
+ int(self.active_border * borderScale))
zoom_edge_bottom = (self.zoom_y
+ self.zoom_h
- int(self.active_border * borderScale))
# Clamp zone edges at center
if zoom_edge_right < zoom_edge_left:
zoom_edge_left = self.zoom_x + int(self.zoom_w/2.0)
zoom_edge_right = zoom_edge_left
if zoom_edge_bottom < zoom_edge_top:
zoom_edge_top = self.zoom_y + int(self.zoom_h/2.0)
zoom_edge_bottom = zoom_edge_top
# Set smoothing values
smoothFactor = 1 if self.update else int((self.smooth * 9) / 10 + 1)
# Set x and y zoom offset
x_o = mousePos[0] - self.source_x
y_o = mousePos[1] - self.source_y
# Set x and y zoom offset
offset_x = offset_y = 0
if x_o < zoom_edge_left:
offset_x = self.check_offset(x_o, zoom_edge_left, smoothFactor)
move = True
elif x_o > zoom_edge_right:
offset_x = self.check_offset(x_o, zoom_edge_right, smoothFactor)
move = True
if y_o < zoom_edge_top:
offset_y = self.check_offset(y_o, zoom_edge_top, smoothFactor)
move = True
elif y_o > zoom_edge_bottom:
offset_y = self.check_offset(y_o, zoom_edge_bottom, smoothFactor)
move = True
# Max speed clamp
#if not self.update:
speed_h = sqrt((offset_x**2)+(offset_y**2))
speed_factor = max(self.max_speed, speed_h)/float(self.max_speed)
if not self.update:
offset_x /= speed_factor
offset_y /= speed_factor
self.zoom_x += offset_x
self.zoom_y += offset_y
if (self.active_border < 0.5):
self.check_pos()
return move
def check_pos(self):
"""
Checks if zoom window exceeds window dimensions and clamps it if
true
"""
if not self.monitor_size_override:
x_min = 0
x_max = self.source_w - self.zoom_w
y_min = 0
y_max = self.source_h - self.zoom_h
else:
x_min = self.source_x_override
x_max = self.source_w - self.zoom_w + self.source_x_override
y_min = self.source_y_override
y_max = self.source_h - self.zoom_h + self.source_y_override
if self.zoom_x < x_min:
self.zoom_x = x_min
elif self.zoom_x > x_max:
self.zoom_x = x_max
if self.zoom_y < y_min:
self.zoom_y = y_min
elif self.zoom_y > y_max:
self.zoom_y = y_max
def set_crop(self, inOut):
"""
Set dimensions of the crop filter used for zooming
:param inOut: direction of the filter zoom, in or out
"""
totalFrames = int(self.zoom_time / self.refresh_rate)
source = obs.obs_get_source_by_name(self.source_name)
crop = obs.obs_source_get_filter_by_name(source, "ZoomCrop")
if crop is None: # create filter
_s = obs.obs_data_create()
obs.obs_data_set_bool(_s, "relative", False)
f = obs.obs_source_create_private("crop_filter",
"ZoomCrop", _s)
obs.obs_source_filter_add(source, f)
obs.obs_source_release(f)
obs.obs_data_release(_s)
s = obs.obs_source_get_settings(crop)
i = obs.obs_data_set_int
if inOut == 0:
self.resetZI()
if self.zo_timer < totalFrames:
self.zo_timer += 1
time = self.cubic_in_out(self.zo_timer / totalFrames)
i(s, "left", int(((1 - time) * self.zoom_x)))
i(s, "top", int(((1 - time) * self.zoom_y)))
i(
s,
"cx",
self.zoom_w + int(time * (self.source_w - self.zoom_w)),
)
i(
s,
"cy",
self.zoom_h + int(time * (self.source_h - self.zoom_h)),
)
self.update = True
else:
i(s, "left", 0)
i(s, "top", 0)
i(s, "cx", self.source_w)
i(s, "cy", self.source_h)
self.update = False
else:
self.resetZO()
if self.zi_timer < totalFrames:
self.zi_timer += 1
time = self.cubic_in_out(self.zi_timer / totalFrames)
i(s, "left", int(time * self.zoom_x))
i(s, "top", int(time * self.zoom_y))
i(
s,
"cx",
self.source_w - int(time * (self.source_w - self.zoom_w)),
)
i(
s,
"cy",
self.source_h - int(time * (self.source_h - self.zoom_h)),
)
self.update = True if time < 0.8 else False
else:
i(s, "left", int(self.zoom_x))
i(s, "top", int(self.zoom_y))
i(s, "cx", int(self.zoom_w))
i(s, "cy", int(self.zoom_h))
self.update = False
obs.obs_source_update(crop, s)
obs.obs_data_release(s)
obs.obs_source_release(source)
obs.obs_source_release(crop)
if (inOut == 0) and (self.zo_timer >= totalFrames):
obs.remove_current_callback()
def tracking(self):
"""
Tracking state function
"""
if self.lock:
if self.track or self.update:
self.follow(get_position())
self.set_crop(int(self.lock))
def tick(self):
"""
Containing function that is run every frame
"""
self.tracking()
zoom = CursorWindow()
# -------------------------------------------------------------------
def script_description():
return description
def script_defaults(settings):
obs.obs_data_set_default_string(settings, "source", "")
obs.obs_data_set_default_bool(settings,
"Manual Monitor Override", False)
obs.obs_data_set_default_bool(settings, "Manual Offset", False)
obs.obs_data_set_default_int(settings, "Width", 1280)
obs.obs_data_set_default_int(settings, "Height", 720)
obs.obs_data_set_default_double(settings, "Border", 0.15)
obs.obs_data_set_default_int(settings, "Speed", 160)
obs.obs_data_set_default_double(settings, "Smooth", 1.0)
obs.obs_data_set_default_int(settings, "Zoom", 300)
obs.obs_data_set_default_int(settings, "Manual X Offset", 0)
obs.obs_data_set_default_int(settings, "Manual Y Offset", 0)
def script_update(settings):
global new_source
source_string = obs.obs_data_get_string(settings, "source")
if source_string == "":
zoom.source_name = zoom.source_type = ""
return
[source, source_type] = source_string.split("||")
if zoom.source_name != source:
zoom.source_name = source
zoom.source_type = source_type
new_source = True
if new_source:
print("Source update")
zoom.update_sources()
sources = obs.obs_enum_sources()
if len(sources) == 0:
print("No sources, likely OBS startup.")
else:
print("Non-initial update")
zoom.update_source_size()
print("Source Name: " + zoom.source_name)
zoom.monitor_override = obs.obs_data_get_bool(settings,
"Manual Monitor Override")
zoom.monitor_override_id = obs.obs_data_get_int(settings, "monitor")
zoom.monitor_size_override = obs.obs_data_get_bool(settings,
"Manual Monitor Dim")
if zoom.monitor_size_override:
zoom.source_w = obs.obs_data_get_int(settings, "Monitor Width")
zoom.source_h = obs.obs_data_get_int(settings, "Monitor Height")
zoom.manual_offset = obs.obs_data_get_bool(settings, "Manual Offset")
zoom.zoom_w = obs.obs_data_get_int(settings, "Width")
zoom.zoom_h = obs.obs_data_get_int(settings, "Height")
zoom.active_border = obs.obs_data_get_double(settings, "Border")
zoom.max_speed = obs.obs_data_get_int(settings, "Speed")
zoom.smooth = obs.obs_data_get_double(settings, "Smooth")
zoom.zoom_time = obs.obs_data_get_double(settings, "Zoom")
if zoom.monitor_size_override or zoom.manual_offset:
zoom.source_x_override = obs.obs_data_get_int(settings,
"Manual X Offset")
zoom.source_y_override = obs.obs_data_get_int(settings,
"Manual Y Offset")
else:
zoom.source_x_override = 0
zoom.source_y_override = 0
def populate_list_property_with_source_names(list_property):
global new_source
print("Updating Source List")
zoom.update_sources()
sources = obs.obs_enum_sources()
print(f"System: {system()}")
if sources is not None:
obs.obs_property_list_clear(list_property)
obs.obs_property_list_add_string(list_property, "", "")
for source in sources:
if system() == "Darwin":
print(f"{obs.obs_source_get_name(source)} | {source}")
source_type = obs.obs_source_get_id(source)
print("DEBUG:", source_type)
if source_type in { "monitor_capture", "window_capture",
"game_capture","xshm_input", "display_capture" }:
name_val = name = obs.obs_source_get_name(source)
name = name + "||" + source_type
obs.obs_property_list_add_string(list_property, name_val, name)
obs.source_list_release(sources)
new_source = True
print(f"New source: {str(new_source)}")
def populate_list_property_with_monitors(list_property):
print("Updating Monitor List")
if zoom.monitors is not None:
obs.obs_property_list_clear(list_property)
obs.obs_property_list_add_int(list_property, "", -1)
monitor_index = 0
for monitor in zoom.monitors:
screen_size = pwc.getScreenSize(monitor)
obs.obs_property_list_add_int(list_property,
f"{monitor}: {screen_size.width} x {screen_size.height}",
monitor_index)
monitor_index += 1
print("Monitor override list updated")
def callback(props, prop, *args):
prop_name = obs.obs_property_name(prop)
monitor_override = obs.obs_properties_get(props, "Manual Monitor Override")
monitor_size_override = obs.obs_properties_get(props, "Manual Monitor Dim")
refresh_monitor = obs.obs_properties_get(props, "Refresh monitors")
source_type = zoom.source_type
if prop_name == "source":
if source_type in {'monitor_capture', 'display_capture'}:
obs.obs_property_set_visible(monitor_override,True)
obs.obs_property_set_visible(refresh_monitor,True)
obs.obs_property_set_visible(monitor_size_override,True)
else:
obs.obs_property_set_visible(monitor_override,False)
obs.obs_property_set_visible(refresh_monitor,False)
obs.obs_property_set_visible(monitor_size_override,False)
obs.obs_property_set_visible(
obs.obs_properties_get(props, "Monitor Width"),
zoom.monitor_size_override)
obs.obs_property_set_visible(
obs.obs_properties_get(props, "Monitor Height"),
zoom.monitor_size_override)
obs.obs_property_set_visible(
obs.obs_properties_get(props, "Manual X Offset"),
zoom.manual_offset)
obs.obs_property_set_visible(
obs.obs_properties_get(props, "Manual Y Offset"),
zoom.manual_offset)
monitor = obs.obs_properties_get(props, "monitor")
obs.obs_property_set_visible(monitor,zoom.monitor_override
and obs.obs_property_visible(monitor_override))
return True
def script_properties():
props = obs.obs_properties_create()
zs = obs.obs_properties_add_list(
props,
"source",
"Zoom Source",
obs.OBS_COMBO_TYPE_LIST,
obs.OBS_COMBO_FORMAT_STRING,
)
populate_list_property_with_source_names(zs)
obs.obs_properties_add_button(props, "Refresh sources",
"Refresh list of sources",
lambda props,prop: True if callback(props, zs) else True)
monitor_override = obs.obs_properties_add_bool(props,
"Manual Monitor Override", "Enable Monitor Override")
m = obs.obs_properties_add_list(
props,
"monitor",
"Monitor Override",
obs.OBS_COMBO_TYPE_LIST,
obs.OBS_COMBO_FORMAT_INT,
)
populate_list_property_with_monitors(m)
rm = obs.obs_properties_add_button(props,
"Refresh monitors", "Refresh list of monitors", lambda props,
prop: True if callback(props, zs) else True)
mon_size = obs.obs_properties_add_bool(props,
"Manual Monitor Dim", "Enable Manual Monitor Dimensions")
mon_w = obs.obs_properties_add_int(props,
"Monitor Width", "Manual Monitor Width", -8000, 8000, 1)
mon_h = obs.obs_properties_add_int(props,
"Monitor Height", "Manual Monitor Height", -8000, 8000, 1)
offset = obs.obs_properties_add_bool(props,
"Manual Offset", "Enable Manual Offset")
mx = obs.obs_properties_add_int(props,
"Manual X Offset", "Manual X Offset", -8000, 8000, 1)
my = obs.obs_properties_add_int(props,
"Manual Y Offset", "Manual Y Offset", -8000, 8000, 1)
obs.obs_properties_add_int(props,
"Width", "Zoom Window Width", 320, 3840, 1)
obs.obs_properties_add_int(props,
"Height", "Zoom Window Height", 240, 3840, 1)
obs.obs_properties_add_float_slider(props,
"Border", "Active Border", 0, 0.5, 0.01)
obs.obs_properties_add_int(props,
"Speed", "Max Scroll Speed", 0, 540, 10)
obs.obs_properties_add_float_slider(props,
"Smooth", "Smooth", 0, 10, 1.00)
obs.obs_properties_add_int_slider(props,
"Zoom", "Zoom Duration (ms)", 0, 1000, 1)
mon_show = (True if
zoom.source_type in { 'monitor_capture', 'display_capture' }
else False)
obs.obs_property_set_visible(monitor_override, mon_show)
obs.obs_property_set_visible(m, zoom.monitor_override)
obs.obs_property_set_visible(rm, zoom.monitor_override)
obs.obs_property_set_visible(mon_h, zoom.monitor_override)
obs.obs_property_set_visible(mon_w, zoom.monitor_override)
obs.obs_property_set_visible(mx, zoom.manual_offset)
obs.obs_property_set_visible(my, zoom.manual_offset)
obs.obs_property_set_modified_callback(zs, callback)
obs.obs_property_set_modified_callback(monitor_override, callback)
obs.obs_property_set_modified_callback(mon_size, callback)
obs.obs_property_set_modified_callback(offset, callback)
return props
def script_load(settings):
global zoom_id_tog
load_settings = loads(obs.obs_data_get_json(settings))
try:
[source, source_type] = load_settings['source'].split("||")
[zoom.source_name, zoom.source_type] = [source, source_type]
except:
print(f"Key 'source' does not exist | {load_settings}")
zoom_id_tog = obs.obs_hotkey_register_frontend(
ZOOM_NAME_TOG, ZOOM_DESC_TOG, toggle_zoom
)
hotkey_save_array = obs.obs_data_get_array(settings, ZOOM_NAME_TOG)
obs.obs_hotkey_load(zoom_id_tog, hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
global follow_id_tog
follow_id_tog = obs.obs_hotkey_register_frontend(
FOLLOW_NAME_TOG, FOLLOW_DESC_TOG, toggle_follow
)
hotkey_save_array = obs.obs_data_get_array(settings, FOLLOW_NAME_TOG)
obs.obs_hotkey_load(follow_id_tog, hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
zoom.update_sources()
zoom.new_source = True
def script_unload():
obs.obs_hotkey_unregister(toggle_zoom)
obs.obs_hotkey_unregister(toggle_follow)
def script_save(settings):
hotkey_save_array = obs.obs_hotkey_save(zoom_id_tog)
obs.obs_data_set_array(settings, ZOOM_NAME_TOG, hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
hotkey_save_array = obs.obs_hotkey_save(follow_id_tog)
obs.obs_data_set_array(settings, FOLLOW_NAME_TOG, hotkey_save_array)
obs.obs_data_array_release(hotkey_save_array)
def toggle_zoom(pressed):
if pressed:
if new_source:
zoom.update_sources()
if zoom.source_name != "" and zoom.flag:
zoom.update_source_size()
obs.timer_add(zoom.tick, zoom.refresh_rate)
zoom.lock = True
zoom.flag = False
elif not zoom.flag:
zoom.flag = True
zoom.lock = False
print(f"Zoom: {zoom.lock}")
if zoom.lock:
print(f"Mouse position: {get_position()}")
def toggle_follow(pressed):
if pressed:
if zoom.track:
zoom.track = False
elif not zoom.track:
zoom.track = True
print(f"Tracking: {zoom.track}")

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
for imapnotify_config in ~/Documents/passwords/*_imapnotify.json; do for imapnotify_config in ~/Documents/Passwords/*_imapnotify.json; do
LOG_FILE=$(sed 's#/#_#g' <<< "$imapnotify_config" ) LOG_FILE=$(sed 's#/#_#g' <<< "$imapnotify_config" )
# sleep for internet to get ready lol # sleep for internet to get ready lol
(sleep 60 && goimapnotify -conf "$imapnotify_config" &> ~/.cache/"$LOG_FILE") & (sleep 60 && goimapnotify -conf "$imapnotify_config" &> ~/.cache/"$LOG_FILE") &

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
unset LOCK_KEEPASSXC unset LOCK_KEEPASSXC

26
bin/bin/yj Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env python
# I didn't write this!
import json,yaml,sys,os
if len(sys.argv) != 2:
print('Usage:\n '+os.path.basename(__file__)+' /path/file{.json|.yml}')
print('\nConverts JSON to YAML, and vice-versa')
sys.exit(0)
path = sys.argv[1]
if not os.path.isfile(path):
print('Bad or non-existant file: '+path)
sys.exit(1)
with open(path) as file:
if path.lower().endswith('json'):
print(yaml.dump(json.load(file), Dumper=yaml.CDumper, allow_unicode=True))
elif path.lower().endswith('yaml') or path.lower().endswith('yml'):
print(json.dumps(yaml.load(file, Loader=yaml.SafeLoader), ensure_ascii=False ,indent=2))
else:
print('Bad file extension. Must be yml or json')

View File

@ -35,7 +35,7 @@ bspc rule -a Thunderbird desktop='^8'
bspc rule -a KeePassXC desktop='^8' bspc rule -a KeePassXC desktop='^8'
# the confirm dialog # the confirm dialog
bspc rule -a "KeePassXC:*:Confirm Auto-Type" sticky=on bspc rule -a "KeePassXC:*:Confirm Auto-Type" sticky=on
bspc rule -a "Dragon-drag-and-drop" sticky=on bspc rule -a "Dragon-drop" sticky=on
bspc rule -a Dino desktop='^8' bspc rule -a Dino desktop='^8'
bspc rule -a Peek state=floating bspc rule -a Peek state=floating

View File

@ -86,6 +86,9 @@ remove warning by use-package
#+end_src #+end_src
Emacs Backups trashing local dir! Emacs Backups trashing local dir!
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package no-littering
(setq auto-save-file-name-transforms
`((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))
(setq backup-directory-alist `(("." . "~/.local/share/emacs-backups"))) (setq backup-directory-alist `(("." . "~/.local/share/emacs-backups")))
(setq make-backup-files t ; backup of a file the first time it is saved. (setq make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks backup-by-copying t ; don't clobber symlinks
@ -198,13 +201,13 @@ Actuall Theme:
(doom-themes-org-config)) (doom-themes-org-config))
#+end_src #+end_src
Transperancy! Transparency!
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; for the first frame ;; for the first frame
(set-frame-parameter nil 'alpha-background 0.9) (set-frame-parameter nil 'alpha-background 0.8)
;; for other frames ;; for other frames
(add-hook 'server-after-make-frame-hook (add-hook 'server-after-make-frame-hook
(lambda nil (set-frame-parameter nil 'alpha-background 0.9))) (lambda nil (set-frame-parameter nil 'alpha-background 0.8)))
#+end_src #+end_src
Center text in the frame, looks nice ;) Center text in the frame, looks nice ;)
@ -520,8 +523,10 @@ Capture
"cl" '(lsp-avy-lens :which-key "Code Action") "cl" '(lsp-avy-lens :which-key "Code Action")
"ci" '(lsp-ui-imenu :which-key "lsp imenu") "ci" '(lsp-ui-imenu :which-key "lsp imenu")
"cr" '(lsp-rename :which-key "rename") "cr" '(lsp-rename :which-key "rename")
"cs" '(lsp-find-refernces :which-key "find refernces") ;"cs" '(lsp-find-refernces :which-key "find refernces")
"cd" '(lsp-find-definition :which-key "goto defintion") ;"cd" '(lsp-find-definition :which-key "goto defintion")
"cd" '(lsp-ui-peek-find-definitions :which-key "goto defintion")
"cs" '(lsp-ui-peek-find-refernces :which-key "find refernces")
#+end_src #+end_src
**** Git (g) **** Git (g)
@ -600,7 +605,7 @@ Capture
(define-key evil-insert-state-map "\C-y" 'yank) (define-key evil-insert-state-map "\C-y" 'yank)
(define-key evil-visual-state-map "\C-y" 'yank) (define-key evil-visual-state-map "\C-y" 'yank)
(define-key evil-normal-state-map "K" 'lsp-ui-doc-glance); TODO: all modes ;(define-key evil-normal-state-map "K" 'lsp-ui-doc-glance); moved to lsp-ui
(define-key evil-visual-state-map "\C-y" 'yank) (define-key evil-visual-state-map "\C-y" 'yank)
;(define-key evil-insert-state-map "\C-k" 'kill-line) ;(define-key evil-insert-state-map "\C-k" 'kill-line)
(define-key evil-normal-state-map "Q" 'call-last-kbd-macro) (define-key evil-normal-state-map "Q" 'call-last-kbd-macro)
@ -922,16 +927,16 @@ use-package
(setq org-log-done 'time) (setq org-log-done 'time)
(setq org-log-into-drawer t) (setq org-log-into-drawer t)
(dolist (face '((org-document-title . 2.0) (dolist (face '((org-document-title . 2.0)
(org-level-1 . 1.2) (org-level-1 . 1.5)
(org-level-2 . 1.1) (org-level-2 . 1.0)
(org-level-3 . 1.05) (org-level-3 . 1.0)
(org-level-4 . 1.0) (org-level-4 . 1.0)
(org-level-5 . 1.1) (org-level-5 . 1.0)
(org-level-6 . 1.1) (org-level-6 . 1.0)
(org-level-7 . 1.1) (org-level-7 . 1.0)
(org-level-8 . 1.1))) (org-level-8 . 1.0)))
;; (set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face))) ;; (set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face)))
(set-face-attribute (car face) nil :font my/ui/varfont :weight 'regular :height (cdr face))) (set-face-attribute (car face) nil :font my/ui/monofont :weight 'regular :height (cdr face)))
;) ;)
(setq org-todo-keyword-faces `(("NOW" (:foreground "white" :background "#444527")) (setq org-todo-keyword-faces `(("NOW" (:foreground "white" :background "#444527"))
@ -1496,7 +1501,7 @@ Stopped using this, I just use Anki like a normal person
(use-package rainbow-delimiters (use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode) :hook (prog-mode . rainbow-delimiters-mode)
(prog-mode . show-paren-mode) (prog-mode . show-paren-mode)
(prog-mode . electric-pair-local-mode) ;(prog-mode . electric-pair-local-mode)
) )
#+end_src #+end_src
@ -1542,7 +1547,11 @@ Counsel Projectile
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package recentf (use-package recentf
:defer 10 :defer 10
:config (recentf-mode 1)) :config (recentf-mode 1)
; https://github.com/emacscollective/no-littering#suggested-settings
(with-eval-after-load 'no-littering
(add-to-list 'recentf-exclude no-littering-var-directory)
(add-to-list 'recentf-exclude no-littering-etc-directory)))
#+end_src #+end_src
*** lsp performance *** lsp performance
@ -1595,6 +1604,8 @@ Lsp UI
;; (lsp-ui-doc-enable nil) ;; (lsp-ui-doc-enable nil)
:bind :bind
(:map lsp-ui-mode-map (:map lsp-ui-mode-map
([remap evil-lookup] . lsp-ui-doc-glance)
([remap xref-find-references] . lsp-ui-peek-find-references)
("C-c z" . lsp-ui-doc-focus-frame) ("C-c z" . lsp-ui-doc-focus-frame)
:map lsp-ui-doc-frame-mode-map :map lsp-ui-doc-frame-mode-map
("C-g" . lsp-ui-doc-unfocus-frame) ("C-g" . lsp-ui-doc-unfocus-frame)
@ -1602,6 +1613,8 @@ Lsp UI
)) ))
#+end_src #+end_src
#+RESULTS:
*** lsp treemacs *** lsp treemacs
#+begin_src emacs-lisp #+begin_src emacs-lisp
;; (use-package lsp-treemacs ;; (use-package lsp-treemacs
@ -1753,9 +1766,6 @@ Auto format
;; comment to disable rustfmt on save ;; comment to disable rustfmt on save
(setq rustic-format-on-save t) (setq rustic-format-on-save t)
(add-hook 'rustic-mode-hook 'my/dev/rustic-mode-hook) (add-hook 'rustic-mode-hook 'my/dev/rustic-mode-hook)
;; (add-hook 'rustic-mode-hook 'electric-pair-mode)
;; (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
;; (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
(add-hook 'rustic-mode-hook 'lsp) (add-hook 'rustic-mode-hook 'lsp)
:custom :custom
(rustic-rustfmt-config-alist '((edition . "2021")))) (rustic-rustfmt-config-alist '((edition . "2021"))))
@ -1866,7 +1876,9 @@ Auto format
;; formats the buffer before saving ;; formats the buffer before saving
;; (add-hook 'before-save-hook 'tide-format-before-save) ;; (add-hook 'before-save-hook 'tide-format-before-save)
(add-hook 'before-save-hook 'prettier-js) (add-hook 'before-save-hook 'prettier-js)
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . js-jsx-mode))
:hook(typescript-mode . setup-tide-mode) :hook(typescript-mode . setup-tide-mode)
:hook(typescript-mode . prettier-mode)
:hook(typescript-mode . lsp)) :hook(typescript-mode . lsp))
#+end_src #+end_src
@ -1889,6 +1901,7 @@ lsp hooks setups
#+begin_src emacs-lisp #+begin_src emacs-lisp
(add-hook 'html-mode-hook 'lsp) (add-hook 'html-mode-hook 'lsp)
(add-hook 'js-mode-hook 'lsp) (add-hook 'js-mode-hook 'lsp)
(add-hook 'js-jsx-mode-hook 'lsp)
#+end_src #+end_src
*** Lua *** Lua
@ -2151,7 +2164,8 @@ ivy bibtex
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package nix-mode (use-package nix-mode
:hook (nix-mode . (lambda () :hook (nix-mode . (lambda ()
(add-hook 'before-save-hook 'nix-mode-format nil t)))) ;(add-hook 'before-save-hook 'nix-mode-format nil t)))); doesn't require nixfmt
(add-hook 'before-save-hook 'nix-format-buffer nil t))))
#+end_src #+end_src
@ -2193,8 +2207,8 @@ ivy bibtex
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package vterm (use-package vterm
:commands vterm :commands vterm
;; :bind (:map vterm-mode-map :bind (:map vterm-mode-map
;; ("C-t" . vterm-toggle)) ("C-t" . vterm-toggle))
:config :config
;;Toggle vterm ;;Toggle vterm
(evil-define-key '(normal visual insert) 'vterm-mode-map (kbd "C-t") 'vterm-toggle) (evil-define-key '(normal visual insert) 'vterm-mode-map (kbd "C-t") 'vterm-toggle)
@ -2424,7 +2438,7 @@ I wrote that, neat isn't it? :P
#+begin_src emacs-lisp :tangle no #+begin_src emacs-lisp :tangle no
;; Doesn't tangle! ;; Doesn't tangle!
;; loaded in use-package (block below) ;; loaded in use-package (block below)
(load "~/Documents/passwords/circe-networks.el") (load "~/Nextcloud/Passwords/circe-networks.el")
; example content ; example content
(add-to-list 'circe-networks `("chat.name/username" :host "irc.example.com" :port 69 (add-to-list 'circe-networks `("chat.name/username" :host "irc.example.com" :port 69
@ -2475,7 +2489,7 @@ I wrote that, neat isn't it? :P
(enable-lui-track) (enable-lui-track)
;(add-to-list 'circe-networks `()) ;(add-to-list 'circe-networks `())
;; adding to list happens here! ;; adding to list happens here!
(load "~/Documents/passwords/circe-networks.el") (load "~/Nextcloud/Passwords/circe-networks.el")
(setq circe-color-nicks-min-constrast-ratio 4.5 (setq circe-color-nicks-min-constrast-ratio 4.5
circe-color-nicks-everywhere t) circe-color-nicks-everywhere t)
:hook (circe-channel-mode . enable-circe-color-nicks) :hook (circe-channel-mode . enable-circe-color-nicks)
@ -2519,9 +2533,12 @@ I wrote that, neat isn't it? :P
* Email (mu4e) * Email (mu4e)
** Package ** Package
#+begin_src emacs-lisp #+begin_src emacs-lisp
(use-package mu4e
:demand (use-package mu4e ;
;; :ensure-system-package mu ;; this line is for nixos
;; until here
;;:ensure-system-package mu
:commands (mu4e)
:bind (:map mu4e-main-mode-map :bind (:map mu4e-main-mode-map
([remap revert-buffer] . mu4e-update-index)) ([remap revert-buffer] . mu4e-update-index))
:custom :custom
@ -2540,8 +2557,8 @@ I wrote that, neat isn't it? :P
(mu4e-view-mode . olivetti-mode) (mu4e-view-mode . olivetti-mode)
(mu4e-main-mode . olivetti-mode) (mu4e-main-mode . olivetti-mode)
(mu4e-compose-mode . flyspell-mode) (mu4e-compose-mode . flyspell-mode)
(mu4e-context-changed . mu4e-update-index) (mu4e-context-changed . mu4e-update-index))
)
#+end_src #+end_src
** Contexts ** Contexts
@ -2550,6 +2567,7 @@ I wrote that, neat isn't it? :P
;; ~/Maildir/Account0/{Inbox,Sent,Trash} ;; ~/Maildir/Account0/{Inbox,Sent,Trash}
;; ~/Maildir/Account1/{Inbox,Sent,Trash} ;; ~/Maildir/Account1/{Inbox,Sent,Trash}
;; where Account0 is context name ;; where Account0 is context name
(with-eval-after-load 'mu4e
(defun my-make-mu4e-context (context-name full-name mail-address signature) (defun my-make-mu4e-context (context-name full-name mail-address signature)
"Return a mu4e context named CONTEXT-NAME with :match-func matching "Return a mu4e context named CONTEXT-NAME with :match-func matching
folder name CONTEXT-NAME in Maildir. The context's `user-mail-address', folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
@ -2597,7 +2615,7 @@ I wrote that, neat isn't it? :P
(mu4e-drafts-folder . ,(concat dir-name "/Drafts")) (mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
(mu4e-trash-folder . ,(concat dir-name "/Trash")) (mu4e-trash-folder . ,(concat dir-name "/Trash"))
(mu4e-refile-folder . ,(concat dir-name "/Archive")) (mu4e-refile-folder . ,(concat dir-name "/Archive"))
(mu4e-compose-signature . ,signature))))) (mu4e-compose-signature . ,signature))))))
;;Fixing duplicate UID errors when using mbsync and mu4e ;;Fixing duplicate UID errors when using mbsync and mu4e
#+end_src #+end_src
@ -2606,6 +2624,7 @@ I wrote that, neat isn't it? :P
;; This is a sample, it doesn't get included in init.el ;; This is a sample, it doesn't get included in init.el
;; I put mine at location specified in the next code block ;; I put mine at location specified in the next code block
;; any number of email can be used ofc ;; any number of email can be used ofc
(with-eval-after-load 'mu4e
(setq mu4e-contexts `( (setq mu4e-contexts `(
,(my-make-mu4e-context ,(my-make-mu4e-context
"maildir-context" "Full Name" "maildir-context" "Full Name"
@ -2613,13 +2632,13 @@ I wrote that, neat isn't it? :P
,(my-make-mu4e-context ,(my-make-mu4e-context
"maildir-context2" "Full Name2" "maildir-context2" "Full Name2"
"Email Address2" "Signature2") "Email Address2" "Signature2")
)) )))
#+end_src #+end_src
or don't include in git source :) or don't include in git source :)
#+begin_src emacs-lisp #+begin_src emacs-lisp
(eval-after-load 'mu4e (with-eval-after-load 'mu4e
(load "~/Documents/passwords/mu4e-context.el")) (load "~/Nextcloud/Passwords/mu4e-context.el"))
#+end_src #+end_src
** Other fixes ** Other fixes
@ -2628,7 +2647,9 @@ see: [[https://github.com/djcb/mu/issues/1136][djcb/mu#1136 Shouldn't set flag T
should only move to trash, not delete entirely from the server should only move to trash, not delete entirely from the server
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setf (alist-get 'trash mu4e-marks)
(with-eval-after-load 'mu4e
(setf (alist-get 'trash mu4e-marks)
(list :char '("d" . "▼") (list :char '("d" . "▼")
:prompt "dtrash" :prompt "dtrash"
:dyn-target (lambda (target msg) :dyn-target (lambda (target msg)
@ -2637,7 +2658,7 @@ should only move to trash, not delete entirely from the server
;; Here's the main difference to the regular trash mark, ;; Here's the main difference to the regular trash mark,
;; no +T before -N so the message is not marked as ;; no +T before -N so the message is not marked as
;; IMAP-deleted: ;; IMAP-deleted:
(mu4e--server-move docid (mu4e--mark-check-target target) "-N")))) (mu4e--server-move docid (mu4e--mark-check-target target) "-N")))))
#+end_src #+end_src
@ -2659,9 +2680,10 @@ I prefer text/plain, over everything >:)
(add-to-list 'mm-discouraged-alternatives "text/richtext") (add-to-list 'mm-discouraged-alternatives "text/richtext")
(add-to-list 'mm-discouraged-alternatives "text/html")) (add-to-list 'mm-discouraged-alternatives "text/html"))
#+end_src #+end_src
** Send email (msmtp) ** Send email (msmtp)
#+begin_src emacs-lisp #+begin_src emacs-lisp
(setq sendmail-program "/usr/bin/msmtp" (setq sendmail-program (executable-find "msmtp") ;"/usr/bin/msmtp"
message-sendmail-f-is-evil t message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from") message-sendmail-extra-arguments '("--read-envelope-from")
send-mail-function 'smtpmail-send-it send-mail-function 'smtpmail-send-it

View File

@ -1,15 +1,17 @@
# Beware! This file is rewritten by htop when settings are changed in the interface. # Beware! This file is rewritten by htop when settings are changed in the interface.
# The parser is also very primitive, and not human-friendly. # The parser is also very primitive, and not human-friendly.
htop_version=3.2.1 htop_version=3.2.2
config_reader_min_version=3 config_reader_min_version=3
fields=0 48 17 18 38 39 40 2 46 47 49 1 fields=0 48 17 18 38 39 40 2 46 47 49 1
hide_kernel_threads=1 hide_kernel_threads=1
hide_userland_threads=1 hide_userland_threads=1
hide_running_in_container=0
shadow_other_users=0 shadow_other_users=0
show_thread_names=0 show_thread_names=0
show_program_path=0 show_program_path=1
highlight_base_name=1 highlight_base_name=0
highlight_deleted_exe=1 highlight_deleted_exe=1
shadow_distribution_path_prefix=0
highlight_megabytes=1 highlight_megabytes=1
highlight_threads=1 highlight_threads=1
highlight_changes=0 highlight_changes=0
@ -18,39 +20,41 @@ find_comm_in_cmdline=1
strip_exe_from_cmdline=1 strip_exe_from_cmdline=1
show_merged_command=1 show_merged_command=1
header_margin=1 header_margin=1
screen_tabs=1 screen_tabs=0
detailed_cpu_time=0 detailed_cpu_time=0
cpu_count_from_one=1 cpu_count_from_one=0
show_cpu_usage=1 show_cpu_usage=1
show_cpu_frequency=0 show_cpu_frequency=0
show_cpu_temperature=0
degree_fahrenheit=0
update_process_names=0 update_process_names=0
account_guest_in_cpu_meter=0 account_guest_in_cpu_meter=0
color_scheme=0 color_scheme=0
enable_mouse=1 enable_mouse=1
delay=20 delay=15
hide_function_bar=0 hide_function_bar=0
header_layout=two_50_50 header_layout=two_50_50
column_meters_0=LeftCPUs2 CPU Battery Blank Blank Blank Memory NetworkIO DiskIO column_meters_0=LeftCPUs2 Memory Swap Clock NetworkIO
column_meter_modes_0=1 1 1 2 2 2 3 4 4 column_meter_modes_0=1 1 1 4 3
column_meters_1=RightCPUs2 Memory Zram Swap Blank Blank Blank LoadAverage Uptime Tasks column_meters_1=RightCPUs2 Tasks LoadAverage Uptime DiskIO
column_meter_modes_1=1 1 1 1 2 2 2 3 4 4 column_meter_modes_1=1 2 2 4 3
tree_view=0 tree_view=0
sort_key=46 sort_key=47
tree_sort_key=46 tree_sort_key=0
sort_direction=-1 sort_direction=-1
tree_sort_direction=1 tree_sort_direction=1
tree_view_always_by_pid=0 tree_view_always_by_pid=0
all_branches_collapsed=0 all_branches_collapsed=0
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
.sort_key=PERCENT_CPU .sort_key=PERCENT_MEM
.tree_sort_key=PERCENT_CPU .tree_sort_key=PID
.tree_view=0 .tree_view=0
.tree_view_always_by_pid=0 .tree_view_always_by_pid=0
.sort_direction=-1 .sort_direction=-1
.tree_sort_direction=1 .tree_sort_direction=1
.all_branches_collapsed=0 .all_branches_collapsed=0
screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
.sort_key=IO_WRITE_RATE .sort_key=IO_RATE
.tree_sort_key=PID .tree_sort_key=PID
.tree_view=0 .tree_view=0
.tree_view_always_by_pid=0 .tree_view_always_by_pid=0

View File

@ -1,5 +1,6 @@
sub-file-paths=ass:srt:sub:Sub:subs:Subs:subtitles:Subtitles sub-file-paths=ass:srt:sub:Sub:subs:Subs:subtitles:Subtitles
sub-auto=fuzzy sub-auto=fuzzy
alang=jpn
screenshot-format=png screenshot-format=png
screenshot-high-bit-depth=yes screenshot-high-bit-depth=yes
@ -10,3 +11,6 @@ screenshot-directory="~/Pictures/screenshots"
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n" screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
force-window=immediate force-window=immediate
hwdec=auto hwdec=auto
script-opts-append=ytdl_hook-ytdl_path=yt-dlp

View File

@ -3,7 +3,7 @@
#################### ####################
# Anki deck for new cards. Subdecks are supported. # Anki deck for new cards. Subdecks are supported.
deck_name=Japanese::Mining deck_name=all::Japanese::Mining
# Model names are listed in `Tools -> Manage note types` menu in Anki. # Model names are listed in `Tools -> Manage note types` menu in Anki.
model_name=animecards model_name=animecards

View File

@ -0,0 +1,275 @@
-- youtube-quality.lua
-- Source: https://github.com/jgreco/mpv-youtube-quality/blob/master/youtube-quality.lua
-- Change youtube video quality on the fly.
--
-- Diplays a menu that lets you switch to different ytdl-format settings while
-- you're in the middle of a video (just like you were using the web player).
--
-- Bound to ctrl-f by default.
local mp = require 'mp'
local utils = require 'mp.utils'
local msg = require 'mp.msg'
local assdraw = require 'mp.assdraw'
local opts = {
--key bindings
toggle_menu_binding = "ctrl+f",
up_binding = "UP",
down_binding = "DOWN",
select_binding = "ENTER",
--formatting / cursors
selected_and_active = "▶ - ",
selected_and_inactive = "● - ",
unselected_and_active = "▷ - ",
unselected_and_inactive = "○ - ",
--font size scales by window, if false requires larger font and padding sizes
scale_playlist_by_window=false,
--playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua
--example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1
--read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags
--undeclared tags will use default osd settings
--these styles will be used for the whole playlist. More specific styling will need to be hacked in
--
--(a monospaced font is recommended but not required)
style_ass_tags = "{\\fnmonospace}",
--paddings for top left corner
text_padding_x = 5,
text_padding_y = 5,
--other
menu_timeout = 10,
--use youtube-dl to fetch a list of available formats (overrides quality_strings)
fetch_formats = true,
--default menu entries
quality_strings=[[
[
{"4320p" : "bestvideo[height<=?4320p]+bestaudio/best"},
{"2160p" : "bestvideo[height<=?2160]+bestaudio/best"},
{"1440p" : "bestvideo[height<=?1440]+bestaudio/best"},
{"1080p" : "bestvideo[height<=?1080]+bestaudio/best"},
{"720p" : "bestvideo[height<=?720]+bestaudio/best"},
{"480p" : "bestvideo[height<=?480]+bestaudio/best"},
{"360p" : "bestvideo[height<=?360]+bestaudio/best"},
{"240p" : "bestvideo[height<=?240]+bestaudio/best"},
{"144p" : "bestvideo[height<=?144]+bestaudio/best"}
]
]],
}
(require 'mp.options').read_options(opts, "youtube-quality")
opts.quality_strings = utils.parse_json(opts.quality_strings)
local destroyer = nil
function show_menu()
local selected = 1
local active = 0
local current_ytdl_format = mp.get_property("ytdl-format")
msg.verbose("current ytdl-format: "..current_ytdl_format)
local num_options = 0
local options = {}
if opts.fetch_formats then
options, num_options = download_formats()
end
if next(options) == nil then
for i,v in ipairs(opts.quality_strings) do
num_options = num_options + 1
for k,v2 in pairs(v) do
options[i] = {label = k, format=v2}
if v2 == current_ytdl_format then
active = i
selected = active
end
end
end
end
--set the cursor to the currently format
for i,v in ipairs(options) do
if v.format == current_ytdl_format then
active = i
selected = active
break
end
end
function selected_move(amt)
selected = selected + amt
if selected < 1 then selected = num_options
elseif selected > num_options then selected = 1 end
timeout:kill()
timeout:resume()
draw_menu()
end
function choose_prefix(i)
if i == selected and i == active then return opts.selected_and_active
elseif i == selected then return opts.selected_and_inactive end
if i ~= selected and i == active then return opts.unselected_and_active
elseif i ~= selected then return opts.unselected_and_inactive end
return "> " --shouldn't get here.
end
function draw_menu()
local ass = assdraw.ass_new()
ass:pos(opts.text_padding_x, opts.text_padding_y)
ass:append(opts.style_ass_tags)
for i,v in ipairs(options) do
ass:append(choose_prefix(i)..v.label.."\\N")
end
local w, h = mp.get_osd_size()
if opts.scale_playlist_by_window then w,h = 0, 0 end
mp.set_osd_ass(w, h, ass.text)
end
function destroy()
timeout:kill()
mp.set_osd_ass(0,0,"")
mp.remove_key_binding("move_up")
mp.remove_key_binding("move_down")
mp.remove_key_binding("select")
mp.remove_key_binding("escape")
destroyer = nil
end
timeout = mp.add_periodic_timer(opts.menu_timeout, destroy)
destroyer = destroy
mp.add_forced_key_binding(opts.up_binding, "move_up", function() selected_move(-1) end, {repeatable=true})
mp.add_forced_key_binding(opts.down_binding, "move_down", function() selected_move(1) end, {repeatable=true})
mp.add_forced_key_binding(opts.select_binding, "select", function()
destroy()
mp.set_property("ytdl-format", options[selected].format)
reload_resume()
end)
mp.add_forced_key_binding(opts.toggle_menu_binding, "escape", destroy)
draw_menu()
return
end
local ytdl = {
path = "yt-dlp",
searched = false,
blacklisted = {}
}
format_cache={}
function download_formats()
local function exec(args)
local ret = utils.subprocess({args = args})
return ret.status, ret.stdout, ret
end
local function table_size(t)
s = 0
for i,v in ipairs(t) do
s = s+1
end
return s
end
local url = mp.get_property("path")
url = string.gsub(url, "ytdl://", "") -- Strip possible ytdl:// prefix.
-- don't fetch the format list if we already have it
if format_cache[url] ~= nil then
local res = format_cache[url]
return res, table_size(res)
end
mp.osd_message("fetching available formats with youtube-dl...", 60)
if not (ytdl.searched) then
local ytdl_mcd = mp.find_config_file("youtube-dl")
if not (ytdl_mcd == nil) then
msg.verbose("found youtube-dl at: " .. ytdl_mcd)
ytdl.path = ytdl_mcd
end
ytdl.searched = true
end
local command = {ytdl.path, "--no-warnings", "--no-playlist", "-J"}
table.insert(command, url)
local es, json, result = exec(command)
if (es < 0) or (json == nil) or (json == "") then
mp.osd_message("fetching formats failed...", 1)
msg.error("failed to get format list: " .. err)
return {}, 0
end
local json, err = utils.parse_json(json)
if (json == nil) then
mp.osd_message("fetching formats failed...", 1)
msg.error("failed to parse JSON data: " .. err)
return {}, 0
end
res = {}
msg.verbose("youtube-dl succeeded!")
for i,v in ipairs(json.formats) do
if v.vcodec ~= "none" then
local fps = v.fps and v.fps.."fps" or ""
local resolution = string.format("%sx%s", v.width, v.height)
local l = string.format("%-9s %-5s (%-4s / %s)", resolution, fps, v.ext, v.vcodec)
local f = string.format("%s+bestaudio/best", v.format_id)
table.insert(res, {label=l, format=f, width=v.width })
end
end
table.sort(res, function(a, b) return a.width > b.width end)
mp.osd_message("", 0)
format_cache[url] = res
return res, table_size(res)
end
-- register script message to show menu
mp.register_script_message("toggle-quality-menu",
function()
if destroyer ~= nil then
destroyer()
else
show_menu()
end
end)
-- keybind to launch menu
mp.add_key_binding(opts.toggle_menu_binding, "quality-menu", show_menu)
-- special thanks to reload.lua (https://github.com/4e6/mpv-reload/)
function reload_resume()
local playlist_pos = mp.get_property_number("playlist-pos")
local reload_duration = mp.get_property_native("duration")
local time_pos = mp.get_property("time-pos")
mp.set_property_number("playlist-pos", playlist_pos)
-- Tries to determine live stream vs. pre-recordered VOD. VOD has non-zero
-- duration property. When reloading VOD, to keep the current time position
-- we should provide offset from the start. Stream doesn't have fixed start.
-- Decent choice would be to reload stream from it's current 'live' positon.
-- That's the reason we don't pass the offset when reloading streams.
if reload_duration and reload_duration > 0 then
local function seeker()
mp.commandv("seek", time_pos, "absolute")
mp.unregister_event(seeker)
end
mp.register_event("file-loaded", seeker)
end
end

View File

@ -756,12 +756,14 @@ interface = eth0
[module/wireless-network] [module/wireless-network]
type = internal/network type = internal/network
interface = wlan0 ;interface = wlan0
interface = wlp8s0
; Normal Module ; Normal Module
[module/network] [module/network]
type = internal/network type = internal/network
interface = wlan0 ;interface = wlan0
interface = wlp8s0
; Seconds to sleep between updates ; Seconds to sleep between updates
; Default: 1 ; Default: 1

View File

@ -468,7 +468,7 @@ map g/ cd /
map g? cd /usr/share/doc/ranger map g? cd /usr/share/doc/ranger
# Custom Commands # Custom Commands
map gd open_with dragon-drag-and-drop -a -x map gd open_with dragon-drop -a -x
# clean latex files # clean latex files
map dlc shell latexmk -c map dlc shell latexmk -c
map dlC shell latexmk -C map dlC shell latexmk -C

View File

@ -294,4 +294,4 @@ mime application/x-executable = "$1"
# Move the file to trash using trash-cli. # Move the file to trash using trash-cli.
label trash, has trash-put = trash-put -- "$@" label trash, has trash-put = trash-put -- "$@"
label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash
has dragon-drag-and-drop, X, flag f = dragon-drag-and-drop -a -x "$@" has dragon-drag-drop, X, flag f = dragon-drag-drop -a -x "$@"

View File

@ -3,5 +3,5 @@
#--write-subs #--write-subs
--embed-subs --embed-subs
--write-auto-subs --write-auto-subs
--sub-langs "en.*" #--sub-langs "en.*,ja.*"

View File

@ -7,6 +7,7 @@ set selection-clipboard clipboard
map u scroll half-up map u scroll half-up
map d scroll half-down map d scroll half-down
map D toggle_page_mode map D toggle_page_mode
# or set first-page-column 1:1 OR 1:2
map r reload map r reload
map R rotate map R rotate
map K zoom in map K zoom in

View File

@ -62,6 +62,10 @@ zplugin ice wait'0' lucid
zinit load agkozak/zsh-z zinit load agkozak/zsh-z
zplugin ice wait'5' lucid
zplugin load chisui/zsh-nix-shell
#zplugin ice wait'1' lucid #zplugin ice wait'1' lucid
#zplugin load marlonrichert/zsh-autocomplete #zplugin load marlonrichert/zsh-autocomplete
@ -187,6 +191,7 @@ alias sudo='sudo '
alias fm='ranger' alias fm='ranger'
alias fm.='. ranger' alias fm.='. ranger'
alias books="fm ~/Nextcloud/Books"
alias ll='ls -alF' alias ll='ls -alF'
alias la='ls -A' alias la='ls -A'
@ -209,6 +214,7 @@ alias ip='ip --color=auto'
alias ytfzfd='YTFZF_PLAYER="youtube-dl --embed-subs --write-sub --sub-lang en" ytfzf' alias ytfzfd='YTFZF_PLAYER="youtube-dl --embed-subs --write-sub --sub-lang en" ytfzf'
alias cargo-doc-server="python -m http.server -d target/doc/ -b 127.0.0.1" alias cargo-doc-server="python -m http.server -d target/doc/ -b 127.0.0.1"
alias startx="exec startx"
#=============================================================================================== #===============================================================================================
@ -275,6 +281,12 @@ export LESS_TERMCAP_so=$(printf '\e[01;33m') # enter standout mode - yellow
export LESS_TERMCAP_ue=$(printf '\e[0m') # leave underline mode export LESS_TERMCAP_ue=$(printf '\e[0m') # leave underline mode
export LESS_TERMCAP_us=$(printf '\e[04;36m') # enter underline mode - cyan export LESS_TERMCAP_us=$(printf '\e[04;36m') # enter underline mode - cyan
# fcitx (japanese)
GTK_IM_MODULE='fcitx'
QT_IM_MODULE='fcitx'
SDL_IM_MODULE='fcitx'
XMODIFIERS='@im=fcitx'
#=============================================================================================== #===============================================================================================
# Load the pure theme, with zsh-async library that's bundled with it # Load the pure theme, with zsh-async library that's bundled with it