Compare commits
37 Commits
a75c34e1dc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
3cf506fedf
|
|||
|
4a9d8189b1
|
|||
|
7483a7acb4
|
|||
|
673a30e1df
|
|||
|
809de7f5a3
|
|||
|
8fc4fd63ff
|
|||
|
d5ed8744f6
|
|||
| 915dc9faf0 | |||
|
a1696ee49b
|
|||
|
f23fe5506d
|
|||
|
ed5688306b
|
|||
|
b4e8dcd75a
|
|||
|
3e56a80ee2
|
|||
|
916bd6b61e
|
|||
|
4a525e2822
|
|||
|
8063f91d8a
|
|||
|
bfda6f4ac2
|
|||
|
8f9df4c730
|
|||
|
34a2f71c6d
|
|||
|
9f469589b4
|
|||
|
a6608b1d81
|
|||
|
3d0c6f8de0
|
|||
|
915f19f142
|
|||
|
94bb499764
|
|||
|
1bf6921992
|
|||
|
4c69672211
|
|||
|
fd35954c9d
|
|||
|
920b4451d9
|
|||
|
1c39877f14
|
|||
|
0c11bfbf80
|
|||
|
d4b4904b0e
|
|||
|
7b6b31204d
|
|||
|
02cace931d
|
|||
|
a78a899f02
|
|||
|
7ce1babeed
|
|||
|
f5a9a20a1f
|
|||
|
3175db4900
|
19
README.md
19
README.md
@@ -1,4 +1,4 @@
|
|||||||
<img src="https://raw.githubusercontent.com/Uyanide/dotfiles/refs/heads/main/assets/works-on-my-machine.png" alt="Works on my machine(s)" width="200" />
|
<img src="https://raw.githubusercontent.com/Uyanide/dotfiles/refs/heads/main/assets/works-on-my-machines.png" alt="Works on my machine(s)" width="200" />
|
||||||
|
|
||||||
## How it looks like...
|
## How it looks like...
|
||||||
|
|
||||||
@@ -73,11 +73,11 @@ This setup is currently only adapted for Niri.
|
|||||||
- `lyrics`, scrolling lyrics player, depends on [a small utility](https://github.com/Uyanide/Spotify_Lyrics) from myself <small>(which also happens to be my frist Golang program :D)</small>.
|
- `lyrics`, scrolling lyrics player, depends on [a small utility](https://github.com/Uyanide/Spotify_Lyrics) from myself <small>(which also happens to be my frist Golang program :D)</small>.
|
||||||
- `lyrics-single`, similar to `lyrics`, but only with a single line and can be easily embeded into the status bar.
|
- `lyrics-single`, similar to `lyrics`, but only with a single line and can be easily embeded into the status bar.
|
||||||
|
|
||||||
## Swww
|
## Awww (Swww)
|
||||||
|
|
||||||
The wallpaper will be automatically blurred when there is a window in focus, which is implemented in the [wallpaper-daemon](https://github.com/Uyanide/dotfiles/blob/main/scripts/wallpaper-daemon) script.
|
The wallpaper will be automatically blurred when there is a window in focus, which is implemented in the [wallpaper-daemon](https://github.com/Uyanide/dotfiles/blob/main/config/scripts/.local/scripts/wallpaper-daemon) script.
|
||||||
|
|
||||||
This feature is only enabled in Niri. Swww also manages wallpapers of the Hyprland setup, yet only in the regular way.
|
This feature is only enabled in Niri. Awww also manages wallpapers of the Hyprland setup, yet only in the regular way.
|
||||||
|
|
||||||
## Wallpaper & Colortheme
|
## Wallpaper & Colortheme
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Based on [codeopshq/dotfiles](https://github.com/codeopshq/dotfiles), also serve
|
|||||||
|
|
||||||
## Grub theme
|
## Grub theme
|
||||||
|
|
||||||
Based on [vinceliuice/Elegant-grub2-themes](https://github.com/vinceliuice/Elegant-grub2-themes) with an [illustration from 紺屋鴉江](https://www.pixiv.net/artworks/119683453).
|
Based on [vinceliuice/Elegant-grub2-themes](https://github.com/vinceliuice/Elegant-grub2-themes) with an [illustration from 紺屋](https://www.pixiv.net/artworks/119683453).
|
||||||
|
|
||||||
## MPV
|
## MPV
|
||||||
|
|
||||||
@@ -100,11 +100,4 @@ Based on [noelsimbolon/mpv-config](https://github.com/noelsimbolon/mpv-config.gi
|
|||||||
|
|
||||||
## Fonts
|
## Fonts
|
||||||
|
|
||||||
including:
|
See [fontconfig.md](https://github.com/Uyanide/dotfiles/blob/main/memo/fontconfig.md).
|
||||||
|
|
||||||
- Maple Mono NF CN
|
|
||||||
- MesloLGM Nerd Font (& Mono)
|
|
||||||
- WenQuanYi Micro Hei
|
|
||||||
- Sour Gummy
|
|
||||||
- Noto Sans
|
|
||||||
- ...
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
@@ -8,6 +8,10 @@ window-padding-y = 10
|
|||||||
|
|
||||||
keybind = ctrl+shift+r=reload_config
|
keybind = ctrl+shift+r=reload_config
|
||||||
|
|
||||||
|
keybind = ctrl+shift+h=write_screen_file:copy
|
||||||
|
keybind = ctrl+shift+j=text:ghostty-capture\n
|
||||||
|
keybind = ctrl+enter=unbind
|
||||||
|
|
||||||
command = exec fish
|
command = exec fish
|
||||||
|
|
||||||
confirm-close-surface = false
|
confirm-close-surface = false
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ window-padding-y = 10
|
|||||||
|
|
||||||
keybind = ctrl+shift+r=reload_config
|
keybind = ctrl+shift+r=reload_config
|
||||||
|
|
||||||
|
keybind = ctrl+shift+h=write_screen_file:copy
|
||||||
|
keybind = ctrl+shift+j=text:ghostty-capture\n
|
||||||
|
keybind = ctrl+enter=unbind
|
||||||
|
|
||||||
command = exec fish
|
command = exec fish
|
||||||
|
|
||||||
confirm-close-surface = false
|
confirm-close-surface = false
|
||||||
@@ -19,3 +23,5 @@ cursor-style = bar
|
|||||||
adjust-cursor-thickness = 3
|
adjust-cursor-thickness = 3
|
||||||
|
|
||||||
custom-shader = cursor-shaders/cursor-smear.glsl
|
custom-shader = cursor-shaders/cursor-smear.glsl
|
||||||
|
|
||||||
|
quit-after-last-window-closed = false
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ bind = Super+Shift, Page_Up, movetoworkspace, -1 # [hidden]
|
|||||||
bind = Super+Alt, S, movetoworkspacesilent, special:s
|
bind = Super+Alt, S, movetoworkspacesilent, special:s
|
||||||
bind = Super, P, pin
|
bind = Super, P, pin
|
||||||
bind = Alt, Tab, cyclenext
|
bind = Alt, Tab, cyclenext
|
||||||
bind = Super, Tab, hyprexpo:expo, toggle # can be: toggle, select, off/disable or on/enable
|
# bind = Super, Tab, hyprexpo:expo, toggle # can be: toggle, select, off/disable or on/enable
|
||||||
bind = Super+Ctrl, T, exec, workspace-new # Create new workspace
|
bind = Super+Ctrl, T, exec, workspace-new # Create new workspace
|
||||||
|
|
||||||
bind = Super, M, exit
|
bind = Super, M, exit
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ map ctrl+down next_window
|
|||||||
cursor_trail 1
|
cursor_trail 1
|
||||||
cursor_shape beam
|
cursor_shape beam
|
||||||
|
|
||||||
remember_window_size no
|
# remember_window_size no
|
||||||
initial_window_width 1021
|
# initial_window_width 1021
|
||||||
|
|
||||||
include Catppuccin-Mocha.conf
|
include Catppuccin-Mocha.conf
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ cpu_load_color=39F900,FDFD09,FF0000
|
|||||||
|
|
||||||
### Display per process memory usage
|
### Display per process memory usage
|
||||||
## Show resident memory and other types, if enabled
|
## Show resident memory and other types, if enabled
|
||||||
procmem
|
# procmem
|
||||||
# procmem_shared
|
# procmem_shared
|
||||||
# procmem_virt
|
# procmem_virt
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
}
|
}
|
||||||
. "$HOME/.local/snippets/apply-color-helper"
|
. "$HOME/.local/snippets/apply-color-helper"
|
||||||
|
|
||||||
file="$path"/config.kdl
|
file="$path"/config/styles.kdl
|
||||||
|
|
||||||
sed -i -E "s/^(\s*active-color\s+\"#)([0-9A-Fa-f]{6})(\")/\1${colorHex}\3/" "$file" || {
|
sed -i -E "s/^(\s*active-color\s+\"#)([0-9A-Fa-f]{6})(\")/\1${colorHex}\3/g" "$file" || {
|
||||||
log_error "Failed to edit ${file}"
|
log_error "Failed to edit ${file}"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,455 +1,8 @@
|
|||||||
/************************Input************************/
|
include "config/input.kdl"
|
||||||
|
include "config/monitors.kdl"
|
||||||
input {
|
include "config/styles.kdl"
|
||||||
keyboard {
|
include "config/execs.kdl"
|
||||||
xkb {
|
include "config/envs.kdl"
|
||||||
layout "de"
|
include "config/rules.kdl"
|
||||||
}
|
include "config/binds.kdl"
|
||||||
|
include "config/misc.kdl"
|
||||||
numlock
|
|
||||||
}
|
|
||||||
|
|
||||||
touchpad {
|
|
||||||
tap
|
|
||||||
natural-scroll
|
|
||||||
scroll-method "two-finger"
|
|
||||||
}
|
|
||||||
|
|
||||||
mouse {
|
|
||||||
accel-speed 0.25
|
|
||||||
}
|
|
||||||
|
|
||||||
trackpoint {
|
|
||||||
off
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the mouse warp to the center of newly focused windows.
|
|
||||||
warp-mouse-to-focus
|
|
||||||
|
|
||||||
// Focus windows and outputs automatically when moving the mouse into them.
|
|
||||||
focus-follows-mouse max-scroll-amount="99%"
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************Output************************/
|
|
||||||
|
|
||||||
output "eDP-1" {
|
|
||||||
mode "2560x1600@240"
|
|
||||||
scale 1.25
|
|
||||||
background-color "#1e1e2e"
|
|
||||||
backdrop-color "#1e1e2e"
|
|
||||||
}
|
|
||||||
|
|
||||||
output "eDP-2" {
|
|
||||||
mode "2560x1600@240"
|
|
||||||
scale 1.25
|
|
||||||
background-color "#1e1e2e"
|
|
||||||
backdrop-color "#1e1e2e"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************Layout************************/
|
|
||||||
|
|
||||||
layout {
|
|
||||||
gaps 0
|
|
||||||
|
|
||||||
center-focused-column "never"
|
|
||||||
|
|
||||||
preset-column-widths {
|
|
||||||
proportion 0.3
|
|
||||||
proportion 0.5
|
|
||||||
proportion 0.7
|
|
||||||
}
|
|
||||||
|
|
||||||
preset-window-heights {
|
|
||||||
proportion 0.5
|
|
||||||
proportion 0.75
|
|
||||||
proportion 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
default-column-width { proportion 0.7; }
|
|
||||||
|
|
||||||
focus-ring {
|
|
||||||
width 2
|
|
||||||
active-color "#89b4fa"
|
|
||||||
inactive-color "#1e1e2e"
|
|
||||||
}
|
|
||||||
|
|
||||||
border {
|
|
||||||
off
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow {
|
|
||||||
on
|
|
||||||
|
|
||||||
softness 30
|
|
||||||
spread 5
|
|
||||||
offset x=0 y=5
|
|
||||||
color "#0007"
|
|
||||||
}
|
|
||||||
|
|
||||||
struts {
|
|
||||||
top 2
|
|
||||||
right 2
|
|
||||||
bottom 3
|
|
||||||
left 2
|
|
||||||
}
|
|
||||||
|
|
||||||
background-color "#1e1e2e"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the "Important Hotkeys" pop-up at startup.
|
|
||||||
hotkey-overlay {
|
|
||||||
skip-at-startup
|
|
||||||
}
|
|
||||||
|
|
||||||
prefer-no-csd
|
|
||||||
|
|
||||||
animations {
|
|
||||||
// off
|
|
||||||
// slowdown 3.0
|
|
||||||
}
|
|
||||||
|
|
||||||
layer-rule {
|
|
||||||
match namespace="^swww-daemonbackdrop$"
|
|
||||||
place-within-backdrop true
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************Autostart************************/
|
|
||||||
|
|
||||||
// Switch configs
|
|
||||||
spawn-sh-at-startup "config-switch niri"
|
|
||||||
|
|
||||||
// Wallpaper
|
|
||||||
spawn-at-startup "wallpaper-daemon"
|
|
||||||
|
|
||||||
// Not necessary maybe ...
|
|
||||||
spawn-at-startup "fcitx5"
|
|
||||||
|
|
||||||
// Core
|
|
||||||
spawn-at-startup "nm-applet"
|
|
||||||
spawn-sh-at-startup "gnome-keyring-daemon --start --components=secrets"
|
|
||||||
spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
|
|
||||||
|
|
||||||
// Clipboard history
|
|
||||||
spawn-sh-at-startup "wl-paste --type text --watch cliphist store"
|
|
||||||
spawn-sh-at-startup "wl-paste --type image --watch cliphist store"
|
|
||||||
|
|
||||||
// wlsunset
|
|
||||||
// spawn-at-startup "sunset"
|
|
||||||
|
|
||||||
// Logitech
|
|
||||||
spawn-sh-at-startup "solaar -w hide"
|
|
||||||
|
|
||||||
// Some other heavy apps
|
|
||||||
spawn-at-startup "sunshine"
|
|
||||||
// spawn-at-startup "spotify"
|
|
||||||
// spawn-at-startup "thunderbird"
|
|
||||||
|
|
||||||
// Idle
|
|
||||||
spawn-at-startup "hypridle"
|
|
||||||
|
|
||||||
// QuickShell
|
|
||||||
spawn-at-startup "quickshell"
|
|
||||||
|
|
||||||
/************************Envs************************/
|
|
||||||
|
|
||||||
environment {
|
|
||||||
// Input Method
|
|
||||||
QT_IM_MODULE "fcitx"
|
|
||||||
XMODIFIERS "@im=fcitx"
|
|
||||||
SDL_IM_MODULE "fcitx"
|
|
||||||
GLFW_IM_MODULE "ibus"
|
|
||||||
INPUT_METHOD "fcitx"
|
|
||||||
|
|
||||||
// Themes
|
|
||||||
QT_QPA_PLATFORM "wayland"
|
|
||||||
QT_QPA_PLATFORMTHEME "kde"
|
|
||||||
QT_STYLE_OVERRIDE "Kvantum"
|
|
||||||
|
|
||||||
// Nvidia
|
|
||||||
LIBVA_DRIVER_NAME "nvidia"
|
|
||||||
__GLX_VENDOR_LIBRARY_NAME "nvidia"
|
|
||||||
NVD_BACKEND "nvidia"
|
|
||||||
|
|
||||||
// Others
|
|
||||||
XCURSOR_SIZE "24"
|
|
||||||
ELECTRON_OZONE_PLATFORM_HINT "wayland"
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************Rules************************/
|
|
||||||
|
|
||||||
// Picture-in-Picture
|
|
||||||
window-rule {
|
|
||||||
match title="^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$"
|
|
||||||
open-floating true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dialog windows
|
|
||||||
window-rule {
|
|
||||||
match title="^(Open File)(.*)$"
|
|
||||||
match title="^(Select a File)(.*)$"
|
|
||||||
match title="^(Choose wallpaper)(.*)$"
|
|
||||||
match title="^(Open Folder)(.*)$"
|
|
||||||
match title="^(Save As)(.*)$"
|
|
||||||
match title="^(Library)(.*)$"
|
|
||||||
match title="^(File Upload)(.*)$"
|
|
||||||
open-floating true
|
|
||||||
}
|
|
||||||
|
|
||||||
// FLoating terminal
|
|
||||||
window-rule {
|
|
||||||
match app-id="com.mitchellh.ghostty"
|
|
||||||
open-floating true
|
|
||||||
default-column-width { proportion 0.5; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal terminal
|
|
||||||
// window-rule {
|
|
||||||
// match app-id="kitty"
|
|
||||||
// default-column-width { proportion 0.3; }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Scrcpy
|
|
||||||
window-rule {
|
|
||||||
match app-id="scrcpy"
|
|
||||||
default-column-width { proportion 0.3; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Editor
|
|
||||||
window-rule {
|
|
||||||
match app-id="org.gnome.TextEditor"
|
|
||||||
default-column-width { proportion 0.3; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other floating
|
|
||||||
window-rule {
|
|
||||||
match app-id="blueberry"
|
|
||||||
match app-id="blueman-manager"
|
|
||||||
match app-id="org.pulseaudio.pavucontrol"
|
|
||||||
match app-id="com.saivert.pwvucontrol"
|
|
||||||
match app-id="Waydroid"
|
|
||||||
match app-id="org.kde.kcalc"
|
|
||||||
match app-id="org.kde.kalk"
|
|
||||||
match app-id="org.gnome.NautilusPreviewer"
|
|
||||||
match app-id="coin"
|
|
||||||
match app-id="wallpaper-carousel"
|
|
||||||
match app-id="be.alexandervanhee.gradia"
|
|
||||||
match title="^(图片查看器)(.*)$" // QQ
|
|
||||||
open-floating true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block from recording
|
|
||||||
window-rule {
|
|
||||||
match app-id="thunderbird"
|
|
||||||
|
|
||||||
block-out-from "screen-capture"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// workspace "first"
|
|
||||||
// workspace "second"
|
|
||||||
|
|
||||||
// Startup in "second" workspace
|
|
||||||
window-rule {
|
|
||||||
// match at-startup=true app-id="Spotify"
|
|
||||||
// match at-startup=true app-id="thunderbird"
|
|
||||||
|
|
||||||
|
|
||||||
open-on-workspace "second"
|
|
||||||
}
|
|
||||||
|
|
||||||
window-rule {
|
|
||||||
match app-id="at.yrlf.wl_mirror"
|
|
||||||
|
|
||||||
// default-column-width { proportion 1.0; }
|
|
||||||
open-floating true
|
|
||||||
// open-maximized-to-edges true
|
|
||||||
// open-on-output "HDMI-A-1"
|
|
||||||
}
|
|
||||||
|
|
||||||
// I love round corners
|
|
||||||
window-rule {
|
|
||||||
geometry-corner-radius 14
|
|
||||||
clip-to-geometry true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************Others************************/
|
|
||||||
|
|
||||||
cursor {
|
|
||||||
xcursor-theme "Bibata-Modern-Ice"
|
|
||||||
xcursor-size 24
|
|
||||||
hide-when-typing
|
|
||||||
}
|
|
||||||
|
|
||||||
debug {
|
|
||||||
render-drm-device "/dev/dri/card0"
|
|
||||||
}
|
|
||||||
|
|
||||||
screenshot-path "~/Pictures/Screenshots/.niri_screenshot.png"
|
|
||||||
|
|
||||||
// gestures {
|
|
||||||
// hot-corners {
|
|
||||||
// off
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/************************Keybindings************************/
|
|
||||||
|
|
||||||
binds {
|
|
||||||
// Apps
|
|
||||||
Mod+C { spawn-sh "code --password-store=gnome-libsecret"; }
|
|
||||||
Mod+E { spawn-sh "dolphin --new-window"; }
|
|
||||||
Mod+W { spawn-sh "zen || zen-browser"; }
|
|
||||||
Mod+X { spawn "gnome-text-editor" "--new-window"; }
|
|
||||||
Mod+B { spawn-sh "pkill -x -n btop || ghostty -e btop"; }
|
|
||||||
Mod+T { spawn "kitty"; }
|
|
||||||
Mod+Return { spawn "kitty"; }
|
|
||||||
Mod+Shift+T { spawn "ghostty"; }
|
|
||||||
Mod+Shift+Return { spawn "ghostty"; }
|
|
||||||
Mod+Shift+W { spawn-sh "wallpaper-carousel"; }
|
|
||||||
Mod+O { spawn-sh "pkill -x -n pwvucontrol || pwvucontrol"; }
|
|
||||||
|
|
||||||
// Quickshell
|
|
||||||
Mod+Space { spawn-sh "qs ipc call panels toggleControlCenter"; }
|
|
||||||
Mod+Shift+D { spawn-sh "qs ipc call panels toggleCalendar"; }
|
|
||||||
Mod+Shift+L { spawn-sh "qs ipc call lyrics toggleBarLyrics"; }
|
|
||||||
Mod+Shift+K { spawn-sh "quickshell-kill || quickshell"; }
|
|
||||||
Mod+I { spawn-sh "qs ipc call idleInhibitor toggleInhibitor"; }
|
|
||||||
Mod+Alt+R { spawn-sh "qs ipc call recording startOrStopRecording"; }
|
|
||||||
Mod+Shift+E { spawn-sh "qs ipc call sunset toggleSunset"; }
|
|
||||||
|
|
||||||
// Rofi
|
|
||||||
Mod+D { spawn-sh "pkill -x rofi || rofi -show run"; }
|
|
||||||
Alt+Space { spawn-sh "pkill -x rofi || rofi -show drun"; }
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
Mod+V { spawn-sh "pkill -x rofi || rofi-cliphist"; }
|
|
||||||
Mod+Period { spawn-sh "pkill -x rofi || rofi-emoji"; }
|
|
||||||
Ctrl+Alt+Delete { spawn-sh "pkill -x wlogout || wlogout -p layer-shell"; }
|
|
||||||
Print { spawn-sh "screenshot-script full"; }
|
|
||||||
Mod+Shift+S { spawn-sh "screenshot-script area"; }
|
|
||||||
Mod+Ctrl+Shift+S { spawn-sh "screenshot-script window"; }
|
|
||||||
Mod+Shift+C { spawn-sh "hyprpicker -a"; }
|
|
||||||
|
|
||||||
// Session
|
|
||||||
Mod+L { spawn-sh "loginctl lock-session"; }
|
|
||||||
|
|
||||||
// Media
|
|
||||||
XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"; }
|
|
||||||
XF86AudioLowerVolume allow-when-locked=true { spawn-sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%-"; }
|
|
||||||
XF86AudioMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; }
|
|
||||||
XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; }
|
|
||||||
XF86AudioPlay allow-when-locked=true { spawn-sh "playerctl play-pause"; }
|
|
||||||
XF86AudioPause allow-when-locked=true { spawn-sh "playerctl play-pause"; }
|
|
||||||
XF86AudioNext allow-when-locked=true { spawn-sh "playerctl next"; }
|
|
||||||
XF86AudioPrev allow-when-locked=true { spawn-sh "playerctl previous"; }
|
|
||||||
|
|
||||||
// Brightness
|
|
||||||
XF86MonBrightnessUp allow-when-locked=true { spawn "set-brightness" "+10%"; }
|
|
||||||
XF86MonBrightnessDown allow-when-locked=true { spawn "set-brightness" "10%-"; }
|
|
||||||
|
|
||||||
// Window management
|
|
||||||
Mod+Tab repeat=false { toggle-overview; }
|
|
||||||
|
|
||||||
Mod+Q repeat=false { close-window; }
|
|
||||||
|
|
||||||
Mod+Left { focus-column-left; }
|
|
||||||
Mod+Down { focus-window-or-workspace-down; }
|
|
||||||
Mod+Up { focus-window-or-workspace-up; }
|
|
||||||
Mod+Right { focus-column-right; }
|
|
||||||
|
|
||||||
Mod+Shift+Left { move-column-left; }
|
|
||||||
Mod+Shift+Down { move-window-down-or-to-workspace-down; }
|
|
||||||
Mod+Shift+Up { move-window-up-or-to-workspace-up; }
|
|
||||||
Mod+Shift+Right { move-column-right; }
|
|
||||||
|
|
||||||
Mod+Home { focus-column-first; }
|
|
||||||
Mod+End { focus-column-last; }
|
|
||||||
Mod+Shift+Home { move-column-to-first; }
|
|
||||||
Mod+Shift+End { move-column-to-last; }
|
|
||||||
|
|
||||||
Mod+Ctrl+Left { focus-monitor-left; }
|
|
||||||
Mod+Ctrl+Down { focus-monitor-down; }
|
|
||||||
Mod+Ctrl+Up { focus-monitor-up; }
|
|
||||||
Mod+Ctrl+Right { focus-monitor-right; }
|
|
||||||
|
|
||||||
Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
|
|
||||||
Mod+Shift+Ctrl+Down { move-window-to-monitor-down; }
|
|
||||||
Mod+Shift+Ctrl+Up { move-window-to-monitor-up; }
|
|
||||||
Mod+Shift+Ctrl+Right { move-window-to-monitor-right; }
|
|
||||||
|
|
||||||
Mod+Page_Down { focus-workspace-down; }
|
|
||||||
Mod+Page_Up { focus-workspace-up; }
|
|
||||||
Mod+Shift+Page_Down { move-window-to-workspace-down; }
|
|
||||||
Mod+Shift+Page_Up { move-window-to-workspace-up; }
|
|
||||||
|
|
||||||
Mod+Ctrl+Shift+Page_Down { move-workspace-down; }
|
|
||||||
Mod+Ctrl+Shift+Page_Up { move-workspace-up; }
|
|
||||||
|
|
||||||
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
|
||||||
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
|
||||||
Mod+Shift+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
|
||||||
Mod+Shift+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
|
||||||
|
|
||||||
Mod+WheelScrollRight cooldown-ms=150 { focus-column-right; }
|
|
||||||
Mod+WheelScrollLeft cooldown-ms=150 { focus-column-left; }
|
|
||||||
Mod+Shift+WheelScrollRight { move-column-right; }
|
|
||||||
Mod+Shift+WheelScrollLeft { move-column-left; }
|
|
||||||
|
|
||||||
Mod+1 { focus-workspace 1; }
|
|
||||||
Mod+2 { focus-workspace 2; }
|
|
||||||
Mod+3 { focus-workspace 3; }
|
|
||||||
Mod+4 { focus-workspace 4; }
|
|
||||||
Mod+5 { focus-workspace 5; }
|
|
||||||
Mod+6 { focus-workspace 6; }
|
|
||||||
Mod+7 { focus-workspace 7; }
|
|
||||||
Mod+8 { focus-workspace 8; }
|
|
||||||
Mod+9 { focus-workspace 9; }
|
|
||||||
Mod+Alt+1 { move-window-to-workspace 1; }
|
|
||||||
Mod+Alt+2 { move-window-to-workspace 2; }
|
|
||||||
Mod+Alt+3 { move-window-to-workspace 3; }
|
|
||||||
Mod+Alt+4 { move-window-to-workspace 4; }
|
|
||||||
Mod+Alt+5 { move-window-to-workspace 5; }
|
|
||||||
Mod+Alt+6 { move-window-to-workspace 6; }
|
|
||||||
Mod+Alt+7 { move-window-to-workspace 7; }
|
|
||||||
Mod+Alt+8 { move-window-to-workspace 8; }
|
|
||||||
Mod+Alt+9 { move-window-to-workspace 9; }
|
|
||||||
|
|
||||||
Mod+Alt+Left { consume-or-expel-window-left; }
|
|
||||||
Mod+Alt+Right { consume-or-expel-window-right; }
|
|
||||||
|
|
||||||
Mod+Shift+Comma { consume-window-into-column; }
|
|
||||||
Mod+Shift+Period { expel-window-from-column; }
|
|
||||||
Mod+Shift+M { toggle-column-tabbed-display; }
|
|
||||||
|
|
||||||
Mod+R { switch-preset-column-width; }
|
|
||||||
Mod+Shift+R { switch-preset-window-height; }
|
|
||||||
Mod+Ctrl+R { reset-window-height; }
|
|
||||||
Mod+F { maximize-column; }
|
|
||||||
Mod+Shift+F { fullscreen-window; }
|
|
||||||
Mod+Ctrl+F { expand-column-to-available-width; }
|
|
||||||
|
|
||||||
Mod+Y { center-column; }
|
|
||||||
|
|
||||||
Mod+Minus { set-column-width "-10%"; }
|
|
||||||
Mod+Plus { set-column-width "+10%"; }
|
|
||||||
|
|
||||||
Mod+Shift+Minus { set-window-height "-10%"; }
|
|
||||||
Mod+Shift+Plus { set-window-height "+10%"; }
|
|
||||||
|
|
||||||
Mod+Alt+Space { toggle-window-floating; }
|
|
||||||
Alt+Tab { switch-focus-between-floating-and-tiling; }
|
|
||||||
|
|
||||||
Mod+Ctrl+W { toggle-column-tabbed-display; }
|
|
||||||
|
|
||||||
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
|
||||||
|
|
||||||
Mod+M allow-inhibiting=false { quit; }
|
|
||||||
|
|
||||||
Mod+Shift+P { spawn-sh "(hyprlock &) && niri msg action power-off-monitors"; }
|
|
||||||
|
|
||||||
Mod+P repeat=false { spawn-sh "wl-mirror $(niri msg --json focused-output | jq -r .name)"; }
|
|
||||||
}
|
|
||||||
|
|||||||
164
config/niri/.config/niri/config/binds.kdl
Normal file
164
config/niri/.config/niri/config/binds.kdl
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
recent-windows {
|
||||||
|
binds {
|
||||||
|
Alt+Tab { next-window; }
|
||||||
|
Alt+Shift+Tab { previous-window; }
|
||||||
|
// dead_circumflex: ^
|
||||||
|
Alt+dead_circumflex { next-window filter="app-id"; }
|
||||||
|
Alt+Shift+dead_circumflex { previous-window filter="app-id"; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binds {
|
||||||
|
// Apps
|
||||||
|
Mod+C { spawn "code"; }
|
||||||
|
Mod+E { spawn "dolphin" "--new-window"; }
|
||||||
|
Mod+W { spawn-sh "zen || zen-browser"; }
|
||||||
|
Mod+X { spawn "gnome-text-editor" "--new-window"; }
|
||||||
|
Mod+B { spawn-sh "pkill -x -n btop || kitty -e btop"; }
|
||||||
|
Mod+T { spawn "ghostty" "+new-window"; }
|
||||||
|
Mod+Return { spawn "ghostty" "+new-window"; }
|
||||||
|
Mod+Shift+T { spawn "kitty"; }
|
||||||
|
Mod+Shift+Return { spawn "kitty"; }
|
||||||
|
Mod+Shift+W { spawn "wallpaper-carousel"; }
|
||||||
|
Mod+O { spawn-sh "pkill -x -n pwvucontrol || pwvucontrol"; }
|
||||||
|
|
||||||
|
// Quickshell
|
||||||
|
Mod+Space { spawn "qs" "ipc" "call" "panels" "toggleControlCenter"; }
|
||||||
|
Mod+Shift+D { spawn "qs" "ipc" "call" "panels" "toggleCalendar"; }
|
||||||
|
Mod+Shift+L { spawn "qs" "ipc" "call" "lyrics" "toggleBarLyrics"; }
|
||||||
|
Mod+Shift+K { spawn-sh "quickshell-kill || quickshell"; }
|
||||||
|
Mod+I { spawn "qs" "ipc" "call" "idleInhibitor" "toggleInhibitor"; }
|
||||||
|
Mod+Alt+R { spawn "qs" "ipc" "call" "recording" "startOrStopRecording"; }
|
||||||
|
Mod+Shift+E { spawn "qs" "ipc" "call" "sunset" "toggleSunset"; }
|
||||||
|
|
||||||
|
// Rofi
|
||||||
|
Mod+D { spawn-sh "pkill -x rofi || rofi -show run"; }
|
||||||
|
Alt+Space { spawn-sh "pkill -x rofi || rofi -show drun"; }
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
Mod+V { spawn-sh "pkill -x rofi || rofi-cliphist"; }
|
||||||
|
Mod+Period { spawn-sh "pkill -x rofi || rofi-emoji"; }
|
||||||
|
Ctrl+Alt+Delete { spawn-sh "pkill -x wlogout || wlogout -p layer-shell"; }
|
||||||
|
Print { spawn "niri" "msg" "action" "screenshot-screen"; }
|
||||||
|
Mod+Shift+S { spawn "niri" "msg" "action" "screenshot"; }
|
||||||
|
Mod+Ctrl+Shift+S { spawn "niri" "msg" "action" "screenshot-window"; }
|
||||||
|
Mod+Shift+C { spawn "hyprpicker" "-a"; }
|
||||||
|
|
||||||
|
// Session
|
||||||
|
Mod+L { spawn "loginctl" "lock-session"; }
|
||||||
|
|
||||||
|
// Media
|
||||||
|
XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"; }
|
||||||
|
XF86AudioLowerVolume allow-when-locked=true { spawn-sh "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%-"; }
|
||||||
|
XF86AudioMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; }
|
||||||
|
XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; }
|
||||||
|
XF86AudioPlay allow-when-locked=true { spawn-sh "playerctl play-pause"; }
|
||||||
|
XF86AudioPause allow-when-locked=true { spawn-sh "playerctl play-pause"; }
|
||||||
|
XF86AudioNext allow-when-locked=true { spawn-sh "playerctl next"; }
|
||||||
|
XF86AudioPrev allow-when-locked=true { spawn-sh "playerctl previous"; }
|
||||||
|
|
||||||
|
// Brightness
|
||||||
|
XF86MonBrightnessUp allow-when-locked=true { spawn "set-brightness" "+10%"; }
|
||||||
|
XF86MonBrightnessDown allow-when-locked=true { spawn "set-brightness" "10%-"; }
|
||||||
|
|
||||||
|
// Window management
|
||||||
|
Mod+Tab repeat=false { toggle-overview; }
|
||||||
|
|
||||||
|
Mod+Q repeat=false { close-window; }
|
||||||
|
|
||||||
|
Mod+Left { focus-column-left; }
|
||||||
|
Mod+Down { focus-window-or-workspace-down; }
|
||||||
|
Mod+Up { focus-window-or-workspace-up; }
|
||||||
|
Mod+Right { focus-column-right; }
|
||||||
|
|
||||||
|
Mod+Shift+Left { move-column-left; }
|
||||||
|
Mod+Shift+Down { move-window-down-or-to-workspace-down; }
|
||||||
|
Mod+Shift+Up { move-window-up-or-to-workspace-up; }
|
||||||
|
Mod+Shift+Right { move-column-right; }
|
||||||
|
|
||||||
|
Mod+Home { focus-column-first; }
|
||||||
|
Mod+End { focus-column-last; }
|
||||||
|
Mod+Shift+Home { move-column-to-first; }
|
||||||
|
Mod+Shift+End { move-column-to-last; }
|
||||||
|
|
||||||
|
Mod+Ctrl+Left { focus-monitor-left; }
|
||||||
|
Mod+Ctrl+Down { focus-monitor-down; }
|
||||||
|
Mod+Ctrl+Up { focus-monitor-up; }
|
||||||
|
Mod+Ctrl+Right { focus-monitor-right; }
|
||||||
|
|
||||||
|
Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
|
||||||
|
Mod+Shift+Ctrl+Down { move-window-to-monitor-down; }
|
||||||
|
Mod+Shift+Ctrl+Up { move-window-to-monitor-up; }
|
||||||
|
Mod+Shift+Ctrl+Right { move-window-to-monitor-right; }
|
||||||
|
|
||||||
|
Mod+Page_Down { focus-workspace-down; }
|
||||||
|
Mod+Page_Up { focus-workspace-up; }
|
||||||
|
Mod+Shift+Page_Down { move-window-to-workspace-down; }
|
||||||
|
Mod+Shift+Page_Up { move-window-to-workspace-up; }
|
||||||
|
|
||||||
|
Mod+Ctrl+Shift+Page_Down { move-workspace-down; }
|
||||||
|
Mod+Ctrl+Shift+Page_Up { move-workspace-up; }
|
||||||
|
|
||||||
|
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
||||||
|
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
||||||
|
Mod+Shift+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
||||||
|
Mod+Shift+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
||||||
|
|
||||||
|
Mod+WheelScrollRight cooldown-ms=150 { focus-column-right; }
|
||||||
|
Mod+WheelScrollLeft cooldown-ms=150 { focus-column-left; }
|
||||||
|
Mod+Shift+WheelScrollRight { move-column-right; }
|
||||||
|
Mod+Shift+WheelScrollLeft { move-column-left; }
|
||||||
|
|
||||||
|
Mod+1 { focus-workspace 1; }
|
||||||
|
Mod+2 { focus-workspace 2; }
|
||||||
|
Mod+3 { focus-workspace 3; }
|
||||||
|
Mod+4 { focus-workspace 4; }
|
||||||
|
Mod+5 { focus-workspace 5; }
|
||||||
|
Mod+6 { focus-workspace 6; }
|
||||||
|
Mod+7 { focus-workspace 7; }
|
||||||
|
Mod+8 { focus-workspace 8; }
|
||||||
|
Mod+9 { focus-workspace 9; }
|
||||||
|
Mod+Alt+1 { move-window-to-workspace 1; }
|
||||||
|
Mod+Alt+2 { move-window-to-workspace 2; }
|
||||||
|
Mod+Alt+3 { move-window-to-workspace 3; }
|
||||||
|
Mod+Alt+4 { move-window-to-workspace 4; }
|
||||||
|
Mod+Alt+5 { move-window-to-workspace 5; }
|
||||||
|
Mod+Alt+6 { move-window-to-workspace 6; }
|
||||||
|
Mod+Alt+7 { move-window-to-workspace 7; }
|
||||||
|
Mod+Alt+8 { move-window-to-workspace 8; }
|
||||||
|
Mod+Alt+9 { move-window-to-workspace 9; }
|
||||||
|
|
||||||
|
Mod+Alt+Left { consume-or-expel-window-left; }
|
||||||
|
Mod+Alt+Right { consume-or-expel-window-right; }
|
||||||
|
|
||||||
|
Mod+Shift+Comma { consume-window-into-column; }
|
||||||
|
Mod+Shift+Period { expel-window-from-column; }
|
||||||
|
Mod+Shift+M { toggle-column-tabbed-display; }
|
||||||
|
|
||||||
|
Mod+R { switch-preset-column-width; }
|
||||||
|
Mod+Shift+R { switch-preset-window-height; }
|
||||||
|
Mod+Ctrl+R { reset-window-height; }
|
||||||
|
Mod+F { maximize-column; }
|
||||||
|
Mod+Shift+F { fullscreen-window; }
|
||||||
|
Mod+Ctrl+F { expand-column-to-available-width; }
|
||||||
|
Mod+M { maximize-window-to-edges; }
|
||||||
|
|
||||||
|
Mod+Y { center-column; }
|
||||||
|
|
||||||
|
Mod+Minus { set-column-width "-10%"; }
|
||||||
|
Mod+Plus { set-column-width "+10%"; }
|
||||||
|
|
||||||
|
Mod+Shift+Minus { set-window-height "-10%"; }
|
||||||
|
Mod+Shift+Plus { set-window-height "+10%"; }
|
||||||
|
|
||||||
|
Mod+Alt+Space { toggle-window-floating; }
|
||||||
|
// Alt+Tab { switch-focus-between-floating-and-tiling; }
|
||||||
|
|
||||||
|
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
||||||
|
|
||||||
|
Mod+Shift+Q allow-inhibiting=false { quit; }
|
||||||
|
|
||||||
|
Mod+Shift+P { spawn-sh "(hyprlock &) && niri msg action power-off-monitors"; }
|
||||||
|
|
||||||
|
Mod+P repeat=false { spawn-sh "wl-mirror $(niri msg --json focused-output | jq -r .name)"; }
|
||||||
|
}
|
||||||
22
config/niri/.config/niri/config/envs.kdl
Normal file
22
config/niri/.config/niri/config/envs.kdl
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
environment {
|
||||||
|
// Input Method
|
||||||
|
QT_IM_MODULE "fcitx"
|
||||||
|
XMODIFIERS "@im=fcitx"
|
||||||
|
SDL_IM_MODULE "fcitx"
|
||||||
|
GLFW_IM_MODULE "ibus"
|
||||||
|
INPUT_METHOD "fcitx"
|
||||||
|
|
||||||
|
// Themes
|
||||||
|
QT_QPA_PLATFORM "wayland"
|
||||||
|
QT_QPA_PLATFORMTHEME "kde"
|
||||||
|
QT_STYLE_OVERRIDE "Kvantum"
|
||||||
|
|
||||||
|
// Nvidia
|
||||||
|
LIBVA_DRIVER_NAME "nvidia"
|
||||||
|
__GLX_VENDOR_LIBRARY_NAME "nvidia"
|
||||||
|
NVD_BACKEND "nvidia"
|
||||||
|
|
||||||
|
// Others
|
||||||
|
XCURSOR_SIZE "24"
|
||||||
|
ELECTRON_OZONE_PLATFORM_HINT "wayland"
|
||||||
|
}
|
||||||
39
config/niri/.config/niri/config/execs.kdl
Normal file
39
config/niri/.config/niri/config/execs.kdl
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Switch configs
|
||||||
|
spawn-at-startup "config-switch" "niri"
|
||||||
|
|
||||||
|
// Wallpaper
|
||||||
|
spawn-at-startup "wallpaper-daemon"
|
||||||
|
|
||||||
|
// Not necessary maybe ...
|
||||||
|
spawn-at-startup "fcitx5"
|
||||||
|
|
||||||
|
// Core
|
||||||
|
spawn-at-startup "nm-applet"
|
||||||
|
spawn-at-startup "gnome-keyring-daemon" "--start" "--components=secrets"
|
||||||
|
spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1"
|
||||||
|
|
||||||
|
// Clipboard history
|
||||||
|
spawn-at-startup "wl-paste" "--type" "text" "--watch" "cliphist" "store"
|
||||||
|
spawn-at-startup "wl-paste" "--type" "image" "--watch" "cliphist" "store"
|
||||||
|
|
||||||
|
// wlsunset
|
||||||
|
// spawn-at-startup "sunset"
|
||||||
|
|
||||||
|
// Logitech
|
||||||
|
spawn-at-startup "solaar" "-w" "hide"
|
||||||
|
|
||||||
|
// Some other heavy apps
|
||||||
|
spawn-at-startup "sunshine"
|
||||||
|
// spawn-at-startup "spotify"
|
||||||
|
// spawn-at-startup "thunderbird"
|
||||||
|
|
||||||
|
// Idle
|
||||||
|
spawn-at-startup "hypridle"
|
||||||
|
|
||||||
|
// QuickShell
|
||||||
|
spawn-at-startup "quickshell"
|
||||||
|
|
||||||
|
// According to (https://ghostty.org/docs/linux/systemd#starting-ghostty-at-login)
|
||||||
|
spawn-sh-at-startup "systemctl start --user app-com.mitchellh.ghostty.service"
|
||||||
|
// No, do not do this, otherwise the envs defined in envs.kdl won't be applied to ghostty.
|
||||||
|
// Unless you have something like "config/shell/.config/fish/prev.d/niri-env.fish"
|
||||||
29
config/niri/.config/niri/config/input.kdl
Normal file
29
config/niri/.config/niri/config/input.kdl
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
input {
|
||||||
|
keyboard {
|
||||||
|
xkb {
|
||||||
|
layout "de"
|
||||||
|
}
|
||||||
|
|
||||||
|
numlock
|
||||||
|
}
|
||||||
|
|
||||||
|
touchpad {
|
||||||
|
tap
|
||||||
|
natural-scroll
|
||||||
|
scroll-method "two-finger"
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse {
|
||||||
|
accel-speed 0.25
|
||||||
|
}
|
||||||
|
|
||||||
|
trackpoint {
|
||||||
|
off
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the mouse warp to the center of newly focused windows.
|
||||||
|
warp-mouse-to-focus
|
||||||
|
|
||||||
|
// Focus windows and outputs automatically when moving the mouse into them.
|
||||||
|
focus-follows-mouse max-scroll-amount="100%"
|
||||||
|
}
|
||||||
11
config/niri/.config/niri/config/misc.kdl
Normal file
11
config/niri/.config/niri/config/misc.kdl
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
screenshot-path "~/Pictures/Screenshots/niri_screenshot_%Y-%m-%d_%H-%M-%S.png"
|
||||||
|
|
||||||
|
debug {
|
||||||
|
render-drm-device "/dev/dri/card0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// gestures {
|
||||||
|
// hot-corners {
|
||||||
|
// off
|
||||||
|
// }
|
||||||
|
// }
|
||||||
22
config/niri/.config/niri/config/monitors.kdl
Normal file
22
config/niri/.config/niri/config/monitors.kdl
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
output "eDP-1" {
|
||||||
|
// off
|
||||||
|
mode "2560x1600@60.002"
|
||||||
|
scale 1.25
|
||||||
|
background-color "#1e1e2e"
|
||||||
|
backdrop-color "#1e1e2e"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "eDP-2" {
|
||||||
|
mode "2560x1600@60.002"
|
||||||
|
scale 1.25
|
||||||
|
background-color "#1e1e2e"
|
||||||
|
backdrop-color "#1e1e2e"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "DP-1" {
|
||||||
|
mode "2560x1440@179.845"
|
||||||
|
scale 1.0
|
||||||
|
background-color "#1e1e2e"
|
||||||
|
backdrop-color "#1e1e2e"
|
||||||
|
// transform "90"
|
||||||
|
}
|
||||||
89
config/niri/.config/niri/config/rules.kdl
Normal file
89
config/niri/.config/niri/config/rules.kdl
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
// Picture-in-Picture
|
||||||
|
window-rule {
|
||||||
|
match title="^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$"
|
||||||
|
open-floating true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialog windows
|
||||||
|
window-rule {
|
||||||
|
match title="^(Open File)(.*)$"
|
||||||
|
match title="^(Select a File)(.*)$"
|
||||||
|
match title="^(Choose wallpaper)(.*)$"
|
||||||
|
match title="^(Open Folder)(.*)$"
|
||||||
|
match title="^(Save As)(.*)$"
|
||||||
|
match title="^(Library)(.*)$"
|
||||||
|
match title="^(File Upload)(.*)$"
|
||||||
|
open-floating true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FLoating terminal
|
||||||
|
window-rule {
|
||||||
|
match app-id="kitty"
|
||||||
|
open-floating true
|
||||||
|
default-column-width { proportion 0.5; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal terminal
|
||||||
|
window-rule {
|
||||||
|
match app-id="com.mitchellh.ghostty"
|
||||||
|
default-column-width { proportion 0.3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scrcpy
|
||||||
|
window-rule {
|
||||||
|
match app-id="scrcpy"
|
||||||
|
default-column-width { proportion 0.3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editor
|
||||||
|
window-rule {
|
||||||
|
match app-id="org.gnome.TextEditor"
|
||||||
|
default-column-width { proportion 0.3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other floating
|
||||||
|
window-rule {
|
||||||
|
match app-id="blueberry"
|
||||||
|
match app-id="blueman-manager"
|
||||||
|
match app-id="org.pulseaudio.pavucontrol"
|
||||||
|
match app-id="com.saivert.pwvucontrol"
|
||||||
|
match app-id="Waydroid"
|
||||||
|
match app-id="^waydroid"
|
||||||
|
match app-id="org.kde.kcalc"
|
||||||
|
match app-id="org.kde.kalk"
|
||||||
|
match app-id="org.gnome.NautilusPreviewer"
|
||||||
|
match app-id="coin"
|
||||||
|
match app-id="wallpaper-carousel"
|
||||||
|
match app-id="be.alexandervanhee.gradia"
|
||||||
|
match title="^(图片查看器)(.*)$" // QQ
|
||||||
|
open-floating true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block from recording
|
||||||
|
window-rule {
|
||||||
|
match app-id="thunderbird"
|
||||||
|
|
||||||
|
block-out-from "screen-capture"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// workspace "first"
|
||||||
|
// workspace "second"
|
||||||
|
|
||||||
|
// Startup in "second" workspace
|
||||||
|
window-rule {
|
||||||
|
// match at-startup=true app-id="Spotify"
|
||||||
|
// match at-startup=true app-id="thunderbird"
|
||||||
|
|
||||||
|
|
||||||
|
open-on-workspace "second"
|
||||||
|
}
|
||||||
|
|
||||||
|
window-rule {
|
||||||
|
match app-id="at.yrlf.wl_mirror"
|
||||||
|
|
||||||
|
// default-column-width { proportion 1.0; }
|
||||||
|
open-floating true
|
||||||
|
// open-maximized-to-edges true
|
||||||
|
// open-on-output "HDMI-A-1"
|
||||||
|
}
|
||||||
86
config/niri/.config/niri/config/styles.kdl
Normal file
86
config/niri/.config/niri/config/styles.kdl
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
layout {
|
||||||
|
gaps 0
|
||||||
|
|
||||||
|
center-focused-column "never"
|
||||||
|
|
||||||
|
preset-column-widths {
|
||||||
|
proportion 0.3
|
||||||
|
proportion 0.5
|
||||||
|
proportion 0.7
|
||||||
|
}
|
||||||
|
|
||||||
|
preset-window-heights {
|
||||||
|
proportion 0.5
|
||||||
|
proportion 0.75
|
||||||
|
proportion 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
default-column-width { proportion 0.7; }
|
||||||
|
|
||||||
|
focus-ring {
|
||||||
|
width 2
|
||||||
|
active-color "#89b4fa"
|
||||||
|
inactive-color "#1e1e2e"
|
||||||
|
}
|
||||||
|
|
||||||
|
border {
|
||||||
|
off
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow {
|
||||||
|
on
|
||||||
|
|
||||||
|
softness 30
|
||||||
|
spread 5
|
||||||
|
offset x=0 y=5
|
||||||
|
color "#0007"
|
||||||
|
}
|
||||||
|
|
||||||
|
struts {
|
||||||
|
top 2
|
||||||
|
right 2
|
||||||
|
bottom 3
|
||||||
|
left 2
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color "#1e1e2e"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Disable the "Important Hotkeys" pop-up at startup.
|
||||||
|
hotkey-overlay {
|
||||||
|
skip-at-startup
|
||||||
|
}
|
||||||
|
|
||||||
|
prefer-no-csd
|
||||||
|
|
||||||
|
animations {
|
||||||
|
// off
|
||||||
|
// slowdown 3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
layer-rule {
|
||||||
|
match namespace="^swww-daemonbackdrop$"
|
||||||
|
place-within-backdrop true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor {
|
||||||
|
xcursor-theme "Bibata-Modern-Ice"
|
||||||
|
xcursor-size 24
|
||||||
|
hide-when-typing
|
||||||
|
}
|
||||||
|
|
||||||
|
// I love round corners
|
||||||
|
window-rule {
|
||||||
|
geometry-corner-radius 14
|
||||||
|
clip-to-geometry true
|
||||||
|
}
|
||||||
|
|
||||||
|
recent-windows {
|
||||||
|
highlight {
|
||||||
|
active-color "#89b4fa"
|
||||||
|
urgent-color "#f38ba8"
|
||||||
|
corner-radius 14
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -131,7 +131,6 @@ Variants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CavaBar {
|
CavaBar {
|
||||||
count: 6
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|||||||
@@ -2,27 +2,17 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import qs.Constants
|
import qs.Constants
|
||||||
import qs.Services
|
import qs.Modules.Bar.Misc
|
||||||
import qs.Utils
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property int count: 6
|
|
||||||
property int barWidth: 5
|
property int barWidth: 5
|
||||||
property int barSpacing: 3
|
property int barSpacing: 3
|
||||||
property bool forceEnable: false
|
|
||||||
|
|
||||||
implicitWidth: root.barWidth * root.count + root.barSpacing * (root.count - 1)
|
implicitWidth: root.barWidth * CavaBarService.count + root.barSpacing * (CavaBarService.count - 1)
|
||||||
implicitHeight: parent.height - 10
|
implicitHeight: parent.height - 10
|
||||||
|
|
||||||
Cava {
|
|
||||||
id: cavaProcess
|
|
||||||
|
|
||||||
count: root.count
|
|
||||||
forceEnable: root.forceEnable
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
spacing: root.barSpacing
|
spacing: root.barSpacing
|
||||||
@@ -32,7 +22,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: cavaProcess.values
|
model: CavaBarService.values
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: root.barWidth
|
width: root.barWidth
|
||||||
@@ -64,7 +54,7 @@ Item {
|
|||||||
else if (mouse.button === Qt.RightButton)
|
else if (mouse.button === Qt.RightButton)
|
||||||
SettingsService.showLyricsBar = !SettingsService.showLyricsBar;
|
SettingsService.showLyricsBar = !SettingsService.showLyricsBar;
|
||||||
else if (mouse.button === Qt.MiddleButton)
|
else if (mouse.button === Qt.MiddleButton)
|
||||||
root.forceEnable = !root.forceEnable;
|
CavaBarService.forceEnable = !CavaBarService.forceEnable;
|
||||||
}
|
}
|
||||||
onWheel: function(wheel) {
|
onWheel: function(wheel) {
|
||||||
if (wheel.angleDelta.y > 0)
|
if (wheel.angleDelta.y > 0)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ MonitorItem {
|
|||||||
action.signal(15);
|
action.signal(15);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
action.exec(["ghostty", "-e", "btop"]);
|
action.exec(["kitty", "-e", "btop"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ MonitorItem {
|
|||||||
action.signal(15);
|
action.signal(15);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
action.exec(["ghostty", "-e", "btop"]);
|
action.exec(["kitty", "-e", "btop"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ MonitorItem {
|
|||||||
action.signal(15);
|
action.signal(15);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
action.exec(["ghostty", "-e", "btop"]);
|
action.exec(["kitty", "-e", "btop"]);
|
||||||
}
|
}
|
||||||
onRightClicked: {
|
onRightClicked: {
|
||||||
_showPercent = !_showPercent;
|
_showPercent = !_showPercent;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ Item {
|
|||||||
return Colors.primary;
|
return Colors.primary;
|
||||||
|
|
||||||
if (model.isActive)
|
if (model.isActive)
|
||||||
return Colors.primary.lighter(130);
|
return Colors.overlay2;
|
||||||
|
|
||||||
if (model.isUrgent)
|
if (model.isUrgent)
|
||||||
return Theme.error;
|
return Theme.error;
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import qs.Utils
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int count: 6
|
||||||
|
property int forceEnable: 6
|
||||||
|
property alias values: cavaProcess.values
|
||||||
|
|
||||||
|
Cava {
|
||||||
|
id: cavaProcess
|
||||||
|
|
||||||
|
count: root.count
|
||||||
|
forceEnable: root.forceEnable
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -67,7 +67,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showLyricsText() {
|
function showLyricsText() {
|
||||||
action.command = ["sh", "-c", "ghostty -e sh -c 'spotify-lyrics fetch | less'"];
|
action.command = ["sh", "-c", "ghostty -e sh -c 'spotify-lyrics fetch 2>/dev/null | less'"];
|
||||||
action.startDetached();
|
action.startDetached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Singleton {
|
|||||||
property bool inOverview: false
|
property bool inOverview: false
|
||||||
property string focusedWindowTitle: ""
|
property string focusedWindowTitle: ""
|
||||||
property string focusedWindowAppId: ""
|
property string focusedWindowAppId: ""
|
||||||
|
property var onScreenshotCaptured: null
|
||||||
|
|
||||||
function updateFocusedWindowTitle() {
|
function updateFocusedWindowTitle() {
|
||||||
if (windows && windows[focusedWindowId]) {
|
if (windows && windows[focusedWindowId]) {
|
||||||
@@ -84,7 +85,8 @@ Singleton {
|
|||||||
const event = JSON.parse(data.trim());
|
const event = JSON.parse(data.trim());
|
||||||
if (event.WorkspacesChanged) {
|
if (event.WorkspacesChanged) {
|
||||||
workspaceProcess.running = true;
|
workspaceProcess.running = true;
|
||||||
} else if (event.WindowsChanged) {
|
}
|
||||||
|
if (event.WindowsChanged) {
|
||||||
try {
|
try {
|
||||||
const windowsData = event.WindowsChanged.windows;
|
const windowsData = event.WindowsChanged.windows;
|
||||||
const windowsMap = {};
|
const windowsMap = {};
|
||||||
@@ -104,9 +106,11 @@ Singleton {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error("Niri", "Error parsing windows event:", e);
|
Logger.error("Niri", "Error parsing windows event:", e);
|
||||||
}
|
}
|
||||||
} else if (event.WorkspaceActivated) {
|
}
|
||||||
|
if (event.WorkspaceActivated) {
|
||||||
workspaceProcess.running = true;
|
workspaceProcess.running = true;
|
||||||
} else if (event.WindowFocusChanged) {
|
}
|
||||||
|
if (event.WindowFocusChanged) {
|
||||||
try {
|
try {
|
||||||
const focusedId = event.WindowFocusChanged.id;
|
const focusedId = event.WindowFocusChanged.id;
|
||||||
if (focusedId) {
|
if (focusedId) {
|
||||||
@@ -123,13 +127,15 @@ Singleton {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error("Niri", "Error parsing window focus event:", e);
|
Logger.error("Niri", "Error parsing window focus event:", e);
|
||||||
}
|
}
|
||||||
} else if (event.OverviewOpenedOrClosed) {
|
}
|
||||||
|
if (event.OverviewOpenedOrClosed) {
|
||||||
try {
|
try {
|
||||||
root.inOverview = event.OverviewOpenedOrClosed.is_open === true;
|
root.inOverview = event.OverviewOpenedOrClosed.is_open === true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error("Niri", "Error parsing overview state:", e);
|
Logger.error("Niri", "Error parsing overview state:", e);
|
||||||
}
|
}
|
||||||
} else if (event.WindowOpenedOrChanged) {
|
}
|
||||||
|
if (event.WindowOpenedOrChanged) {
|
||||||
try {
|
try {
|
||||||
const targetWin = event.WindowOpenedOrChanged.window;
|
const targetWin = event.WindowOpenedOrChanged.window;
|
||||||
const id = targetWin.id;
|
const id = targetWin.id;
|
||||||
@@ -165,9 +171,10 @@ Singleton {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error("Niri", "Error parsing window opened/changed event:", e);
|
Logger.error("Niri", "Error parsing window opened/changed event:", e);
|
||||||
}
|
}
|
||||||
} else if (event.windowClosed) {
|
}
|
||||||
|
if (event.WindowClosed) {
|
||||||
try {
|
try {
|
||||||
const closedId = event.windowClosed.id;
|
const closedId = event.WindowClosed.id;
|
||||||
if (closedId && (root.windows && root.windows[closedId])) {
|
if (closedId && (root.windows && root.windows[closedId])) {
|
||||||
delete root.windows[closedId];
|
delete root.windows[closedId];
|
||||||
if (root.focusedWindowId === closedId) {
|
if (root.focusedWindowId === closedId) {
|
||||||
@@ -179,6 +186,17 @@ Singleton {
|
|||||||
Logger.error("Niri", "Error parsing window closed event:", e);
|
Logger.error("Niri", "Error parsing window closed event:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event.ScreenshotCaptured) {
|
||||||
|
try {
|
||||||
|
const path = event.ScreenshotCaptured.path || "";
|
||||||
|
if (!path) return;
|
||||||
|
if (root.onScreenshotCaptured && typeof root.onScreenshotCaptured === "function") {
|
||||||
|
root.onScreenshotCaptured(path);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Logger.error("Niri", "Error parsing screenshot captured event:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error("Niri", "Error parsing event stream:", e, data);
|
Logger.error("Niri", "Error parsing event stream:", e, data);
|
||||||
}
|
}
|
||||||
|
|||||||
17
config/quickshell/.config/quickshell/Services/Screenshot.qml
Normal file
17
config/quickshell/.config/quickshell/Services/Screenshot.qml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
function onScreenshotCaptured(path) {
|
||||||
|
if (!path || typeof path !== "string")
|
||||||
|
return ;
|
||||||
|
|
||||||
|
console.log("Screenshot captured at path:", path);
|
||||||
|
Quickshell.execDetached(["screenshot-script", "edit", path]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ ShellRoot {
|
|||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
SunsetService;
|
SunsetService;
|
||||||
|
Niri.onScreenshotCaptured = Screenshot.onScreenshotCaptured;
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification {
|
Notification {
|
||||||
|
|||||||
@@ -9,8 +9,10 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
PALETTES = {
|
PALETTES = {
|
||||||
"catppuccin-mocha": {
|
"catppuccin-mocha": {
|
||||||
@@ -50,77 +52,121 @@ SCRIPTS = {
|
|||||||
"wlogout": [CONFIG_DIR / ".alt" / "wlogout-default" / "apply-color", CONFIG_DIR / ".alt" / "wlogout-niri" / "apply-color"],
|
"wlogout": [CONFIG_DIR / ".alt" / "wlogout-default" / "apply-color", CONFIG_DIR / ".alt" / "wlogout-niri" / "apply-color"],
|
||||||
"yazi": [CONFIG_DIR / "yazi" / "apply-color"],
|
"yazi": [CONFIG_DIR / "yazi" / "apply-color"],
|
||||||
}
|
}
|
||||||
# or simply `find ${CONFIG_DIR} -type f -iname 'apply-color*'` to get all available scripts,
|
# or simply `find -L ${CONFIG_DIR} -type f -iname 'apply-color*'` to get all available scripts,
|
||||||
# but I need the exact application names anyway, so hardcoding does make some sense
|
# but I do need the exact application names anyway, so hardcoding does make some sense
|
||||||
|
|
||||||
|
|
||||||
def hex2rgb(hex_color: str) -> tuple[int, int, int]:
|
def hex2rgb(hex_color: str) -> tuple[int, int, int]:
|
||||||
|
"""#rrggbb to (r, g, b)"""
|
||||||
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) # type: ignore
|
return tuple(int(hex_color[i:i + 2], 16) for i in (0, 2, 4)) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
def clamp(x, minimum, maximum) -> float:
|
||||||
|
"""Clamp x to the range [minimum, maximum]"""
|
||||||
|
return max(minimum, min(x, maximum))
|
||||||
|
|
||||||
|
|
||||||
|
def rgb2hsv(rr: int, gg: int, bb: int) -> tuple[float, float, float]:
|
||||||
|
"""(r, g, b) 0-255 to (h, s, v)"""
|
||||||
|
r, g, b = rr/255.0, gg/255.0, bb/255.0
|
||||||
|
r = clamp(r, 0.0, 1.0)
|
||||||
|
g = clamp(g, 0.0, 1.0)
|
||||||
|
b = clamp(b, 0.0, 1.0)
|
||||||
|
mx = max(r, g, b)
|
||||||
|
mn = min(r, g, b)
|
||||||
|
df = mx-mn
|
||||||
|
h = 0.0
|
||||||
|
if mx == mn:
|
||||||
|
h = 0.0
|
||||||
|
elif mx == r:
|
||||||
|
h = (60 * ((g-b)/df) + 360) % 360
|
||||||
|
elif mx == g:
|
||||||
|
h = (60 * ((b-r)/df) + 120) % 360
|
||||||
|
elif mx == b:
|
||||||
|
h = (60 * ((r-g)/df) + 240) % 360
|
||||||
|
if mx == 0:
|
||||||
|
s = 0.0
|
||||||
|
else:
|
||||||
|
s = (df/mx)*100
|
||||||
|
v = mx*100
|
||||||
|
return h, s, v
|
||||||
|
|
||||||
|
|
||||||
def extract_color(image_path: str) -> str:
|
def extract_color(image_path: str) -> str:
|
||||||
|
"""Extract a dominant color from the image and return it as a #rrggbb string."""
|
||||||
|
# Only import when needed
|
||||||
from colorthief import ColorThief
|
from colorthief import ColorThief
|
||||||
return "#{:02x}{:02x}{:02x}".format(*ColorThief(image_path).get_color(quality=10))
|
ct = ColorThief(image_path)
|
||||||
|
|
||||||
|
# Get first 5 dominant colors
|
||||||
|
palette = ct.get_palette(color_count=5, quality=10)
|
||||||
|
|
||||||
|
best_color = None
|
||||||
|
max_score = -1.0
|
||||||
|
|
||||||
|
for color in palette:
|
||||||
|
h, s, v = rgb2hsv(*color)
|
||||||
|
|
||||||
|
# Filter out undesirable colors
|
||||||
|
# Too dark
|
||||||
|
if v < 20:
|
||||||
|
continue
|
||||||
|
# Too light
|
||||||
|
if v > 95 and s < 5:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Saturation first, then value
|
||||||
|
score = s * 2.0 + v
|
||||||
|
|
||||||
|
if score > max_score:
|
||||||
|
max_score = score
|
||||||
|
best_color = color
|
||||||
|
|
||||||
|
# Fallback to the most dominant color
|
||||||
|
if best_color is None:
|
||||||
|
best_color = ct.get_color(quality=10)
|
||||||
|
|
||||||
|
return "#{:02x}{:02x}{:02x}".format(*best_color)
|
||||||
|
|
||||||
|
|
||||||
def match_color(color: str, palette: dict[str, str]) -> str:
|
def match_color(color: str, palette: dict[str, str]) -> str:
|
||||||
""" Matches a given color (rrggbb hex) to the closest color in the palette."""
|
"""Match the given #rrggbb color to the closest flavor in the palette."""
|
||||||
# HUE distance of the given and returned color must no<t exceed this value
|
|
||||||
HUE_THRESHOLD = 60.0 # degrees
|
|
||||||
|
|
||||||
color = color.lower().strip().removeprefix('#')
|
color = color.lower().strip().removeprefix('#')
|
||||||
|
target_rgb = hex2rgb(color)
|
||||||
|
target_h, target_s, target_v = rgb2hsv(*target_rgb)
|
||||||
|
|
||||||
# weigh by CCIR 601 luminosity
|
# Warn if not representative (nearly grayscale)
|
||||||
fr, fg, fb = 0.299 / 255 / 255, 0.587 / 255 / 255, 0.114 / 255 / 255
|
if target_s < 5:
|
||||||
lfr, lfg, lfb = 0.299 / 255, 0.587 / 255, 0.114 / 255
|
print(f"Warning: Extracted color {color} is nearly grayscale. Matching might be inaccurate.")
|
||||||
|
|
||||||
def color_distance(c1: str, c2: str) -> float:
|
def get_weighted_distance(hex_val: str) -> float:
|
||||||
r1, g1, b1 = hex2rgb(c1)
|
p_rgb = hex2rgb(hex_val)
|
||||||
r2, g2, b2 = hex2rgb(c2)
|
p_h, p_s, p_v = rgb2hsv(*p_rgb)
|
||||||
diff_l = (lfr * (r1 - r2) + lfg * (g1 - g2) + lfb * (b1 - b2))
|
|
||||||
diff_r = fr * (r1 - r2) ** 2
|
|
||||||
diff_g = fg * (g1 - g2) ** 2
|
|
||||||
diff_b = fb * (b1 - b2) ** 2
|
|
||||||
return (diff_r + diff_g + diff_b) * 0.75 + diff_l ** 2
|
|
||||||
|
|
||||||
def color_distance_hue(c1: str, c2: str) -> float:
|
# RGB distance with weighting
|
||||||
def rgb2hue(r, g, b) -> float:
|
rmean = (target_rgb[0] + p_rgb[0]) / 2
|
||||||
r, g, b = r / 255.0, g / 255.0, b / 255.0
|
dr = target_rgb[0] - p_rgb[0]
|
||||||
mx = max(r, g, b)
|
dg = target_rgb[1] - p_rgb[1]
|
||||||
mn = min(r, g, b)
|
db = target_rgb[2] - p_rgb[2]
|
||||||
diff = mx - mn
|
rgb_distance = ((2 + rmean / 256) * dr**2 + 4 * dg**2 + (2 + (255 - rmean) / 256) * db**2) ** 0.5
|
||||||
|
|
||||||
if diff == 0:
|
# Hue difference (with wrapping)
|
||||||
return 0.0
|
hue_diff = abs(target_h - p_h)
|
||||||
|
if hue_diff > 180:
|
||||||
|
hue_diff = 360 - hue_diff
|
||||||
|
|
||||||
if mx == r:
|
# Increase hue weight when saturation is high
|
||||||
hue = (g - b) / diff + (6 if g < b else 0)
|
hue_weight = 2.0 if target_s > 20 else 0.5
|
||||||
elif mx == g:
|
|
||||||
hue = (b - r) / diff + 2
|
|
||||||
else:
|
|
||||||
hue = (r - g) / diff + 4
|
|
||||||
|
|
||||||
return hue * 60
|
return rgb_distance + (hue_diff * hue_weight * 3)
|
||||||
r1, g1, b1 = hex2rgb(c1)
|
|
||||||
r2, g2, b2 = hex2rgb(c2)
|
|
||||||
return abs(rgb2hue(r1, g1, b1) - rgb2hue(r2, g2, b2))
|
|
||||||
|
|
||||||
closest_color = min(palette.keys(), key=lambda k: color_distance(color, palette[k]))
|
closest_flavor = min(palette.keys(), key=lambda k: get_weighted_distance(palette[k]))
|
||||||
print(f"Matched color {color} to {closest_color}")
|
print(f"Matched color #{color} to {closest_flavor} (#{palette[closest_flavor]})")
|
||||||
|
return closest_flavor
|
||||||
# if the hue distance is too large, rematch
|
|
||||||
if color_distance_hue(color, palette[closest_color]) > HUE_THRESHOLD:
|
|
||||||
print(f"Color {color} is too far from {closest_color}, rematching'")
|
|
||||||
else:
|
|
||||||
return closest_color
|
|
||||||
|
|
||||||
closest_color = min(palette.keys(), key=lambda k: color_distance_hue(color, palette[k]))
|
|
||||||
print(f"Rematched color {color} to {closest_color}")
|
|
||||||
|
|
||||||
return closest_color
|
|
||||||
|
|
||||||
|
|
||||||
def pick_flavor(palette: dict[str, str]) -> str:
|
def pick_flavor_interactive(palette: dict[str, str]) -> str:
|
||||||
|
"""Prompt the user to pick a flavor interactively."""
|
||||||
def is_interactive() -> bool:
|
def is_interactive() -> bool:
|
||||||
return sys.stdin.isatty() and sys.stdout.isatty()
|
return sys.stdin.isatty() and sys.stdout.isatty()
|
||||||
|
|
||||||
@@ -153,6 +199,27 @@ def pick_flavor(palette: dict[str, str]) -> str:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def run_script(script_path: Path, args: list[str]):
|
||||||
|
"""Helper to run a single script safely."""
|
||||||
|
script_str = str(script_path)
|
||||||
|
if not script_path.exists():
|
||||||
|
print(f"Warning: Script not found: {script_str}")
|
||||||
|
return
|
||||||
|
if not os.access(script_path, os.X_OK):
|
||||||
|
print(f"Warning: Script not executable: {script_str}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
cmd = [script_str] + args
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||||
|
if result.returncode != 0:
|
||||||
|
print(f"Error running {script_path}:\n{result.stderr.strip()}")
|
||||||
|
else:
|
||||||
|
print(f"✓ {script_path}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Exception running {script_path}: {e}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Change color theme for various applications.")
|
parser = argparse.ArgumentParser(description="Change color theme for various applications.")
|
||||||
parser.add_argument('-i', '--image', type=str, help="Path to the image")
|
parser.add_argument('-i', '--image', type=str, help="Path to the image")
|
||||||
@@ -186,7 +253,7 @@ def main():
|
|||||||
flavor = match_color(color, palette)
|
flavor = match_color(color, palette)
|
||||||
print(f"Matched color: {flavor}")
|
print(f"Matched color: {flavor}")
|
||||||
else:
|
else:
|
||||||
flavor = pick_flavor(palette)
|
flavor = pick_flavor_interactive(palette)
|
||||||
return flavor
|
return flavor
|
||||||
|
|
||||||
def parse_apps() -> tuple[set[str], set[str]]:
|
def parse_apps() -> tuple[set[str], set[str]]:
|
||||||
@@ -222,15 +289,18 @@ def main():
|
|||||||
|
|
||||||
print(f"Applying flavor '{flavor}' for {len(apps)} applications.")
|
print(f"Applying flavor '{flavor}' for {len(apps)} applications.")
|
||||||
|
|
||||||
|
script_args = [palette_name, flavor, palette[flavor]]
|
||||||
|
tasks = []
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=8) as executor:
|
||||||
for app in apps:
|
for app in apps:
|
||||||
for script in SCRIPTS[app]:
|
for script in SCRIPTS[app]:
|
||||||
print(f"Running {script}:")
|
tasks.append(executor.submit(run_script, script, script_args))
|
||||||
ret = os.system(f'"{script}" {palette_name} {flavor} {palette[flavor]}')
|
|
||||||
print(f"{script} exited with code {ret}")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
os.system(
|
subprocess.run([
|
||||||
f'notify-send -a "change-colortheme" "Colortheme Changed" "Palette: {palette_name};\nFlavor: {flavor};\nApplied to {len(apps)} applications."')
|
"notify-send", "-a", "change-colortheme", "Colortheme Changed",
|
||||||
|
f"Palette: {palette_name}\nFlavor: {flavor}"
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -35,6 +35,29 @@ fi
|
|||||||
[ -z "$image" ] && exit 1
|
[ -z "$image" ] && exit 1
|
||||||
[ ! -f "$image" ] && exit 1
|
[ ! -f "$image" ] && exit 1
|
||||||
|
|
||||||
|
# Obtain screen resolution
|
||||||
|
|
||||||
|
screen_width=$2
|
||||||
|
screen_height=$3
|
||||||
|
|
||||||
|
[ -z "$screen_width" ] && {
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
|
||||||
|
screen_width=$(hyprctl -j monitors | jq '.[0].resolution.x')
|
||||||
|
elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
||||||
|
screen_width=$(niri msg focused-output | grep 'Current mode' | awk '{print $3}' | cut -d'x' -f1)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z "$screen_height" ] && {
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
|
||||||
|
screen_height=$(hyprctl -j monitors | jq '.[0].resolution.y')
|
||||||
|
elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
||||||
|
screen_height=$(niri msg focused-output | grep 'Current mode' | awk '{print $3}' | cut -d'x' -f2)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z "$screen_width" ] && screen_width=2560
|
||||||
|
[ -z "$screen_height" ] && screen_height=1440
|
||||||
|
|
||||||
# $HOME/.config/wallpaper-chooser/config.json:
|
# $HOME/.config/wallpaper-chooser/config.json:
|
||||||
# ```json
|
# ```json
|
||||||
@@ -44,45 +67,65 @@ fi
|
|||||||
# }
|
# }
|
||||||
# ```
|
# ```
|
||||||
# So in order to let the most recently used wallpapers appear first:
|
# So in order to let the most recently used wallpapers appear first:
|
||||||
touch "$image"
|
touch "$image" 2>/dev/null || true # ignore errors
|
||||||
|
|
||||||
|
|
||||||
# Copy image to local wallpaper directory
|
# Copy image to local wallpaper directory
|
||||||
|
|
||||||
ext=${image##*.}
|
wallpaper_ext="png"
|
||||||
random_name=$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 16)
|
random_name=$(tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 16)
|
||||||
current_dir="$HOME/.local/share/wallpaper/current"
|
current_dir="$HOME/.local/share/wallpaper/current"
|
||||||
image_copied="$current_dir/wallpaper-${random_name}.${ext}"
|
wallpaper_image="$current_dir/wallpaper-${random_name}.${wallpaper_ext}"
|
||||||
|
|
||||||
mkdir -p "$current_dir" || {
|
mkdir -p "$current_dir" || {
|
||||||
echo "Could not create directory $current_dir"
|
echo "Could not create directory $current_dir"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_img=$(mktemp --suffix=."$ext") || exit 1
|
temp_img=$(mktemp --suffix=."$wallpaper_ext") || exit 1
|
||||||
trap 'rm -f "$temp_img"' EXIT
|
trap 'rm -f "$temp_img"' EXIT
|
||||||
cp "$image" "$temp_img" || exit 1
|
magick "$image" -resize "${screen_width}x${screen_height}^" -gravity center -extent "${screen_width}x${screen_height}" "$temp_img" || {
|
||||||
rm -f "${current_dir:?}"/wallpaper-*
|
echo "Could not resize and crop image"
|
||||||
cp -f "$temp_img" "$image_copied" || {
|
|
||||||
echo "Could not copy image to $current_dir"
|
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
cp "$temp_img" "$wallpaper_image" || exit 1
|
||||||
|
hash="$(md5sum "$image" | awk '{print $1}')-${screen_width}x${screen_height}"
|
||||||
|
|
||||||
|
# Clean up old wallpapers
|
||||||
|
|
||||||
|
find "$current_dir" -type f -name "wallpaper-*" ! -name "$(basename "$wallpaper_image")" -delete
|
||||||
|
|
||||||
# Generate blurred wallpaper
|
# Generate blurred wallpaper
|
||||||
|
|
||||||
blur_dir="$HOME/.local/share/wallpaper/blurred"
|
blur_dir="$HOME/.local/share/wallpaper/blurred"
|
||||||
mkdir -p "$blur_dir" || {
|
blur_cache_dir="$HOME/.local/share/wallpaper/blurred-cache"
|
||||||
|
mkdir -p "$blur_dir" "$blur_cache_dir" || {
|
||||||
echo "Could not create cache directory"
|
echo "Could not create cache directory"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
rm -f "${blur_dir:?}"/blurred-*
|
blurred_image="$blur_dir/blurred-${random_name}.${wallpaper_ext}"
|
||||||
blurred_image="$blur_dir/blurred-${random_name}.$ext"
|
blurred_cache_image="$blur_cache_dir/${hash}.${wallpaper_ext}"
|
||||||
|
|
||||||
## Time consuming task (magick -blur) in background
|
## Time consuming task (magick -blur) in background
|
||||||
(
|
(
|
||||||
# notify-send -a "change-wallpaper" "Generating Blurred Wallpaper" "This may take a few seconds..."
|
# notify-send -a "change-wallpaper" "Generating Blurred Wallpaper" "This may take a few seconds..."
|
||||||
|
|
||||||
sigma=$(magick identify -format "%w %h" "$image_copied" | awk -v f=0.01 '{
|
### Check if cached blurred image exists
|
||||||
|
if [ -f "$blurred_cache_image" ]; then
|
||||||
|
# sleep 1 # Some ugly workaround
|
||||||
|
if ! cp -f "$blurred_cache_image" "$blurred_image"; then
|
||||||
|
echo "Could not copy cached blurred image"
|
||||||
|
# exit 1 # Non-critical error
|
||||||
|
else
|
||||||
|
find "$blur_dir" -type f -name "blurred-*" ! -name "$(basename "$blurred_image")" -delete
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
||||||
|
swww img -n backdrop "$blurred_image" --transition-type fade --transition-duration 2 >/dev/null 2>/dev/null
|
||||||
|
fi
|
||||||
|
notify-send -a "change-wallpaper" "Blurred Wallpaper From Cache" "$blurred_image" -i "$blurred_image"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
sigma=$(magick identify -format "%w %h" "$wallpaper_image" | awk -v f=0.01 '{
|
||||||
m=($1>$2)?$1:$2;
|
m=($1>$2)?$1:$2;
|
||||||
s=m*f;
|
s=m*f;
|
||||||
if(s<2) s=2;
|
if(s<2) s=2;
|
||||||
@@ -91,19 +134,27 @@ blurred_image="$blur_dir/blurred-${random_name}.$ext"
|
|||||||
}')
|
}')
|
||||||
|
|
||||||
### use a temporary file to avoid incomplete file being used
|
### use a temporary file to avoid incomplete file being used
|
||||||
temp_blurred=$(mktemp --suffix=."$ext") || exit 1
|
temp_blurred=$(mktemp --suffix=."$wallpaper_ext") || exit 1
|
||||||
trap 'rm -f "${temp_blurred}"' EXIT
|
trap 'rm -f "${temp_blurred}"' EXIT
|
||||||
magick "$image_copied" -blur 0x"$sigma" "$temp_blurred" || {
|
magick "$wallpaper_image" -blur 0x"$sigma" "$temp_blurred" || {
|
||||||
echo "Could not create blurred image"
|
echo "Could not create blurred image"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
mv -f "$temp_blurred" "$blurred_image" || {
|
mv -f "$temp_blurred" "$blurred_image" || {
|
||||||
echo "Could not move blurred image to cache directory"
|
echo "Could not move blurred image to cache directory"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find "$blur_dir" -type f -name "blurred-*" ! -name "$(basename "$blurred_image")" -delete
|
||||||
|
|
||||||
|
cp -f "$blurred_image" "$blurred_cache_image" || {
|
||||||
|
echo "Could not cache blurred image"
|
||||||
|
# exit 1 # Non-critical error
|
||||||
|
}
|
||||||
|
|
||||||
if [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
if [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
||||||
swww img -n backdrop "$blurred_image" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null
|
swww img -n backdrop "$blurred_image" --transition-type fade --transition-duration 2 >/dev/null 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
notify-send -a "change-wallpaper" "Blurred Wallpaper Generated" "$blurred_image" -i "$blurred_image"
|
notify-send -a "change-wallpaper" "Blurred Wallpaper Generated" "$blurred_image" -i "$blurred_image"
|
||||||
@@ -112,17 +163,18 @@ blurred_image="$blur_dir/blurred-${random_name}.$ext"
|
|||||||
# Apply wallpaper
|
# Apply wallpaper
|
||||||
|
|
||||||
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
|
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
|
||||||
swww img -n background "$image_copied" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null
|
swww img -n background "$wallpaper_image" --transition-type fade --transition-duration 2 >/dev/null 2>/dev/null
|
||||||
|
|
||||||
notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$image_copied"
|
notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$wallpaper_image"
|
||||||
|
|
||||||
change-colortheme -i "$image_copied" || exit 1
|
change-colortheme -i "$wallpaper_image" || exit 1
|
||||||
elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then
|
||||||
swww img -n background "$image_copied" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null
|
### Handled in wallpaper-daemon
|
||||||
|
# swww img -n background "$wallpaper_image" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null
|
||||||
|
|
||||||
notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$image_copied"
|
notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$wallpaper_image"
|
||||||
|
|
||||||
change-colortheme -i "$image_copied" || exit 1
|
change-colortheme -i "$wallpaper_image" || exit 1
|
||||||
else
|
else
|
||||||
echo "Unsupported desktop environment: $XDG_CURRENT_DESKTOP"
|
echo "Unsupported desktop environment: $XDG_CURRENT_DESKTOP"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
54
config/scripts/.local/scripts/ghostty-capture
Executable file
54
config/scripts/.local/scripts/ghostty-capture
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Description:
|
||||||
|
# Use a sequence of keybinds to open the scrollback(or screen) buffer in editor (default to vim)
|
||||||
|
# without switching contexts.
|
||||||
|
# (It will be much easier if write_<screen|scrollback>_file:open is correctly implemented)
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - ghostty (of course)
|
||||||
|
# - wl-clipboard
|
||||||
|
#
|
||||||
|
# Example configuration in ~/.config/ghostty/config:
|
||||||
|
# # ctrl+shift+h>j to open the screen buffer in editor
|
||||||
|
# keybind = ctrl+shift+h=write_screen_file:copy
|
||||||
|
# keybind = ctrl+shift+j=text:ghostty-capture\n
|
||||||
|
# Or without wl-paste:
|
||||||
|
# # ctrl+shift+h>j > Enter to open the screen buffer in editor
|
||||||
|
# keybind = ctrl+shift+j=text:ghostty-capture\x20
|
||||||
|
# keybind = ctrl+shift+h=write_screen_file:paste
|
||||||
|
|
||||||
|
if [ -z "$1" ] && ! command -v wl-paste &> /dev/null; then
|
||||||
|
echo "Error: wl-paste not found." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
file=${1:-$(wl-paste --no-newline)}
|
||||||
|
|
||||||
|
[ -z "$file" ] && {
|
||||||
|
echo "No file provided or found in clipboard." >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -f "$file" ] || {
|
||||||
|
echo "File does not exist: $file" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$file" in
|
||||||
|
/tmp/*/*.txt) ;;
|
||||||
|
*)
|
||||||
|
echo "Possibily not a Ghostty generated temp file: $file" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$EDITOR" == *"code"* ]]; then
|
||||||
|
$EDITOR --wait "$file"
|
||||||
|
else
|
||||||
|
${EDITOR:-vim} "$file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$file"
|
||||||
|
|
||||||
|
rmdir "$(dirname "$file")" 2>/dev/null
|
||||||
56
config/scripts/.local/scripts/playlive
Executable file
56
config/scripts/.local/scripts/playlive
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Description:
|
||||||
|
# Play the video embedded in a live photo file (or so-called Motion Photo).
|
||||||
|
# The literal tags differ between manufacturers, so this script looks for
|
||||||
|
# the common 'ftyp' box that indicates the start of an MP4 video stream
|
||||||
|
# instead of "MotionPhotoVideo" or "EmbeddedVideo" or something.
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - mpv or vlc media player installed.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# - playlive <file>
|
||||||
|
# - case `config/scripts/.local/share/applications/playlive.desktop` is installed,
|
||||||
|
# right-click on a live photo file in file manager and choose "Open With..." ->
|
||||||
|
# "Play Live Photo".
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "${1:-}" ]; then
|
||||||
|
echo "Usage: $0 <file>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
play_cmd=()
|
||||||
|
if command -v mpv >/dev/null 2>&1; then
|
||||||
|
play_cmd=(mpv --title="Live Photo View" --keep-open=no --loop-file=no --loop-playlist=no --idle=no)
|
||||||
|
elif command -v vlc >/dev/null 2>&1; then
|
||||||
|
play_cmd=(vlc --play-and-exit)
|
||||||
|
else
|
||||||
|
echo "Error: No suitable media player found." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
file="$1"
|
||||||
|
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
echo "Error: File '$file' not found." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp_video=$(mktemp --suffix=.mp4)
|
||||||
|
trap 'rm -f "$tmp_video"' EXIT
|
||||||
|
|
||||||
|
offset=$(grep -aobP "ftyp(mp42|isom)" "$file" | tail -n 1 | cut -d: -f1 || true)
|
||||||
|
|
||||||
|
if [ -z "$offset" ]; then
|
||||||
|
echo "Error: No valid video stream found in '$file'." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mp4_offset=$((offset - 3))
|
||||||
|
|
||||||
|
tail -c "+$mp4_offset" "$file" > "$tmp_video"
|
||||||
|
|
||||||
|
"${play_cmd[@]}" "$tmp_video"
|
||||||
@@ -7,5 +7,7 @@ for child in $(pgrep -P "$pid" 2>/dev/null); do
|
|||||||
kill "$child"
|
kill "$child"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
sleep 0.3
|
||||||
|
|
||||||
kill "$pid"
|
kill "$pid"
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
#
|
#
|
||||||
# Requirements:
|
# Requirements:
|
||||||
# - hyprshot (for Hyprland)
|
# - hyprshot (for Hyprland)
|
||||||
# - - (niri has screenshot functionality built-in)
|
# - grim + slurp (for Niri)
|
||||||
# - gradia (for editing)
|
# - gradia (for editing)
|
||||||
# - glib bindings for python
|
# - glib bindings for python
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
import fcntl
|
||||||
from os import environ
|
from os import environ
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@@ -31,12 +32,13 @@ class ScreenshotType(Enum):
|
|||||||
FULL = "full"
|
FULL = "full"
|
||||||
AREA = "area"
|
AREA = "area"
|
||||||
WINDOW = "window"
|
WINDOW = "window"
|
||||||
|
EDIT = "edit"
|
||||||
|
|
||||||
|
|
||||||
SCREENSHOT_DIR = Path.home() / "Pictures" / "Screenshots"
|
SCREENSHOT_DIR = Path.home() / "Pictures" / "Screenshots"
|
||||||
|
|
||||||
|
|
||||||
def wait_until_file_exists(filepath: Path, timeout: int = 5):
|
def wait_until_file_exists(filepath: Path, timeout: int = 1):
|
||||||
"""Wait until a file exists or timeout."""
|
"""Wait until a file exists or timeout."""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
while not filepath.exists():
|
while not filepath.exists():
|
||||||
@@ -47,41 +49,60 @@ def wait_until_file_exists(filepath: Path, timeout: int = 5):
|
|||||||
|
|
||||||
|
|
||||||
def take_screenshot(filepath: Path, typeStr: str):
|
def take_screenshot(filepath: Path, typeStr: str):
|
||||||
|
lockFD = open("/tmp/screenshot-script.lock", "w")
|
||||||
|
try:
|
||||||
|
fcntl.flock(lockFD, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
except IOError:
|
||||||
|
lockFD.close()
|
||||||
|
raise RuntimeError("Another screenshot is currently being taken.")
|
||||||
|
|
||||||
|
try:
|
||||||
type = ScreenshotType(typeStr)
|
type = ScreenshotType(typeStr)
|
||||||
currentDesktop = environ.get("XDG_CURRENT_DESKTOP", "")
|
currentDesktop = environ.get("XDG_CURRENT_DESKTOP", "")
|
||||||
if "Hyprland" in currentDesktop:
|
if "Hyprland" in currentDesktop:
|
||||||
cmd = {
|
cmd = {
|
||||||
ScreenshotType.FULL: f"hyprshot -z -m output -m active -o {SCREENSHOT_DIR} -f ", # since I only have one monitor
|
# since I only have one monitor
|
||||||
|
ScreenshotType.FULL: f"hyprshot -z -m output -m active -o {SCREENSHOT_DIR} -f ",
|
||||||
ScreenshotType.AREA: f"hyprshot -z -m region -o {SCREENSHOT_DIR} -f ",
|
ScreenshotType.AREA: f"hyprshot -z -m region -o {SCREENSHOT_DIR} -f ",
|
||||||
ScreenshotType.WINDOW: f"hyprshot -z -m window -o {SCREENSHOT_DIR} -f ",
|
ScreenshotType.WINDOW: f"hyprshot -z -m window -o {SCREENSHOT_DIR} -f ",
|
||||||
}
|
}
|
||||||
process = subprocess.run(f"{cmd[type]}{filepath.name}", shell=True)
|
process = subprocess.run(f"{cmd[type]}{filepath.name}", shell=True)
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
raise RuntimeError("Failed to take screenshot: hyprshot command failed.")
|
raise RuntimeError("Failed to take screenshot: hyprshot command failed.")
|
||||||
wait_until_file_exists(filepath)
|
if not wait_until_file_exists(filepath):
|
||||||
|
raise RuntimeError("Failed to take screenshot: output file not found after hyprshot command.")
|
||||||
|
|
||||||
elif "niri" in currentDesktop:
|
elif "niri" in currentDesktop:
|
||||||
|
niriScreenshotPath = SCREENSHOT_DIR / ".niri_screenshot.png"
|
||||||
cmd = {
|
cmd = {
|
||||||
|
# niri's built-in screenshot commands are asynchronous, which does not wait for the user to select the area.
|
||||||
|
# and the selection ui is drawn inside of niri without its state exposed to external programs.
|
||||||
|
# so we use grim + slurp for area mode and niri's built-in commands for others.
|
||||||
ScreenshotType.FULL: "niri msg action screenshot-screen",
|
ScreenshotType.FULL: "niri msg action screenshot-screen",
|
||||||
ScreenshotType.AREA: "niri msg action screenshot",
|
ScreenshotType.AREA: f" grim -g \"$(slurp)\" -t png {niriScreenshotPath} && cat {niriScreenshotPath} | wl-copy",
|
||||||
ScreenshotType.WINDOW: "niri msg action screenshot-window",
|
ScreenshotType.WINDOW: "niri msg action screenshot-window",
|
||||||
}
|
}
|
||||||
niriScreenshotPath = SCREENSHOT_DIR / ".niri_screenshot.png"
|
|
||||||
if niriScreenshotPath.exists():
|
if niriScreenshotPath.exists():
|
||||||
niriScreenshotPath.unlink()
|
niriScreenshotPath.unlink()
|
||||||
# if os.system(cmd[type]):
|
|
||||||
process = subprocess.run(cmd[type], shell=True)
|
process = subprocess.run(cmd[type], shell=True)
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
raise RuntimeError("Failed to take screenshot: niri built-in screenshot command failed.")
|
print(process.returncode)
|
||||||
wait_until_file_exists(niriScreenshotPath)
|
raise RuntimeError("Failed to take screenshot: niri screenshot command failed.")
|
||||||
if niriScreenshotPath.exists():
|
|
||||||
|
if wait_until_file_exists(niriScreenshotPath):
|
||||||
# niriScreenshotPath.rename(filepath)
|
# niriScreenshotPath.rename(filepath)
|
||||||
copy2(niriScreenshotPath, filepath)
|
copy2(niriScreenshotPath, filepath)
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Failed to take screenshot: screenshot file nto found after niri command.")
|
raise RuntimeError("Failed to take screenshot: output file not found after niri command.")
|
||||||
wait_until_file_exists(filepath)
|
if not wait_until_file_exists(filepath):
|
||||||
|
raise RuntimeError("Failed to take screenshot: output file not found after copying.")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# print("Unsupported desktop environment.")
|
# print("Unsupported desktop environment.")
|
||||||
raise RuntimeError("Unsupported desktop environment.")
|
raise RuntimeError("Unsupported desktop environment.")
|
||||||
|
finally:
|
||||||
|
fcntl.flock(lockFD, fcntl.LOCK_UN)
|
||||||
|
lockFD.close()
|
||||||
|
|
||||||
|
|
||||||
def edit_screenshot(filepath: Path):
|
def edit_screenshot(filepath: Path):
|
||||||
@@ -105,8 +126,16 @@ if __name__ == "__main__":
|
|||||||
choices=[t.value for t in ScreenshotType],
|
choices=[t.value for t in ScreenshotType],
|
||||||
help="Type of screenshot to take.",
|
help="Type of screenshot to take.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"path",
|
||||||
|
nargs="?",
|
||||||
|
default="",
|
||||||
|
help="Path of the given screenshot file (for edit type only).",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
filepath: Path = Path()
|
||||||
|
if not args.type == ScreenshotType.EDIT.value:
|
||||||
# file path
|
# file path
|
||||||
SCREENSHOT_DIR.mkdir(parents=True, exist_ok=True)
|
SCREENSHOT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
filename = gen_file_name()
|
filename = gen_file_name()
|
||||||
@@ -114,10 +143,12 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# take screenshot
|
# take screenshot
|
||||||
take_screenshot(filepath, args.type)
|
take_screenshot(filepath, args.type)
|
||||||
|
else:
|
||||||
# check if successful
|
if not args.path:
|
||||||
|
raise RuntimeError("Path argument is required for edit type.")
|
||||||
|
filepath = Path(args.path).expanduser()
|
||||||
if not filepath.exists():
|
if not filepath.exists():
|
||||||
raise RuntimeError("Failed to take screenshot: screenshot file not found.")
|
raise RuntimeError(f"File does not exist: {filepath}")
|
||||||
|
|
||||||
# create loop instance
|
# create loop instance
|
||||||
loop = GLib.MainLoop()
|
loop = GLib.MainLoop()
|
||||||
@@ -140,9 +171,9 @@ if __name__ == "__main__":
|
|||||||
loop.quit()
|
loop.quit()
|
||||||
|
|
||||||
n = Notify.Notification.new(
|
n = Notify.Notification.new(
|
||||||
"Screenshot Taken",
|
|
||||||
# Mako doesn't have action buttons displayed with notification cards,
|
# Mako doesn't have action buttons displayed with notification cards,
|
||||||
"Click to edit",
|
"Click to edit",
|
||||||
|
str(filepath),
|
||||||
)
|
)
|
||||||
n.add_action(
|
n.add_action(
|
||||||
# so default action is used, which will be triggered on simply clicking the notification card
|
# so default action is used, which will be triggered on simply clicking the notification card
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ def getNiriSocket():
|
|||||||
|
|
||||||
|
|
||||||
def _log(msg: str):
|
def _log(msg: str):
|
||||||
print(msg)
|
# print(msg)
|
||||||
|
|
||||||
# logFIle = Path("/tmp/niri-autoblur.log")
|
# logFIle = Path("/tmp/niri-autoblur.log")
|
||||||
# try:
|
# try:
|
||||||
@@ -75,7 +75,7 @@ def swwwLoadImg(namespace: str, wallpaper: Path):
|
|||||||
|
|
||||||
def swwwStartDaemon(namespace: str):
|
def swwwStartDaemon(namespace: str):
|
||||||
# Check if daemon is already running
|
# Check if daemon is already running
|
||||||
cmd = ["pgrep", "-f", f"swww daemon -n {namespace}"], "-u", str(getuid())
|
cmd = ["pgrep", "-f", f"swww-daemon -n {namespace}", "-u", str(getuid())]
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(cmd, text=True)
|
output = subprocess.check_output(cmd, text=True)
|
||||||
pids = output.strip().splitlines()
|
pids = output.strip().splitlines()
|
||||||
@@ -104,13 +104,15 @@ class AutoBlur:
|
|||||||
_blurredDir: Path
|
_blurredDir: Path
|
||||||
_isBlurred = threading.Event()
|
_isBlurred = threading.Event()
|
||||||
_thread: threading.Thread | None = None
|
_thread: threading.Thread | None = None
|
||||||
_lastWallpaer: Path | None = None
|
_lastWallpaper: Path | None = None
|
||||||
_isFirst = True
|
_isFirst = True
|
||||||
|
_applyLock: threading.Lock
|
||||||
|
|
||||||
def __init__(self, normalDir, blurredDir, interval=0.2):
|
def __init__(self, normalDir, blurredDir, interval=0.2):
|
||||||
self._interval = interval
|
self._interval = interval
|
||||||
self._normalDir = normalDir
|
self._normalDir = normalDir
|
||||||
self._blurredDir = blurredDir
|
self._blurredDir = blurredDir
|
||||||
|
self._applyLock = threading.Lock()
|
||||||
|
|
||||||
# Niri will send "WindowsChanged" event on connect, so no need to init here
|
# Niri will send "WindowsChanged" event on connect, so no need to init here
|
||||||
# init state
|
# init state
|
||||||
@@ -204,13 +206,14 @@ class AutoBlur:
|
|||||||
sleep(self._interval)
|
sleep(self._interval)
|
||||||
|
|
||||||
def _apply(self, wallpaper: Path) -> bool:
|
def _apply(self, wallpaper: Path) -> bool:
|
||||||
if wallpaper == self._lastWallpaer:
|
with self._applyLock:
|
||||||
|
if wallpaper == self._lastWallpaper:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not swwwLoadImg("background", wallpaper):
|
if not swwwLoadImg("background", wallpaper):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self._lastWallpaer = wallpaper
|
self._lastWallpaper = wallpaper
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -339,14 +342,22 @@ if __name__ == "__main__":
|
|||||||
swwwLoadImg("background", normal)
|
swwwLoadImg("background", normal)
|
||||||
|
|
||||||
# Connect to Niri socket
|
# Connect to Niri socket
|
||||||
_log(f"[Main] connecting to Niri socket")
|
_log("[Main] connecting to Niri socket")
|
||||||
niri_socket = getNiriSocket()
|
niri_socket = getNiriSocket()
|
||||||
if not niri_socket:
|
if not niri_socket:
|
||||||
_log("[Main] NIRI_SOCKET environment variable is not set.")
|
_log("[Main] NIRI_SOCKET environment variable is not set.")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
if not connectNiri(niri_socket, handleEvent):
|
if not connectNiri(niri_socket, handleEvent):
|
||||||
exit(1)
|
_log("[Main] Connection lost or failed.")
|
||||||
|
except Exception as e:
|
||||||
|
_log(f"[Main] Exception in connection loop: {e}")
|
||||||
|
|
||||||
|
_log("[Main] Retrying in 3 seconds...")
|
||||||
|
sleep(3)
|
||||||
|
|
||||||
|
niri_socket = getNiriSocket() or niri_socket
|
||||||
elif desktop == "Hyprland":
|
elif desktop == "Hyprland":
|
||||||
_log("[Main] running in Hyprland")
|
_log("[Main] running in Hyprland")
|
||||||
_log("[Main] starting swww daemon")
|
_log("[Main] starting swww daemon")
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=Play Live Photo
|
||||||
|
Comment=Play embedded video from Live Photos
|
||||||
|
Exec=/home/kolkas/.local/scripts/playlive %f
|
||||||
|
Icon=multimedia-video-player
|
||||||
|
Terminal=false
|
||||||
|
Categories=AudioVideo;Video;Utility;
|
||||||
|
MimeType=image/jpeg;image/heic;image/heif;
|
||||||
@@ -2,9 +2,14 @@
|
|||||||
|
|
||||||
# Description:
|
# Description:
|
||||||
# Select which GPU to use for rendering for Hyprland and Niri.
|
# Select which GPU to use for rendering for Hyprland and Niri.
|
||||||
|
#
|
||||||
|
# envs exported:
|
||||||
|
# HYPR_AQ_DRM_DEVICES - Colon-separated list of DRM device paths for Hyprland's aq_drm
|
||||||
|
# BRIGHTNESSCTL_DEVICE - Device identifier for brightnessctl
|
||||||
|
|
||||||
# AMD -> Nvidia -> Intel
|
# Constants
|
||||||
prefer_order=(amd nvidia intel)
|
niri_config_file="$HOME/.config/niri/config/misc.kdl"
|
||||||
|
prefer_order=(amd nvidia intel) # AMD -> Nvidia -> Intel
|
||||||
|
|
||||||
# Get vendor and path of each GPU
|
# Get vendor and path of each GPU
|
||||||
default_dri_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)"
|
default_dri_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)"
|
||||||
@@ -59,14 +64,20 @@ for who in "${prefer_order[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Update niri config
|
# Update niri config
|
||||||
for file in "$HOME/.config/niri/config.kdl" "$HOME/.config/niri/config.kdl.template"; do
|
function update_niri_config() {
|
||||||
[[ -f "$file" ]] || continue
|
local config_file="$1"
|
||||||
|
local device_path="$2"
|
||||||
|
|
||||||
if grep -qE '^\s*render-drm-device\s+"[^"]+"' "$file"; then
|
[[ -f "$config_file" ]] || return
|
||||||
current="$(grep -E '^\s*render-drm-device\s+"[^"]+"' "$file" | sed -E 's/^\s*render-drm-device\s+"([^"]+)".*/\1/')"
|
|
||||||
[[ "$current" == "$primary_device" ]] && continue
|
if grep -qE '^\s*render-drm-device\s+"[^"]+"' "$config_file"; then
|
||||||
sed -i -E "s|^(\s*render-drm-device\s+)\"[^\"]+\"|\1\"$primary_device\"|" "$file"
|
local current
|
||||||
|
current="$(grep -E '^\s*render-drm-device\s+"[^"]+"' "$config_file" | sed -E 's/^\s*render-drm-device\s+"([^"]+)".*/\1/')"
|
||||||
|
[[ "$current" == "$device_path" ]] && return
|
||||||
|
sed -i -E "s|^(\s*render-drm-device\s+)\"[^\"]+\"|\1\"$device_path\"|" "$config_file"
|
||||||
else
|
else
|
||||||
printf '\ndebug {\nrender-drm-device "%s"\n}\n' "$primary_device" >> "$file"
|
printf '\ndebug {\nrender-drm-device "%s"\n}\n' "$device_path" >> "$config_file"
|
||||||
fi
|
fi
|
||||||
done
|
}
|
||||||
|
|
||||||
|
update_niri_config "$niri_config_file" "$primary_device"
|
||||||
@@ -4,12 +4,16 @@
|
|||||||
[ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env"
|
[ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env"
|
||||||
[ -d "$HOME/go/bin" ] && export PATH="$HOME/go/bin:$PATH"
|
[ -d "$HOME/go/bin" ] && export PATH="$HOME/go/bin:$PATH"
|
||||||
|
|
||||||
[ -x "$HOME/.local/scripts/ssh-init" ] && eval "$(ssh-init)"
|
[ -x "$HOME/.local/scripts/ssh-init" ] && eval "$(ssh-init)" >/dev/null 2>&1
|
||||||
|
|
||||||
command -v nvim >/dev/null 2>&1 && {
|
command -v nvim >/dev/null 2>&1 && {
|
||||||
export EDITOR=nvim
|
export EDITOR=nvim
|
||||||
export VISUAL=nvim
|
export VISUAL=nvim
|
||||||
}
|
}
|
||||||
|
|
||||||
|
command -v f >/dev/null 2>&1 || {
|
||||||
|
alias f="exec fish"
|
||||||
|
}
|
||||||
|
|
||||||
[ -f "$HOME/.profile" ] && . "$HOME/.profile"
|
[ -f "$HOME/.profile" ] && . "$HOME/.profile"
|
||||||
[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"
|
[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"
|
||||||
|
|||||||
2
config/shell/.config/fish/post.d/.gitignore
vendored
2
config/shell/.config/fish/post.d/.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!fetch.fish
|
!fetch.fish
|
||||||
!fetch.fish.template
|
|
||||||
!sshs.fish
|
!sshs.fish
|
||||||
!alias.fish
|
!alias.fish
|
||||||
|
!ghostty.fish
|
||||||
@@ -85,8 +85,32 @@ alias ....='cd ../../..'
|
|||||||
# grep
|
# grep
|
||||||
alias grep="grep --color=auto"
|
alias grep="grep --color=auto"
|
||||||
|
|
||||||
|
|
||||||
# others
|
# others
|
||||||
if type -q tty-clock
|
if type -q tty-clock
|
||||||
alias clock="tty-clock -c -C 4"
|
alias clock="tty-clock -c -C 4"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if type -q git
|
||||||
|
function gcp
|
||||||
|
if test (count $argv) -eq 0
|
||||||
|
git commit -a -m "👐 foo: too lazy to come up with a helpful commit message :)" || return 1
|
||||||
|
else
|
||||||
|
git commit -a -m "$argv" || return 1
|
||||||
|
end
|
||||||
|
git push
|
||||||
|
end
|
||||||
|
|
||||||
|
if type -q wl-paste
|
||||||
|
alias gc="git clone \$(wl-paste)"
|
||||||
|
|
||||||
|
if type -q idea
|
||||||
|
function pingo
|
||||||
|
cd "$HOME/Repositories/PGdP" || return 1
|
||||||
|
set -l repo (wl-paste)
|
||||||
|
git clone $repo || return 1
|
||||||
|
set -l repo_name (basename $repo .git)
|
||||||
|
nohup idea $repo_name >/dev/null 2>&1 & disown
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
if not set -q fetch_logo_type
|
if not set -q fetch_logo_type
|
||||||
set -g fetch_logo_type "auto"
|
set -g fetch_logo_type auto
|
||||||
end
|
end
|
||||||
|
|
||||||
if not set -q fetch_color
|
if not set -q fetch_color
|
||||||
set -g fetch_color "#89b4fa"
|
set -g fetch_color "#89b4fa"
|
||||||
end
|
end
|
||||||
|
|
||||||
if test "$fetch_logo_type" = "symbols"
|
if test "$fetch_logo_type" = symbols
|
||||||
set -g fetch_args "--logo-type raw --logo-width 42 --logo \"$HOME/.config/fastfetch/logo_ros/42x.symbols\" --color \"$fetch_color\""
|
set -g fetch_args "--logo-type raw --logo-width 42 --logo \"$HOME/.config/fastfetch/logo_ros/42x.symbols\" --color \"$fetch_color\""
|
||||||
set -g fetch_args_brief "--logo-type raw --logo-width 28 --logo \"$HOME/.config/fastfetch/logo_ros/28x.symbols\" --color \"$fetch_color\""
|
set -g fetch_args_brief "--logo-type raw --logo-width 28 --logo \"$HOME/.config/fastfetch/logo_ros/28x.symbols\" --color \"$fetch_color\""
|
||||||
else if test "$fetch_logo_type" = "logo"
|
else if test "$fetch_logo_type" = logo
|
||||||
set -g fetch_args "--logo-type builtin"
|
set -g fetch_args "--logo-type builtin"
|
||||||
set -g fetch_args_brief "--logo-type small"
|
set -g fetch_args_brief "--logo-type small"
|
||||||
else if test "$fetch_logo_type" = "sixel"
|
else if test "$fetch_logo_type" = sixel
|
||||||
set -g fetch_args "--logo-type raw --logo-width 42 --logo \"$HOME/.config/fastfetch/logo_ros/42x.sixel\" --color \"$fetch_color\""
|
set -g fetch_args "--logo-type raw --logo-width 42 --logo \"$HOME/.config/fastfetch/logo_ros/42x.sixel\" --color \"$fetch_color\""
|
||||||
set -g fetch_args_brief "--logo-type raw --logo-width 28 --logo \"$HOME/.config/fastfetch/logo_ros/28x.sixel\" --color \"$fetch_color\""
|
set -g fetch_args_brief "--logo-type raw --logo-width 28 --logo \"$HOME/.config/fastfetch/logo_ros/28x.sixel\" --color \"$fetch_color\""
|
||||||
else # "kitty" or "auto" and others
|
else # "kitty" or "auto" and others
|
||||||
@@ -24,15 +24,15 @@ if type -q fastfetch
|
|||||||
alias ff="fastfetch -c $HOME/.config/fastfetch/config.jsonc $fetch_args"
|
alias ff="fastfetch -c $HOME/.config/fastfetch/config.jsonc $fetch_args"
|
||||||
|
|
||||||
if test -f "$HOME/.config/fastfetch/brief.jsonc"
|
if test -f "$HOME/.config/fastfetch/brief.jsonc"
|
||||||
alias ff-brief="fastfetch -c $HOME/.config/fastfetch/brief.jsonc $fetch_args_brief"
|
alias ffb="fastfetch -c $HOME/.config/fastfetch/brief.jsonc $fetch_args_brief"
|
||||||
else
|
else
|
||||||
alias ff-brief=ff
|
alias ffb=ff
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# add 'set -g no_fetch' somewhere other than post.d to disable fetching
|
# add 'set -g no_fetch' somewhere other than post.d to disable fetching
|
||||||
if not set -q no_fetch
|
if not set -q no_fetch
|
||||||
if type -q ff-brief
|
if type -q ffb
|
||||||
ff-brief
|
ffb
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
1
config/shell/.config/fish/prev.d/.gitignore
vendored
1
config/shell/.config/fish/prev.d/.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
!prompt.fish
|
!prompt.fish
|
||||||
!theme.fish
|
!theme.fish
|
||||||
!env.fish
|
!env.fish
|
||||||
|
!niri-env.fish
|
||||||
22
config/shell/.config/fish/prev.d/niri-env.fish
Normal file
22
config/shell/.config/fish/prev.d/niri-env.fish
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
if test -n "$XDG_CURRENT_DESKTOP"; and test "$XDG_CURRENT_DESKTOP" = "niri"
|
||||||
|
set -l env_config "$HOME/.config/niri/config/envs.kdl"
|
||||||
|
|
||||||
|
if test -f "$env_config"
|
||||||
|
while read -la line
|
||||||
|
# Remove comments
|
||||||
|
set line (string replace -r '//.*' '' -- "$line")
|
||||||
|
# Trim whitespace
|
||||||
|
set line (string trim -- "$line")
|
||||||
|
# Skip "environment" block lines
|
||||||
|
if test -z "$line"; or string match -q "environment*" -- "$line"; or test "$line" = "}"
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
# Match lines like: VARIABLE "value" where VARIABLE is alphanumeric/underscore
|
||||||
|
set -l matches (string match -r '^([0-9A-Za-z_]+)\s+"(.*)"$' -- "$line")
|
||||||
|
# If have a matches, set the environment variable
|
||||||
|
if test (count $matches) -eq 3
|
||||||
|
set -xg $matches[2] $matches[3]
|
||||||
|
end
|
||||||
|
end < "$env_config"
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,17 +1,13 @@
|
|||||||
{
|
{
|
||||||
"wallpaper": {
|
"wallpaper": {
|
||||||
"dirs": [
|
"dirs": ["~/Pictures/backgrounds", "/media/Beta/壁纸/库"],
|
||||||
"~/Pictures/backgrounds",
|
"excludes": ["~/Pictures/backgrounds/nao-stars-crop-adjust-flop.jpg", "~/Pictures/backgrounds/miku-gate.jpg"]
|
||||||
"/media/Beta/壁纸/库"
|
|
||||||
],
|
|
||||||
"excludes": [
|
|
||||||
"~/Pictures/backgrounds/nao-stars-crop-adjust-flop.jpg",
|
|
||||||
"~/Pictures/backgrounds/miku-gate.jpg",
|
|
||||||
"~/Pictures/backgrounds/README.md"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"confirm": "change-wallpaper \"%1\""
|
"confirm": "change-wallpaper \"%1\" 2560 1600"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"no_loading_screen": false
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
"type": "date",
|
"type": "date",
|
||||||
|
|||||||
Submodule config/wallpaper/Pictures/backgrounds updated: cbe612b64b...719962a4ae
@@ -7,7 +7,7 @@
|
|||||||
/* Font(s) */
|
/* Font(s) */
|
||||||
* {
|
* {
|
||||||
/* main font icons CJK fallback */
|
/* main font icons CJK fallback */
|
||||||
font-family: 'Sour Gummy Light', 'Meslo LGM Nerd Font Mono', 'WenQuanYi Micro Hei', 'Noto Sans', sans-serif;
|
font-family: 'Sour Gummy Light', 'Meslo LGM Nerd Font Mono', 'Sarasa UI SC', 'Noto Sans', sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
--password-store=gnome-libsecret
|
|
||||||
--enable-features=UseOzonePlatform
|
|
||||||
--ozone-platform=wayland
|
|
||||||
--use-gl=desktop
|
|
||||||
--enable-wayland-ime
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
require("yaziline"):setup({
|
-- require("yaziline"):setup({
|
||||||
separator_style = "angly",
|
-- separator_style = "angly",
|
||||||
select_symbol = "",
|
-- select_symbol = "",
|
||||||
yank_symbol = "",
|
-- yank_symbol = "",
|
||||||
filename_max_length = 24, -- trim when filename > 24
|
-- filename_max_length = 24, -- trim when filename > 24
|
||||||
filename_trim_length = 6, -- trim 6 chars from both ends
|
-- filename_trim_length = 6, -- trim 6 chars from both ends
|
||||||
})
|
-- })
|
||||||
-- require("starship"):setup {
|
-- require("starship"):setup {
|
||||||
-- config_file = "~/.config/yazi/starship.toml",
|
-- config_file = "~/.config/yazi/starship.toml",
|
||||||
-- }
|
-- }
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ keymap = [
|
|||||||
# { on = "<C-r>", run = "select_all --state=none", desc = "Inverse selection of all files" },
|
# { on = "<C-r>", run = "select_all --state=none", desc = "Inverse selection of all files" },
|
||||||
|
|
||||||
# Find
|
# Find
|
||||||
{ on = "<C-p>", run = "plugin fzf", desc = "Jump to a directory or reveal a file using fzf" },
|
{ on = "<C-f>", run = "plugin fzf", desc = "Jump to a directory or reveal a file using fzf" },
|
||||||
{ on = [
|
{ on = [
|
||||||
"z",
|
"z",
|
||||||
"o",
|
"o",
|
||||||
@@ -105,7 +105,7 @@ keymap = [
|
|||||||
{ on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" },
|
{ on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" },
|
||||||
|
|
||||||
# Open
|
# Open
|
||||||
{ on = "r", run = "open --interactive", desc = "Open selected files interactively" },
|
{ on = "L", run = "open --interactive", desc = "Open selected files interactively" },
|
||||||
|
|
||||||
# Create
|
# Create
|
||||||
{ on = "T", run = "create", desc = "Create a file (ends with / for directories)" },
|
{ on = "T", run = "create", desc = "Create a file (ends with / for directories)" },
|
||||||
@@ -361,7 +361,9 @@ keymap = [
|
|||||||
keymap = [
|
keymap = [
|
||||||
# Navigation
|
# Navigation
|
||||||
{ on = "u", run = "arrow -1", desc = "Move up" },
|
{ on = "u", run = "arrow -1", desc = "Move up" },
|
||||||
|
{ on = "<Up>", run = "arrow -1", desc = "Move up" },
|
||||||
{ on = "e", run = "arrow 1", desc = "Move down" },
|
{ on = "e", run = "arrow 1", desc = "Move down" },
|
||||||
|
{ on = "<Down>", run = "arrow 1", desc = "Move down" },
|
||||||
|
|
||||||
# Close
|
# Close
|
||||||
{ on = "<Esc>", run = "close", desc = "Close spotter" },
|
{ on = "<Esc>", run = "close", desc = "Close spotter" },
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 - sxyazi
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2022 Himanshu
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<div align="center">
|
|
||||||
<img src="https://github.com/sxyazi/yazi/blob/main/assets/logo.png?raw=true" alt="Yazi logo" width="20%">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 align="center">
|
|
||||||
Onedark Flavor for <a href="https://github.com/sxyazi/yazi">Yazi</a>
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
## 👀 Preview
|
|
||||||
|
|
||||||
<img src="preview.png" width="600" />
|
|
||||||
|
|
||||||
## 🎨 Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Linux/macOS
|
|
||||||
git clone https://github.com/BennyOe/onedark.yazi.git ~/.config/yazi/flavors/onedark.yazi
|
|
||||||
|
|
||||||
# Windows
|
|
||||||
git clone https://github.com/BennyOe/onedark.yazi.git %AppData%\yazi\config\flavors\onedark.yazi
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚙️ Usage
|
|
||||||
|
|
||||||
Add the these lines to your `theme.toml` configuration file to use it:
|
|
||||||
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[flavor]
|
|
||||||
dark = "onedark"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📜 License
|
|
||||||
|
|
||||||
The flavor is MIT-licensed, and the included tmTheme is also MIT-licensed.
|
|
||||||
|
|
||||||
Check the [LICENSE](LICENSE) and [LICENSE-tmtheme](LICENSE-tmtheme) file for more details.
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
# : Manager {{{
|
|
||||||
[manager]
|
|
||||||
cwd = { fg = "#61AFEF" } # Blue
|
|
||||||
|
|
||||||
# Hovered
|
|
||||||
hovered = { bg = "#282C34" } # Darkened background
|
|
||||||
preview_hovered = { underline = true }
|
|
||||||
|
|
||||||
# Find
|
|
||||||
find_keyword = { fg = "#E06C75", italic = true, underline = true } # Red
|
|
||||||
find_position = { fg = "#E5C07B", italic = true } # Orange
|
|
||||||
|
|
||||||
# Marker
|
|
||||||
marker_copied = { fg = "#ABB2BF", bg = "#98C379" } # Light gray on Green
|
|
||||||
marker_cut = { fg = "#ABB2BF", bg = "#E06C75" } # Light gray on Red
|
|
||||||
marker_marked = { fg = "#ABB2BF", bg = "#56B6C2" } # Light gray on cyan
|
|
||||||
marker_selected = { fg = "#ABB2BF", bg = "#E5C07B" } # Light gray on Orange
|
|
||||||
|
|
||||||
# Tab
|
|
||||||
tab_active = { bg = "#282C34", fg = "#61AFEF" } # Darkened background, Blue text
|
|
||||||
tab_inactive = {}
|
|
||||||
tab_width = 1
|
|
||||||
|
|
||||||
# Count
|
|
||||||
count_copied = { fg = "#98C379", bg = "#282C34" } # Green on Darkened background
|
|
||||||
count_cut = { fg = "#E06C75", bg = "#282C34" } # Red on Darkened background
|
|
||||||
count_selected = { fg = "#98C379", bg = "#282C34" } # Green on Darkened background
|
|
||||||
|
|
||||||
# Border
|
|
||||||
border_symbol = "│"
|
|
||||||
border_style = { fg = "#282C34" } # Darkened background
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Status {{{
|
|
||||||
[status]
|
|
||||||
separator_open = ""
|
|
||||||
separator_close = ""
|
|
||||||
separator_style = { fg = "#61AFEF", bg = "#282C34" } # Blue on Darkened background
|
|
||||||
|
|
||||||
# Mode
|
|
||||||
mode_normal = { fg = "#282C34", bg = "#61AFEF", bold = true } # Dark gray on Blue
|
|
||||||
mode_select = { fg = "#282C34", bg = "#61AFEF", bold = true } # Dark gray on Blue
|
|
||||||
mode_unset = { fg = "#282C34", bg = "#61AFEF", bold = true } # Dark gray on Blue
|
|
||||||
|
|
||||||
# Progress
|
|
||||||
progress_label = { fg = "#ABB2BF", bold = true } # Light gray
|
|
||||||
progress_normal = { fg = "#98C379", bg = "#282C34" } # Green on Darkened background
|
|
||||||
progress_error = { fg = "#E06C75", bg = "#282C34" } # Red on Darkened background
|
|
||||||
|
|
||||||
# Permissions
|
|
||||||
permissions_t = { fg = "#98C379" } # Green
|
|
||||||
permissions_r = { fg = "#E06C75" } # Red
|
|
||||||
permissions_w = { fg = "#E5C07B" } # Orange
|
|
||||||
permissions_x = { fg = "#98C379" } # Green
|
|
||||||
permissions_s = { fg = "#ABB2BF" } # Light gray
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Select {{{
|
|
||||||
[select]
|
|
||||||
border = { fg = "#98C379" } # Green
|
|
||||||
active = { fg = "#E5C07B", bold = true } # Orange
|
|
||||||
inactive = {}
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Input {{{
|
|
||||||
[input]
|
|
||||||
border = { fg = "#98C379" } # Green
|
|
||||||
title = {}
|
|
||||||
value = {}
|
|
||||||
selected = { reversed = true }
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Completion {{{
|
|
||||||
[completion]
|
|
||||||
border = { fg = "#98C379" } # Green
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Tasks {{{
|
|
||||||
[tasks]
|
|
||||||
border = { fg = "#98C379" } # Green
|
|
||||||
title = {}
|
|
||||||
hovered = { fg = "#E5C07B", underline = true } # Orange
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Which {{{
|
|
||||||
[which]
|
|
||||||
mask = { bg = "#282C34" } # Darkened background
|
|
||||||
cand = { fg = "#98C379" } # Green
|
|
||||||
rest = { fg = "#ABB2BF" } # Light gray
|
|
||||||
desc = { fg = "#E5C07B" } # Orange
|
|
||||||
separator = " "
|
|
||||||
separator_style = { fg = "#ABB2BF" } # Light gray
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Help {{{
|
|
||||||
[help]
|
|
||||||
on = { fg = "#98C379" } # Green
|
|
||||||
run = { fg = "#E5C07B" } # Orange
|
|
||||||
hovered = { reversed = true, bold = true }
|
|
||||||
footer = { fg = "#ABB2BF", bg = "#000000" } # Light gray on Black
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : Notify {{{
|
|
||||||
[notify]
|
|
||||||
title_info = { fg = "#98C379" } # Green
|
|
||||||
title_warn = { fg = "#E06C75" } # Red
|
|
||||||
title_error = { fg = "#E5C07B" } # Orange
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
|
|
||||||
# : File-specific styles {{{
|
|
||||||
|
|
||||||
[filetype]
|
|
||||||
|
|
||||||
rules = [
|
|
||||||
# Images
|
|
||||||
{ mime = "image/*", fg = "#E5C07B" }, # Orange
|
|
||||||
|
|
||||||
# Media
|
|
||||||
{ mime = "video/*", fg = "#E06C75" }, # Red
|
|
||||||
{ mime = "audio/*", fg = "#E06C75" }, # Red
|
|
||||||
|
|
||||||
# Archives
|
|
||||||
{ mime = "application/zip", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-tar", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-bzip*", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-bzip2", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-7z-compressed", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-rar", fg = "#C678DD" }, # Magenta
|
|
||||||
{ mime = "application/x-xz", fg = "#C678DD" }, # Magenta
|
|
||||||
|
|
||||||
# Documents
|
|
||||||
{ mime = "application/doc", fg = "#98C379" }, # Green
|
|
||||||
{ mime = "application/pdf", fg = "#98C379" }, # Green
|
|
||||||
{ mime = "application/rtf", fg = "#98C379" }, # Green
|
|
||||||
{ mime = "application/vnd.*", fg = "#98C379" }, # Green
|
|
||||||
|
|
||||||
# Fallback
|
|
||||||
{ name = "*", fg = "#ABB2BF" }, # Blue
|
|
||||||
{ name = "*/", fg = "#61AFEF" } # Blue
|
|
||||||
]
|
|
||||||
|
|
||||||
# : }}}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1010 KiB |
@@ -1,560 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>author</key>
|
|
||||||
<string>Template: Chris Kempson, Scheme: Lalit Magant (http://github.com/tilal6991)</string>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Base16 OneDark</string>
|
|
||||||
<key>semanticClass</key>
|
|
||||||
<string>theme.base16.onedark</string>
|
|
||||||
<key>colorSpaceName</key>
|
|
||||||
<string>sRGB</string>
|
|
||||||
<key>gutterSettings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#353b45</string>
|
|
||||||
<key>divider</key>
|
|
||||||
<string>#353b45</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#545862</string>
|
|
||||||
<key>selectionBackground</key>
|
|
||||||
<string>#3e4451</string>
|
|
||||||
<key>selectionForeground</key>
|
|
||||||
<string>#565c64</string>
|
|
||||||
</dict>
|
|
||||||
<key>settings</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#282c34</string>
|
|
||||||
<key>caret</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
<key>invisibles</key>
|
|
||||||
<string>#545862</string>
|
|
||||||
<key>lineHighlight</key>
|
|
||||||
<string>#54586255</string>
|
|
||||||
<key>selection</key>
|
|
||||||
<string>#3e4451</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Text</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>variable.parameter.function</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Comments</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>comment, punctuation.definition.comment</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#545862</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Punctuation</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Delimiters</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>none</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Operators</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>keyword.operator</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Keywords</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>keyword</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Variables</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>variable</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Functions</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>entity.name.function, meta.require, support.function.any-method, variable.function, variable.annotation, support.macro</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#61afef</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Labels</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>entity.name.label</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#be5046</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Classes</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>support.class, entity.name.class, entity.name.type.class</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e5c07b</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Classes</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>meta.class</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c8ccd4</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Methods</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>keyword.other.special-method</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#61afef</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Storage</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>storage</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Support</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>support.function</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#56b6c2</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Strings, Inherited Class</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>string, constant.other.symbol, entity.other.inherited-class</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#98c379</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Integers</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>constant.numeric</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Floats</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>none</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Boolean</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>none</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Constants</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>constant</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Tags</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>entity.name.tag</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Attributes</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>entity.other.attribute-name</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Attribute IDs</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>entity.other.attribute-name.id, punctuation.definition.entity</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#61afef</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Selector</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>meta.selector</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Values</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>none</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Headings</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>fontStyle</key>
|
|
||||||
<string></string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#61afef</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Units</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>keyword.other.unit</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Bold</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.bold, punctuation.definition.bold</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>fontStyle</key>
|
|
||||||
<string>bold</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e5c07b</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Italic</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.italic, punctuation.definition.italic</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>fontStyle</key>
|
|
||||||
<string>italic</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Code</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.raw.inline</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#98c379</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Link Text</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Link Url</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>meta.link</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Lists</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.list</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Quotes</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.quote</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Separator</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>meta.separator</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#3e4451</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#abb2bf</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Inserted</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.inserted</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#98c379</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Deleted</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.deleted</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Changed</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>markup.changed</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Colors</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>constant.other.color</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#56b6c2</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Regular Expressions</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>string.regexp</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#56b6c2</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Escape Characters</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>constant.character.escape</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#56b6c2</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Embedded</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>punctuation.section.embedded, variable.interpolation</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c678dd</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Illegal</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>invalid.illegal</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#e06c75</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c8ccd4</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Broken</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>invalid.broken</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#d19a66</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#282c34</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Deprecated</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>invalid.deprecated</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#be5046</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c8ccd4</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>name</key>
|
|
||||||
<string>Unimplemented</string>
|
|
||||||
<key>scope</key>
|
|
||||||
<string>invalid.unimplemented</string>
|
|
||||||
<key>settings</key>
|
|
||||||
<dict>
|
|
||||||
<key>background</key>
|
|
||||||
<string>#545862</string>
|
|
||||||
<key>foreground</key>
|
|
||||||
<string>#c8ccd4</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>uuid</key>
|
|
||||||
<string>uuid</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
[[plugin.deps]]
|
[[plugin.deps]]
|
||||||
use = "yazi-rs/plugins:git"
|
use = "yazi-rs/plugins:git"
|
||||||
rev = "d1c8baa"
|
rev = "2301ff8"
|
||||||
hash = "63b6c222bf2103b3023389dde5e2ecfe"
|
hash = "27ca02f49fd236b5cc7bf03c243859fe"
|
||||||
|
|
||||||
[[plugin.deps]]
|
[[plugin.deps]]
|
||||||
use = "yazi-rs/plugins:smart-enter"
|
use = "yazi-rs/plugins:smart-enter"
|
||||||
rev = "d1c8baa"
|
rev = "2301ff8"
|
||||||
hash = "56fdabc96fc1f4d53c96eb884b02a5be"
|
hash = "56fdabc96fc1f4d53c96eb884b02a5be"
|
||||||
|
|
||||||
[[plugin.deps]]
|
[[plugin.deps]]
|
||||||
@@ -20,8 +20,8 @@ hash = "e17c11b605d989568a1d1741ca17c584"
|
|||||||
|
|
||||||
[[plugin.deps]]
|
[[plugin.deps]]
|
||||||
use = "llanosrocas/yaziline"
|
use = "llanosrocas/yaziline"
|
||||||
rev = "e79b067"
|
rev = "e7042a8"
|
||||||
hash = "f590c5b7d0730e8d6023b1b34ddf7ead"
|
hash = "9c2ab18ff5368056904e4ebb61b17571"
|
||||||
|
|
||||||
[flavor]
|
[flavor]
|
||||||
deps = []
|
deps = []
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ local function setup(st, opts)
|
|||||||
|
|
||||||
Linemode:children_add(function(self)
|
Linemode:children_add(function(self)
|
||||||
local url = self._file.url
|
local url = self._file.url
|
||||||
local repo = st.dirs[tostring(url.base)]
|
local repo = st.dirs[tostring(url.base or url.parent)]
|
||||||
local code
|
local code
|
||||||
if repo then
|
if repo then
|
||||||
code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)]
|
code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)]
|
||||||
@@ -208,7 +208,7 @@ end
|
|||||||
|
|
||||||
---@type UnstableFetcher
|
---@type UnstableFetcher
|
||||||
local function fetch(_, job)
|
local function fetch(_, job)
|
||||||
local cwd = job.files[1].url.base
|
local cwd = job.files[1].url.base or job.files[1].url.parent
|
||||||
local repo = root(cwd)
|
local repo = root(cwd)
|
||||||
if not repo then
|
if not repo then
|
||||||
remove(tostring(cwd))
|
remove(tostring(cwd))
|
||||||
|
|||||||
@@ -2,37 +2,59 @@
|
|||||||
|
|
||||||
Simple lualine-like status line for yazi.
|
Simple lualine-like status line for yazi.
|
||||||
|
|
||||||
Read more about features and configuration [here](#features).
|

|
||||||
|

|
||||||
|
|
||||||

|
All supported features are listed [here](#features). More presets are available [here](#presets).
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- yazi version >= [25.5.28](https://github.com/sxyazi/yazi/releases/tag/v25.5.28)
|
- yazi version >= [917e1f5](https://github.com/sxyazi/yazi/commit/917e1f54a10445f2e25147c4b81a3c77d8233632)
|
||||||
- Font with symbol support. For example [Nerd Fonts](https://www.nerdfonts.com/).
|
- Font with symbol support. For example [Nerd Fonts](https://www.nerdfonts.com/).
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
To keep the plugin up to date, there are two branches: `main` and `nightly`.
|
||||||
|
The `main` branch follows major yazi releases, while `nightly` is linked to specific yazi commits or changes.
|
||||||
|
|
||||||
|
This setup allows shipping stable versions on time, while giving early access to "cutting-edge" changes. See matrix below.
|
||||||
|
|
||||||
|
<details close>
|
||||||
|
<summary>Compatibility matrix</summary>
|
||||||
|
|
||||||
|
| yaziline | yazi |
|
||||||
|
| :------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------- |
|
||||||
|
| [v2.5.2](https://github.com/llanosrocas/yaziline.yazi/releases/tag/v2.5.2) | [917e1f5](https://github.com/sxyazi/yazi/commit/917e1f54a10445f2e25147c4b81a3c77d8233632) |
|
||||||
|
| [v2.5.1](https://github.com/llanosrocas/yaziline.yazi/releases/tag/v2.5.1) | [917e1f5](https://github.com/sxyazi/yazi/commit/917e1f54a10445f2e25147c4b81a3c77d8233632) |
|
||||||
|
| [v2.5.0](https://github.com/llanosrocas/yaziline.yazi/releases/tag/v2.5.0) | [v25.5.28](https://github.com/sxyazi/yazi/releases/tag/v25.5.28) |
|
||||||
|
| [v2.4.0](https://github.com/llanosrocas/yaziline.yazi/releases/tag/v2.4.0) | [v25.4.8](https://github.com/sxyazi/yazi/releases/tag/v25.4.8) |
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
1. Using yazi package manager
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ya pkg add llanosrocas/yaziline
|
ya pkg add llanosrocas/yaziline
|
||||||
```
|
```
|
||||||
|
|
||||||
Or manually copy `main.lua` to the `~/.config/yazi/plugins/yaziline.yazi/main.lua`
|
_Or manually copy `main.lua` to the `~/.config/yazi/plugins/yaziline.yazi/main.lua`_
|
||||||
|
|
||||||
## Usage
|
2. Add this line to your `~/.config/yazi/init.lua`:
|
||||||
|
|
||||||
Add this to your `~/.config/yazi/init.lua`:
|
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
require("yaziline"):setup()
|
require("yaziline"):setup()
|
||||||
```
|
```
|
||||||
|
|
||||||
Optionally, configure line:
|
## Configuration
|
||||||
|
|
||||||
|
This is default config, if you want to see presets go to [this section](#presets).
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
require("yaziline"):setup({
|
require("yaziline"):setup({
|
||||||
color = "#98c379", -- main theme color
|
color = "#98c379",
|
||||||
secondary_color = "#5A6078", -- secondary color
|
secondary_color = "#5A6078",
|
||||||
default_files_color = "darkgray", -- color of the file counter when it's inactive
|
default_files_color = "darkgray", -- color of the file counter when it's inactive
|
||||||
selected_files_color = "white",
|
selected_files_color = "white",
|
||||||
yanked_files_color = "green",
|
yanked_files_color = "green",
|
||||||
@@ -51,10 +73,18 @@ require("yaziline"):setup({
|
|||||||
|
|
||||||
filename_max_length = 24, -- truncate when filename > 24
|
filename_max_length = 24, -- truncate when filename > 24
|
||||||
filename_truncate_length = 6, -- leave 6 chars on both sides
|
filename_truncate_length = 6, -- leave 6 chars on both sides
|
||||||
filename_truncate_separator = "..." -- the separator of the truncated filename
|
filename_truncate_separator = "..."
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
By default yaziline uses color values from your `theme.toml`:
|
||||||
|
|
||||||
|
- mode and position font color: th.which.mask.bg
|
||||||
|
- default_files_color: which.separator_style.fg
|
||||||
|
- selected_files_color: mgr.count_selected.bg
|
||||||
|
- yanked_files_color: mgr.count_copied.bg
|
||||||
|
- cut_files_color: mgr.count_cut.bg
|
||||||
|
|
||||||
```
|
```
|
||||||
MODE size long_file...name.md S 0 Y 0
|
MODE size long_file...name.md S 0 Y 0
|
||||||
| | | | | | | | |
|
| | | | | | | | |
|
||||||
@@ -71,73 +101,16 @@ require("yaziline"):setup({
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Preconfigured separators
|
### Presets
|
||||||
|
|
||||||
Choose your style:
|
|
||||||
|
|
||||||
- `angly`
|
- `angly`
|
||||||

|

|
||||||
- `curvy`
|
- `curvy`
|
||||||

|

|
||||||
- `liney`
|
- `liney`
|
||||||

|

|
||||||
- `empty`
|
- `empty`
|
||||||

|

|
||||||
|
|
||||||
### Separator customization
|
|
||||||
|
|
||||||
You can provide your own symbols for separators combined with preconfigured separators. For example:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
require("yaziline"):setup({
|
|
||||||
-- Optinal config
|
|
||||||
separator_style = "angly", -- preconfigured style
|
|
||||||
separator_open = "", -- instead of
|
|
||||||
separator_close = "", -- instead of
|
|
||||||
separator_open_thin = "", -- change to anything
|
|
||||||
separator_close_thin = "", -- change to anything
|
|
||||||
separator_head = "", -- to match the style
|
|
||||||
separator_tail = "" -- to match the style
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
_You can find more symbols [here](https://www.nerdfonts.com/cheat-sheet)_
|
|
||||||
|
|
||||||
### File actions icons
|
|
||||||
|
|
||||||
You can provide your own symbols for `select` and `yank`. For example:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
require("yaziline"):setup({
|
|
||||||
-- Optinal config
|
|
||||||
select_symbol = "", -- "S" by default
|
|
||||||
yank_symbol = "" -- "Y" by default
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
_You can find more symbols [here](https://www.nerdfonts.com/cheat-sheet)_
|
|
||||||
|
|
||||||
### Colors and font weight
|
|
||||||
|
|
||||||
By default yaziline uses color values from your `theme.toml` (or flavor) but you can set custom colors in the `init.lua`:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
require("yaziline"):setup({
|
|
||||||
color = "#98c379",
|
|
||||||
default_files_color = "darkgray",
|
|
||||||
selected_files_color = "white",
|
|
||||||
yanked_files_color = "green",
|
|
||||||
cut_files_color = "red",
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
For example, here is how my line looks like:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Selected and Yanked Counter
|
### Selected and Yanked Counter
|
||||||
|
|
||||||
@@ -149,9 +122,9 @@ Displays the truncated filename on the left, which is useful for smaller windows
|
|||||||
|
|
||||||
```lua
|
```lua
|
||||||
require("yaziline"):setup({
|
require("yaziline"):setup({
|
||||||
filename_max_length = 24, -- truncate when filename > 24
|
filename_max_length = 24,
|
||||||
filename_truncate_length = 6, -- leave 6 chars on both sides
|
filename_truncate_length = 6,
|
||||||
filename_truncate_separator = "..." -- the separator of the truncated filename
|
filename_truncate_separator = "..."
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ local function setup(_, options)
|
|||||||
color = options.color or nil,
|
color = options.color or nil,
|
||||||
secondary_color = options.secondary_color or nil,
|
secondary_color = options.secondary_color or nil,
|
||||||
default_files_color = options.default_files_color
|
default_files_color = options.default_files_color
|
||||||
or th.which.separator_style.fg
|
or th.which.separator_style:fg()
|
||||||
or "darkgray",
|
or "darkgray",
|
||||||
selected_files_color = options.selected_files_color
|
selected_files_color = options.selected_files_color
|
||||||
or th.mgr.count_selected.bg
|
or th.mgr.count_selected:bg()
|
||||||
or "white",
|
or "white",
|
||||||
yanked_files_color = options.selected_files_color
|
yanked_files_color = options.selected_files_color
|
||||||
or th.mgr.count_copied.bg
|
or th.mgr.count_copied:bg()
|
||||||
or "green",
|
or "green",
|
||||||
cut_files_color = options.cut_files_color
|
cut_files_color = options.cut_files_color
|
||||||
or th.mgr.count_cut.bg
|
or th.mgr.count_cut:bg()
|
||||||
or "red",
|
or "red",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,10 +55,10 @@ local function setup(_, options)
|
|||||||
local style = self:style()
|
local style = self:style()
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(current_separator_style.separator_head)
|
ui.Span(current_separator_style.separator_head)
|
||||||
:fg(config.color or style.main.bg),
|
:fg(config.color or style.main:bg()),
|
||||||
ui.Span(" " .. mode .. " ")
|
ui.Span(" " .. mode .. " ")
|
||||||
:fg(th.which.mask.bg)
|
:fg(th.which.mask:bg())
|
||||||
:bg(config.color or style.main.bg),
|
:bg(config.color or style.main:bg()),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,8 +68,8 @@ local function setup(_, options)
|
|||||||
|
|
||||||
local style = self:style()
|
local style = self:style()
|
||||||
return ui.Span(current_separator_style.separator_close .. " " .. ya.readable_size(size) .. " ")
|
return ui.Span(current_separator_style.separator_close .. " " .. ya.readable_size(size) .. " ")
|
||||||
:fg(config.color or style.main.bg)
|
:fg(config.color or style.main:bg())
|
||||||
:bg(config.secondary_color or th.which.separator_style.fg)
|
:bg(config.secondary_color or th.which.separator_style:fg())
|
||||||
end
|
end
|
||||||
|
|
||||||
function Status:utf8_sub(str, start_char, end_char)
|
function Status:utf8_sub(str, start_char, end_char)
|
||||||
@@ -99,23 +99,23 @@ local function setup(_, options)
|
|||||||
|
|
||||||
function Status:name()
|
function Status:name()
|
||||||
local h = self._current.hovered
|
local h = self._current.hovered
|
||||||
|
local style = self:style()
|
||||||
if not h then
|
if not h then
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(current_separator_style.separator_close .. " ")
|
ui.Span(current_separator_style.separator_close .. " ")
|
||||||
:fg(config.secondary_color or th.which.separator_style.fg),
|
:fg(config.secondary_color or th.which.separator_style:fg()),
|
||||||
ui.Span("Empty dir")
|
ui.Span("Empty dir")
|
||||||
:fg(config.color or style.main.bg),
|
:fg(config.color or style.main:bg()),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local truncated_name = self:truncate_name(h.name, config.filename_max_length)
|
local truncated_name = self:truncate_name(h.name, config.filename_max_length)
|
||||||
|
|
||||||
local style = self:style()
|
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(current_separator_style.separator_close .. " ")
|
ui.Span(current_separator_style.separator_close .. " ")
|
||||||
:fg(config.secondary_color or th.which.separator_style.fg),
|
:fg(config.secondary_color or th.which.separator_style:fg()),
|
||||||
ui.Span(truncated_name)
|
ui.Span(truncated_name)
|
||||||
:fg(config.color or style.main.bg),
|
:fg(config.color or style.main:bg()),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ local function setup(_, options)
|
|||||||
|
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(" " .. current_separator_style.separator_close_thin .. " ")
|
ui.Span(" " .. current_separator_style.separator_close_thin .. " ")
|
||||||
:fg(th.which.separator_style.fg),
|
:fg(th.which.separator_style:fg()),
|
||||||
ui.Span(config.select_symbol .. " " .. files_selected .. " ")
|
ui.Span(config.select_symbol .. " " .. files_selected .. " ")
|
||||||
:fg(selected_fg),
|
:fg(selected_fg),
|
||||||
ui.Span(yanked_text .. " ")
|
ui.Span(yanked_text .. " ")
|
||||||
@@ -160,7 +160,7 @@ local function setup(_, options)
|
|||||||
local time = (cha.mtime or 0) // 1
|
local time = (cha.mtime or 0) // 1
|
||||||
|
|
||||||
return ui.Span(os.date("%Y-%m-%d %H:%M", time) .. " " .. current_separator_style.separator_open_thin .. " ")
|
return ui.Span(os.date("%Y-%m-%d %H:%M", time) .. " " .. current_separator_style.separator_open_thin .. " ")
|
||||||
:fg(th.which.separator_style.fg)
|
:fg(th.which.separator_style:fg())
|
||||||
end
|
end
|
||||||
|
|
||||||
function Status:percent()
|
function Status:percent()
|
||||||
@@ -182,13 +182,13 @@ local function setup(_, options)
|
|||||||
local style = self:style()
|
local style = self:style()
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(" " .. current_separator_style.separator_open)
|
ui.Span(" " .. current_separator_style.separator_open)
|
||||||
:fg(config.secondary_color or th.which.separator_style.fg),
|
:fg(config.secondary_color or th.which.separator_style:fg()),
|
||||||
ui.Span(percent)
|
ui.Span(percent)
|
||||||
:fg(config.color or style.main.bg)
|
:fg(config.color or style.main:bg())
|
||||||
:bg(config.secondary_color or th.which.separator_style.fg),
|
:bg(config.secondary_color or th.which.separator_style:fg()),
|
||||||
ui.Span(current_separator_style.separator_open)
|
ui.Span(current_separator_style.separator_open)
|
||||||
:fg(config.color or style.main.bg)
|
:fg(config.color or style.main:bg())
|
||||||
:bg(config.secondary_color or th.which.separator_style.fg),
|
:bg(config.secondary_color or th.which.separator_style:fg()),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -199,9 +199,9 @@ local function setup(_, options)
|
|||||||
local style = self:style()
|
local style = self:style()
|
||||||
return ui.Line({
|
return ui.Line({
|
||||||
ui.Span(string.format(" %2d/%-2d ", math.min(cursor + 1, length), length))
|
ui.Span(string.format(" %2d/%-2d ", math.min(cursor + 1, length), length))
|
||||||
:fg(th.which.mask.bg)
|
:fg(th.which.mask:bg())
|
||||||
:bg(config.color or style.main.bg),
|
:bg(config.color or style.main:bg()),
|
||||||
ui.Span(current_separator_style.separator_tail):fg(config.color or style.main.bg),
|
ui.Span(current_separator_style.separator_tail):fg(config.color or style.main:bg()),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
|
|
||||||
"blocks": [
|
|
||||||
{
|
|
||||||
"alignment": "left",
|
|
||||||
"segments": [
|
|
||||||
{
|
|
||||||
"foreground": "#89b4fa",
|
|
||||||
"properties": {
|
|
||||||
"windows": "\ue62a"
|
|
||||||
},
|
|
||||||
"style": "plain",
|
|
||||||
"template": "{{.Icon}}",
|
|
||||||
"type": "os"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#89b4fa",
|
|
||||||
"style": "plain",
|
|
||||||
"template": " {{.UserName}}",
|
|
||||||
"type": "session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#89b4fa",
|
|
||||||
"style": "plain",
|
|
||||||
"template": "@{{.HostName}}",
|
|
||||||
"type": "session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#94e2d5",
|
|
||||||
"properties": {
|
|
||||||
"folder_separator_icon": "/",
|
|
||||||
"style": "letter"
|
|
||||||
},
|
|
||||||
"style": "powerline",
|
|
||||||
"template": " \uf07b {{ .Path }} ",
|
|
||||||
"type": "path"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#a6e3a1",
|
|
||||||
"powerline_symbol": "\ue0b1",
|
|
||||||
"properties": {
|
|
||||||
"branch_icon": " ",
|
|
||||||
"fetch_stash_count": true,
|
|
||||||
"fetch_status": true,
|
|
||||||
"fetch_upstream_icon": true,
|
|
||||||
"fetch_worktree_count": true
|
|
||||||
},
|
|
||||||
"style": "powerline",
|
|
||||||
"template": " {{ .UpstreamIcon }} {{ .HEAD }}{{if .BranchStatus }} {{ .BranchStatus }}{{ end }}{{ if .Working.Changed }} \uf044 {{ .Working.String }}{{ end }}{{ if and (.Working.Changed) (.Staging.Changed) }} |{{ end }}{{ if .Staging.Changed }} \uf046 {{ .Staging.String }}{{ end }}{{ if gt .StashCount 0 }} \ueb4b {{ .StashCount }}{{ end }} ",
|
|
||||||
"type": "git"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#f9e2af",
|
|
||||||
"powerline_symbol": "\ue0b1",
|
|
||||||
"template": " \ue235 {{ if .Error }}{{ .Error }}{{ else }}{{ if .Venv }}{{ .Venv }} {{ end }}{{ .Full }}{{ end }} ",
|
|
||||||
"style": "powerline",
|
|
||||||
"type": "python"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "prompt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"alignment": "left",
|
|
||||||
"newline": true,
|
|
||||||
"segments": [
|
|
||||||
{
|
|
||||||
"foreground": "#fab387",
|
|
||||||
"style": "plain",
|
|
||||||
"template": "\ue3bf ",
|
|
||||||
"type": "root"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"foreground": "#89b4fa",
|
|
||||||
"foreground_templates": [
|
|
||||||
"{{ if gt .Code 0 }}#f38ba8{{ end }}"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"always_enabled": true
|
|
||||||
},
|
|
||||||
"style": "plain",
|
|
||||||
"template": "{{ if gt .Code 0 }}{{ .Code }} {{ end }}# ",
|
|
||||||
"type": "status"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "prompt"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"transient_prompt": {
|
|
||||||
"background": "transparent",
|
|
||||||
"foreground_templates": [
|
|
||||||
"{{ if gt .Code 0 }}#f38ba8{{ end }}"
|
|
||||||
],
|
|
||||||
"foreground": "#89b4fa",
|
|
||||||
"template": "# "
|
|
||||||
},
|
|
||||||
"version": 3
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
--ozone-platform-hint=auto
|
|
||||||
--enable-wayland-ime
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
--ozone-platform-hint=auto
|
|
||||||
--enable-wayland-ime
|
|
||||||
@@ -1,80 +1,61 @@
|
|||||||
感觉不适合放到 stow 包里,毕竟这取决于系统上安装了哪些字体。那就放 memo 里好了。
|
### Font packages (involved in fontconfig)
|
||||||
|
|
||||||
> path: `~/.config/fontconfig/fonts.conf`.
|
- ttf-sarasa-gothi
|
||||||
|
- ttf-symbola (AUR)
|
||||||
|
- noto-fonts
|
||||||
|
- noto-fonts-cjk
|
||||||
|
- noto-fonts-emoji
|
||||||
|
- ttf-nerd-fonts-symbols
|
||||||
|
- maplemono-nf-cn (AUR)
|
||||||
|
|
||||||
|
### Other fonts (used but not involved in fontconfig)
|
||||||
|
|
||||||
|
- Sour Gummy
|
||||||
|
- Font Awesome 6 Free
|
||||||
|
- Meslo LGM Nerd Font Mono
|
||||||
|
|
||||||
|
### Fontconfig configuration
|
||||||
|
|
||||||
|
> `~/.config/fontconfig/fonts.conf`
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<?xml version='1.0'?>
|
<?xml version='1.0'?>
|
||||||
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
|
<!DOCTYPE fontconfig SYSTEM 'urn:fontconfig:fonts.dtd'>
|
||||||
<fontconfig>
|
<fontconfig>
|
||||||
<!--
|
|
||||||
Artificial oblique for fonts without an italic or oblique version
|
|
||||||
-->
|
|
||||||
<match target="font">
|
<match target="font">
|
||||||
<!-- check to see if the font is roman -->
|
<edit mode="assign" name="antialias"><bool>true</bool></edit>
|
||||||
<test name="slant">
|
<edit mode="assign" name="hinting"><bool>true</bool></edit>
|
||||||
<const>roman</const>
|
<edit mode="assign" name="hintstyle"><const>hintslight</const></edit>
|
||||||
</test>
|
<edit mode="assign" name="rgba"><const>none</const></edit>
|
||||||
<!-- check to see if the pattern requested non-roman -->
|
|
||||||
<test compare="not_eq" name="slant" target="pattern">
|
|
||||||
<const>roman</const>
|
|
||||||
</test>
|
|
||||||
<!-- multiply the matrix to slant the font -->
|
|
||||||
<edit mode="assign" name="matrix">
|
|
||||||
<times>
|
|
||||||
<name>matrix</name>
|
|
||||||
<matrix>
|
|
||||||
<double>1</double>
|
|
||||||
<double>0.2</double>
|
|
||||||
<double>0</double>
|
|
||||||
<double>1</double>
|
|
||||||
</matrix>
|
|
||||||
</times>
|
|
||||||
</edit>
|
|
||||||
<!-- pretend the font is oblique now -->
|
|
||||||
<edit mode="assign" name="slant">
|
|
||||||
<const>oblique</const>
|
|
||||||
</edit>
|
|
||||||
<!-- and disable embedded bitmaps for artificial oblique -->
|
|
||||||
<edit mode="assign" name="embeddedbitmap">
|
|
||||||
<bool>false</bool>
|
|
||||||
</edit>
|
|
||||||
</match>
|
</match>
|
||||||
<!--
|
|
||||||
Synthetic emboldening for fonts that do not have bold face available
|
<!-- For danmuku -->
|
||||||
-->
|
<match target="pattern">
|
||||||
<match target="font">
|
<test name="family">
|
||||||
<!-- check to see if the weight in the font is less than medium which possibly need emboldening -->
|
<string>Noto Sans CJK SC</string>
|
||||||
<test compare="less_eq" name="weight">
|
|
||||||
<const>medium</const>
|
|
||||||
</test>
|
</test>
|
||||||
<!-- check to see if the pattern requests bold -->
|
<edit name="family" mode="append">
|
||||||
<test compare="more_eq" name="weight" target="pattern">
|
<string>Symbola</string>
|
||||||
<const>bold</const>
|
|
||||||
</test>
|
|
||||||
<!--
|
|
||||||
set the embolden flag
|
|
||||||
needed for applications using cairo, e.g. gucharmap, gedit, ...
|
|
||||||
-->
|
|
||||||
<edit mode="assign" name="embolden">
|
|
||||||
<bool>true</bool>
|
|
||||||
</edit>
|
|
||||||
<!--
|
|
||||||
set weight to bold
|
|
||||||
needed for applications using Xft directly, e.g. Firefox, ...
|
|
||||||
-->
|
|
||||||
<edit mode="assign" name="weight">
|
|
||||||
<const>bold</const>
|
|
||||||
</edit>
|
</edit>
|
||||||
</match>
|
</match>
|
||||||
|
|
||||||
<alias>
|
<alias>
|
||||||
<family>sans-serif</family>
|
<family>sans-serif</family>
|
||||||
<prefer>
|
<prefer>
|
||||||
<family>Noto Sans</family>
|
<family>Sarasa UI SC</family>
|
||||||
<family>Noto Sans CJK SC</family>
|
<family>Sarasa UI J</family>
|
||||||
<family>Noto Sans CJK JP</family>
|
<family>Noto Color Emoji</family>
|
||||||
<family>Noto Sans CJK KR</family>
|
<family>Symbols Nerd Font</family>
|
||||||
<family>Maple Mono NF CN</family>
|
</prefer>
|
||||||
|
</alias>
|
||||||
|
|
||||||
|
<alias>
|
||||||
|
<family>system-ui</family>
|
||||||
|
<prefer>
|
||||||
|
<family>Sarasa UI SC</family>
|
||||||
|
<family>Sarasa UI J</family>
|
||||||
|
<family>Noto Color Emoji</family>
|
||||||
|
<family>Symbols Nerd Font</family>
|
||||||
</prefer>
|
</prefer>
|
||||||
</alias>
|
</alias>
|
||||||
|
|
||||||
@@ -84,8 +65,8 @@
|
|||||||
<family>Noto Serif</family>
|
<family>Noto Serif</family>
|
||||||
<family>Noto Serif CJK SC</family>
|
<family>Noto Serif CJK SC</family>
|
||||||
<family>Noto Serif CJK JP</family>
|
<family>Noto Serif CJK JP</family>
|
||||||
<family>Noto Serif CJK KR</family>
|
<family>Noto Color Emoji</family>
|
||||||
<family>Maple Mono NF CN</family>
|
<family>Symbols Nerd Font</family>
|
||||||
</prefer>
|
</prefer>
|
||||||
</alias>
|
</alias>
|
||||||
|
|
||||||
@@ -93,10 +74,10 @@
|
|||||||
<family>monospace</family>
|
<family>monospace</family>
|
||||||
<prefer>
|
<prefer>
|
||||||
<family>Maple Mono NF CN</family>
|
<family>Maple Mono NF CN</family>
|
||||||
<family>Noto Sans Mono</family>
|
<family>Sarasa Mono SC</family>
|
||||||
<family>Noto Sans Mono CJK SC</family>
|
<family>Sarasa Mono J</family>
|
||||||
<family>Noto Sans Mono CJK JP</family>
|
<family>Noto Color Emoji</family>
|
||||||
<family>Noto Sans Mono CJK KR</family>
|
<family>Symbols Nerd Font</family>
|
||||||
</prefer>
|
</prefer>
|
||||||
</alias>
|
</alias>
|
||||||
</fontconfig>
|
</fontconfig>
|
||||||
|
|||||||
108
memo/git-remote.md
Normal file
108
memo/git-remote.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
## Gitea with custom SSH port
|
||||||
|
|
||||||
|
Since in most cases Gitea will be deployed within containers, it cannot use the same port (`22`) as the host machine to handle git operations via SSH. In my case the port `222` is used instead. Meanwhiles, this can cause some extra steps to set the correct remote URL for local repositories, since the port is different from the default one.
|
||||||
|
|
||||||
|
There are few approaches to handle this:
|
||||||
|
|
||||||
|
1. Edit `~/.ssh/config`
|
||||||
|
|
||||||
|
like:
|
||||||
|
|
||||||
|
```
|
||||||
|
Host gitea
|
||||||
|
HostName git.example.tld
|
||||||
|
User git
|
||||||
|
Port 222
|
||||||
|
IdentityFile /path/to/private/key
|
||||||
|
```
|
||||||
|
|
||||||
|
then:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote add origin gitea:username/repo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Use full URL with port
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
>
|
||||||
|
> The `scp`-like syntax `user@host:repo.git` does not support port specification. `ssh://` URL scheme must be used instead.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote add origin ssh://git@example.tld:222/username/repo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Use `GIT_SSH_COMMAND` environment variable
|
||||||
|
|
||||||
|
```sh
|
||||||
|
GIT_SSH_COMMAND='ssh -p 222'
|
||||||
|
```
|
||||||
|
|
||||||
|
4. and more...
|
||||||
|
- aliases
|
||||||
|
- scripts
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
## Local Repo with Multiple Remotes
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
>
|
||||||
|
> Check current remotes with:
|
||||||
|
>
|
||||||
|
> ```sh
|
||||||
|
> git remote -v
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> and remove a remote with:
|
||||||
|
>
|
||||||
|
> ```sh
|
||||||
|
> git remote remove <name>
|
||||||
|
> ```
|
||||||
|
|
||||||
|
Local repositories can have multiple remotes configured. This is useful when pushing to the primary repository and also to a backup repository.
|
||||||
|
|
||||||
|
And there are multiple ways to add multiple remotes:
|
||||||
|
|
||||||
|
1. Use different names for remotes
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote add origin ssh://git@example.tld/username/repo.git
|
||||||
|
|
||||||
|
git remote add backup ssh://git@backup.tld/username/repo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
then push to both remotes:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git push origin main
|
||||||
|
git push backup main
|
||||||
|
```
|
||||||
|
|
||||||
|
Without referring to remotes explicitly, git will use `origin` by default. To fetch from all remotes, use `git fetch --all` or directly `git pull --all`.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
>
|
||||||
|
> The command `git push --all` is for pushing all local branches, not for pushing to all configured remote URLs.
|
||||||
|
|
||||||
|
2. Use `git remote set-url --add`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote add origin ssh://git@example.tld/username/repo.git
|
||||||
|
git remote set-url --add origin ssh://git@backup.tld/username/repo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
then push to both remotes:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git push origin
|
||||||
|
```
|
||||||
|
|
||||||
|
A single `git push origin` will push to all URLs configured for the `origin` remote.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
>
|
||||||
|
> By default, `git fetch` and `git pull` will only interact with the first (fetch) URL configured for a remote.
|
||||||
|
>
|
||||||
|
> The `git fetch --all` command fetches from all configured **remotes** (e.g., `origin`, `backup`), not from all URLs within a single remote.
|
||||||
|
>
|
||||||
|
> Similarly, `git pull --all` will first run `git fetch --all` and then merge the current local branch with its upstream branch. The merge action only applies to the current branch.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
things I have installed:
|
things I have installed:
|
||||||
|
|
||||||
full KDE Plasma 6 setup # non-essential for sure
|
full KDE Plasma 6 setup
|
||||||
which can provide:
|
which can provide:
|
||||||
SDDM theme # Breeze is enough
|
SDDM theme # Breeze is enough
|
||||||
kcalc/kalc # calculator(s), what's the difference?
|
kcalc/kalc # calculator(s), what's the difference?
|
||||||
|
|||||||
133
memo/kmscon.md
Normal file
133
memo/kmscon.md
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
> 鬼知道这有什么意义,但是在 tty 里用 monospace 和 cjk 字体真的很酷
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
AUR - `kmscon`
|
||||||
|
|
||||||
|
## 启用
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo ln -s '/usr/lib/systemd/system/kmsconvt@.service' '/etc/systemd/system/autovt@.service'
|
||||||
|
```
|
||||||
|
|
||||||
|
以及保留 tty1 为 getty:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl enable getty@tty1.service
|
||||||
|
```
|
||||||
|
|
||||||
|
理由:
|
||||||
|
|
||||||
|
- kmscon 中通过命令行启动图形 session 会遇到问题。
|
||||||
|
- 通常 tty1 用于运行图形界面,不需要 kmscon 提供的各种特性。
|
||||||
|
|
||||||
|
## 修改默认配置
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo systemctl edit autovt@.service
|
||||||
|
```
|
||||||
|
|
||||||
|
然后添加以下内容:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=/usr/bin/kmscon --vt=%I --seats=seat0 --no-switchvt
|
||||||
|
```
|
||||||
|
|
||||||
|
解释:
|
||||||
|
|
||||||
|
- 默认的 `ExecStart` 携带的参数会覆盖所有配置文件中的对应项,需要先清空。
|
||||||
|
- 保留默认参数 `--login` 前的部分,因为我看不出不这么做的理由。
|
||||||
|
|
||||||
|
然后就可以在 `/etc/kmscon/kmscon.conf` 添加自定义的配置了。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
login=/bin/login -p -f kolkas
|
||||||
|
font-name=MesloLGM Nerd Font Mono, Maple Mono NF CN
|
||||||
|
font-size=14
|
||||||
|
```
|
||||||
|
|
||||||
|
其中:
|
||||||
|
|
||||||
|
- `login=/bin/login -p -f kolkas` 指定自动登录用户。
|
||||||
|
- `font-name` 和 `font-size` 用于设置字体和大小。
|
||||||
|
|
||||||
|
### 关于自动登录的补充说明
|
||||||
|
|
||||||
|
如果想让 kmscon 在自动登录的同时启动非登陆 shell (例如 fish),可以将配置改为:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
login=/usr/bin/su - kolkas -s /usr/local/bin/fish-login-wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
其中 `fish-login-wrapper` 内容为:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -f /etc/profile ]; then
|
||||||
|
source /etc/profile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f ~/.bash_profile ]; then
|
||||||
|
source ~/.bash_profile
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 设置环境变量以供后续脚本检测
|
||||||
|
export IS_KMSCON=1
|
||||||
|
|
||||||
|
# 设定 fastfetch 的 logo 类型为 logo (config/shell/.config/fish/post.d/fetch.fish 会读取该变量)
|
||||||
|
export fetch_logo_type=logo
|
||||||
|
|
||||||
|
exec /usr/bin/fish
|
||||||
|
```
|
||||||
|
|
||||||
|
如果不需要读取 profile 文件而直接将 fish 作为登陆 shell,可以将配置改为:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
login=/usr/bin/su - kolkas -s /usr/bin/fish --login
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关于字体的补充说明
|
||||||
|
|
||||||
|
- kmscon 上 2 字符宽的 nerd font 图标会被裁剪至 1 字符宽。可以使用带有 Mono 后缀的 Meslo 系字体作为首选字体,它的图标字符只有 1 字符宽。
|
||||||
|
|
||||||
|
- [Archwiki - KMSCON](https://wiki.archlinux.org/title/KMSCON) 上提供了另一种更改字体的方法,即修改 fontconfig 配置,具体做法为在 monospace 字体族中前置添加字体。但这会影响所有使用 fontconfig 和 monospace 字体族的程序,个人认为并非首选。
|
||||||
|
|
||||||
|
## 检测当前终端是否为 kmscon
|
||||||
|
|
||||||
|
> 以下代码片段适用于 fish shell
|
||||||
|
|
||||||
|
检测所有祖先进程中是否有 kmscon:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
function is_kmscon
|
||||||
|
set -l pid %self
|
||||||
|
while test $pid -gt 1
|
||||||
|
set -l info (ps -o ppid=,comm= -p $pid | string trim)
|
||||||
|
set -l ppid (echo $info | awk '{print $1}')
|
||||||
|
set -l name (echo $info | awk '{print $2}')
|
||||||
|
|
||||||
|
if string match -q "kmscon" $name
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
set pid $ppid
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_kmscon
|
||||||
|
# 在 kmscon 中
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
或如果配置了 [环境变量](#关于自动登录的补充说明):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
if test -n "$IS_KMSCON"
|
||||||
|
# 在 kmscon 中
|
||||||
|
end
|
||||||
|
```
|
||||||
116
memo/kvm-virtio-accel3D.md
Normal file
116
memo/kvm-virtio-accel3D.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
这是一个关于 **Linux (Arch) 宿主机** + **Linux (Gentoo) 客户机** 在 KVM/QEMU 环境下启用 **Virtio-GPU 3D 加速** 遇到黑屏问题的**非完整**排查与解决记录。
|
||||||
|
|
||||||
|
## What
|
||||||
|
|
||||||
|
- **环境**:Host: Arch Linux (Kernel 6.x) | Guest: Gentoo Linux | QEMU v10.x。
|
||||||
|
|
||||||
|
- **配置**:使用 virtio-vga 或 virtio-gpu 显卡,配合 SPICE 协议。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<video>
|
||||||
|
<model type="virtio" heads="1" primary="yes">
|
||||||
|
<acceleration accel3d="yes"/>
|
||||||
|
</model>
|
||||||
|
</video>
|
||||||
|
|
||||||
|
<graphics type="spice">
|
||||||
|
<listen type="none"/>
|
||||||
|
<image compression="off"/>
|
||||||
|
<gl enable="yes" rendernode="/dev/dri/by-path/pci-0000:00:02.0-render"/>
|
||||||
|
</graphics>
|
||||||
|
```
|
||||||
|
|
||||||
|
- **现象**:
|
||||||
|
|
||||||
|
- 虚拟机启动后黑屏,无法进入图形界面。
|
||||||
|
- SSH 连接正常,系统内核正常运行。
|
||||||
|
- SPICE 窗口内能看到鼠标光标(表示连接建立),但无画面。
|
||||||
|
- 关键日志 (`/var/log/libvirt/qemu/xxx.log`):
|
||||||
|
|
||||||
|
```log
|
||||||
|
warning: console: no gl-unblock within one second
|
||||||
|
warning: spice: no gl-draw-done within one second
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
初步分析为 OpenGL 渲染死锁,可能由以下因素叠加导致:
|
||||||
|
|
||||||
|
1. 权限不足:QEMU 进程无法访问宿主机的 **/dev/dri/\*** 设备。
|
||||||
|
|
||||||
|
2. XML 配置缺失:未显式开启 virtio 设备的 3D 加速位。
|
||||||
|
|
||||||
|
3. 渲染管线冲突:SPICE 直接处理 GL 上下文容易发生阻塞,尤其是当 Guest 从 VGA 模式切换到 GL 模式时。
|
||||||
|
|
||||||
|
## How
|
||||||
|
|
||||||
|
### 1. 确认权限
|
||||||
|
|
||||||
|
QEMU 运行用户(通常是 `libvirt-qemu`)必须有权访问 GPU 渲染节点。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 检查组
|
||||||
|
groups libvirt-qemu
|
||||||
|
|
||||||
|
# 如果没有 'render' 组,将加之
|
||||||
|
sudo gpasswd -a libvirt-qemu render
|
||||||
|
|
||||||
|
# 重启
|
||||||
|
sudo systemctl restart libvirtd
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. EGL-Headless 分离渲染
|
||||||
|
|
||||||
|
这是解决黑屏死锁最稳妥的方案。通过引入 `egl-headless`,将 OpenGL 渲染(在后台 GPU 完成)与 SPICE 显示传输(在前台完成)解耦。
|
||||||
|
|
||||||
|
1. **显卡部分** (`<video>`):必须显式开启 `accel3d`。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<video>
|
||||||
|
<model type="virtio" heads="1" primary="yes">
|
||||||
|
<acceleration accel3d="yes"/>
|
||||||
|
</model>
|
||||||
|
...
|
||||||
|
</video>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **图形部分** (`<graphics>`):移除 `<gl>` 节点,改为使用 `egl-headless`。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<graphics type="egl-headless">
|
||||||
|
<gl rendernode="/dev/dri/by-path/pci-0000:00:02.0-render"/>
|
||||||
|
</graphics>
|
||||||
|
|
||||||
|
<graphics type="spice">
|
||||||
|
<listen type="none"/>
|
||||||
|
<image compression="off"/>
|
||||||
|
</graphics>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 客户机配置 (Gentoo)
|
||||||
|
|
||||||
|
在 Gentoo Guest 内部,确保驱动栈完整。
|
||||||
|
|
||||||
|
1. **Portage 配置** ( 或其他位置):
|
||||||
|
|
||||||
|
- `/etc/portage/make.conf`
|
||||||
|
|
||||||
|
```conf
|
||||||
|
VIDEO_CARDS="virtgl"
|
||||||
|
```
|
||||||
|
|
||||||
|
- 或 `/etc/portage/package.use/00video_cards`
|
||||||
|
|
||||||
|
```conf
|
||||||
|
*/* VIDEO_CARDS: virtgl
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **安装必要软件包**:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
emerge --ask --changed-use media-libs/mesa
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **内核配置**: 需开启 DRM 和 Virtio GPU 支持。
|
||||||
|
|
||||||
|
### 4. 重启
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
things I have installed:
|
things I have installed:
|
||||||
|
|
||||||
everything in `./hyprland-ricing.txt`, in addition to:
|
in addition to everything in `./hyprland-ricing.txt`:
|
||||||
|
|
||||||
xwayland-satellite
|
xwayland-satellite
|
||||||
wlsunset
|
wlsunset
|
||||||
|
grim # see /config/scripts/.local/scripts/screenshot-script
|
||||||
Reference in New Issue
Block a user