mirror of https://github.com/Flinner/dots.git
Compare commits
12 Commits
ec0c51c07a
...
22d2a9d827
Author | SHA1 | Date |
---|---|---|
Flinner Yuu | 22d2a9d827 | |
Flinner Yuu | 16b557435e | |
Flinner Yuu | 3bcffbbfc1 | |
Flinner Yuu | a13773dc70 | |
Flinner Yuu | e94a61b04f | |
Flinner Yuu | 534dff1aa8 | |
Flinner Yuu | 6ea2071b36 | |
Flinner Yuu | 51eb11db16 | |
Flinner Yuu | cbe9cc8788 | |
Flinner Yuu | 48720c1722 | |
Flinner Yuu | ce8ee58b97 | |
Flinner Yuu | 39abcc64e4 |
|
@ -18,6 +18,7 @@ env:
|
|||
TERM: xterm-256color
|
||||
|
||||
window:
|
||||
opacity: 0.9
|
||||
# Window dimensions (changes require restart)
|
||||
#
|
||||
# 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`.
|
||||
# The value `0.0` is completely transparent and `1.0` is opaque.
|
||||
#background_opacity: 1.0
|
||||
background_opacity: 0.9
|
||||
|
||||
#selection:
|
||||
# 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
|
||||
# - (Windows) powershell
|
||||
shell:
|
||||
program: /usr/bin/zsh
|
||||
program: zsh
|
||||
# args:
|
||||
# - --login
|
||||
# Startup directory
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#xset r rate 400 100
|
||||
##emacs -fs &
|
||||
rm -rf ~/.cache/fontconfig
|
||||
|
@ -23,7 +23,6 @@ source ~/.fehbg
|
|||
#(sleep 1 && keynav)&
|
||||
# warped > keynav
|
||||
(sleep 1 && warpd)&
|
||||
(sleep 0 && ~/bin/keyboard ) &
|
||||
killall wired
|
||||
(sleep 1 && wired ) &
|
||||
#(sleep 3 && optimus-manager-qt) &
|
||||
|
@ -33,8 +32,10 @@ killall wired
|
|||
(sleep 6 && bspc rule -r KeePassXC ) &
|
||||
|
||||
(sleep 5 && syncthing -no-browser) &
|
||||
(sleep 100 && nextcloud --background) &
|
||||
|
||||
#(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 $(pgrep --full "davmail")
|
||||
|
@ -54,9 +55,20 @@ killall goimapnotify
|
|||
#done
|
||||
~/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
|
||||
|
||||
|
|
|
@ -1,14 +1,35 @@
|
|||
#!/bin/bash
|
||||
|
||||
PYTORCH_NO_CUDA_MEMORY_CACHING=1
|
||||
|
||||
[ -z "$2" ] && echo "usage: input.mp4 output.mp4"
|
||||
[ -z "$2" ] && exit
|
||||
|
||||
VIDEO="$1"
|
||||
VIDEO_OUTPUT="$2"
|
||||
|
||||
TMP_RAW_AUDIO=$(mktemp --suffix ".mp3")
|
||||
TMP_VOCALS_DIR=$(mktemp --directory)
|
||||
TMP_VOCALS=$(mktemp --suffix ".mp3")
|
||||
mkdir -p ~/tmp/demusicify
|
||||
echo "Created ~/tmp/demusicify"
|
||||
|
||||
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
|
||||
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
|
||||
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"
|
||||
|
||||
|
@ -29,8 +50,3 @@ ffmpeg \
|
|||
-c:v copy \
|
||||
-map 0 -map 1:a \
|
||||
-y "$VIDEO_OUTPUT"
|
||||
|
||||
|
||||
rm "$TMP_RAW_AUDIO"
|
||||
rm "$TMP_VOCALS"
|
||||
rm -rf "$TMP_VOCALS_DIR"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
setxkbmap -option ctrl:swapcaps
|
||||
setxkbmap -option altwin:swap_lalt_lwin
|
||||
setxkbmap -model pc105 -layout us,ar -variant ,qwerty -option grp:shifts_toggle
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DEVICE_BUS_ID=$(lspci | grep "VGA compatible controller: NVIDIA" | awk '{print $1}')
|
||||
|
||||
|
|
|
@ -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 "$@"
|
|
@ -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}")
|
|
@ -1,6 +1,6 @@
|
|||
#!/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" )
|
||||
# sleep for internet to get ready lol
|
||||
(sleep 60 && goimapnotify -conf "$imapnotify_config" &> ~/.cache/"$LOG_FILE") &
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
unset LOCK_KEEPASSXC
|
||||
|
|
|
@ -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')
|
||||
|
|
@ -35,7 +35,7 @@ bspc rule -a Thunderbird desktop='^8'
|
|||
bspc rule -a KeePassXC desktop='^8'
|
||||
# the confirm dialog
|
||||
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 Peek state=floating
|
||||
|
|
|
@ -86,6 +86,9 @@ remove warning by use-package
|
|||
#+end_src
|
||||
Emacs Backups trashing local dir!
|
||||
#+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 make-backup-files t ; backup of a file the first time it is saved.
|
||||
backup-by-copying t ; don't clobber symlinks
|
||||
|
@ -198,17 +201,17 @@ Actuall Theme:
|
|||
(doom-themes-org-config))
|
||||
#+end_src
|
||||
|
||||
Transperancy!
|
||||
Transparency!
|
||||
#+begin_src emacs-lisp
|
||||
;; for the first frame
|
||||
(set-frame-parameter nil 'alpha-background 0.9)
|
||||
(set-frame-parameter nil 'alpha-background 0.8)
|
||||
;; for other frames
|
||||
(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
|
||||
|
||||
Center text in the frame, looks nice ;)
|
||||
#+begin_src emacs-lisp
|
||||
#+begin_src emacs-lisp
|
||||
(use-package olivetti
|
||||
:diminish
|
||||
:hook (text-mode . olivetti-mode)
|
||||
|
@ -520,8 +523,10 @@ Capture
|
|||
"cl" '(lsp-avy-lens :which-key "Code Action")
|
||||
"ci" '(lsp-ui-imenu :which-key "lsp imenu")
|
||||
"cr" '(lsp-rename :which-key "rename")
|
||||
"cs" '(lsp-find-refernces :which-key "find refernces")
|
||||
"cd" '(lsp-find-definition :which-key "goto defintion")
|
||||
;"cs" '(lsp-find-refernces :which-key "find refernces")
|
||||
;"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
|
||||
|
||||
**** Git (g)
|
||||
|
@ -600,7 +605,7 @@ Capture
|
|||
(define-key evil-insert-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-insert-state-map "\C-k" 'kill-line)
|
||||
(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-into-drawer t)
|
||||
(dolist (face '((org-document-title . 2.0)
|
||||
(org-level-1 . 1.2)
|
||||
(org-level-2 . 1.1)
|
||||
(org-level-3 . 1.05)
|
||||
(org-level-1 . 1.5)
|
||||
(org-level-2 . 1.0)
|
||||
(org-level-3 . 1.0)
|
||||
(org-level-4 . 1.0)
|
||||
(org-level-5 . 1.1)
|
||||
(org-level-6 . 1.1)
|
||||
(org-level-7 . 1.1)
|
||||
(org-level-8 . 1.1)))
|
||||
(org-level-5 . 1.0)
|
||||
(org-level-6 . 1.0)
|
||||
(org-level-7 . 1.0)
|
||||
(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/monofont :weight 'regular :height (cdr face)))
|
||||
;)
|
||||
|
||||
(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
|
||||
:hook (prog-mode . rainbow-delimiters-mode)
|
||||
(prog-mode . show-paren-mode)
|
||||
(prog-mode . electric-pair-local-mode)
|
||||
;(prog-mode . electric-pair-local-mode)
|
||||
)
|
||||
#+end_src
|
||||
|
||||
|
@ -1542,7 +1547,11 @@ Counsel Projectile
|
|||
#+begin_src emacs-lisp
|
||||
(use-package recentf
|
||||
: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
|
||||
|
||||
*** lsp performance
|
||||
|
@ -1585,23 +1594,27 @@ Counsel Projectile
|
|||
|
||||
Lsp UI
|
||||
#+begin_src emacs-lisp
|
||||
(use-package lsp-ui
|
||||
:ensure
|
||||
:commands lsp-ui-mode
|
||||
:custom
|
||||
(lsp-ui-peek-always-show t)
|
||||
(lsp-ui-doc-mode t)
|
||||
(lsp-ui-sideline-show-hover nil)
|
||||
;; (lsp-ui-doc-enable nil)
|
||||
:bind
|
||||
(:map lsp-ui-mode-map
|
||||
("C-c z" . lsp-ui-doc-focus-frame)
|
||||
:map lsp-ui-doc-frame-mode-map
|
||||
("C-g" . lsp-ui-doc-unfocus-frame)
|
||||
("C-c z" . lsp-ui-doc-unfocus-frame)
|
||||
))
|
||||
(use-package lsp-ui
|
||||
:ensure
|
||||
:commands lsp-ui-mode
|
||||
:custom
|
||||
(lsp-ui-peek-always-show t)
|
||||
(lsp-ui-doc-mode t)
|
||||
(lsp-ui-sideline-show-hover nil)
|
||||
;; (lsp-ui-doc-enable nil)
|
||||
:bind
|
||||
(: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)
|
||||
:map lsp-ui-doc-frame-mode-map
|
||||
("C-g" . lsp-ui-doc-unfocus-frame)
|
||||
("C-c z" . lsp-ui-doc-unfocus-frame)
|
||||
))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
|
||||
*** lsp treemacs
|
||||
#+begin_src emacs-lisp
|
||||
;; (use-package lsp-treemacs
|
||||
|
@ -1753,9 +1766,6 @@ Auto format
|
|||
;; comment to disable rustfmt on save
|
||||
(setq rustic-format-on-save t)
|
||||
(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)
|
||||
:custom
|
||||
(rustic-rustfmt-config-alist '((edition . "2021"))))
|
||||
|
@ -1866,7 +1876,9 @@ Auto format
|
|||
;; formats the buffer before saving
|
||||
;; (add-hook 'before-save-hook 'tide-format-before-save)
|
||||
(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 . prettier-mode)
|
||||
:hook(typescript-mode . lsp))
|
||||
#+end_src
|
||||
|
||||
|
@ -1889,6 +1901,7 @@ lsp hooks setups
|
|||
#+begin_src emacs-lisp
|
||||
(add-hook 'html-mode-hook 'lsp)
|
||||
(add-hook 'js-mode-hook 'lsp)
|
||||
(add-hook 'js-jsx-mode-hook 'lsp)
|
||||
#+end_src
|
||||
|
||||
*** Lua
|
||||
|
@ -2151,7 +2164,8 @@ ivy bibtex
|
|||
#+begin_src emacs-lisp
|
||||
(use-package nix-mode
|
||||
: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
|
||||
|
||||
|
@ -2193,8 +2207,8 @@ ivy bibtex
|
|||
#+begin_src emacs-lisp
|
||||
(use-package vterm
|
||||
:commands vterm
|
||||
;; :bind (:map vterm-mode-map
|
||||
;; ("C-t" . vterm-toggle))
|
||||
:bind (:map vterm-mode-map
|
||||
("C-t" . vterm-toggle))
|
||||
:config
|
||||
;;Toggle vterm
|
||||
(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
|
||||
;; Doesn't tangle!
|
||||
;; loaded in use-package (block below)
|
||||
(load "~/Documents/passwords/circe-networks.el")
|
||||
(load "~/Nextcloud/Passwords/circe-networks.el")
|
||||
|
||||
; example content
|
||||
(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)
|
||||
;(add-to-list 'circe-networks `())
|
||||
;; 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
|
||||
circe-color-nicks-everywhere t)
|
||||
:hook (circe-channel-mode . enable-circe-color-nicks)
|
||||
|
@ -2519,9 +2533,12 @@ I wrote that, neat isn't it? :P
|
|||
* Email (mu4e)
|
||||
** Package
|
||||
#+begin_src emacs-lisp
|
||||
(use-package mu4e
|
||||
:demand
|
||||
;; :ensure-system-package mu
|
||||
|
||||
(use-package mu4e ;
|
||||
;; this line is for nixos
|
||||
;; until here
|
||||
;;:ensure-system-package mu
|
||||
:commands (mu4e)
|
||||
:bind (:map mu4e-main-mode-map
|
||||
([remap revert-buffer] . mu4e-update-index))
|
||||
:custom
|
||||
|
@ -2540,8 +2557,8 @@ I wrote that, neat isn't it? :P
|
|||
(mu4e-view-mode . olivetti-mode)
|
||||
(mu4e-main-mode . olivetti-mode)
|
||||
(mu4e-compose-mode . flyspell-mode)
|
||||
(mu4e-context-changed . mu4e-update-index)
|
||||
)
|
||||
(mu4e-context-changed . mu4e-update-index))
|
||||
|
||||
#+end_src
|
||||
|
||||
** Contexts
|
||||
|
@ -2550,6 +2567,7 @@ I wrote that, neat isn't it? :P
|
|||
;; ~/Maildir/Account0/{Inbox,Sent,Trash}
|
||||
;; ~/Maildir/Account1/{Inbox,Sent,Trash}
|
||||
;; where Account0 is context name
|
||||
(with-eval-after-load 'mu4e
|
||||
(defun my-make-mu4e-context (context-name full-name mail-address signature)
|
||||
"Return a mu4e context named CONTEXT-NAME with :match-func matching
|
||||
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-trash-folder . ,(concat dir-name "/Trash"))
|
||||
(mu4e-refile-folder . ,(concat dir-name "/Archive"))
|
||||
(mu4e-compose-signature . ,signature)))))
|
||||
(mu4e-compose-signature . ,signature))))))
|
||||
;;Fixing duplicate UID errors when using mbsync and mu4e
|
||||
#+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
|
||||
;; I put mine at location specified in the next code block
|
||||
;; any number of email can be used ofc
|
||||
(with-eval-after-load 'mu4e
|
||||
(setq mu4e-contexts `(
|
||||
,(my-make-mu4e-context
|
||||
"maildir-context" "Full Name"
|
||||
|
@ -2613,13 +2632,13 @@ I wrote that, neat isn't it? :P
|
|||
,(my-make-mu4e-context
|
||||
"maildir-context2" "Full Name2"
|
||||
"Email Address2" "Signature2")
|
||||
))
|
||||
)))
|
||||
#+end_src
|
||||
|
||||
or don't include in git source :)
|
||||
#+begin_src emacs-lisp
|
||||
(eval-after-load 'mu4e
|
||||
(load "~/Documents/passwords/mu4e-context.el"))
|
||||
(with-eval-after-load 'mu4e
|
||||
(load "~/Nextcloud/Passwords/mu4e-context.el"))
|
||||
#+end_src
|
||||
|
||||
** Other fixes
|
||||
|
@ -2628,16 +2647,18 @@ 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
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (target msg)
|
||||
(mu4e-get-trash-folder msg))
|
||||
:action (lambda (docid msg target)
|
||||
;; Here's the main difference to the regular trash mark,
|
||||
;; no +T before -N so the message is not marked as
|
||||
;; IMAP-deleted:
|
||||
(mu4e--server-move docid (mu4e--mark-check-target target) "-N"))))
|
||||
|
||||
(with-eval-after-load 'mu4e
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (target msg)
|
||||
(mu4e-get-trash-folder msg))
|
||||
:action (lambda (docid msg target)
|
||||
;; Here's the main difference to the regular trash mark,
|
||||
;; no +T before -N so the message is not marked as
|
||||
;; IMAP-deleted:
|
||||
(mu4e--server-move docid (mu4e--mark-check-target target) "-N")))))
|
||||
|
||||
#+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/html"))
|
||||
#+end_src
|
||||
|
||||
** Send email (msmtp)
|
||||
#+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-extra-arguments '("--read-envelope-from")
|
||||
send-mail-function 'smtpmail-send-it
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
# Beware! This file is rewritten by htop when settings are changed in the interface.
|
||||
# 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
|
||||
fields=0 48 17 18 38 39 40 2 46 47 49 1
|
||||
hide_kernel_threads=1
|
||||
hide_userland_threads=1
|
||||
hide_running_in_container=0
|
||||
shadow_other_users=0
|
||||
show_thread_names=0
|
||||
show_program_path=0
|
||||
highlight_base_name=1
|
||||
show_program_path=1
|
||||
highlight_base_name=0
|
||||
highlight_deleted_exe=1
|
||||
shadow_distribution_path_prefix=0
|
||||
highlight_megabytes=1
|
||||
highlight_threads=1
|
||||
highlight_changes=0
|
||||
|
@ -18,39 +20,41 @@ find_comm_in_cmdline=1
|
|||
strip_exe_from_cmdline=1
|
||||
show_merged_command=1
|
||||
header_margin=1
|
||||
screen_tabs=1
|
||||
screen_tabs=0
|
||||
detailed_cpu_time=0
|
||||
cpu_count_from_one=1
|
||||
cpu_count_from_one=0
|
||||
show_cpu_usage=1
|
||||
show_cpu_frequency=0
|
||||
show_cpu_temperature=0
|
||||
degree_fahrenheit=0
|
||||
update_process_names=0
|
||||
account_guest_in_cpu_meter=0
|
||||
color_scheme=0
|
||||
enable_mouse=1
|
||||
delay=20
|
||||
delay=15
|
||||
hide_function_bar=0
|
||||
header_layout=two_50_50
|
||||
column_meters_0=LeftCPUs2 CPU Battery Blank Blank Blank Memory NetworkIO DiskIO
|
||||
column_meter_modes_0=1 1 1 2 2 2 3 4 4
|
||||
column_meters_1=RightCPUs2 Memory Zram Swap Blank Blank Blank LoadAverage Uptime Tasks
|
||||
column_meter_modes_1=1 1 1 1 2 2 2 3 4 4
|
||||
column_meters_0=LeftCPUs2 Memory Swap Clock NetworkIO
|
||||
column_meter_modes_0=1 1 1 4 3
|
||||
column_meters_1=RightCPUs2 Tasks LoadAverage Uptime DiskIO
|
||||
column_meter_modes_1=1 2 2 4 3
|
||||
tree_view=0
|
||||
sort_key=46
|
||||
tree_sort_key=46
|
||||
sort_key=47
|
||||
tree_sort_key=0
|
||||
sort_direction=-1
|
||||
tree_sort_direction=1
|
||||
tree_view_always_by_pid=0
|
||||
all_branches_collapsed=0
|
||||
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command
|
||||
.sort_key=PERCENT_CPU
|
||||
.tree_sort_key=PERCENT_CPU
|
||||
.tree_view=0
|
||||
.tree_view_always_by_pid=0
|
||||
.sort_direction=-1
|
||||
.tree_sort_direction=1
|
||||
.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
|
||||
.sort_key=IO_WRITE_RATE
|
||||
.sort_key=PERCENT_MEM
|
||||
.tree_sort_key=PID
|
||||
.tree_view=0
|
||||
.tree_view_always_by_pid=0
|
||||
.sort_direction=-1
|
||||
.tree_sort_direction=1
|
||||
.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
|
||||
.sort_key=IO_RATE
|
||||
.tree_sort_key=PID
|
||||
.tree_view=0
|
||||
.tree_view_always_by_pid=0
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
sub-file-paths=ass:srt:sub:Sub:subs:Subs:subtitles:Subtitles
|
||||
sub-auto=fuzzy
|
||||
alang=jpn
|
||||
|
||||
screenshot-format=png
|
||||
screenshot-high-bit-depth=yes
|
||||
|
@ -10,3 +11,6 @@ screenshot-directory="~/Pictures/screenshots"
|
|||
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
|
||||
force-window=immediate
|
||||
hwdec=auto
|
||||
|
||||
script-opts-append=ytdl_hook-ytdl_path=yt-dlp
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
####################
|
||||
|
||||
# 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_name=animecards
|
||||
|
|
|
@ -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
|
|
@ -756,12 +756,14 @@ interface = eth0
|
|||
|
||||
[module/wireless-network]
|
||||
type = internal/network
|
||||
interface = wlan0
|
||||
;interface = wlan0
|
||||
interface = wlp8s0
|
||||
|
||||
; Normal Module
|
||||
[module/network]
|
||||
type = internal/network
|
||||
interface = wlan0
|
||||
;interface = wlan0
|
||||
interface = wlp8s0
|
||||
|
||||
; Seconds to sleep between updates
|
||||
; Default: 1
|
||||
|
|
|
@ -468,7 +468,7 @@ map g/ cd /
|
|||
map g? cd /usr/share/doc/ranger
|
||||
|
||||
# Custom Commands
|
||||
map gd open_with dragon-drag-and-drop -a -x
|
||||
map gd open_with dragon-drop -a -x
|
||||
# clean latex files
|
||||
map dlc shell latexmk -c
|
||||
map dlC shell latexmk -C
|
||||
|
|
|
@ -294,4 +294,4 @@ mime application/x-executable = "$1"
|
|||
# Move the file to trash using trash-cli.
|
||||
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
|
||||
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 "$@"
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
#--write-subs
|
||||
--embed-subs
|
||||
--write-auto-subs
|
||||
--sub-langs "en.*"
|
||||
#--sub-langs "en.*,ja.*"
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ set selection-clipboard clipboard
|
|||
map u scroll half-up
|
||||
map d scroll half-down
|
||||
map D toggle_page_mode
|
||||
# or set first-page-column 1:1 OR 1:2
|
||||
map r reload
|
||||
map R rotate
|
||||
map K zoom in
|
||||
|
|
12
zsh/.zshrc
12
zsh/.zshrc
|
@ -62,6 +62,10 @@ zplugin ice wait'0' lucid
|
|||
zinit load agkozak/zsh-z
|
||||
|
||||
|
||||
zplugin ice wait'5' lucid
|
||||
zplugin load chisui/zsh-nix-shell
|
||||
|
||||
|
||||
#zplugin ice wait'1' lucid
|
||||
#zplugin load marlonrichert/zsh-autocomplete
|
||||
|
||||
|
@ -187,6 +191,7 @@ alias sudo='sudo '
|
|||
|
||||
alias fm='ranger'
|
||||
alias fm.='. ranger'
|
||||
alias books="fm ~/Nextcloud/Books"
|
||||
|
||||
alias ll='ls -alF'
|
||||
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 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_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
|
||||
|
|
Loading…
Reference in New Issue