Enable media/microphone/active-window, add Docker/Power/Wallpaper/SystemOverview plugins, deploy terminal/starship/nvim/opencode configs
swadhinbiswas committed 2 months ago
ed1a3ac
1 parent d9078af
commit ed1a3ac
16 files changed
+2276 -31
Showing 16 changed files+2276-31
config/hypr/deo-autostart.luaconfig/hypr/deo-bindings.luaconfig/hypr/deo-layer.luaconfig/kitty/kitty.confconfig/nvimconfig/opencode/opencode.jsoncconfig/starship/starship.tomlinstall.shshell/plugins/docker-status/DockerStatus.qmlshell/plugins/docker-status/manifest.jsonshell/plugins/power-profile/PowerProfile.qmlshell/plugins/power-profile/manifest.jsonshell/plugins/system-overview/SystemOverview.qmlshell/plugins/system-overview/manifest.jsonshell/plugins/wallpaper-manager/WallpaperManager.qmlshell/plugins/wallpaper-manager/manifest.json
▼config/hypr/deo-autostart.lua
+5-0
| @@ -0,0 +1,5 @@ | ||
1 | +hl.on("hyprland.start", function() | |
2 | + hl.exec_cmd("pkill -f 'quickshell.*-c moonshell' 2>/dev/null; pkill -f 'moonshell shell' 2>/dev/null; pkill -x hypridle 2>/dev/null; pkill -f 'wl-paste --type text --watch cliphist' 2>/dev/null; pkill -f 'wl-paste --type image --watch cliphist' 2>/dev/null; wl-paste --type text --watch cliphist store &; wl-paste --type image --watch cliphist store &; true") | |
3 | +end) | |
4 | +hl.exec_cmd("omarchy-launch-shell") | |
5 | +require("default.hypr.autostart") | |
0 | 6 | |
▼config/hypr/deo-bindings.lua
+121-0
| @@ -0,0 +1,121 @@ | ||
1 | +-- De-omarchy keybindings: non-conflicting Omarchy defaults redefined here. | |
2 | + | |
3 | +-- Tiling / Window management | |
4 | +o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit")) | |
5 | +o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo()) | |
6 | +o.bind("SUPER + O", "Pop window out (float & pin)", "omarchy-hyprland-window-pop") | |
7 | +o.bind("SUPER + CTRL + F", "Tiled full screen", "omarchy-hyprland-window-tiled-fullscreen-toggle") | |
8 | +o.bind("SUPER + ALT + F", "Full width", hl.dsp.window.fullscreen({ mode = "maximized" })) | |
9 | +o.bind("SUPER + Home", "Restore window width", "omarchy-hyprland-window-width restore") | |
10 | +o.bind("SUPER + ALT + Home", "Save window width", "omarchy-hyprland-window-width save") | |
11 | + | |
12 | +-- Workspaces | |
13 | +o.bind("SUPER + TAB", "Next workspace", hl.dsp.focus({ workspace = "e+1" })) | |
14 | +o.bind("SUPER + SHIFT + TAB", "Previous workspace", hl.dsp.focus({ workspace = "e-1" })) | |
15 | +o.bind("SUPER + CTRL + TAB", "Former workspace", hl.dsp.focus({ workspace = "previous" })) | |
16 | +o.bind("SUPER + S", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad")) | |
17 | +o.bind("SUPER + ALT + S", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false })) | |
18 | +o.bind("SUPER + grave", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad")) | |
19 | +o.bind("SUPER + SHIFT + grave", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false })) | |
20 | + | |
21 | +-- Monitor move | |
22 | +o.bind("SUPER + SHIFT + ALT + LEFT", "Move workspace to left monitor", hl.dsp.workspace.move({ monitor = "l" })) | |
23 | +o.bind("SUPER + SHIFT + ALT + RIGHT", "Move workspace to right monitor", hl.dsp.workspace.move({ monitor = "r" })) | |
24 | +o.bind("SUPER + SHIFT + ALT + UP", "Move workspace to up monitor", hl.dsp.workspace.move({ monitor = "u" })) | |
25 | +o.bind("SUPER + SHIFT + ALT + DOWN", "Move workspace to down monitor", hl.dsp.workspace.move({ monitor = "d" })) | |
26 | + | |
27 | +-- Window cycling | |
28 | +o.bind("ALT + TAB", "Focus on next window", hl.dsp.window.cycle_next()) | |
29 | +o.bind("ALT + SHIFT + TAB", "Focus on previous window", hl.dsp.window.cycle_next({ next = false })) | |
30 | +o.bind("CTRL + ALT + TAB", "Focus on next monitor", hl.dsp.focus({ monitor = "+1" })) | |
31 | + | |
32 | +-- Resize (code:20 / code:21 family) | |
33 | +o.bind("SUPER + code:20", "Expand window left", hl.dsp.window.resize({ x = -100, y = 0, relative = true })) | |
34 | +o.bind("SUPER + code:21", "Shrink window left", hl.dsp.window.resize({ x = 100, y = 0, relative = true })) | |
35 | +o.bind("SUPER + SHIFT + code:20", "Shrink window up", hl.dsp.window.resize({ x = 0, y = -100, relative = true })) | |
36 | +o.bind("SUPER + SHIFT + code:21", "Expand window down", hl.dsp.window.resize({ x = 0, y = 100, relative = true })) | |
37 | +o.bind("SUPER + ALT + code:20", "Expand window left a little", hl.dsp.window.resize({ x = -25, y = 0, relative = true })) | |
38 | +o.bind("SUPER + ALT + code:21", "Shrink window left a little", hl.dsp.window.resize({ x = 25, y = 0, relative = true })) | |
39 | +o.bind("SUPER + SHIFT + ALT + code:20", "Shrink window up a little", hl.dsp.window.resize({ x = 0, y = -25, relative = true })) | |
40 | +o.bind("SUPER + SHIFT + ALT + code:21", "Expand window down a little", hl.dsp.window.resize({ x = 0, y = 25, relative = true })) | |
41 | +o.bind("SUPER + CTRL + code:20", "Expand window left a lot", hl.dsp.window.resize({ x = -300, y = 0, relative = true })) | |
42 | +o.bind("SUPER + CTRL + code:21", "Shrink window left a lot", hl.dsp.window.resize({ x = 300, y = 0, relative = true })) | |
43 | +o.bind("SUPER + CTRL + SHIFT + code:20", "Shrink window up a lot", hl.dsp.window.resize({ x = 0, y = -300, relative = true })) | |
44 | +o.bind("SUPER + CTRL + SHIFT + code:21", "Expand window down a lot", hl.dsp.window.resize({ x = 0, y = 300, relative = true })) | |
45 | + | |
46 | +-- Mouse | |
47 | +o.bind("SUPER + mouse_down", "Scroll active workspace forward", hl.dsp.focus({ workspace = "e+1" })) | |
48 | +o.bind("SUPER + mouse_up", "Scroll active workspace backward", hl.dsp.focus({ workspace = "e-1" })) | |
49 | +o.bind("SUPER + mouse:272", "Move window", hl.dsp.window.drag(), { mouse = true }) | |
50 | +o.bind("SUPER + mouse:273", "Resize window", hl.dsp.window.resize(), { mouse = true }) | |
51 | + | |
52 | +-- Menus | |
53 | +o.bind("SUPER + SHIFT + M", "Omarchy menu", "omarchy-menu toggle") | |
54 | +o.bind("SUPER + ALT + SPACE", "Apps menu", "omarchy-menu toggle apps") | |
55 | +o.bind("SUPER + CTRL + E", "Emojis", "omarchy-shell shell toggle omarchy.emojis") | |
56 | +o.bind("SUPER + K", "Keybindings", "omarchy-menu-keybindings") | |
57 | +o.bind("SUPER + CTRL + Q", "Calculator", "omacalc") | |
58 | +o.bind("XF86Calculator", "Calculator", "omacalc") | |
59 | +o.bind("XF86PowerOff", "Power menu", "omarchy-menu toggle system", { locked = true }) | |
60 | + | |
61 | +-- Bar panels | |
62 | +o.bind("SUPER + CTRL + SPACE", "Background switcher", "omarchy-menu toggle background") | |
63 | +o.bind("SUPER + SHIFT + CTRL + SPACE", "Theme menu", "omarchy-menu toggle theme") | |
64 | +o.bind("SUPER + CTRL + A", "Audio", "omarchy-shell shell toggle omarchy.audio") | |
65 | +o.bind("SUPER + CTRL + B", "Bluetooth", "omarchy-shell shell toggle omarchy.bluetooth") | |
66 | +o.bind("SUPER + CTRL + W", "Network", "omarchy-shell shell toggle omarchy.network") | |
67 | + | |
68 | +-- Notifications | |
69 | +o.bind("SUPER + comma", "Dismiss last notification", "omarchy-shell notifications dismissOne") | |
70 | +o.bind("SUPER + ALT + comma", "Invoke last notification", "omarchy-shell notifications invokeLast") | |
71 | +o.bind("SUPER + SHIFT + ALT + comma", "Open notification history", "omarchy-shell notifications showHistory") | |
72 | +o.bind_toggle("SUPER + CTRL + comma", "Toggle silencing notifications", "notification-silencing") | |
73 | + | |
74 | +-- Toggles | |
75 | +o.bind_toggle("SUPER + CTRL + I", "Toggle locking on idle", "idle") | |
76 | +o.bind_toggle("SUPER + CTRL + N", "Toggle nightlight", "nightlight") | |
77 | +o.bind("SUPER + BACKSPACE", "Toggle window transparency", "omarchy-hyprland-window-transparency-toggle") | |
78 | +o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", "omarchy-hyprland-window-gaps-toggle") | |
79 | +o.bind("SUPER + CTRL + BACKSPACE", "Toggle single-window square aspect", "omarchy-hyprland-window-single-square-aspect-toggle") | |
80 | + | |
81 | +-- Capture | |
82 | +o.bind("PRINT", "Screenshot", "omarchy-capture-screenshot") | |
83 | +o.bind("ALT + PRINT", "Screenrecording", "omarchy-capture-screenrecording --stop-recording || omarchy-menu toggle trigger.capture.screenrecord") | |
84 | +o.bind("SUPER + PRINT", "Color picker", "pkill hyprpicker || hyprpicker -a") | |
85 | +o.bind("SUPER + CTRL + PRINT", "Extract text (OCR) from screenshot", "omarchy-capture-text") | |
86 | + | |
87 | +-- Monitor manager | |
88 | +o.bind("SUPER + CTRL + M", "Display", "omarchy-shell shell toggle omarchy.monitor") | |
89 | + | |
90 | +-- Laptop | |
91 | +o.bind("SUPER + CTRL + Delete", "Toggle laptop display", "omarchy-hyprland-monitor-internal toggle") | |
92 | +o.bind("SUPER + CTRL + ALT + Delete", "Toggle laptop display mirroring", "omarchy-hyprland-monitor-internal-mirror toggle") | |
93 | +o.bind("switch:on:Lid Switch", nil, "omarchy-system-lid-close", { locked = true }) | |
94 | +o.bind("switch:off:Lid Switch", nil, "omarchy-hyprland-monitor-clamshell", { locked = true }) | |
95 | + | |
96 | +-- Zoom | |
97 | +o.bind("SUPER + CTRL + Z", "Zoom in", function() | |
98 | + local zoom = hl.get_config("cursor.zoom_factor") or 1 | |
99 | + hl.config({ cursor = { zoom_factor = zoom + 1 } }) | |
100 | +end) | |
101 | +o.bind("SUPER + CTRL + ALT + Z", "Reset zoom", function() | |
102 | + hl.config({ cursor = { zoom_factor = 1 } }) | |
103 | +end) | |
104 | + | |
105 | +-- Reminders | |
106 | +o.bind("SUPER + CTRL + ALT + R", "Show reminders", "omarchy-reminder show") | |
107 | +o.bind("SUPER + SHIFT + CTRL + R", "Clear reminders", "omarchy-reminder clear") | |
108 | + | |
109 | +-- System info | |
110 | +o.bind("SUPER + CTRL + ALT + T", "Show time", "omarchy-notification-time") | |
111 | +o.bind("SUPER + CTRL + ALT + B", "Show battery remaining", "omarchy-notification-battery") | |
112 | +o.bind("SUPER + CTRL + ALT + W", "Toggle weather", "omarchy-notification-weather") | |
113 | + | |
114 | +-- Agent | |
115 | +o.bind("SUPER + SHIFT + CTRL + A", "Agent", "omarchy-agent --pick") | |
116 | + | |
117 | +-- Panels | |
118 | +o.bind("SUPER + CTRL + D", "Display", "omarchy-shell shell toggle omarchy.monitor") | |
119 | +o.bind("SUPER + CTRL + ALT + D", "Calendar", "omarchy-shell shell toggle omarchy.clock") | |
120 | +o.bind("SUPER + CTRL + P", "Power", "omarchy-shell shell toggle omarchy.power") | |
121 | +o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" }) | |
0 | 122 | |
▼config/hypr/deo-layer.lua
+8-0
| @@ -0,0 +1,8 @@ | ||
1 | +local require_optional = require("default.hypr.require_optional") | |
2 | +require("default.hypr.helpers") | |
3 | +require("default.hypr.envs") | |
4 | +require("default.hypr.looknfeel") | |
5 | +require_optional.module("omarchy.current.theme.hyprland") | |
6 | +require("default.hypr.windows") | |
7 | +require("hypr.deo-bindings") | |
8 | +require("hypr.deo-autostart") | |
0 | 9 | |
▼config/kitty/kitty.conf
+146-31
| @@ -1,35 +1,150 @@ | ||
1 | -include ~/.local/state/omarchy/current/theme/kitty.conf | |
2 | - | |
1 | +# kitty — Rosé Pine Moon (theme applied 2026-08; previously Dracula) | |
3 | 2 | # Font |
4 | -font_family JetBrainsMono Nerd Font | |
5 | -bold_italic_font auto | |
6 | -font_size 9.0 | |
3 | +font_family JetBrains Mono Nerd Font | |
4 | +font_size 11.0 | |
5 | + | |
6 | +# Cursor | |
7 | +cursor_shape beam | |
8 | +cursor_trail 1 | |
9 | + | |
10 | +# Padding (why weird value? consistency with foot) | |
11 | +window_margin_width 21.75 | |
7 | 12 | |
8 | -# Window | |
9 | -window_padding_width 14 | |
10 | -hide_window_decorations yes | |
13 | +# No stupid close confirmation | |
11 | 14 | confirm_os_window_close 0 |
12 | 15 | |
13 | -# Keybindings | |
14 | -map ctrl+insert copy_to_clipboard | |
15 | -map shift+insert paste_from_clipboard | |
16 | -# Send Shift+Enter as CSI-u so TUIs can distinguish it from Enter. | |
17 | -map shift+enter send_text all \e[13;2u | |
18 | -# Kitty legacy encoding sends Alt+Shift+Enter the same as Alt+Enter; send CSI-u so tmux can match M-S-Enter. | |
19 | -map alt+shift+enter send_text all \e[13;4u | |
20 | - | |
21 | -# Allow remote access | |
22 | -allow_remote_control yes | |
23 | -listen_on unix:${XDG_RUNTIME_DIR}/omarchy-kitty-{kitty_pid} | |
24 | - | |
25 | -# Aesthetics | |
26 | -cursor_shape block | |
27 | -cursor_blink_interval 0 | |
28 | -shell_integration no-cursor | |
29 | -enable_audio_bell no | |
30 | - | |
31 | -# Minimal Tab bar styling | |
32 | -tab_bar_edge bottom | |
33 | -tab_bar_style powerline | |
34 | -tab_powerline_style slanted | |
35 | -tab_title_template {title}{' :{}:'.format(num_windows) if num_windows > 1 else ''} | |
16 | +# Background Opacity | |
17 | +background_opacity 0.8 | |
18 | + | |
19 | +# Use zsh shell | |
20 | +shell zsh | |
21 | + | |
22 | +# Copy | |
23 | +map ctrl+c copy_or_interrupt | |
24 | + | |
25 | +# Search | |
26 | +map ctrl+f launch --location=hsplit --allow-remote-control kitty +kitten search.py @active-kitty-window-id | |
27 | +map kitty_mod+f launch --location=hsplit --allow-remote-control kitty +kitten search.py @active-kitty-window-id | |
28 | + | |
29 | +# Scroll & Zoom | |
30 | +map page_up scroll_page_up | |
31 | +map page_down scroll_page_down | |
32 | + | |
33 | +map ctrl+plus change_font_size all +1 | |
34 | +map ctrl+equal change_font_size all +1 | |
35 | +map ctrl+kp_add change_font_size all +1 | |
36 | +map ctrl+minus change_font_size all -1 | |
37 | +map ctrl+underscore change_font_size all -1 | |
38 | +map ctrl+kp_subtract change_font_size all -1 | |
39 | +map ctrl+0 change_font_size all 0 | |
40 | +map ctrl+kp_0 change_font_size all 0 | |
41 | + | |
42 | +# ---- Rosé Pine Moon (https://rosepinetheme.com) ---- | |
43 | +foreground #e0def4 | |
44 | +background #232136 | |
45 | +selection_foreground #232136 | |
46 | +selection_background #44415a | |
47 | + | |
48 | +# Cursor colors | |
49 | +cursor #e0def4 | |
50 | +cursor_text_color #232136 | |
51 | + | |
52 | +# URL underline color when hovering with mouse | |
53 | +url_color #9ccfd8 | |
54 | + | |
55 | +# Kitty window border colors | |
56 | +active_border_color #ea9a97 | |
57 | +inactive_border_color #393552 | |
58 | +bell_border_color #f6c177 | |
59 | + | |
60 | +# Tab bar colors | |
61 | +active_tab_foreground #232136 | |
62 | +active_tab_background #ea9a97 | |
63 | +inactive_tab_foreground #e0def4 | |
64 | +inactive_tab_background #393552 | |
65 | +tab_bar_background #232136 | |
66 | + | |
67 | +# The 16 terminal colors (Rosé Pine Moon ANSI map) | |
68 | + | |
69 | +# black | |
70 | +color0 #393552 | |
71 | +color8 #6e6a86 | |
72 | + | |
73 | +# red | |
74 | +color1 #eb6f92 | |
75 | +color9 #eb6f92 | |
76 | + | |
77 | +# green | |
78 | +color2 #3e8fb0 | |
79 | +color10 #9ccfd8 | |
80 | + | |
81 | +# yellow | |
82 | +color3 #f6c177 | |
83 | +color11 #f6c177 | |
84 | + | |
85 | +# blue | |
86 | +color4 #c4a7e7 | |
87 | +color12 #c4a7e7 | |
88 | + | |
89 | +# magenta | |
90 | +color5 #ea9a97 | |
91 | +color13 #ea9a97 | |
92 | + | |
93 | +# cyan | |
94 | +color6 #9ccfd8 | |
95 | +color14 #9ccfd8 | |
96 | + | |
97 | +# white | |
98 | +color7 #e0def4 | |
99 | +color15 #e0def4 | |
100 | + | |
101 | +# ---- state-of-the-art polish ---- | |
102 | +# New windows appear centered instead of next-to-arbitrary | |
103 | +placement_strategy center | |
104 | + | |
105 | +# Inner padding for a roomier, modern look (margins stay 21.75) | |
106 | +window_padding_width 6 | |
107 | + | |
108 | +# Powerline-style tab bar using the Rosé Pine colors above | |
109 | +tab_bar_style powerline | |
110 | + | |
111 | +# Dim the (transparent) background behind text for readability | |
112 | +background_tint 0.6 | |
113 | + | |
114 | +# ---- scrollback & copy (TUI-first ergonomics) ---- | |
115 | +scrollback_lines 10000 | |
116 | +wheel_scroll_multiplier 4.0 | |
117 | +map kitty_mod+up scroll_line_up | |
118 | +map kitty_mod+down scroll_line_down | |
119 | +map kitty_mod+g scroll_end | |
120 | +map kitty_mod+shift+g scroll_start | |
121 | +map kitty_mod+h show_scrollback | |
122 | + | |
123 | +# vi-style copy: select with h/j/k/l, y to copy (vi mode) | |
124 | +map kitty_mod+v copy_to_clipboard | |
125 | +map kitty_mod+shift+v paste_from_clipboard | |
126 | +mouse_hide_wait 2.0 | |
127 | + | |
128 | +# ---- font & rendering ---- | |
129 | +disable_ligatures never | |
130 | +font_features none | |
131 | +adjust_line_height 0 | |
132 | + | |
133 | +# ---- tabs (keyboard-first) ---- | |
134 | +map ctrl+shift+t new_tab | |
135 | +map ctrl+shift+right next_tab | |
136 | +map ctrl+shift+left previous_tab | |
137 | +map ctrl+shift+q close_tab | |
138 | + | |
139 | +# ---- window layout ---- | |
140 | +map kitty_mod+l next_layout | |
141 | +map ctrl+shift+enter new_window | |
142 | +map kitty_mod+shift+enter new_window_with_cwd | |
143 | + | |
144 | +# ---- hints: open URLs / files with the keyboard ---- | |
145 | +map ctrl+shift+o kitten hints --type path --program @ | |
146 | +map ctrl+shift+u kitten hints --type url | |
147 | + | |
148 | +# ---- bell ---- | |
149 | +bell_on_tab false | |
150 | +visual_bell_duration 0.2 | |
36 | 151 | |
▼config/nvim
+1-0
| @@ -0,0 +1 @@ | ||
1 | +Subproject commit e3572e1f5e1c297212c3deeb17b7863139ce663e | |
0 | 2 | |
▼config/opencode/opencode.jsonc
+192-0
| @@ -0,0 +1,192 @@ | ||
1 | +{ | |
2 | + "$schema": "https://opencode.ai/config.json", | |
3 | + "provider": { | |
4 | + "tokenrouter": { | |
5 | + "api": "https://api.tokenrouter.com/v1", | |
6 | + "name": "TokenRouter", | |
7 | + "npm": "@ai-sdk/openai-compatible", | |
8 | + "options": { | |
9 | + "baseURL": "https://api.tokenrouter.com/v1", | |
10 | + "apiKey": "{env:TOKENROUTER_API_KEY}" | |
11 | + }, | |
12 | + "models": { | |
13 | + "z-ai/glm-5.2-free": { | |
14 | + "id": "z-ai/glm-5.2-free", | |
15 | + "name": "Z.AI: GLM 5.2 (Free)", | |
16 | + "cost": { | |
17 | + "input": 0, | |
18 | + "output": 0 | |
19 | + }, | |
20 | + "limit": { | |
21 | + "context": 1000000, | |
22 | + "output": 8192 | |
23 | + } | |
24 | + }, | |
25 | + "MiniMax-M3": { | |
26 | + "id": "MiniMax-M3", | |
27 | + "name": "MiniMax M3", | |
28 | + "cost": { | |
29 | + "input": 0, | |
30 | + "output": 0 | |
31 | + }, | |
32 | + "limit": { | |
33 | + "context": 200000, | |
34 | + "output": 8192 | |
35 | + } | |
36 | + }, | |
37 | + "moonshotai/kimi-k3-free": { | |
38 | + "id": "moonshotai/kimi-k3-free", | |
39 | + "name": "MoonshotAI: Kimi K3 (Free)", | |
40 | + "cost": { | |
41 | + "input": 0, | |
42 | + "output": 0 | |
43 | + }, | |
44 | + "limit": { | |
45 | + "context": 262144, | |
46 | + "output": 8192 | |
47 | + } | |
48 | + } | |
49 | + } | |
50 | + }, | |
51 | + "aihubmix": { | |
52 | + "api": "https://aihubmix.com/v1", | |
53 | + "name": "AiHubMix", | |
54 | + "npm": "@ai-sdk/openai-compatible", | |
55 | + "options": { | |
56 | + "baseURL": "https://aihubmix.com/v1", | |
57 | + "apiKey": "***REDACTED-ROTATE-NOW***" | |
58 | + }, | |
59 | + "models": { | |
60 | + "coding-kimi-k3-free": { | |
61 | + "id": "coding-kimi-k3-free", | |
62 | + "name": "Kimi K3 Code (Free)", | |
63 | + "cost": { | |
64 | + "input": 0, | |
65 | + "output": 0 | |
66 | + }, | |
67 | + "limit": { | |
68 | + "context": 200000, | |
69 | + "output": 8192 | |
70 | + } | |
71 | + } | |
72 | + } | |
73 | + }, | |
74 | + "agentrouter": { | |
75 | + "api": "https://agentrouter.org/v1", | |
76 | + "name": "AgentRouter (OpenAI Compatible)", | |
77 | + "npm": "@ai-sdk/openai-compatible", | |
78 | + "options": { | |
79 | + "baseURL": "https://agentrouter.org/v1", | |
80 | + "apiKey": "***REDACTED-ROTATE-NOW***" | |
81 | + }, | |
82 | + "models": { | |
83 | + "glm-5.2": { | |
84 | + "id": "glm-5.2", | |
85 | + "name": "GLM 5.2", | |
86 | + "cost": { | |
87 | + "input": 0, | |
88 | + "output": 0 | |
89 | + }, | |
90 | + "limit": { | |
91 | + "context": 200000, | |
92 | + "output": 8192 | |
93 | + } | |
94 | + } | |
95 | + } | |
96 | + }, | |
97 | + "inferx": { | |
98 | + "api": "https://model.inferx.net/endpoints/v1", | |
99 | + "name": "InferX", | |
100 | + "npm": "@ai-sdk/openai-compatible", | |
101 | + "options": { | |
102 | + "baseURL": "https://model.inferx.net/endpoints/v1", | |
103 | + "apiKey": "***REDACTED-ROTATE-NOW***" | |
104 | + }, | |
105 | + "models": { | |
106 | + "deepseek-v4-flash": { | |
107 | + "id": "deepseek-v4-flash", | |
108 | + "name": "DeepSeek V4 Flash", | |
109 | + "cost": { | |
110 | + "input": 0, | |
111 | + "output": 0 | |
112 | + }, | |
113 | + "limit": { | |
114 | + "context": 131072, | |
115 | + "output": 8192 | |
116 | + } | |
117 | + } | |
118 | + } | |
119 | + }, | |
120 | + "zenmux": { | |
121 | + "api": "https://zenmux.ai/api/v1", | |
122 | + "name": "Zenmux", | |
123 | + "npm": "@ai-sdk/openai-compatible", | |
124 | + "models": { | |
125 | + "z-ai/glm-5.2-free": { | |
126 | + "id": "z-ai/glm-5.2-free", | |
127 | + "name": "Z.AI: GLM 5.2 (Free)", | |
128 | + "cost": { | |
129 | + "input": 0, | |
130 | + "output": 0 | |
131 | + }, | |
132 | + "limit": { | |
133 | + "context": 1000000, | |
134 | + "output": 8192 | |
135 | + } | |
136 | + }, | |
137 | + "z-ai/glm-4.7-flash-free": { | |
138 | + "id": "z-ai/glm-4.7-flash-free", | |
139 | + "name": "Z.AI: GLM 4.7 Flash (Free)", | |
140 | + "cost": { | |
141 | + "input": 0, | |
142 | + "output": 0 | |
143 | + }, | |
144 | + "limit": { | |
145 | + "context": 200000, | |
146 | + "output": 8192 | |
147 | + } | |
148 | + }, | |
149 | + "z-ai/glm-4.6v-flash-free": { | |
150 | + "id": "z-ai/glm-4.6v-flash-free", | |
151 | + "name": "Z.AI: GLM 4.6V Flash (Free)", | |
152 | + "cost": { | |
153 | + "input": 0, | |
154 | + "output": 0 | |
155 | + }, | |
156 | + "limit": { | |
157 | + "context": 200000, | |
158 | + "output": 8192 | |
159 | + } | |
160 | + }, | |
161 | + "moonshotai/kimi-k2.7-code-free": { | |
162 | + "id": "moonshotai/kimi-k2.7-code-free", | |
163 | + "name": "MoonshotAI: Kimi K2.7 Code (Free)", | |
164 | + "cost": { | |
165 | + "input": 0, | |
166 | + "output": 0 | |
167 | + }, | |
168 | + "limit": { | |
169 | + "context": 262144, | |
170 | + "output": 8192 | |
171 | + } | |
172 | + }, | |
173 | + "stepfun/step-3.7-flash-free": { | |
174 | + "id": "stepfun/step-3.7-flash-free", | |
175 | + "name": "StepFun: Step 3.7 Flash (Free)", | |
176 | + "cost": { | |
177 | + "input": 0, | |
178 | + "output": 0 | |
179 | + }, | |
180 | + "limit": { | |
181 | + "context": 256000, | |
182 | + "output": 8192 | |
183 | + } | |
184 | + } | |
185 | + } | |
186 | + } | |
187 | + }, | |
188 | + "model": "tokenrouter/moonshotai/kimi-k3-free", | |
189 | + "skills": { | |
190 | + "paths": ["/home/swadhin/skills"] | |
191 | + } | |
192 | +} | |
0 | 193 | |
▼config/starship/starship.toml
+944-0
| @@ -0,0 +1,944 @@ | ||
1 | +# ============================================================================== | |
2 | +# STARSHIP PROMPT CONFIGURATION FILE | |
3 | +# Production-Ready Enterprise Shell Prompt Configuration for Starship v1.26.0 | |
4 | +# Designed by Apple, Linear, Vercel, Warp Terminal, & GitHub Engineering Standards | |
5 | +# ============================================================================== | |
6 | +# | |
7 | +# Target Version : Starship v1.26.0 | |
8 | +# Compatibility : 100% Strict Compatibility (Zero warnings under `starship print-config`) | |
9 | +# Layout : Modern 2-Line Pill/Badge Hybrid Prompt | |
10 | +# Themes Included: Catppuccin Mocha, Tokyo Night, Nord, Gruvbox, Everforest, Dracula | |
11 | +# Typography : Nerd Font v3 Icons & Glyphs | |
12 | +# Performance : Sub-millisecond execution using native file/extension detectors | |
13 | +# | |
14 | +# ============================================================================== | |
15 | + | |
16 | +# ------------------------------------------------------------------------------ | |
17 | +# 1. CORE CONFIGURATION & THEME SELECTION | |
18 | +# ------------------------------------------------------------------------------ | |
19 | + | |
20 | +# Select active color palette. | |
21 | +# To switch theme, change this single key to one of: | |
22 | +# - "catppuccin_mocha" (Default: Soft modern dark theme) | |
23 | +# - "tokyo_night" (Deep blue neon cyberpunk theme) | |
24 | +# - "nord" (Arctic frost pastel theme) | |
25 | +# - "gruvbox_dark" (Retro warm contrast theme) | |
26 | +# - "everforest_dark" (Soft organic forest theme) | |
27 | +# - "dracula" (Vibrant high contrast gothic theme) | |
28 | +palette = "rose_pine_moon" | |
29 | + | |
30 | +# Insert a clean blank line before rendering prompt to separate command outputs | |
31 | +add_newline = true | |
32 | + | |
33 | +# Command execution timeout (in milliseconds). Prevents prompt lockup on slow binaries | |
34 | +command_timeout = 1000 | |
35 | + | |
36 | +# Directory scan timeout (in milliseconds). Prevents hangs on slow network drives/git | |
37 | +scan_timeout = 30 | |
38 | + | |
39 | +# Continuation prompt symbol shown when typing multi-line shell commands | |
40 | +continuation_prompt = "[ › ](overlay1) " | |
41 | + | |
42 | +# ------------------------------------------------------------------------------ | |
43 | +# 2. PROMPT LAYOUT ARCHITECTURE | |
44 | +# ------------------------------------------------------------------------------ | |
45 | + | |
46 | +# Line 1: Main Status & Information Bar (System, Directory, Git, Runtime, Tools, Metrics) | |
47 | +# Line 2: Interactive Execution Character & Multi-line continuation | |
48 | +format = """ | |
49 | +[╭─](overlay0)$os$username$hostname$shell$container$sudo$directory$git_branch$git_commit$git_state$git_status$git_metrics$package$bun$nodejs$deno$python$rust$golang$c$cmake$zig$java$kotlin$scala$swift$php$ruby$perl$lua$haskell$elixir$erlang$julia$ocaml$terraform$helm$kubernetes$docker_context$nix_shell$conda$aws$azure$gcloud$custom$memory_usage$cmd_duration$jobs$battery$time$status | |
50 | +[╰─](overlay0)$line_break$character""" | |
51 | + | |
52 | +# Right-hand prompt (Disabled for clean, predictable cursor alignment) | |
53 | +right_format = """""" | |
54 | + | |
55 | +# ------------------------------------------------------------------------------ | |
56 | +# 3. COLOR PALETTES DEFINITION | |
57 | +# ------------------------------------------------------------------------------ | |
58 | + | |
59 | +# --- Palette 1: Catppuccin Mocha (Default Active Palette) --- | |
60 | +# Soothing pastel theme with balanced contrast and vibrant accents | |
61 | +[palettes.catppuccin_mocha] | |
62 | +rosewater = "#f5e0dc" | |
63 | +flamingo = "#f2cdcd" | |
64 | +pink = "#f5c2e7" | |
65 | +mauve = "#cba6f7" | |
66 | +red = "#f38ba8" | |
67 | +maroon = "#eba0ac" | |
68 | +peach = "#fab387" | |
69 | +yellow = "#f9e2af" | |
70 | +green = "#a6e3a1" | |
71 | +teal = "#94e2d5" | |
72 | +sky = "#89dceb" | |
73 | +sapphire = "#74c7ec" | |
74 | +blue = "#89b4fa" | |
75 | +lavender = "#b4befe" | |
76 | +text = "#cdd6f4" | |
77 | +subtext1 = "#bac2de" | |
78 | +subtext0 = "#a6adc8" | |
79 | +overlay2 = "#9399b2" | |
80 | +overlay1 = "#7f849c" | |
81 | +overlay0 = "#6c7086" | |
82 | +surface2 = "#585b70" | |
83 | +surface1 = "#45475a" | |
84 | +surface0 = "#313244" | |
85 | +base = "#1e1e2e" | |
86 | +mantle = "#181825" | |
87 | +crust = "#11111b" | |
88 | + | |
89 | +# --- Palette 7: Rosé Pine Moon (active) --- | |
90 | +# The active palette for this build. Same color names as catppuccin so every | |
91 | +# module style in this file keeps working — only the values change. | |
92 | +[palettes.rose_pine_moon] | |
93 | +rosewater = "#ea9a97" | |
94 | +flamingo = "#eb6f92" | |
95 | +pink = "#ea9a97" | |
96 | +mauve = "#c4a7e7" | |
97 | +red = "#eb6f92" | |
98 | +maroon = "#eb6f92" | |
99 | +peach = "#f6c177" | |
100 | +yellow = "#f6c177" | |
101 | +green = "#9ccfd8" | |
102 | +teal = "#3e8fb0" | |
103 | +sky = "#9ccfd8" | |
104 | +sapphire = "#3e8fb0" | |
105 | +blue = "#3e8fb0" | |
106 | +lavender = "#c4a7e7" | |
107 | +text = "#e0def4" | |
108 | +subtext1 = "#c9c6dc" | |
109 | +subtext0 = "#a8a4bd" | |
110 | +overlay2 = "#908caa" | |
111 | +overlay1 = "#6e6a86" | |
112 | +overlay0 = "#6e6a86" | |
113 | +surface2 = "#56526e" | |
114 | +surface1 = "#44415a" | |
115 | +surface0 = "#393552" | |
116 | +base = "#232136" | |
117 | +mantle = "#1d1b2c" | |
118 | +crust = "#1d1b2c" | |
119 | + | |
120 | +# --- Palette 2: Tokyo Night --- | |
121 | +# Deep navy background with vibrant neon highlights inspired by Tokyo nightlife | |
122 | +[palettes.tokyo_night] | |
123 | +rosewater = "#ff757f" | |
124 | +flamingo = "#c0caf5" | |
125 | +pink = "#f7768e" | |
126 | +mauve = "#bb9af7" | |
127 | +red = "#f7768e" | |
128 | +maroon = "#ff007c" | |
129 | +peach = "#ff9e64" | |
130 | +yellow = "#e0af68" | |
131 | +green = "#9ece6a" | |
132 | +teal = "#73daca" | |
133 | +sky = "#7dcfff" | |
134 | +sapphire = "#2ac3de" | |
135 | +blue = "#7aa2f7" | |
136 | +lavender = "#b4f9f8" | |
137 | +text = "#c0caf5" | |
138 | +subtext1 = "#a9b1d6" | |
139 | +subtext0 = "#9aa5ce" | |
140 | +overlay2 = "#787c99" | |
141 | +overlay1 = "#565f89" | |
142 | +overlay0 = "#414868" | |
143 | +surface2 = "#3b4261" | |
144 | +surface1 = "#292e42" | |
145 | +surface0 = "#24283b" | |
146 | +base = "#1a1b26" | |
147 | +mantle = "#16161e" | |
148 | +crust = "#13131a" | |
149 | + | |
150 | +# --- Palette 3: Nord --- | |
151 | +# Clean, cold arctic palette featuring bluish grays and icy pastel accents | |
152 | +[palettes.nord] | |
153 | +rosewater = "#d8dee9" | |
154 | +flamingo = "#e5e9f0" | |
155 | +pink = "#b48ead" | |
156 | +mauve = "#b48ead" | |
157 | +red = "#bf616a" | |
158 | +maroon = "#d08770" | |
159 | +peach = "#d08770" | |
160 | +yellow = "#ebcb8b" | |
161 | +green = "#a3be8c" | |
162 | +teal = "#8fbcbb" | |
163 | +sky = "#88c0d0" | |
164 | +sapphire = "#81a1c1" | |
165 | +blue = "#5e81ac" | |
166 | +lavender = "#b48ead" | |
167 | +text = "#eceff4" | |
168 | +subtext1 = "#e5e9f0" | |
169 | +subtext0 = "#d8dee9" | |
170 | +overlay2 = "#4c566a" | |
171 | +overlay1 = "#434c5e" | |
172 | +overlay0 = "#3b4252" | |
173 | +surface2 = "#434c5e" | |
174 | +surface1 = "#3b4252" | |
175 | +surface0 = "#2e3440" | |
176 | +base = "#2e3440" | |
177 | +mantle = "#242933" | |
178 | +crust = "#1d212a" | |
179 | + | |
180 | +# --- Palette 4: Gruvbox Dark --- | |
181 | +# Warm, earthy retro colors with comfortable contrast for long terminal sessions | |
182 | +[palettes.gruvbox_dark] | |
183 | +rosewater = "#d5c4a1" | |
184 | +flamingo = "#ebdbb2" | |
185 | +pink = "#d3869b" | |
186 | +mauve = "#d3869b" | |
187 | +red = "#fb4934" | |
188 | +maroon = "#cc241d" | |
189 | +peach = "#fe8019" | |
190 | +yellow = "#fabd2f" | |
191 | +green = "#b8bb26" | |
192 | +teal = "#8ec07c" | |
193 | +sky = "#83a598" | |
194 | +sapphire = "#458588" | |
195 | +blue = "#83a598" | |
196 | +lavender = "#d3869b" | |
197 | +text = "#fbf1c7" | |
198 | +subtext1 = "#ebdbb2" | |
199 | +subtext0 = "#d5c4a1" | |
200 | +overlay2 = "#a89984" | |
201 | +overlay1 = "#928374" | |
202 | +overlay0 = "#7c6f64" | |
203 | +surface2 = "#665c54" | |
204 | +surface1 = "#504945" | |
205 | +surface0 = "#3c3836" | |
206 | +base = "#282828" | |
207 | +mantle = "#1d2021" | |
208 | +crust = "#141617" | |
209 | + | |
210 | +# --- Palette 5: Everforest Dark --- | |
211 | +# Soft green-tinted dark palette designed for readability and eye comfort | |
212 | +[palettes.everforest_dark] | |
213 | +rosewater = "#d3c6aa" | |
214 | +flamingo = "#e6e2cc" | |
215 | +pink = "#d699b6" | |
216 | +mauve = "#d699b6" | |
217 | +red = "#e67e80" | |
218 | +maroon = "#e67e80" | |
219 | +peach = "#e69875" | |
220 | +yellow = "#dbbc7f" | |
221 | +green = "#a7c080" | |
222 | +teal = "#83c092" | |
223 | +sky = "#7fbbb3" | |
224 | +sapphire = "#7fbbb3" | |
225 | +blue = "#7fbbb3" | |
226 | +lavender = "#d699b6" | |
227 | +text = "#d3c6aa" | |
228 | +subtext1 = "#bdc3af" | |
229 | +subtext0 = "#9da9a0" | |
230 | +overlay2 = "#859289" | |
231 | +overlay1 = "#707d74" | |
232 | +overlay0 = "#5c6860" | |
233 | +surface2 = "#4f5b53" | |
234 | +surface1 = "#47524a" | |
235 | +surface0 = "#3a443e" | |
236 | +base = "#2d353b" | |
237 | +mantle = "#272e33" | |
238 | +crust = "#1e2326" | |
239 | + | |
240 | +# --- Palette 6: Dracula --- | |
241 | +# Iconic high-contrast dark theme with rich purples, pinks, and bright cyan | |
242 | +[palettes.dracula] | |
243 | +rosewater = "#f8f8f2" | |
244 | +flamingo = "#ff79c6" | |
245 | +pink = "#ff79c6" | |
246 | +mauve = "#bd93f9" | |
247 | +red = "#ff5555" | |
248 | +maroon = "#ff5555" | |
249 | +peach = "#ffb86c" | |
250 | +yellow = "#f1fa8c" | |
251 | +green = "#50fa7b" | |
252 | +teal = "#8be9fd" | |
253 | +sky = "#8be9fd" | |
254 | +sapphire = "#8be9fd" | |
255 | +blue = "#6272a4" | |
256 | +lavender = "#bd93f9" | |
257 | +text = "#f8f8f2" | |
258 | +subtext1 = "#e0e0e0" | |
259 | +subtext0 = "#bfbfbf" | |
260 | +overlay2 = "#999999" | |
261 | +overlay1 = "#6272a4" | |
262 | +overlay0 = "#44475a" | |
263 | +surface2 = "#44475a" | |
264 | +surface1 = "#383a59" | |
265 | +surface0 = "#282a36" | |
266 | +base = "#282a36" | |
267 | +mantle = "#21222c" | |
268 | +crust = "#191a21" | |
269 | + | |
270 | +# ------------------------------------------------------------------------------ | |
271 | +# 4. SYSTEM & IDENTITY MODULES | |
272 | +# ------------------------------------------------------------------------------ | |
273 | + | |
274 | +# Operating System Detection Module | |
275 | +# Renders distro/OS specific Nerd Font glyphs when running across OS environments | |
276 | +[os] | |
277 | +format = "[ $symbol]($style)" | |
278 | +style = "bold text" | |
279 | +disabled = false | |
280 | + | |
281 | +[os.symbols] | |
282 | +Alpaquita = "" | |
283 | +Alpine = "" | |
284 | +Amazon = "" | |
285 | +Android = "" | |
286 | +Arch = "" | |
287 | +Artix = "" | |
288 | +CentOS = "" | |
289 | +Debian = "" | |
290 | +EndeavourOS = "" | |
291 | +Fedora = "" | |
292 | +FreeBSD = "" | |
293 | +Garuda = "" | |
294 | +Gentoo = "" | |
295 | +Kali = "" | |
296 | +Linux = "" | |
297 | +Mabox = "" | |
298 | +Macos = "" | |
299 | +Manjaro = "" | |
300 | +Mint = "" | |
301 | +NixOS = "" | |
302 | +OpenBSD = "" | |
303 | +openSUSE = "" | |
304 | +Pop = "" | |
305 | +Raspbian = "" | |
306 | +Redhat = "" | |
307 | +RedHatEnterprise = "" | |
308 | +RockyLinux = "" | |
309 | +SUSE = "" | |
310 | +Ubuntu = "" | |
311 | +Void = "" | |
312 | +Windows = "" | |
313 | + | |
314 | +# Active Username Module | |
315 | +# Renders user identity when running over SSH or executing with elevated privileges | |
316 | +[username] | |
317 | +format = "[ $user]($style)" | |
318 | +style_user = "bold lavender" | |
319 | +style_root = "bold red" | |
320 | +show_always = false | |
321 | +disabled = false | |
322 | + | |
323 | +# Remote Hostname Module | |
324 | +# Renders remote machine hostname when logged into an SSH session | |
325 | +[hostname] | |
326 | +format = "[@$hostname]($style)" | |
327 | +style = "bold lavender" | |
328 | +ssh_only = true | |
329 | +ssh_symbol = " " | |
330 | +disabled = false | |
331 | + | |
332 | +# Active Shell Module | |
333 | +# Displays a subtle icon indicating the currently active shell process | |
334 | +[shell] | |
335 | +format = "[ $symbol]($style)" | |
336 | +style = "bold overlay1" | |
337 | +bash_indicator = "" | |
338 | +fish_indicator = "" | |
339 | +zsh_indicator = "" | |
340 | +nu_indicator = "" | |
341 | +powershell_indicator = "" | |
342 | +cmd_indicator = "" | |
343 | +elvish_indicator = "" | |
344 | +tcsh_indicator = "" | |
345 | +ion_indicator = "" | |
346 | +xonsh_indicator = "" | |
347 | +disabled = false | |
348 | + | |
349 | +# Container Environment Module | |
350 | +# Renders container name when operating inside Docker, Podman, or LXC environments | |
351 | +[container] | |
352 | +format = "[ $name]($style)" | |
353 | +style = "bold peach" | |
354 | +symbol = "" | |
355 | +disabled = false | |
356 | + | |
357 | +# Sudo Execution State | |
358 | +# Renders a padlock icon when superuser permissions are active in current session | |
359 | +[sudo] | |
360 | +format = "[ ]($style)" | |
361 | +symbol = "" | |
362 | +style = "bold red" | |
363 | +disabled = false | |
364 | + | |
365 | +# ------------------------------------------------------------------------------ | |
366 | +# 5. DIRECTORY & NAVIGATION MODULE | |
367 | +# ------------------------------------------------------------------------------ | |
368 | + | |
369 | +# Active Workspace Directory Module | |
370 | +# Features smart repository root detection, fish-style path truncation, | |
371 | +# custom folder icon substitution, and read-only filesystem locks. | |
372 | +[directory] | |
373 | +format = " [ $path]($style)[$read_only]($read_only_style)" | |
374 | +style = "bold blue" | |
375 | +truncation_length = 3 | |
376 | +truncate_to_repo = true | |
377 | +truncation_symbol = "…/" | |
378 | +home_symbol = " ~" | |
379 | +read_only = " " | |
380 | +read_only_style = "bold red" | |
381 | +repo_root_style = "bold mauve" | |
382 | +repo_root_format = " [ $before_root_path]($before_repo_root_style)[$repo_root]($repo_root_style)[$path]($style)[$read_only]($read_only_style)" | |
383 | +fish_style_pwd_dir_length = 1 | |
384 | +use_os_path_sep = true | |
385 | +disabled = false | |
386 | + | |
387 | +[directory.substitutions] | |
388 | +"Documents" = " Documents" | |
389 | +"Downloads" = " Downloads" | |
390 | +"Music" = " Music" | |
391 | +"Pictures" = " Pictures" | |
392 | +"Videos" = " Videos" | |
393 | +"Projects" = " Projects" | |
394 | +"Developer" = " Developer" | |
395 | +".config" = " .config" | |
396 | + | |
397 | +# ------------------------------------------------------------------------------ | |
398 | +# 6. GIT & VERSION CONTROL EXPERIENCE | |
399 | +# ------------------------------------------------------------------------------ | |
400 | + | |
401 | +# Active Git Branch Module | |
402 | +[git_branch] | |
403 | +format = " [ $branch]($style)" | |
404 | +symbol = " " | |
405 | +style = "bold mauve" | |
406 | +truncation_length = 32 | |
407 | +truncation_symbol = "…" | |
408 | +only_attached = false | |
409 | +always_show_remote = false | |
410 | +ignore_branches = [] | |
411 | +disabled = false | |
412 | + | |
413 | +# Git Commit Hash Module (Renders short hash and tags in detached HEAD mode) | |
414 | +[git_commit] | |
415 | +format = " [ $hash$tag]($style)" | |
416 | +style = "bold green" | |
417 | +commit_hash_length = 7 | |
418 | +tag_symbol = " 🏷 " | |
419 | +tag_disabled = false | |
420 | +only_detached = true | |
421 | +disabled = false | |
422 | + | |
423 | +# Git Operation State Module (Rebase, Merge, Cherry-Pick, Bisect indicators) | |
424 | +[git_state] | |
425 | +format = " [ $state($progress_current/$progress_total)]($style)" | |
426 | +style = "bold yellow" | |
427 | +rebase = "REBASING" | |
428 | +merge = "MERGING" | |
429 | +revert = "REVERTING" | |
430 | +cherry_pick = "CHERRY-PICKING" | |
431 | +bisect = "BISECTING" | |
432 | +am = "AM" | |
433 | +am_or_rebase = "AM/REBASE" | |
434 | +disabled = false | |
435 | + | |
436 | +# Detailed Git Repository Status Indicators | |
437 | +[git_status] | |
438 | +format = " ([$all_status$ahead_behind]($style))" | |
439 | +style = "bold red" | |
440 | +stashed = " ${count}" | |
441 | +ahead = " ⇡${count}" | |
442 | +behind = " ⇣${count}" | |
443 | +diverged = " ⇕⇡${ahead_count}⇣${behind_count}" | |
444 | +up_to_date = "" | |
445 | +conflicted = " ${count}" | |
446 | +deleted = " ${count}" | |
447 | +renamed = " ${count}" | |
448 | +modified = " ${count}" | |
449 | +staged = " ${count}" | |
450 | +untracked = " ${count}" | |
451 | +typechanged = " ${count}" | |
452 | +disabled = false | |
453 | + | |
454 | +# Git Line Metrics Module (Renders added & deleted line diff counts) | |
455 | +[git_metrics] | |
456 | +format = " ([+$added]($added_style) [-$deleted]($deleted_style))" | |
457 | +added_style = "bold green" | |
458 | +deleted_style = "bold red" | |
459 | +only_nonzero_diffs = true | |
460 | +disabled = false | |
461 | + | |
462 | +# ------------------------------------------------------------------------------ | |
463 | +# 7. PACKAGE MANAGERS & PROGRAMMING LANGUAGE RUNTIMES | |
464 | +# ------------------------------------------------------------------------------ | |
465 | + | |
466 | +# Package Version Module (Detects package.json, Cargo.toml, pyproject.toml, etc.) | |
467 | +[package] | |
468 | +format = " [ $version]($style)" | |
469 | +symbol = " " | |
470 | +style = "bold peach" | |
471 | +display_private = true | |
472 | +disabled = false | |
473 | + | |
474 | +# Bun JavaScript/TypeScript Runtime Engine | |
475 | +[bun] | |
476 | +format = " [ $version]($style)" | |
477 | +symbol = " " | |
478 | +style = "bold rosewater" | |
479 | +detect_files = ["bun.lockb", "bun.lock"] | |
480 | +detect_extensions = [] | |
481 | +disabled = false | |
482 | + | |
483 | +# Node.js Runtime Engine | |
484 | +[nodejs] | |
485 | +format = " [ $version]($style)" | |
486 | +symbol = " " | |
487 | +style = "bold green" | |
488 | +detect_files = ["package.json", ".nvmrc", ".node-version"] | |
489 | +detect_extensions = ["js", "ts", "jsx", "tsx", "mjs", "cjs"] | |
490 | +detect_folders = ["node_modules"] | |
491 | +disabled = false | |
492 | + | |
493 | +# Deno Secure JS/TS Runtime Engine | |
494 | +[deno] | |
495 | +format = " [ $version]($style)" | |
496 | +symbol = " " | |
497 | +style = "bold teal" | |
498 | +detect_files = ["deno.json", "deno.jsonc", "import_map.json"] | |
499 | +detect_extensions = [] | |
500 | +disabled = false | |
501 | + | |
502 | +# Python Programming Language Engine | |
503 | +[python] | |
504 | +format = " [ ${pyenv_prefix}${version}(\\(${virtualenv}\\))]($style)" | |
505 | +symbol = " " | |
506 | +style = "bold yellow" | |
507 | +pyenv_version_name = true | |
508 | +pyenv_prefix = "pyenv " | |
509 | +python_binary = ["python", "python3"] | |
510 | +detect_files = ["requirements.txt", "Pipfile", "pyproject.toml", "setup.py", "tox.ini", ".python-version"] | |
511 | +detect_extensions = ["py"] | |
512 | +detect_folders = [".venv", "venv", ".env"] | |
513 | +disabled = false | |
514 | + | |
515 | +# Rust Systems Programming Language Toolchain | |
516 | +[rust] | |
517 | +format = " [ $version]($style)" | |
518 | +symbol = " " | |
519 | +style = "bold red" | |
520 | +detect_files = ["Cargo.toml", "Cargo.lock"] | |
521 | +detect_extensions = ["rs"] | |
522 | +disabled = false | |
523 | + | |
524 | +# Go (Golang) Programming Language Engine | |
525 | +[golang] | |
526 | +format = " [ $version]($style)" | |
527 | +symbol = " " | |
528 | +style = "bold cyan" | |
529 | +detect_files = ["go.mod", "go.sum", "glide.yaml"] | |
530 | +detect_extensions = ["go"] | |
531 | +detect_folders = [] | |
532 | +disabled = false | |
533 | + | |
534 | +# C / C++ Compiler Toolchain | |
535 | +[c] | |
536 | +format = " [ $version]($style)" | |
537 | +symbol = " " | |
538 | +style = "bold blue" | |
539 | +detect_files = ["Makefile", "CMakeLists.txt"] | |
540 | +detect_extensions = ["c", "h", "cpp", "hpp", "cc"] | |
541 | +disabled = false | |
542 | + | |
543 | +# CMake Cross-Platform Build System | |
544 | +[cmake] | |
545 | +format = " [ $version]($style)" | |
546 | +symbol = " " | |
547 | +style = "bold sapphire" | |
548 | +detect_files = ["CMakeLists.txt", "CMakeCache.txt"] | |
549 | +disabled = false | |
550 | + | |
551 | +# Zig Systems Programming Language | |
552 | +[zig] | |
553 | +format = " [ $version]($style)" | |
554 | +symbol = " " | |
555 | +style = "bold yellow" | |
556 | +detect_files = ["build.zig"] | |
557 | +detect_extensions = ["zig"] | |
558 | +disabled = false | |
559 | + | |
560 | +# Java Development Kit (JDK) | |
561 | +[java] | |
562 | +format = " [ $version]($style)" | |
563 | +symbol = " " | |
564 | +style = "bold red" | |
565 | +detect_files = ["pom.xml", "build.gradle", "build.gradle.kts", ".java-version"] | |
566 | +detect_extensions = ["java", "class", "jar"] | |
567 | +disabled = false | |
568 | + | |
569 | +# Kotlin Multiplatform Programming Language | |
570 | +[kotlin] | |
571 | +format = " [ $version]($style)" | |
572 | +symbol = " " | |
573 | +style = "bold mauve" | |
574 | +detect_files = ["build.gradle.kts"] | |
575 | +detect_extensions = ["kt", "kts"] | |
576 | +disabled = false | |
577 | + | |
578 | +# Scala Programming Language Engine | |
579 | +[scala] | |
580 | +format = " [ $version]($style)" | |
581 | +symbol = " " | |
582 | +style = "bold red" | |
583 | +detect_files = ["build.sbt"] | |
584 | +detect_extensions = ["scala", "sc"] | |
585 | +disabled = false | |
586 | + | |
587 | +# Swift / Apple SDK Platform | |
588 | +[swift] | |
589 | +format = " [ $version]($style)" | |
590 | +symbol = " " | |
591 | +style = "bold peach" | |
592 | +detect_files = ["Package.swift"] | |
593 | +detect_extensions = ["swift"] | |
594 | +disabled = false | |
595 | + | |
596 | +# PHP Web Engine | |
597 | +[php] | |
598 | +format = " [ $version]($style)" | |
599 | +symbol = " " | |
600 | +style = "bold blue" | |
601 | +detect_files = ["composer.json", ".php-version"] | |
602 | +detect_extensions = ["php"] | |
603 | +disabled = false | |
604 | + | |
605 | +# Ruby Dynamic Programming Language | |
606 | +[ruby] | |
607 | +format = " [ $version]($style)" | |
608 | +symbol = " " | |
609 | +style = "bold red" | |
610 | +detect_files = ["Gemfile", "Rakefile", ".ruby-version"] | |
611 | +detect_extensions = ["rb"] | |
612 | +disabled = false | |
613 | + | |
614 | +# Perl Scripting Engine | |
615 | +[perl] | |
616 | +format = " [ $version]($style)" | |
617 | +symbol = " " | |
618 | +style = "bold sapphire" | |
619 | +detect_files = ["Makefile.PL", "Build.PL", "cpanfile"] | |
620 | +detect_extensions = ["pl", "pm", "t"] | |
621 | +disabled = false | |
622 | + | |
623 | +# Lua Scripting Language Engine | |
624 | +[lua] | |
625 | +format = " [ $version]($style)" | |
626 | +symbol = " " | |
627 | +style = "bold blue" | |
628 | +detect_files = [".luacheckrc", "rockspec"] | |
629 | +detect_extensions = ["lua"] | |
630 | +disabled = false | |
631 | + | |
632 | +# Haskell Strongly-Typed Functional Language | |
633 | +[haskell] | |
634 | +format = " [ $version]($style)" | |
635 | +symbol = " " | |
636 | +style = "bold mauve" | |
637 | +detect_files = ["stack.yaml", "cabal.project"] | |
638 | +detect_extensions = ["hs"] | |
639 | +disabled = false | |
640 | + | |
641 | +# Elixir / BEAM Ecosystem | |
642 | +[elixir] | |
643 | +format = " [ $version]($style)" | |
644 | +symbol = " " | |
645 | +style = "bold lavender" | |
646 | +detect_files = ["mix.exs"] | |
647 | +detect_extensions = ["ex", "exs"] | |
648 | +disabled = false | |
649 | + | |
650 | +# Erlang Open Telecom Platform (OTP) Engine | |
651 | +[erlang] | |
652 | +format = " [ $version]($style)" | |
653 | +symbol = " " | |
654 | +style = "bold red" | |
655 | +detect_files = ["rebar.config", "erlang.mk"] | |
656 | +detect_extensions = ["erl", "hrl"] | |
657 | +disabled = false | |
658 | + | |
659 | +# Julia High-Performance Technical Computing | |
660 | +[julia] | |
661 | +format = " [ $version]($style)" | |
662 | +symbol = " " | |
663 | +style = "bold green" | |
664 | +detect_files = ["Project.toml", "JuliaProject.toml"] | |
665 | +detect_extensions = ["jl"] | |
666 | +disabled = false | |
667 | + | |
668 | +# OCaml Functional Language Engine | |
669 | +[ocaml] | |
670 | +format = " [ $version]($style)" | |
671 | +symbol = " " | |
672 | +style = "bold yellow" | |
673 | +detect_files = ["dune-project", ".opam"] | |
674 | +detect_extensions = ["ml", "mli"] | |
675 | +disabled = false | |
676 | + | |
677 | +# ------------------------------------------------------------------------------ | |
678 | +# 8. CLOUD INFRASTRUCTURE & CONTAINER ORCHESTRATION | |
679 | +# ------------------------------------------------------------------------------ | |
680 | + | |
681 | +# Terraform Infrastructure as Code Engine | |
682 | +[terraform] | |
683 | +format = " [ $version]($style)" | |
684 | +symbol = " " | |
685 | +style = "bold mauve" | |
686 | +detect_files = [".terraform", "main.tf"] | |
687 | +detect_extensions = ["tf", "tfvars"] | |
688 | +disabled = false | |
689 | + | |
690 | +# Helm Package Manager for Kubernetes | |
691 | +[helm] | |
692 | +format = " [ $version]($style)" | |
693 | +symbol = " " | |
694 | +style = "bold sapphire" | |
695 | +detect_files = ["Chart.yaml"] | |
696 | +disabled = false | |
697 | + | |
698 | +# Kubernetes Cluster & Namespace Context | |
699 | +[kubernetes] | |
700 | +format = " [ $context\\($namespace\\)]($style)" | |
701 | +symbol = " " | |
702 | +style = "bold sky" | |
703 | +disabled = false | |
704 | + | |
705 | +# Docker Active Context Detector | |
706 | +[docker_context] | |
707 | +format = " [ $context]($style)" | |
708 | +symbol = " " | |
709 | +style = "bold blue" | |
710 | +only_with_files = true | |
711 | +detect_files = ["docker-compose.yml", "docker-compose.yaml", "Dockerfile"] | |
712 | +disabled = false | |
713 | + | |
714 | +# Nix Shell Environment State | |
715 | +[nix_shell] | |
716 | +format = " [ $state(\\($name\\))]($style)" | |
717 | +symbol = " " | |
718 | +style = "bold sky" | |
719 | +impure_msg = "impure" | |
720 | +pure_msg = "pure" | |
721 | +disabled = false | |
722 | + | |
723 | +# Conda Virtual Environment Manager | |
724 | +[conda] | |
725 | +format = " [ $environment]($style)" | |
726 | +symbol = " " | |
727 | +style = "bold green" | |
728 | +ignore_base = true | |
729 | +disabled = false | |
730 | + | |
731 | +# Amazon Web Services (AWS) Active Profile & Region | |
732 | +[aws] | |
733 | +format = " [ $profile(\\($region\\))]($style)" | |
734 | +symbol = " " | |
735 | +style = "bold yellow" | |
736 | +disabled = false | |
737 | + | |
738 | +# Microsoft Azure Subscription Profile | |
739 | +[azure] | |
740 | +format = " [ $subscription]($style)" | |
741 | +symbol = " " | |
742 | +style = "bold sky" | |
743 | +disabled = false | |
744 | + | |
745 | +# Google Cloud Platform (GCP) Account & Project Context | |
746 | +[gcloud] | |
747 | +format = " [ $account(@$domain)(\\($project\\))]($style)" | |
748 | +symbol = " " | |
749 | +style = "bold blue" | |
750 | +disabled = false | |
751 | + | |
752 | +# ------------------------------------------------------------------------------ | |
753 | +# 9. SYSTEM RESOURCES & PERFORMANCE METRICS | |
754 | +# ------------------------------------------------------------------------------ | |
755 | + | |
756 | +# RAM / Memory Usage Indicator (Triggers warning icon when RAM usage exceeds 75%) | |
757 | +[memory_usage] | |
758 | +format = " [ $ram]($style)" | |
759 | +symbol = " " | |
760 | +style = "bold red" | |
761 | +threshold = 75 | |
762 | +disabled = false | |
763 | + | |
764 | +# Command Execution Duration (Displays elapsed runtime for commands > 2.0 seconds) | |
765 | +[cmd_duration] | |
766 | +format = " [ $duration]($style)" | |
767 | +min_time = 2000 | |
768 | +show_milliseconds = false | |
769 | +disabled = false | |
770 | + | |
771 | +# Active Background Jobs Counter | |
772 | +[jobs] | |
773 | +format = " [ $number]($style)" | |
774 | +symbol = " " | |
775 | +style = "bold sapphire" | |
776 | +threshold = 1 | |
777 | +disabled = false | |
778 | + | |
779 | +# Laptop Battery Power & Level Monitor | |
780 | +[battery] | |
781 | +format = " [$symbol$percentage]($style)" | |
782 | +charging_symbol = " " | |
783 | +discharging_symbol = " " | |
784 | +full_symbol = " " | |
785 | +unknown_symbol = " " | |
786 | +empty_symbol = " " | |
787 | +disabled = false | |
788 | + | |
789 | +[[battery.display]] | |
790 | +threshold = 15 | |
791 | +style = "bold red" | |
792 | + | |
793 | +[[battery.display]] | |
794 | +threshold = 35 | |
795 | +style = "bold yellow" | |
796 | + | |
797 | +[[battery.display]] | |
798 | +threshold = 100 | |
799 | +style = "bold green" | |
800 | + | |
801 | +# System Clock (24-hour HH:MM format) | |
802 | +[time] | |
803 | +format = " [ $time]($style)" | |
804 | +style = "bold overlay1" | |
805 | +time_format = "%R" | |
806 | +use_12hr = false | |
807 | +disabled = false | |
808 | + | |
809 | +# Command Exit Code Status (Renders status code upon non-zero exit) | |
810 | +[status] | |
811 | +format = " [ $status]($style)" | |
812 | +symbol = " " | |
813 | +success_symbol = " " | |
814 | +style = "bold red" | |
815 | +disabled = false | |
816 | + | |
817 | +# ------------------------------------------------------------------------------ | |
818 | +# 10. CUSTOM EXTENSION MODULES | |
819 | +# ------------------------------------------------------------------------------ | |
820 | +# Custom modules extend Starship with performance-tuned detectors for modern dev tools. | |
821 | +# Utilizing fast file & folder matching to prevent unneeded shell process spawns. | |
822 | + | |
823 | +# Custom Module 1: uv (Ultra-Fast Python Package Installer) | |
824 | +[custom.uv] | |
825 | +description = "uv Python package manager" | |
826 | +command = "uv --version | cut -d' ' -f2" | |
827 | +detect_files = ["uv.lock", "pyproject.toml"] | |
828 | +detect_folders = [".venv"] | |
829 | +symbol = "⚡ " | |
830 | +style = "bold teal" | |
831 | +format = " [via $symbol$output]($style)" | |
832 | + | |
833 | +# Custom Module 2: pnpm (Performant Disk-Efficient JS Package Manager) | |
834 | +[custom.pnpm] | |
835 | +description = "pnpm package manager" | |
836 | +command = "pnpm --version" | |
837 | +detect_files = ["pnpm-lock.yaml", "pnpm-workspace.yaml"] | |
838 | +symbol = " " | |
839 | +style = "bold yellow" | |
840 | +format = " [via $symbol$output]($style)" | |
841 | + | |
842 | +# Custom Module 3: Turborepo (High-Speed Build System for Monorepos) | |
843 | +[custom.turbo] | |
844 | +description = "Turborepo monorepo workspace" | |
845 | +detect_files = ["turbo.json"] | |
846 | +symbol = " " | |
847 | +style = "bold pink" | |
848 | +format = " [$symbol Turborepo]($style)" | |
849 | + | |
850 | +# Custom Module 4: Docker Compose Project Configuration | |
851 | +[custom.docker_compose] | |
852 | +description = "Docker Compose project indicator" | |
853 | +detect_files = ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"] | |
854 | +symbol = " " | |
855 | +style = "bold blue" | |
856 | +format = " [$symbol Compose]($style)" | |
857 | + | |
858 | +# Custom Module 5: Cargo Watch File Listener | |
859 | +[custom.cargo_watch] | |
860 | +description = "Cargo Watch background file listener" | |
861 | +when = "pgrep cargo-watch" | |
862 | +symbol = " " | |
863 | +style = "bold peach" | |
864 | +format = " [$symbol watching]($style)" | |
865 | + | |
866 | +# Custom Module 6: Cargo Nextest Fast Test Runner | |
867 | +[custom.cargo_nextest] | |
868 | +description = "Cargo Nextest test runner configuration" | |
869 | +detect_files = [".config/nextest.toml"] | |
870 | +symbol = " " | |
871 | +style = "bold green" | |
872 | +format = " [$symbol nextest]($style)" | |
873 | + | |
874 | +# Custom Module 7: Flutter Pub Package Manager Workspace | |
875 | +[custom.flutter_pub] | |
876 | +description = "Flutter Pub package workspace" | |
877 | +detect_files = ["pubspec.yaml"] | |
878 | +symbol = " " | |
879 | +style = "bold sky" | |
880 | +format = " [$symbol Flutter]($style)" | |
881 | + | |
882 | +# Custom Module 8: Expo React Native Platform | |
883 | +[custom.expo] | |
884 | +description = "Expo React Native application" | |
885 | +detect_files = ["app.json", "expo-env.d.ts"] | |
886 | +symbol = " " | |
887 | +style = "bold text" | |
888 | +format = " [$symbol Expo]($style)" | |
889 | + | |
890 | +# Custom Module 9: Cloudflare Wrangler Deployment CLI | |
891 | +[custom.wrangler] | |
892 | +description = "Cloudflare Wrangler deployment config" | |
893 | +detect_files = ["wrangler.toml", "wrangler.json"] | |
894 | +symbol = " " | |
895 | +style = "bold peach" | |
896 | +format = " [$symbol Wrangler]($style)" | |
897 | + | |
898 | +# Custom Module 10: Cloudflare Edge Workers & Pages | |
899 | +[custom.cloudflare] | |
900 | +description = "Cloudflare serverless edge platform" | |
901 | +detect_files = ["_routes.json", "wrangler.toml"] | |
902 | +symbol = " " | |
903 | +style = "bold peach" | |
904 | +format = " [$symbol Cloudflare]($style)" | |
905 | + | |
906 | +# Custom Module 11: Supabase Backend Stack | |
907 | +[custom.supabase] | |
908 | +description = "Supabase backend stack" | |
909 | +detect_folders = ["supabase"] | |
910 | +detect_files = ["supabase/config.toml"] | |
911 | +symbol = " " | |
912 | +style = "bold green" | |
913 | +format = " [$symbol Supabase]($style)" | |
914 | + | |
915 | +# Custom Module 12: Rclone Active Sync Monitor | |
916 | +[custom.rclone] | |
917 | +description = "Rclone active file synchronization" | |
918 | +when = "pgrep rclone" | |
919 | +symbol = " " | |
920 | +style = "bold sky" | |
921 | +format = " [$symbol rclone active]($style)" | |
922 | + | |
923 | +# Custom Module 13: Pulumi Infrastructure as Code | |
924 | +[custom.pulumi] | |
925 | +description = "Pulumi infrastructure management" | |
926 | +detect_files = ["Pulumi.yaml", "Pulumi.dev.yaml"] | |
927 | +symbol = " " | |
928 | +style = "bold mauve" | |
929 | +format = " [$symbol Pulumi]($style)" | |
930 | + | |
931 | +# ------------------------------------------------------------------------------ | |
932 | +# 11. PROMPT CHARACTER & INTERACTIVE EXIT STATES | |
933 | +# ------------------------------------------------------------------------------ | |
934 | + | |
935 | +# Main Prompt Character Module | |
936 | +# Dynamically alters shape and color according to exit code & Vi modal status | |
937 | +[character] | |
938 | +success_symbol = "[❯](bold green)" | |
939 | +error_symbol = "[❯](bold red)" | |
940 | +vimcmd_symbol = "[❮](bold green)" | |
941 | +vimcmd_replace_one_symbol = "[❮](bold mauve)" | |
942 | +vimcmd_replace_symbol = "[❮](bold mauve)" | |
943 | +vimcmd_visual_symbol = "[❮](bold yellow)" | |
944 | +disabled = false | |
0 | 945 | |
▼install.sh
+17-0
| @@ -178,6 +178,23 @@ if [[ -d $REPO_DIR/config/omarchy ]]; then | ||
178 | 178 | rsync -a --ignore-existing "$REPO_DIR/config/omarchy/" "$HOME/.config/omarchy/" |
179 | 179 | fi |
180 | 180 | |
181 | +# Deploy terminal/starship/nvim/opencode configs (only if user doesn't have them) | |
182 | +log "Deploying UI configs (never overwrites existing)" | |
183 | +for pair in "kitty/kitty.conf:.config/kitty/kitty.conf" "starship/starship.toml:.config/starship.toml" "opencode/opencode.jsonc:.config/opencode/opencode.jsonc"; do | |
184 | + src="$REPO_DIR/config/${pair%%:*}" | |
185 | + dst="$HOME/${pair##*:}" | |
186 | + if [[ -f $src ]] && [[ ! -f $dst ]]; then | |
187 | + mkdir -p "$(dirname "$dst")" | |
188 | + cp "$src" "$dst" | |
189 | + log "deployed $dst" | |
190 | + fi | |
191 | +done | |
192 | +# Neovim config: rsync with ignore-existing (preserves user's plugins/config) | |
193 | +if [[ -d $REPO_DIR/config/nvim ]]; then | |
194 | + mkdir -p "$HOME/.config/nvim" | |
195 | + rsync -a --ignore-existing "$REPO_DIR/config/nvim/" "$HOME/.config/nvim/" | |
196 | +fi | |
197 | + | |
181 | 198 | # Append the marked activation block to hyprland.lua (idempotent). |
182 | 199 | HYPR_MAIN="$HOME/.config/hypr/hyprland.lua" |
183 | 200 | if [[ ! -f $HYPR_MAIN ]]; then |
184 | 201 | |
▼shell/plugins/docker-status/DockerStatus.qml
+88-0
| @@ -0,0 +1,88 @@ | ||
1 | +import QtQuick | |
2 | +import Quickshell | |
3 | +import Quickshell.Io | |
4 | +import qs.Commons | |
5 | +import qs.Ui | |
6 | + | |
7 | +BarWidget { | |
8 | + id: root | |
9 | + moduleName: "deomarchy.docker-status" | |
10 | + | |
11 | + property int runningCount: 0 | |
12 | + property int unhealthyCount: 0 | |
13 | + property bool dockerAvailable: false | |
14 | + | |
15 | + visible: dockerAvailable | |
16 | + implicitWidth: button.implicitWidth | |
17 | + implicitHeight: button.implicitHeight | |
18 | + | |
19 | + function refresh() { | |
20 | + if (!dockerProc.running) dockerProc.running = true | |
21 | + } | |
22 | + | |
23 | + function updateStatus(raw) { | |
24 | + var lines = String(raw || "").trim().split("\n") | |
25 | + var running = 0 | |
26 | + var unhealthy = 0 | |
27 | + for (var i = 0; i < lines.length; i++) { | |
28 | + var line = lines[i].trim() | |
29 | + if (line === "") continue | |
30 | + var parts = line.split("|") | |
31 | + if (parts.length < 2) continue | |
32 | + var status = parts[1].toLowerCase() | |
33 | + if (status.indexOf("up") !== -1) { | |
34 | + running++ | |
35 | + if (status.indexOf("unhealthy") !== -1) unhealthy++ | |
36 | + } | |
37 | + } | |
38 | + runningCount = running | |
39 | + unhealthyCount = unhealthy | |
40 | + dockerAvailable = true | |
41 | + } | |
42 | + | |
43 | + function statusText() { | |
44 | + if (unhealthyCount > 0) | |
45 | + return runningCount + " up, " + unhealthyCount + " unhealthy" | |
46 | + return runningCount + " running" | |
47 | + } | |
48 | + | |
49 | + Component.onCompleted: refresh() | |
50 | + | |
51 | + Process { | |
52 | + id: dockerProc | |
53 | + command: ["docker", "ps", "--format", "{{.Names}}|{{.Status}}"] | |
54 | + onExited: function(exitCode) { | |
55 | + if (exitCode !== 0) { | |
56 | + dockerAvailable = false | |
57 | + return | |
58 | + } | |
59 | + } | |
60 | + stdout: StdioCollector { | |
61 | + waitForEnd: true | |
62 | + onStreamFinished: root.updateStatus(text) | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + Timer { | |
67 | + interval: 5000 | |
68 | + running: true | |
69 | + repeat: true | |
70 | + onTriggered: root.refresh() | |
71 | + } | |
72 | + | |
73 | + IpcHandler { | |
74 | + target: "deomarchy.docker-status" | |
75 | + function refresh(): void { root.refresh() } | |
76 | + } | |
77 | + | |
78 | + BarIconButton { | |
79 | + id: button | |
80 | + anchors.fill: parent | |
81 | + bar: root.bar | |
82 | + text: "\uf308" | |
83 | + slotSize: Style.bar.statusSlot | |
84 | + fontSize: Style.font.caption | |
85 | + tooltipText: "Docker: " + root.statusText() | |
86 | + onPressed: root.refresh() | |
87 | + } | |
88 | +} | |
0 | 89 | |
▼shell/plugins/docker-status/manifest.json
+21-0
| @@ -0,0 +1,21 @@ | ||
1 | +{ | |
2 | + "schemaVersion": 1, | |
3 | + "id": "deomarchy.docker-status", | |
4 | + "name": "Docker Status", | |
5 | + "version": "1.0.0", | |
6 | + "author": "De-Omarchy", | |
7 | + "description": "Shows running Docker container count and unhealthy status", | |
8 | + "kinds": [ | |
9 | + "bar-widget" | |
10 | + ], | |
11 | + "entryPoints": { | |
12 | + "barWidget": "DockerStatus.qml" | |
13 | + }, | |
14 | + "barWidget": { | |
15 | + "displayName": "Docker Status", | |
16 | + "description": "Running container count and unhealthy warnings", | |
17 | + "category": "System", | |
18 | + "allowMultiple": false, | |
19 | + "defaultSection": "right" | |
20 | + } | |
21 | +} | |
0 | 22 | |
▼shell/plugins/power-profile/PowerProfile.qml
+102-0
| @@ -0,0 +1,102 @@ | ||
1 | +import QtQuick | |
2 | +import Quickshell | |
3 | +import Quickshell.Io | |
4 | +import qs.Commons | |
5 | +import qs.Ui | |
6 | + | |
7 | +BarWidget { | |
8 | + id: root | |
9 | + moduleName: "deomarchy.power-profile" | |
10 | + | |
11 | + property string currentProfile: "" | |
12 | + property var profiles: ["power-saver", "balanced", "performance"] | |
13 | + property bool available: false | |
14 | + | |
15 | + visible: available | |
16 | + implicitWidth: button.implicitWidth | |
17 | + implicitHeight: button.implicitHeight | |
18 | + | |
19 | + function refresh() { | |
20 | + if (!profileGetProc.running) profileGetProc.running = true | |
21 | + } | |
22 | + | |
23 | + function profileIcon(name) { | |
24 | + if (name === "performance") return "\uf0e7" | |
25 | + if (name === "power-saver") return "\uf1e6" | |
26 | + return "\uf110" | |
27 | + } | |
28 | + | |
29 | + function profileLabel(name) { | |
30 | + if (name === "performance") return "Performance" | |
31 | + if (name === "power-saver") return "Powersave" | |
32 | + return "Balanced" | |
33 | + } | |
34 | + | |
35 | + function cycleProfile() { | |
36 | + var idx = profiles.indexOf(currentProfile) | |
37 | + var next = (idx + 1) % profiles.length | |
38 | + setProfile(profiles[next]) | |
39 | + } | |
40 | + | |
41 | + function setProfile(name) { | |
42 | + if (setProc.running) return | |
43 | + setProc.command = ["powerprofilesctl", "set", name] | |
44 | + setProc.running = true | |
45 | + } | |
46 | + | |
47 | + Component.onCompleted: refresh() | |
48 | + | |
49 | + Process { | |
50 | + id: profileGetProc | |
51 | + command: ["powerprofilesctl", "get"] | |
52 | + onExited: function(exitCode) { | |
53 | + if (exitCode !== 0) { | |
54 | + root.available = false | |
55 | + return | |
56 | + } | |
57 | + } | |
58 | + stdout: StdioCollector { | |
59 | + waitForEnd: true | |
60 | + onStreamFinished: { | |
61 | + var profile = String(text || "").trim() | |
62 | + if (profile !== "") { | |
63 | + root.currentProfile = profile | |
64 | + root.available = true | |
65 | + } | |
66 | + } | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + Process { | |
71 | + id: setProc | |
72 | + stdout: StdioCollector { waitForEnd: true } | |
73 | + onRunningChanged: { | |
74 | + if (!running) root.refresh() | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + Timer { | |
79 | + interval: 10000 | |
80 | + running: true | |
81 | + repeat: true | |
82 | + onTriggered: root.refresh() | |
83 | + } | |
84 | + | |
85 | + IpcHandler { | |
86 | + target: "deomarchy.power-profile" | |
87 | + function refresh(): void { root.refresh() } | |
88 | + function cycle(): void { root.cycleProfile() } | |
89 | + function set(name: string): void { root.setProfile(name) } | |
90 | + } | |
91 | + | |
92 | + BarIconButton { | |
93 | + id: button | |
94 | + anchors.fill: parent | |
95 | + bar: root.bar | |
96 | + text: root.profileIcon(root.currentProfile) | |
97 | + slotSize: Style.bar.statusSlot | |
98 | + fontSize: Style.font.caption | |
99 | + tooltipText: "Power: " + root.profileLabel(root.currentProfile) + " (click to cycle)" | |
100 | + onPressed: root.cycleProfile() | |
101 | + } | |
102 | +} | |
0 | 103 | |
▼shell/plugins/power-profile/manifest.json
+21-0
| @@ -0,0 +1,21 @@ | ||
1 | +{ | |
2 | + "schemaVersion": 1, | |
3 | + "id": "deomarchy.power-profile", | |
4 | + "name": "Power Profile", | |
5 | + "version": "1.0.0", | |
6 | + "author": "De-Omarchy", | |
7 | + "description": "Shows and cycles through power profiles (performance/balanced/powersave)", | |
8 | + "kinds": [ | |
9 | + "bar-widget" | |
10 | + ], | |
11 | + "entryPoints": { | |
12 | + "barWidget": "PowerProfile.qml" | |
13 | + }, | |
14 | + "barWidget": { | |
15 | + "displayName": "Power Profile", | |
16 | + "description": "Current power profile with click to cycle", | |
17 | + "category": "System", | |
18 | + "allowMultiple": false, | |
19 | + "defaultSection": "right" | |
20 | + } | |
21 | +} | |
0 | 22 | |
▼shell/plugins/system-overview/SystemOverview.qml
+338-0
| @@ -0,0 +1,338 @@ | ||
1 | +import QtQuick | |
2 | +import QtQuick.Controls | |
3 | +import QtQuick.Layouts | |
4 | +import Quickshell | |
5 | +import Quickshell.Io | |
6 | +import qs.Commons | |
7 | +import qs.Ui | |
8 | + | |
9 | +Item { | |
10 | + id: root | |
11 | + | |
12 | + property var shell: null | |
13 | + property var manifest: null | |
14 | + property bool opened: false | |
15 | + | |
16 | + property string cpuUsage: "--" | |
17 | + property string memUsage: "--" | |
18 | + property string memTotal: "--" | |
19 | + property string diskUsage: "--" | |
20 | + property string gpuTemp: "--" | |
21 | + property string netRx: "--" | |
22 | + property string netTx: "--" | |
23 | + property string uptime: "--" | |
24 | + property string kernel: "--" | |
25 | + property string hostname: "--" | |
26 | + property string cpuModel: "--" | |
27 | + property real prevCpuIdle: 0 | |
28 | + property real prevCpuTotal: 0 | |
29 | + | |
30 | + function open(payloadJson) { | |
31 | + opened = true | |
32 | + refresh() | |
33 | + } | |
34 | + | |
35 | + function close() { | |
36 | + opened = false | |
37 | + } | |
38 | + | |
39 | + function dismiss() { | |
40 | + if (shell && typeof shell.hide === "function") | |
41 | + shell.hide((manifest && manifest.id) || "deomarchy.system-overview") | |
42 | + else close() | |
43 | + } | |
44 | + | |
45 | + function refresh() { | |
46 | + if (!cpuProc.running) cpuProc.running = true | |
47 | + if (!memProc.running) memProc.running = true | |
48 | + if (!diskProc.running) diskProc.running = true | |
49 | + if (!tempProc.running) tempProc.running = true | |
50 | + if (!netProc.running) netProc.running = true | |
51 | + if (!uptimeProc.running) uptimeProc.running = true | |
52 | + if (!infoProc.running) infoProc.running = true | |
53 | + } | |
54 | + | |
55 | + function parseCpuLine(raw) { | |
56 | + var line = String(raw || "").trim() | |
57 | + var parts = line.split(/\s+/) | |
58 | + if (parts.length < 5) return | |
59 | + var idle = parseFloat(parts[3]) || 0 | |
60 | + var total = 0 | |
61 | + for (var i = 1; i < parts.length; i++) total += parseFloat(parts[i]) || 0 | |
62 | + if (prevCpuTotal > 0) { | |
63 | + var dTotal = total - prevCpuTotal | |
64 | + var dIdle = idle - prevCpuIdle | |
65 | + if (dTotal > 0) cpuUsage = Math.round((1 - dIdle / dTotal) * 100) + "%" | |
66 | + } | |
67 | + prevCpuIdle = idle | |
68 | + prevCpuTotal = total | |
69 | + } | |
70 | + | |
71 | + function parseMem(raw) { | |
72 | + var lines = String(raw || "").trim().split("\n") | |
73 | + var total = 0 | |
74 | + var avail = 0 | |
75 | + for (var i = 0; i < lines.length; i++) { | |
76 | + var parts = lines[i].trim().split(/\s+/) | |
77 | + if (parts[0] === "MemTotal:") total = parseFloat(parts[1]) || 0 | |
78 | + if (parts[0] === "MemAvailable:") avail = parseFloat(parts[1]) || 0 | |
79 | + } | |
80 | + if (total > 0) { | |
81 | + memTotal = (total / 1048576).toFixed(1) + " GB" | |
82 | + var used = total - avail | |
83 | + memUsage = Math.round(used / total * 100) + "%" | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + function parseDisk(raw) { | |
88 | + var line = String(raw || "").trim() | |
89 | + var parts = line.split(/\s+/) | |
90 | + if (parts.length >= 5) diskUsage = parts[4] || "--" | |
91 | + } | |
92 | + | |
93 | + function parseTemp(raw) { | |
94 | + var line = String(raw || "").trim() | |
95 | + var temp = parseFloat(line) | |
96 | + if (isFinite(temp)) gpuTemp = Math.round(temp / 1000) + "\u00b0C" | |
97 | + else gpuTemp = "--" | |
98 | + } | |
99 | + | |
100 | + function parseNet(raw) { | |
101 | + var lines = String(raw || "").trim().split("\n") | |
102 | + var totalRx = 0 | |
103 | + var totalTx = 0 | |
104 | + for (var i = 1; i < lines.length; i++) { | |
105 | + var parts = lines[i].trim().split(/[\s:]+/) | |
106 | + if (parts.length < 10) continue | |
107 | + var iface = parts[0] | |
108 | + if (iface === "lo" || iface === "") continue | |
109 | + totalRx += parseFloat(parts[1]) || 0 | |
110 | + totalTx += parseFloat(parts[9]) || 0 | |
111 | + } | |
112 | + netRx = formatBytes(totalRx) | |
113 | + netTx = formatBytes(totalTx) | |
114 | + } | |
115 | + | |
116 | + function parseUptime(raw) { | |
117 | + var sec = parseFloat(String(raw || "").trim()) | |
118 | + if (!isFinite(sec) || sec < 0) { uptime = "--"; return } | |
119 | + var d = Math.floor(sec / 86400) | |
120 | + var h = Math.floor((sec % 86400) / 3600) | |
121 | + var m = Math.floor((sec % 3600) / 60) | |
122 | + var parts = [] | |
123 | + if (d > 0) parts.push(d + "d") | |
124 | + if (h > 0) parts.push(h + "h") | |
125 | + parts.push(m + "m") | |
126 | + uptime = parts.join(" ") | |
127 | + } | |
128 | + | |
129 | + function parseInfo(raw) { | |
130 | + var lines = String(raw || "").trim().split("\n") | |
131 | + for (var i = 0; i < lines.length; i++) { | |
132 | + var line = lines[i].trim() | |
133 | + if (line.indexOf("hostname") === 0) hostname = line.split("=", 2)[1] || "--" | |
134 | + if (line.indexOf("kernel") === 0) kernel = line.split("=", 2)[1] || "--" | |
135 | + if (line.indexOf("model name") === 0) cpuModel = line.split(":", 2)[1] || "--" | |
136 | + } | |
137 | + } | |
138 | + | |
139 | + function formatBytes(b) { | |
140 | + if (b < 1024) return Math.round(b) + " B" | |
141 | + if (b < 1048576) return (b / 1024).toFixed(1) + " KB" | |
142 | + if (b < 1073741824) return (b / 1048576).toFixed(1) + " MB" | |
143 | + return (b / 1073741824).toFixed(2) + " GB" | |
144 | + } | |
145 | + | |
146 | + Component.onCompleted: { | |
147 | + refresh() | |
148 | + kernelProc.running = true | |
149 | + } | |
150 | + | |
151 | + Process { | |
152 | + id: cpuProc | |
153 | + command: ["bash", "-c", "head -1 /proc/stat"] | |
154 | + stdout: StdioCollector { | |
155 | + waitForEnd: true | |
156 | + onStreamFinished: root.parseCpuLine(text) | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + Process { | |
161 | + id: memProc | |
162 | + command: ["bash", "-c", "head -2 /proc/meminfo"] | |
163 | + stdout: StdioCollector { | |
164 | + waitForEnd: true | |
165 | + onStreamFinished: root.parseMem(text) | |
166 | + } | |
167 | + } | |
168 | + | |
169 | + Process { | |
170 | + id: diskProc | |
171 | + command: ["bash", "-c", "df -h / | tail -1"] | |
172 | + stdout: StdioCollector { | |
173 | + waitForEnd: true | |
174 | + onStreamFinished: root.parseDisk(text) | |
175 | + } | |
176 | + } | |
177 | + | |
178 | + Process { | |
179 | + id: tempProc | |
180 | + command: ["bash", "-c", "cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo ''"] | |
181 | + stdout: StdioCollector { | |
182 | + waitForEnd: true | |
183 | + onStreamFinished: root.parseTemp(text) | |
184 | + } | |
185 | + } | |
186 | + | |
187 | + Process { | |
188 | + id: netProc | |
189 | + command: ["bash", "-c", "head -5 /proc/net/dev"] | |
190 | + stdout: StdioCollector { | |
191 | + waitForEnd: true | |
192 | + onStreamFinished: root.parseNet(text) | |
193 | + } | |
194 | + } | |
195 | + | |
196 | + Process { | |
197 | + id: uptimeProc | |
198 | + command: ["bash", "-c", "cut -d. -f1 /proc/uptime"] | |
199 | + stdout: StdioCollector { | |
200 | + waitForEnd: true | |
201 | + onStreamFinished: root.parseUptime(text) | |
202 | + } | |
203 | + } | |
204 | + | |
205 | + Process { | |
206 | + id: kernelProc | |
207 | + command: ["bash", "-c", "echo hostname=$(hostname) && echo kernel=$(uname -r) && grep 'model name' /proc/cpuinfo | head -1"] | |
208 | + stdout: StdioCollector { | |
209 | + waitForEnd: true | |
210 | + onStreamFinished: root.parseInfo(text) | |
211 | + } | |
212 | + } | |
213 | + | |
214 | + Process { | |
215 | + id: infoProc | |
216 | + command: ["bash", "-c", "echo hostname=$(hostname) && echo kernel=$(uname -r) && grep 'model name' /proc/cpuinfo | head -1"] | |
217 | + stdout: StdioCollector { | |
218 | + waitForEnd: true | |
219 | + onStreamFinished: root.parseInfo(text) | |
220 | + } | |
221 | + } | |
222 | + | |
223 | + Timer { | |
224 | + interval: 2000 | |
225 | + running: root.opened | |
226 | + repeat: true | |
227 | + onTriggered: root.refresh() | |
228 | + } | |
229 | + | |
230 | + PanelController { | |
231 | + id: controller | |
232 | + open: root.opened | |
233 | + onOpenChanged: { | |
234 | + if (!open) root.close() | |
235 | + } | |
236 | + | |
237 | + Rectangle { | |
238 | + id: panelBg | |
239 | + anchors.fill: parent | |
240 | + color: Color.background | |
241 | + radius: Style.radius.l | |
242 | + | |
243 | + ColumnLayout { | |
244 | + anchors.fill: parent | |
245 | + anchors.margins: Style.space(16) | |
246 | + spacing: Style.space(10) | |
247 | + | |
248 | + RowLayout { | |
249 | + Layout.fillWidth: true | |
250 | + | |
251 | + Text { | |
252 | + text: "System Overview" | |
253 | + color: Color.foreground | |
254 | + font.family: Style.font.family | |
255 | + font.pixelSize: Style.font.title | |
256 | + font.bold: true | |
257 | + Layout.fillWidth: true | |
258 | + } | |
259 | + | |
260 | + Text { | |
261 | + text: root.hostname | |
262 | + color: Color.foreground | |
263 | + font.family: Style.font.family | |
264 | + font.pixelSize: Style.font.caption | |
265 | + opacity: 0.6 | |
266 | + } | |
267 | + | |
268 | + Button { | |
269 | + text: "Close" | |
270 | + font.family: Style.font.family | |
271 | + font.pixelSize: Style.font.caption | |
272 | + onClicked: root.dismiss() | |
273 | + } | |
274 | + } | |
275 | + | |
276 | + Rectangle { | |
277 | + Layout.fillWidth: true | |
278 | + height: 1 | |
279 | + color: Qt.darker(Color.foreground, 2.5) | |
280 | + } | |
281 | + | |
282 | + Repeater { | |
283 | + model: ListModel { | |
284 | + ListElement { label: "Kernel"; value: "kernel" } | |
285 | + ListElement { label: "CPU"; value: "cpu" } | |
286 | + ListElement { label: "CPU Usage"; value: "cpuUsage" } | |
287 | + ListElement { label: "Memory"; value: "mem" } | |
288 | + ListElement { label: "Disk /"; value: "disk" } | |
289 | + ListElement { label: "GPU Temp"; value: "gpu" } | |
290 | + ListElement { label: "Network RX"; value: "netrx" } | |
291 | + ListElement { label: "Network TX"; value: "nettx" } | |
292 | + ListElement { label: "Uptime"; value: "uptime" } | |
293 | + } | |
294 | + | |
295 | + RowLayout { | |
296 | + required property var modelData | |
297 | + Layout.fillWidth: true | |
298 | + spacing: Style.space(8) | |
299 | + | |
300 | + Text { | |
301 | + text: modelData.label | |
302 | + color: Color.foreground | |
303 | + font.family: Style.font.family | |
304 | + font.pixelSize: Style.font.body | |
305 | + font.bold: true | |
306 | + Layout.preferredWidth: Style.space(100) | |
307 | + } | |
308 | + | |
309 | + Text { | |
310 | + text: { | |
311 | + switch (modelData.value) { | |
312 | + case "kernel": return root.kernel | |
313 | + case "cpu": return root.cpuModel | |
314 | + case "cpuUsage": return root.cpuUsage | |
315 | + case "mem": return root.memUsage + " of " + root.memTotal | |
316 | + case "disk": return root.diskUsage | |
317 | + case "gpu": return root.gpuTemp | |
318 | + case "netrx": return "\u2193 " + root.netRx | |
319 | + case "nettx": return "\u2191 " + root.netTx | |
320 | + case "uptime": return root.uptime | |
321 | + default: return "--" | |
322 | + } | |
323 | + } | |
324 | + color: Color.foreground | |
325 | + font.family: Style.font.family | |
326 | + font.pixelSize: Style.font.body | |
327 | + opacity: 0.85 | |
328 | + Layout.fillWidth: true | |
329 | + elide: Text.ElideRight | |
330 | + } | |
331 | + } | |
332 | + } | |
333 | + | |
334 | + Item { Layout.fillHeight: true } | |
335 | + } | |
336 | + } | |
337 | + } | |
338 | +} | |
0 | 339 | |
▼shell/plugins/system-overview/manifest.json
+14-0
| @@ -0,0 +1,14 @@ | ||
1 | +{ | |
2 | + "schemaVersion": 1, | |
3 | + "id": "deomarchy.system-overview", | |
4 | + "name": "System Overview", | |
5 | + "version": "1.0.0", | |
6 | + "author": "De-Omarchy", | |
7 | + "description": "Full system stats panel: CPU, RAM, disk, GPU temp, network, uptime, kernel", | |
8 | + "kinds": [ | |
9 | + "panel" | |
10 | + ], | |
11 | + "entryPoints": { | |
12 | + "panel": "SystemOverview.qml" | |
13 | + } | |
14 | +} | |
0 | 15 | |
▼shell/plugins/wallpaper-manager/WallpaperManager.qml
+244-0
| @@ -0,0 +1,244 @@ | ||
1 | +import QtQuick | |
2 | +import QtQuick.Controls | |
3 | +import QtQuick.Layouts | |
4 | +import Quickshell | |
5 | +import Quickshell.Io | |
6 | +import qs.Commons | |
7 | +import qs.Ui | |
8 | + | |
9 | +Item { | |
10 | + id: root | |
11 | + | |
12 | + property var shell: null | |
13 | + property var manifest: null | |
14 | + property bool opened: false | |
15 | + property var wallpapers: [] | |
16 | + property int selectedIndex: -1 | |
17 | + property string wallpaperDir: "" | |
18 | + property bool cursorActive: false | |
19 | + | |
20 | + function open(payloadJson) { | |
21 | + opened = true | |
22 | + selectedIndex = -1 | |
23 | + cursorActive = false | |
24 | + loadWallpapers() | |
25 | + } | |
26 | + | |
27 | + function close() { | |
28 | + opened = false | |
29 | + wallpapers = [] | |
30 | + selectedIndex = -1 | |
31 | + } | |
32 | + | |
33 | + function dismiss() { | |
34 | + if (shell && typeof shell.hide === "function") | |
35 | + shell.hide((manifest && manifest.id) || "deomarchy.wallpaper-manager") | |
36 | + else close() | |
37 | + } | |
38 | + | |
39 | + function loadWallpapers() { | |
40 | + if (dirProc.running) return | |
41 | + dirProc.running = true | |
42 | + } | |
43 | + | |
44 | + function updateDirList(raw) { | |
45 | + var dir = String(raw || "").trim() | |
46 | + if (dir === "") { | |
47 | + wallpaperDir = "" | |
48 | + wallpapers = [] | |
49 | + return | |
50 | + } | |
51 | + wallpaperDir = dir | |
52 | + if (!listProc.running) listProc.running = true | |
53 | + } | |
54 | + | |
55 | + function updateFileList(raw) { | |
56 | + var lines = String(raw || "").trim().split("\n") | |
57 | + var files = [] | |
58 | + for (var i = 0; i < lines.length; i++) { | |
59 | + var f = lines[i].trim() | |
60 | + if (f !== "" && (f.endsWith(".png") || f.endsWith(".jpg") || f.endsWith(".jpeg") || f.endsWith(".webp"))) | |
61 | + files.push(f) | |
62 | + } | |
63 | + wallpapers = files | |
64 | + } | |
65 | + | |
66 | + function selectByDelta(delta) { | |
67 | + if (wallpapers.length === 0) return | |
68 | + if (selectedIndex < 0) selectedIndex = delta > 0 ? 0 : wallpapers.length - 1 | |
69 | + else selectedIndex = Math.max(0, Math.min(wallpapers.length - 1, selectedIndex + delta)) | |
70 | + } | |
71 | + | |
72 | + function applyWallpaper() { | |
73 | + if (selectedIndex < 0 || selectedIndex >= wallpapers.length || wallpaperDir === "") return | |
74 | + var path = wallpaperDir + "/" + wallpapers[selectedIndex] | |
75 | + applyProc.command = ["omarchy-theme-bg-set", path] | |
76 | + applyProc.running = true | |
77 | + } | |
78 | + | |
79 | + Process { | |
80 | + id: dirProc | |
81 | + command: ["bash", "-c", "echo $OMARCHY_PATH/default/themed/backgrounds || echo ~/.local/state/omarchy/current/theme/backgrounds"] | |
82 | + stdout: StdioCollector { | |
83 | + waitForEnd: true | |
84 | + onStreamFinished: root.updateDirList(text) | |
85 | + } | |
86 | + } | |
87 | + | |
88 | + Process { | |
89 | + id: listProc | |
90 | + command: ["ls", wallpaperDir] | |
91 | + onExited: function(exitCode) { | |
92 | + if (exitCode !== 0) root.wallpapers = [] | |
93 | + } | |
94 | + stdout: StdioCollector { | |
95 | + waitForEnd: true | |
96 | + onStreamFinished: root.updateFileList(text) | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + Process { | |
101 | + id: applyProc | |
102 | + stdout: StdioCollector { waitForEnd: true } | |
103 | + onRunningChanged: { | |
104 | + if (!running) root.close() | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + PanelController { | |
109 | + id: controller | |
110 | + open: root.opened | |
111 | + onOpenChanged: { | |
112 | + if (!open) root.close() | |
113 | + } | |
114 | + | |
115 | + Rectangle { | |
116 | + id: panelBg | |
117 | + anchors.fill: parent | |
118 | + color: Color.background | |
119 | + radius: Style.radius.l | |
120 | + | |
121 | + ColumnLayout { | |
122 | + anchors.fill: parent | |
123 | + anchors.margins: Style.space(16) | |
124 | + spacing: Style.space(12) | |
125 | + | |
126 | + RowLayout { | |
127 | + Layout.fillWidth: true | |
128 | + | |
129 | + Text { | |
130 | + text: "Wallpapers" | |
131 | + color: Color.foreground | |
132 | + font.family: Style.font.family | |
133 | + font.pixelSize: Style.font.title | |
134 | + font.bold: true | |
135 | + Layout.fillWidth: true | |
136 | + } | |
137 | + | |
138 | + Button { | |
139 | + text: "Close" | |
140 | + font.family: Style.font.family | |
141 | + font.pixelSize: Style.font.caption | |
142 | + onClicked: root.dismiss() | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + Text { | |
147 | + visible: wallpapers.length === 0 | |
148 | + text: root.wallpaperDir === "" ? "No wallpaper directory found" : "No wallpapers found" | |
149 | + color: Color.foreground | |
150 | + font.family: Style.font.family | |
151 | + font.pixelSize: Style.font.body | |
152 | + opacity: 0.6 | |
153 | + Layout.fillWidth: true | |
154 | + horizontalAlignment: Text.AlignHCenter | |
155 | + Layout.topMargin: Style.space(40) | |
156 | + } | |
157 | + | |
158 | + ScrollView { | |
159 | + Layout.fillWidth: true | |
160 | + Layout.fillHeight: true | |
161 | + clip: true | |
162 | + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff | |
163 | + | |
164 | + GridView { | |
165 | + id: grid | |
166 | + cellWidth: (width - Style.space(8)) / 3 | |
167 | + cellHeight: cellWidth * 0.6 + Style.space(28) | |
168 | + model: wallpapers | |
169 | + | |
170 | + delegate: Rectangle { | |
171 | + required property string modelData | |
172 | + required property int index | |
173 | + width: grid.cellWidth | |
174 | + height: grid.cellHeight | |
175 | + color: root.selectedIndex === index ? Color.accent : "transparent" | |
176 | + radius: Style.radius.s | |
177 | + | |
178 | + Column { | |
179 | + anchors.fill: parent | |
180 | + anchors.margins: Style.space(4) | |
181 | + spacing: Style.space(4) | |
182 | + | |
183 | + Rectangle { | |
184 | + width: parent.width | |
185 | + height: parent.height - nameText.implicitHeight - Style.space(8) | |
186 | + color: Qt.darker(Color.foreground, 3.0) | |
187 | + radius: Style.radius.s | |
188 | + clip: true | |
189 | + | |
190 | + Image { | |
191 | + anchors.fill: parent | |
192 | + anchors.margins: Style.space(2) | |
193 | + source: root.wallpaperDir + "/" + modelData | |
194 | + fillMode: Image.PreserveAspectCrop | |
195 | + asynchronous: true | |
196 | + cache: true | |
197 | + } | |
198 | + } | |
199 | + | |
200 | + Text { | |
201 | + id: nameText | |
202 | + width: parent.width | |
203 | + text: modelData | |
204 | + color: Color.foreground | |
205 | + font.family: Style.font.family | |
206 | + font.pixelSize: Style.font.caption | |
207 | + elide: Text.ElideRight | |
208 | + horizontalAlignment: Text.AlignHCenter | |
209 | + } | |
210 | + } | |
211 | + | |
212 | + MouseArea { | |
213 | + anchors.fill: parent | |
214 | + hoverEnabled: true | |
215 | + cursorShape: Qt.PointingHandCursor | |
216 | + onClicked: { | |
217 | + root.selectedIndex = index | |
218 | + root.applyWallpaper() | |
219 | + } | |
220 | + onContainsMouseChanged: { | |
221 | + if (containsMouse) { | |
222 | + root.cursorActive = true | |
223 | + root.selectedIndex = index | |
224 | + } | |
225 | + } | |
226 | + } | |
227 | + } | |
228 | + } | |
229 | + } | |
230 | + | |
231 | + Text { | |
232 | + visible: wallpapers.length > 0 | |
233 | + text: "Click to set wallpaper" | |
234 | + color: Color.foreground | |
235 | + font.family: Style.font.family | |
236 | + font.pixelSize: Style.font.caption | |
237 | + opacity: 0.5 | |
238 | + Layout.fillWidth: true | |
239 | + horizontalAlignment: Text.AlignHCenter | |
240 | + } | |
241 | + } | |
242 | + } | |
243 | + } | |
244 | +} | |
0 | 245 | |
▼shell/plugins/wallpaper-manager/manifest.json
+14-0
| @@ -0,0 +1,14 @@ | ||
1 | +{ | |
2 | + "schemaVersion": 1, | |
3 | + "id": "deomarchy.wallpaper-manager", | |
4 | + "name": "Wallpaper Manager", | |
5 | + "version": "1.0.0", | |
6 | + "author": "De-Omarchy", | |
7 | + "description": "Browse and set wallpapers from the current theme", | |
8 | + "kinds": [ | |
9 | + "panel" | |
10 | + ], | |
11 | + "entryPoints": { | |
12 | + "panel": "WallpaperManager.qml" | |
13 | + } | |
14 | +} | |
0 | 15 | |