feat: add sketchybar and hammerspoon configs
This commit is contained in:
parent
c1d49a8954
commit
d3fb4fa158
56 changed files with 2025 additions and 1548 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,3 +2,4 @@ result
|
|||
/.pre-commit-config.yaml
|
||||
home/emacs/config/var
|
||||
.direnv
|
||||
.claude
|
||||
|
|
|
|||
7
.stylua.toml
Normal file
7
.stylua.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
column_width = 160
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferSingle"
|
||||
call_parentheses = "None"
|
||||
collapse_simple_statement = "Always"
|
||||
40
bin/yabai-create-space
Executable file
40
bin/yabai-create-space
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Ensure exactly 10 spaces exist on the main display (display 1)
|
||||
# These can then be moved to other displays as needed
|
||||
|
||||
DESIRED_SPACES=10
|
||||
MAIN_DISPLAY=1
|
||||
|
||||
# Get current number of spaces on main display
|
||||
CURRENT_SPACE_COUNT=$(yabai -m query --spaces --display "$MAIN_DISPLAY" | jq 'length')
|
||||
|
||||
echo "Current spaces on display $MAIN_DISPLAY: $CURRENT_SPACE_COUNT"
|
||||
echo "Desired spaces: $DESIRED_SPACES"
|
||||
|
||||
# Focus main display first
|
||||
yabai -m display --focus "$MAIN_DISPLAY"
|
||||
|
||||
if [ "$CURRENT_SPACE_COUNT" -lt "$DESIRED_SPACES" ]; then
|
||||
MISSING_SPACES=$((DESIRED_SPACES - CURRENT_SPACE_COUNT))
|
||||
echo "Creating $MISSING_SPACES spaces on display $MAIN_DISPLAY..."
|
||||
|
||||
for i in $(seq 1 $MISSING_SPACES); do
|
||||
yabai -m space --create
|
||||
echo "Created space $((CURRENT_SPACE_COUNT + i))"
|
||||
done
|
||||
elif [ "$CURRENT_SPACE_COUNT" -gt "$DESIRED_SPACES" ]; then
|
||||
EXTRA_SPACES=$((CURRENT_SPACE_COUNT - DESIRED_SPACES))
|
||||
echo "Removing $EXTRA_SPACES extra spaces from display $MAIN_DISPLAY..."
|
||||
|
||||
# Get the last space on main display and destroy it
|
||||
for i in $(seq 1 $EXTRA_SPACES); do
|
||||
LAST_SPACE=$(yabai -m query --spaces --display "$MAIN_DISPLAY" | jq 'map(select(."is-native-fullscreen" == false))[-1].index')
|
||||
yabai -m space --destroy "$LAST_SPACE"
|
||||
echo "Destroyed space $LAST_SPACE"
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Total spaces on display $MAIN_DISPLAY: $(yabai -m query --spaces --display $MAIN_DISPLAY | jq 'length')"
|
||||
|
||||
sketchybar --trigger space_change --trigger windows_on_spaces
|
||||
|
|
@ -49,3 +49,5 @@ if functions -q fish_vi_key_bindings
|
|||
else
|
||||
bind \et sesh-list
|
||||
end
|
||||
|
||||
alias vim "nvim"
|
||||
|
|
|
|||
3
config/home/.hammerspoon/init.lua
Normal file
3
config/home/.hammerspoon/init.lua
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
require 'keyboard'
|
||||
|
||||
hs.alert.show 'Hammerspoon config loaded'
|
||||
12
config/home/.hammerspoon/keyboard/init.lua
Normal file
12
config/home/.hammerspoon/keyboard/init.lua
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
local keymap = require 'keyboard.keymaps'
|
||||
|
||||
require 'keyboard.yabai'
|
||||
|
||||
-- General keymap
|
||||
-- reload config
|
||||
keymap.super {
|
||||
key = 'c',
|
||||
mods = { 'shift' },
|
||||
message = 'Reload Hammerspoon config',
|
||||
fn = function() hs.reload() end,
|
||||
}
|
||||
18
config/home/.hammerspoon/keyboard/keymaps.lua
Normal file
18
config/home/.hammerspoon/keyboard/keymaps.lua
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
local M = {}
|
||||
|
||||
M.super_key = 'alt'
|
||||
|
||||
M.super = function(opts)
|
||||
local mods = { M.super_key }
|
||||
if opts.mods then
|
||||
for _, mod in ipairs(opts.mods) do
|
||||
table.insert(mods, mod)
|
||||
end
|
||||
end
|
||||
|
||||
if opts.message then return hs.hotkey.bind(mods, opts.key, opts.message, opts.fn, opts.release, opts.repeat_fn) end
|
||||
|
||||
return hs.hotkey.bind(mods, opts.key, opts.fn, opts.release, opts.repeat_fn)
|
||||
end
|
||||
|
||||
return M
|
||||
137
config/home/.hammerspoon/keyboard/yabai.lua
Normal file
137
config/home/.hammerspoon/keyboard/yabai.lua
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
local keymap = require 'keyboard.keymaps'
|
||||
|
||||
local yabai_cmd = '/etc/profiles/per-user/rayandrew/bin/yabai'
|
||||
local jq_cmd = '/etc/profiles/per-user/rayandrew/bin/jq'
|
||||
|
||||
local function yabai_query(query, jq_filter)
|
||||
local cmd = yabai_cmd .. ' -m query ' .. query
|
||||
if jq_filter then cmd = cmd .. ' | ' .. jq_cmd .. ' ' .. jq_filter end
|
||||
local handle = io.popen(cmd)
|
||||
local result = handle:read('*a'):gsub('%s+', '')
|
||||
handle:close()
|
||||
return result
|
||||
end
|
||||
|
||||
local function yabai(commands, logic)
|
||||
local cmd_string = ''
|
||||
for i, cmd in ipairs(commands) do
|
||||
if i == 1 then
|
||||
cmd_string = yabai_cmd .. ' -m ' .. cmd
|
||||
else
|
||||
if logic == 'and' then
|
||||
cmd_string = cmd_string .. ' && ' .. yabai_cmd .. ' -m ' .. cmd
|
||||
elseif logic == 'or' then
|
||||
cmd_string = cmd_string .. ' || ' .. yabai_cmd .. ' -m ' .. cmd
|
||||
else
|
||||
cmd_string = cmd_string .. ' ; ' .. yabai_cmd .. ' -m ' .. cmd
|
||||
end
|
||||
end
|
||||
end
|
||||
os.execute(cmd_string)
|
||||
end
|
||||
|
||||
local function yabai_key(opts)
|
||||
keymap.super {
|
||||
key = opts.key,
|
||||
mods = opts.mods,
|
||||
message = opts.message,
|
||||
fn = function() yabai(opts.commands, opts.logic) end,
|
||||
}
|
||||
end
|
||||
|
||||
keymap.super {
|
||||
key = 'return',
|
||||
-- message = "Spawn Ghostty",
|
||||
fn = function()
|
||||
-- hs.application.launchOrFocus("Ghostty")
|
||||
-- hs.timer.doAfter(0.1, function()
|
||||
-- hs.eventtap.keyStroke({ "cmd" }, "n")
|
||||
-- end)
|
||||
os.execute 'open -na Ghostty'
|
||||
end,
|
||||
}
|
||||
|
||||
yabai_key { key = 'f', commands = { 'window --toggle zoom-fullscreen' } }
|
||||
yabai_key { key = 'l', commands = { 'space --focus recent' } }
|
||||
yabai_key { key = 'm', commands = { 'space --toggle mission-control' } }
|
||||
yabai_key { key = 'p', commands = { 'window --toggle pip' } }
|
||||
yabai_key { key = 'g', commands = { 'space --toggle padding', 'space --toggle gap' } }
|
||||
yabai_key { key = 'r', commands = { 'space --rotate 90' } }
|
||||
yabai_key { key = 't', commands = { 'window --toggle float', 'window --grid 4:4:1:1:2:2' } }
|
||||
|
||||
yabai_key { key = "'", commands = { 'space --layout stack' } }
|
||||
yabai_key { key = ';', commands = { 'space --layout bsp' } }
|
||||
yabai_key { key = 'tab', commands = { 'space --focus recent' } }
|
||||
|
||||
-- navigation
|
||||
yabai_key { key = 'h', commands = { 'window --focus west', 'display --focus west' }, logic = 'or' }
|
||||
yabai_key { key = 'j', commands = { 'window --focus south', 'display --focus south' }, logic = 'or' }
|
||||
yabai_key { key = 'k', commands = { 'window --focus north', 'display --focus north' }, logic = 'or' }
|
||||
yabai_key { key = 'l', commands = { 'window --focus east', 'display --focus east' }, logic = 'or' }
|
||||
|
||||
-- move windows (swap within space, or move to adjacent display if at edge)
|
||||
yabai_key { mods = { 'shift' }, key = 'h', commands = { 'window --swap west', 'window --display west', 'display --focus west' }, logic = 'or' }
|
||||
yabai_key { mods = { 'shift' }, key = 'j', commands = { 'window --swap south', 'window --display south', 'display --focus south' }, logic = 'or' }
|
||||
yabai_key { mods = { 'shift' }, key = 'k', commands = { 'window --swap north', 'window --display north', 'display --focus north' }, logic = 'or' }
|
||||
yabai_key { mods = { 'shift' }, key = 'l', commands = { 'window --swap east', 'window --display east', 'display --focus east' }, logic = 'or' }
|
||||
|
||||
-- spaces - focus space and its display
|
||||
local function focus_space(space_num)
|
||||
local display = yabai_query('--spaces', "'.[] | select(.index == " .. space_num .. ") | .display'")
|
||||
|
||||
if display and display ~= '' then
|
||||
os.execute(yabai_cmd .. ' -m display --focus ' .. display)
|
||||
hs.timer.usleep(50000) -- 50ms delay
|
||||
end
|
||||
|
||||
os.execute(yabai_cmd .. ' -m space --focus ' .. space_num)
|
||||
end
|
||||
|
||||
keymap.super { key = '1', fn = function() focus_space(1) end }
|
||||
keymap.super { key = '2', fn = function() focus_space(2) end }
|
||||
keymap.super { key = '3', fn = function() focus_space(3) end }
|
||||
keymap.super { key = '4', fn = function() focus_space(4) end }
|
||||
keymap.super { key = '5', fn = function() focus_space(5) end }
|
||||
keymap.super { key = '6', fn = function() focus_space(6) end }
|
||||
keymap.super { key = '7', fn = function() focus_space(7) end }
|
||||
keymap.super { key = '8', fn = function() focus_space(8) end }
|
||||
keymap.super { key = '9', fn = function() focus_space(9) end }
|
||||
keymap.super { key = '0', fn = function() focus_space(10) end }
|
||||
|
||||
-- move window to space and follow
|
||||
yabai_key { mods = { 'shift' }, key = '1', commands = { 'window --space 1', 'space --focus 1' } }
|
||||
yabai_key { mods = { 'shift' }, key = '2', commands = { 'window --space 2', 'space --focus 2' } }
|
||||
yabai_key { mods = { 'shift' }, key = '3', commands = { 'window --space 3', 'space --focus 3' } }
|
||||
yabai_key { mods = { 'shift' }, key = '4', commands = { 'window --space 4', 'space --focus 4' } }
|
||||
yabai_key { mods = { 'shift' }, key = '5', commands = { 'window --space 5', 'space --focus 5' } }
|
||||
yabai_key { mods = { 'shift' }, key = '6', commands = { 'window --space 6', 'space --focus 6' } }
|
||||
yabai_key { mods = { 'shift' }, key = '7', commands = { 'window --space 7', 'space --focus 7' } }
|
||||
yabai_key { mods = { 'shift' }, key = '8', commands = { 'window --space 8', 'space --focus 8' } }
|
||||
yabai_key { mods = { 'shift' }, key = '9', commands = { 'window --space 9', 'space --focus 9' } }
|
||||
yabai_key { mods = { 'shift' }, key = '0', commands = { 'window --space 10', 'space --focus 10' } }
|
||||
|
||||
-- move current space between displays
|
||||
yabai_key { mods = { 'ctrl' }, key = 'h', message = 'Move space to left display', commands = { 'space --display west' } }
|
||||
yabai_key { mods = { 'ctrl' }, key = 'l', message = 'Move space to right display', commands = { 'space --display east' } }
|
||||
|
||||
-- create new space and move window to it
|
||||
keymap.super {
|
||||
key = 'n',
|
||||
mods = { 'shift' },
|
||||
message = 'Create new space and move window',
|
||||
fn = function()
|
||||
os.execute(yabai_cmd .. ' -m space --create')
|
||||
hs.timer.usleep(100000) -- 100ms
|
||||
|
||||
local index = yabai_query('--spaces --display', '\'map(select(."is-native-fullscreen" == false))[-1].index\'')
|
||||
|
||||
if index and index ~= '' then
|
||||
os.execute(yabai_cmd .. ' -m window --space ' .. index)
|
||||
os.execute(yabai_cmd .. ' -m space --focus ' .. index)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
-- split type - use insert direction to control next window placement
|
||||
yabai_key { key = 'v', commands = { 'window --insert east' } }
|
||||
yabai_key { key = 'v', mods = { 'shift' }, commands = { 'window --insert south' } }
|
||||
321
config/sketchybar/app_icons.lua
Normal file
321
config/sketchybar/app_icons.lua
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
-- these seem to get disentangled to https://github.com/kvndrsslr/sketchybar-app-font/tree/main/mappings
|
||||
return {
|
||||
['Live'] = ':ableton:',
|
||||
['Activity Monitor'] = ':numbers:', -- no pre-existing, sadly
|
||||
['Adobe Bridge'] = ':adobe_bridge:',
|
||||
['Affinity Designer'] = ':affinity_designer:',
|
||||
['Affinity Designer 2'] = ':affinity_designer_2:',
|
||||
['Affinity Photo'] = ':affinity_photo:',
|
||||
['Affinity Photo 2'] = ':affinity_photo_2:',
|
||||
['Affinity Publisher'] = ':affinity_publisher:',
|
||||
['Affinity Publisher 2'] = ':affinity_publisher_2:',
|
||||
['Airmail'] = ':airmail:',
|
||||
['Alacritty'] = ':alacritty:',
|
||||
['Alfred'] = ':alfred:',
|
||||
['Android Messages'] = ':android_messages:',
|
||||
['Android Studio'] = ':android_studio:',
|
||||
['Anki'] = ':anki:',
|
||||
['Anytype'] = ':anytype:',
|
||||
['App Eraser'] = ':app_eraser:',
|
||||
['App Store'] = ':app_store:',
|
||||
['Arc'] = ':arc:',
|
||||
['Arduino'] = ':arduino:',
|
||||
['Arduino IDE'] = ':arduino:',
|
||||
['Atom'] = ':atom:',
|
||||
['Audacity'] = ':audacity:',
|
||||
['Bambu Studio'] = ':bambu_studio:',
|
||||
['MoneyMoney'] = ':bank:',
|
||||
['Battle.net'] = ':battle_net:',
|
||||
['Bear'] = ':bear:',
|
||||
['BetterTouchTool'] = ':bettertouchtool:',
|
||||
['Bilibili'] = ':bilibili:',
|
||||
['哔哩哔哩'] = ':bilibili:',
|
||||
['Bitwarden'] = ':bit_warden:',
|
||||
['Blender'] = ':blender:',
|
||||
['BluOS Controller'] = ':bluos_controller:',
|
||||
['Calibre'] = ':book:',
|
||||
['Brave Browser'] = ':brave_browser:',
|
||||
['BusyCal'] = ':busycal:',
|
||||
['Calculator'] = ':calculator:',
|
||||
['Calculette'] = ':calculator:',
|
||||
['Calendar'] = ':calendar:',
|
||||
['日历'] = ':calendar:',
|
||||
['Fantastical'] = ':calendar:',
|
||||
['Cron'] = ':calendar:',
|
||||
['Amie'] = ':calendar:',
|
||||
['Calendrier'] = ':calendar:',
|
||||
['Notion Calendar'] = ':calendar:',
|
||||
['Caprine'] = ':caprine:',
|
||||
['Amazon Chime'] = ':chime:',
|
||||
['Citrix Workspace'] = ':citrix:',
|
||||
['Citrix Viewer'] = ':citrix:',
|
||||
['Claude'] = ':claude:',
|
||||
['ClickUp'] = ':click_up:',
|
||||
['Code'] = ':code:',
|
||||
['Code - Insiders'] = ':code:',
|
||||
['Cold Turkey Blocker'] = ':cold_turkey_blocker:',
|
||||
['Color Picker'] = ':color_picker:',
|
||||
['数码测色计'] = ':color_picker:',
|
||||
['Copilot'] = ':copilot:',
|
||||
['CotEditor'] = ':coteditor:',
|
||||
['Creative Cloud'] = ':creative_cloud:',
|
||||
['Cursor'] = ':cursor:',
|
||||
['Cypress'] = ':cypress:',
|
||||
['DataGrip'] = ':datagrip:',
|
||||
['DataSpell'] = ':dataspell:',
|
||||
['DaVinci Resolve'] = ':davinciresolve:',
|
||||
['Deezer'] = ':deezer:',
|
||||
['Default'] = ':default:',
|
||||
['CleanMyMac X'] = ':desktop:',
|
||||
['DEVONthink 3'] = ':devonthink3:',
|
||||
['DingTalk'] = ':dingtalk:',
|
||||
['钉钉'] = ':dingtalk:',
|
||||
['阿里钉'] = ':dingtalk:',
|
||||
['Discord'] = ':discord:',
|
||||
['Discord Canary'] = ':discord:',
|
||||
['Discord PTB'] = ':discord:',
|
||||
['Vesktop'] = ':discord:',
|
||||
['Docker'] = ':docker:',
|
||||
['Docker Desktop'] = ':docker:',
|
||||
['GrandTotal'] = ':dollar:',
|
||||
['Receipts'] = ':dollar:',
|
||||
['Double Commander'] = ':doublecmd:',
|
||||
['Drafts'] = ':drafts:',
|
||||
['draw.io'] = ':draw_io:',
|
||||
['Dropbox'] = ':dropbox:',
|
||||
['Element'] = ':element:',
|
||||
['Emacs'] = ':emacs:',
|
||||
['Evernote Legacy'] = ':evernote_legacy:',
|
||||
['FaceTime'] = ':face_time:',
|
||||
['FaceTime 通话'] = ':face_time:',
|
||||
['Figma'] = ':figma:',
|
||||
['Final Cut Pro'] = ':final_cut_pro:',
|
||||
['Finder'] = ':finder:',
|
||||
['访达'] = ':finder:',
|
||||
['Firefox'] = ':firefox:',
|
||||
['Firefox Developer Edition'] = ':firefox_developer_edition:',
|
||||
['Firefox Nightly'] = ':firefox_developer_edition:',
|
||||
['Folx'] = ':folx:',
|
||||
['Fork'] = ':fork:',
|
||||
['FreeTube'] = ':freetube:',
|
||||
['Fusion'] = ':fusion:',
|
||||
['System Preferences'] = ':gear:',
|
||||
['System Settings'] = ':gear:',
|
||||
['系统设置'] = ':gear:',
|
||||
['Réglages Système'] = ':gear:',
|
||||
['GitHub Desktop'] = ':git_hub:',
|
||||
['Godot'] = ':godot:',
|
||||
['GoLand'] = ':goland:',
|
||||
['Chromium'] = ':google_chrome:',
|
||||
['Google Chrome'] = ':google_chrome:',
|
||||
['Google Chrome Canary'] = ':google_chrome:',
|
||||
['Grammarly Editor'] = ':grammarly:',
|
||||
['Home Assistant'] = ':home_assistant:',
|
||||
['Hyper'] = ':hyper:',
|
||||
['IntelliJ IDEA'] = ':idea:',
|
||||
['IINA'] = ':iina:',
|
||||
['Adobe Illustrator'] = ':illustrator:',
|
||||
['Illustrator'] = ':illustrator:',
|
||||
['Adobe InDesign'] = ':indesign:',
|
||||
['InDesign'] = ':indesign:',
|
||||
['Inkdrop'] = ':inkdrop:',
|
||||
['Inkscape'] = ':inkscape:',
|
||||
['Insomnia'] = ':insomnia:',
|
||||
['Iris'] = ':iris:',
|
||||
['iTerm'] = ':iterm:',
|
||||
['iTerm2'] = ':iterm:',
|
||||
['Jellyfin Media Player'] = ':jellyfin:',
|
||||
['Joplin'] = ':joplin:',
|
||||
['카카오톡'] = ':kakaotalk:',
|
||||
['KakaoTalk'] = ':kakaotalk:',
|
||||
['Kakoune'] = ':kakoune:',
|
||||
['KeePassXC'] = ':kee_pass_x_c:',
|
||||
['Keyboard Maestro'] = ':keyboard_maestro:',
|
||||
['Keynote'] = ':keynote:',
|
||||
['Keynote 讲演'] = ':keynote:',
|
||||
['kitty'] = ':kitty:',
|
||||
['League of Legends'] = ':league_of_legends:',
|
||||
['LibreWolf'] = ':libre_wolf:',
|
||||
['Adobe Lightroom'] = ':lightroom:',
|
||||
['Lightroom Classic'] = ':lightroomclassic:',
|
||||
['LINE'] = ':line:',
|
||||
['Linear'] = ':linear:',
|
||||
['LM Studio'] = ':lm_studio:',
|
||||
['LocalSend'] = ':localsend:',
|
||||
['Logic Pro'] = ':logicpro:',
|
||||
['Logseq'] = ':logseq:',
|
||||
['Canary Mail'] = ':mail:',
|
||||
['HEY'] = ':mail:',
|
||||
['Mail'] = ':mail:',
|
||||
['Mailspring'] = ':mail:',
|
||||
['MailMate'] = ':mail:',
|
||||
['Superhuman'] = ':mail:',
|
||||
['Spark'] = ':mail:',
|
||||
['邮件'] = ':mail:',
|
||||
['MAMP'] = ':mamp:',
|
||||
['MAMP PRO'] = ':mamp:',
|
||||
['Maps'] = ':maps:',
|
||||
['News'] = ':sioyek:',
|
||||
['Ghostty'] = ':terminal:',
|
||||
['Google Maps'] = ':maps:',
|
||||
['Marta'] = ':marta:',
|
||||
['Matlab'] = ':matlab:',
|
||||
['Mattermost'] = ':mattermost:',
|
||||
['Messages'] = ':messages:',
|
||||
['信息'] = ':messages:',
|
||||
['Nachrichten'] = ':messages:',
|
||||
['Messenger'] = ':messenger:',
|
||||
['Microsoft Edge'] = ':microsoft_edge:',
|
||||
['Microsoft Excel'] = ':microsoft_excel:',
|
||||
['Microsoft Outlook'] = ':microsoft_outlook:',
|
||||
['Microsoft PowerPoint'] = ':microsoft_power_point:',
|
||||
['Microsoft Remote Desktop'] = ':microsoft_remote_desktop:',
|
||||
['Microsoft Teams'] = ':microsoft_teams:',
|
||||
['Microsoft Teams (work or school)'] = ':microsoft_teams:',
|
||||
['Microsoft Word'] = ':microsoft_word:',
|
||||
['Min'] = ':min_browser:',
|
||||
['Miro'] = ':miro:',
|
||||
['MongoDB Compass'] = ':mongodb:',
|
||||
['mpv'] = ':mpv:',
|
||||
['Mullvad Browser'] = ':mullvad_browser:',
|
||||
['Music'] = ':music:',
|
||||
['音乐'] = ':music:',
|
||||
['Musique'] = ':music:',
|
||||
['PWNeovide'] = ':neovide:',
|
||||
['Neovide'] = ':neovide:',
|
||||
['neovide'] = ':neovide:',
|
||||
['Neovim'] = ':neovim:',
|
||||
['neovim'] = ':neovim:',
|
||||
['nvim'] = ':neovim:',
|
||||
['网易云音乐'] = ':netease_music:',
|
||||
['Noodl'] = ':noodl:',
|
||||
['Noodl Editor'] = ':noodl:',
|
||||
['NordVPN'] = ':nord_vpn:',
|
||||
['Notability'] = ':notability:',
|
||||
['Notes'] = ':notes:',
|
||||
['备忘录'] = ':notes:',
|
||||
['Notion'] = ':notion:',
|
||||
['Nova'] = ':nova:',
|
||||
['Numbers'] = ':numbers:',
|
||||
['Numbers 表格'] = ':numbers:',
|
||||
['Obsidian'] = ':obsidian:',
|
||||
['OBS'] = ':obsstudio:',
|
||||
['OmniFocus'] = ':omni_focus:',
|
||||
['1Password'] = ':one_password:',
|
||||
['Open Video Downloader'] = ':open_video_downloader:',
|
||||
['ChatGPT'] = ':openai:',
|
||||
['OpenVPN Connect'] = ':openvpn_connect:',
|
||||
['Opera'] = ':opera:',
|
||||
['OrbStack'] = ':orbstack:',
|
||||
['OrcaSlicer'] = ':orcaslicer:',
|
||||
['Orion'] = ':orion:',
|
||||
['Orion RC'] = ':orion:',
|
||||
['Pages'] = ':pages:',
|
||||
['Pages 文稿'] = ':pages:',
|
||||
['Parallels Desktop'] = ':parallels:',
|
||||
['Parsec'] = ':parsec:',
|
||||
['Preview'] = ':pdf:',
|
||||
['预览'] = ':pdf:',
|
||||
['Skim'] = ':pdf:',
|
||||
['zathura'] = ':pdf:',
|
||||
['Aperçu'] = ':pdf:',
|
||||
['PDF Expert'] = ':pdf_expert:',
|
||||
['Pearcleaner'] = ':pearcleaner:',
|
||||
['Phoenix Slides'] = ':phoenix_slides:',
|
||||
['Adobe Photoshop'] = ':photoshop:',
|
||||
['PhpStorm'] = ':php_storm:',
|
||||
['Pi-hole Remote'] = ':pihole:',
|
||||
['Pine'] = ':pine:',
|
||||
['Plex'] = ':plex:',
|
||||
['Plexamp'] = ':plexamp:',
|
||||
['Podcasts'] = ':podcasts:',
|
||||
['播客'] = ':podcasts:',
|
||||
['PomoDone App'] = ':pomodone:',
|
||||
['Postman'] = ':postman:',
|
||||
['Proton Mail'] = ':proton_mail:',
|
||||
['Proton Mail Bridge'] = ':proton_mail:',
|
||||
['PrusaSlicer'] = ':prusaslicer:',
|
||||
['SuperSlicer'] = ':prusaslicer:',
|
||||
['PyCharm'] = ':pycharm:',
|
||||
['QQ'] = ':qq:',
|
||||
['QQ音乐'] = ':qqmusic:',
|
||||
['QQMusic'] = ':qqmusic:',
|
||||
['Quantumult X'] = ':quantumult_x:',
|
||||
['qutebrowser'] = ':qute_browser:',
|
||||
['Raindrop.io'] = ':raindrop_io:',
|
||||
['Reeder'] = ':reeder5:',
|
||||
['Reminders'] = ':reminders:',
|
||||
['提醒事项'] = ':reminders:',
|
||||
['Rappels'] = ':reminders:',
|
||||
['Replit'] = ':replit:',
|
||||
['Rider'] = ':rider:',
|
||||
['JetBrains Rider'] = ':rider:',
|
||||
['Rio'] = ':rio:',
|
||||
['Royal TSX'] = ':royaltsx:',
|
||||
['Safari'] = ':safari:',
|
||||
['Safari浏览器'] = ':safari:',
|
||||
['Safari Technology Preview'] = ':safari:',
|
||||
['Sequel Ace'] = ':sequel_ace:',
|
||||
['Sequel Pro'] = ':sequel_pro:',
|
||||
['Setapp'] = ':setapp:',
|
||||
['SF Symbols'] = ':sf_symbols:',
|
||||
['Signal'] = ':signal:',
|
||||
['sioyek'] = ':sioyek:',
|
||||
['Sketch'] = ':sketch:',
|
||||
['Skype'] = ':skype:',
|
||||
['Slack'] = ':slack:',
|
||||
['Spark Desktop'] = ':spark:',
|
||||
['Spotify'] = ':spotify:',
|
||||
['Spotlight'] = ':spotlight:',
|
||||
['Sublime Text'] = ':sublime_text:',
|
||||
['Strongbox'] = ':one_password:',
|
||||
['superProductivity'] = ':superproductivity:',
|
||||
['Tana'] = ':tana:',
|
||||
['TeamSpeak 3'] = ':team_speak:',
|
||||
['Telegram'] = ':telegram:',
|
||||
['Terminal'] = ':terminal:',
|
||||
['终端'] = ':terminal:',
|
||||
['Typora'] = ':text:',
|
||||
['Microsoft To Do'] = ':things:',
|
||||
['Things'] = ':things:',
|
||||
['Thunderbird'] = ':thunderbird:',
|
||||
['TickTick'] = ':tick_tick:',
|
||||
['TIDAL'] = ':tidal:',
|
||||
['Tiny RDM'] = ':tinyrdm:',
|
||||
['Todoist'] = ':todoist:',
|
||||
['Toggl Track'] = ':toggl_track:',
|
||||
['Tor Browser'] = ':tor_browser:',
|
||||
['Tower'] = ':tower:',
|
||||
['Transmit'] = ':transmit:',
|
||||
['Trello'] = ':trello:',
|
||||
['Tweetbot'] = ':twitter:',
|
||||
['Twitter'] = ':twitter:',
|
||||
['UTM'] = ':utm:',
|
||||
['MacVim'] = ':vim:',
|
||||
['Vim'] = ':vim:',
|
||||
['VimR'] = ':vim:',
|
||||
['Vivaldi'] = ':vivaldi:',
|
||||
['VLC'] = ':vlc:',
|
||||
['VMware Fusion'] = ':vmware_fusion:',
|
||||
['VSCodium'] = ':vscodium:',
|
||||
['Warp'] = ':warp:',
|
||||
['WebStorm'] = ':web_storm:',
|
||||
['微信'] = ':wechat:',
|
||||
['WeChat'] = ':wechat:',
|
||||
['企业微信'] = ':wecom:',
|
||||
['WeCom'] = ':wecom:',
|
||||
['WezTerm'] = ':wezterm:',
|
||||
['WhatsApp'] = ':whats_app:',
|
||||
['WhatsApp'] = ':whats_app:',
|
||||
['Xcode'] = ':xcode:',
|
||||
['Yandex Music'] = ':yandex_music:',
|
||||
['Yuque'] = ':yuque:',
|
||||
['语雀'] = ':yuque:',
|
||||
['Zed'] = ':zed:',
|
||||
['Zen Browser'] = ':zen_browser:',
|
||||
['Zeplin'] = ':zeplin:',
|
||||
['zoom.us'] = ':zoom:',
|
||||
['Zotero'] = ':zotero:',
|
||||
['Zulip'] = ':zulip:',
|
||||
['Zen'] = ':zen_browser:',
|
||||
}
|
||||
23
config/sketchybar/bar.lua
Normal file
23
config/sketchybar/bar.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require 'colors'
|
||||
|
||||
local bar_height = 35
|
||||
|
||||
sbar.bar {
|
||||
blur_radius = 20,
|
||||
border_color = colors.bar.border,
|
||||
border_width = 2,
|
||||
color = colors.bar.bg,
|
||||
corner_radius = 5,
|
||||
height = bar_height,
|
||||
margin = 10,
|
||||
notch_width = 0,
|
||||
padding_left = 10,
|
||||
padding_right = 10,
|
||||
position = 'top',
|
||||
shadow = true,
|
||||
sticky = true,
|
||||
topmost = false,
|
||||
y_offset = 2,
|
||||
}
|
||||
49
config/sketchybar/colors.lua
Normal file
49
config/sketchybar/colors.lua
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
local function with_alpha(color, alpha)
|
||||
if alpha > 1.0 or alpha < 0.0 then return color end
|
||||
return (color & 0x00ffffff) | (math.floor(alpha * 255.0) << 24)
|
||||
end
|
||||
|
||||
return {
|
||||
fg = 0xffd3b58d,
|
||||
black = 0xff181819,
|
||||
white = 0xffd3b58d,
|
||||
red = 0xffF92672,
|
||||
blue = 0xff66D9EF,
|
||||
grey = 0xff7f8490,
|
||||
transparent = 0x00000000,
|
||||
|
||||
bg1 = 0xff072626,
|
||||
bg2 = 0xff1a1b1c,
|
||||
|
||||
bar = {
|
||||
bg = 0xff072626,
|
||||
border = 0xffFD971F,
|
||||
},
|
||||
popup = {
|
||||
bg = with_alpha(0xff072626, 0.6),
|
||||
border = 0xffFD971F,
|
||||
},
|
||||
|
||||
with_alpha = with_alpha,
|
||||
}
|
||||
|
||||
-- return {
|
||||
-- fg = 0xff181819,
|
||||
-- black = 0xff181819,
|
||||
-- white = 0xffffffff,
|
||||
-- red = 0xffff0000,
|
||||
-- blue = 0xff0000ff,
|
||||
-- grey = 0xff7f8490,
|
||||
-- transparent = 0x00000000,
|
||||
--
|
||||
-- bar = {
|
||||
-- bg = 0xffffffff,
|
||||
-- border = 0xff000000,
|
||||
-- },
|
||||
-- popup = {
|
||||
-- bg = with_alpha(0xffffffff, 0.6),
|
||||
-- border = 0xff000000,
|
||||
-- },
|
||||
--
|
||||
-- with_alpha = with_alpha,
|
||||
-- }
|
||||
92
config/sketchybar/icons.lua
Normal file
92
config/sketchybar/icons.lua
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
local settings = require 'settings'
|
||||
|
||||
local icons = {
|
||||
sf_symbols = {
|
||||
plus = '',
|
||||
loading = '',
|
||||
apple = '',
|
||||
gear = '',
|
||||
cpu = '',
|
||||
clipboard = '',
|
||||
|
||||
switch = {
|
||||
on = '',
|
||||
off = '',
|
||||
},
|
||||
volume = {
|
||||
_100 = '',
|
||||
_66 = '',
|
||||
_33 = '',
|
||||
_10 = '',
|
||||
_0 = '',
|
||||
},
|
||||
battery = {
|
||||
_100 = '',
|
||||
_75 = '',
|
||||
_50 = '',
|
||||
_25 = '',
|
||||
_0 = '',
|
||||
charging = '',
|
||||
},
|
||||
wifi = {
|
||||
upload = '',
|
||||
download = '',
|
||||
connected = '',
|
||||
disconnected = '',
|
||||
router = '',
|
||||
},
|
||||
media = {
|
||||
back = '',
|
||||
forward = '',
|
||||
play_pause = '',
|
||||
},
|
||||
},
|
||||
|
||||
-- Alternative NerdFont icons
|
||||
nerdfont = {
|
||||
plus = '',
|
||||
loading = '',
|
||||
apple = '',
|
||||
gear = '',
|
||||
cpu = '',
|
||||
clipboard = 'Missing Icon',
|
||||
|
||||
switch = {
|
||||
on = '',
|
||||
off = '',
|
||||
},
|
||||
volume = {
|
||||
_100 = '',
|
||||
_66 = '',
|
||||
_33 = '',
|
||||
_10 = '',
|
||||
_0 = '',
|
||||
},
|
||||
battery = {
|
||||
_100 = '',
|
||||
_75 = '',
|
||||
_50 = '',
|
||||
_25 = '',
|
||||
_0 = '',
|
||||
charging = '',
|
||||
},
|
||||
wifi = {
|
||||
upload = '',
|
||||
download = '',
|
||||
connected = '',
|
||||
disconnected = '',
|
||||
router = 'Missing Icon',
|
||||
},
|
||||
media = {
|
||||
back = '',
|
||||
forward = '',
|
||||
play_pause = '',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if not (settings.icons == 'NerdFont') then
|
||||
return icons.sf_symbols
|
||||
else
|
||||
return icons.nerdfont
|
||||
end
|
||||
56
config/sketchybar/init.lua
Normal file
56
config/sketchybar/init.lua
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
sbar.default {
|
||||
updates = 'when_shown',
|
||||
icon = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Bold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
background = { image = { corner_radius = 9 } },
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = 'Semibold',
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
},
|
||||
background = {
|
||||
height = 30,
|
||||
corner_radius = 12,
|
||||
border_width = 1,
|
||||
-- border_color = colors.bar.border,
|
||||
image = {
|
||||
corner_radius = 8,
|
||||
-- border_color = colors.grey,
|
||||
border_width = 1,
|
||||
},
|
||||
},
|
||||
popup = {
|
||||
background = {
|
||||
border_width = 1,
|
||||
corner_radius = 8,
|
||||
border_color = colors.popup.border,
|
||||
color = colors.popup.bg,
|
||||
shadow = { drawing = true },
|
||||
},
|
||||
blur_radius = 20,
|
||||
},
|
||||
padding_left = 5,
|
||||
padding_right = 5,
|
||||
scroll_texts = true,
|
||||
}
|
||||
|
||||
require 'bar'
|
||||
require 'items'
|
||||
242
config/sketchybar/items/aerospace.lua
Normal file
242
config/sketchybar/items/aerospace.lua
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
-- https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/sbar-config-libs/items/aerospaces.lua
|
||||
|
||||
local Promise = require 'promise'
|
||||
local colors = require 'colors'
|
||||
local utils = require 'utils'
|
||||
local settings = require 'settings'
|
||||
local app_icons = require 'app_icons'
|
||||
|
||||
local function getAllWorkspaces()
|
||||
return utils.sbarExecP "aerospace list-workspaces --all --format '%{workspace}%{monitor-appkit-nsscreen-screens-id}%{monitor-id}%{monitor-name}' --json"
|
||||
end
|
||||
|
||||
local function getVisibleWorkspaces()
|
||||
return utils.sbarExecP "aerospace list-workspaces --visible --monitor all --format '%{workspace}%{monitor-appkit-nsscreen-screens-id}%{monitor-id}%{monitor-name}' --json"
|
||||
end
|
||||
|
||||
local function getAllWindows()
|
||||
return utils.sbarExecP "aerospace list-windows --all --format '%{app-name}%{window-title}%{workspace}%{monitor-id}%{monitor-appkit-nsscreen-screens-id}%{monitor-name}' --json"
|
||||
end
|
||||
|
||||
local function getMonitorId(obj)
|
||||
if obj['monitor-name'] then
|
||||
if obj['monitor-name'] == 'ZOWIE XL LCD' then
|
||||
return '2'
|
||||
elseif obj['monitor-name'] == 'LG ULTRAWIDE' then
|
||||
return '1'
|
||||
end
|
||||
end
|
||||
if obj['monitor-appkit-nsscreen-screens-id'] then return obj['monitor-appkit-nsscreen-screens-id'] end
|
||||
return obj['monitor-id']
|
||||
end
|
||||
|
||||
local spaces = {}
|
||||
local space_paddings = {}
|
||||
local brackets = {}
|
||||
local state = {
|
||||
workspaces = {},
|
||||
updating = false,
|
||||
}
|
||||
|
||||
function getState()
|
||||
local newstate = {
|
||||
workspaces = {},
|
||||
}
|
||||
|
||||
for workspaceid, space in pairs(spaces) do
|
||||
newstate.workspaces[workspaceid] = {
|
||||
monitor = 0,
|
||||
active = false,
|
||||
empty = true,
|
||||
apps = {},
|
||||
appicons = '',
|
||||
}
|
||||
end
|
||||
|
||||
return Promise.all({ getAllWorkspaces(), getVisibleWorkspaces(), getAllWindows() }):thenCall(function(values)
|
||||
local all, visible, apps = values[1], values[2], values[3]
|
||||
for _, workspace in ipairs(all) do
|
||||
local workspaceid = workspace['workspace']
|
||||
newstate.workspaces[workspaceid]['id'] = workspaceid
|
||||
newstate.workspaces[workspaceid]['monitor'] = getMonitorId(workspace)
|
||||
end
|
||||
|
||||
for _, workspace in ipairs(visible) do
|
||||
local workspaceid = workspace['workspace']
|
||||
newstate.workspaces[workspaceid]['active'] = true
|
||||
end
|
||||
|
||||
for _, window in ipairs(apps) do
|
||||
local workspaceid = window['workspace']
|
||||
local appname = window['app-name']
|
||||
newstate.workspaces[workspaceid]['apps'][appname] = true
|
||||
newstate.workspaces[workspaceid]['empty'] = false
|
||||
end
|
||||
|
||||
for workspaceid, workspacestate in pairs(newstate.workspaces) do
|
||||
local appkeys = {}
|
||||
for app in pairs(workspacestate['apps']) do
|
||||
table.insert(appkeys, app)
|
||||
end
|
||||
table.sort(appkeys)
|
||||
if #appkeys > 0 then
|
||||
for _, app in ipairs(appkeys) do
|
||||
local lookup = app_icons[app]
|
||||
local icon = ((lookup == nil) and app_icons['Default'] or lookup)
|
||||
workspacestate['appicons'] = workspacestate['appicons'] .. ' ' .. icon
|
||||
end
|
||||
else
|
||||
workspacestate['appicons'] = ''
|
||||
end
|
||||
-- print(utils.dump(workspacestate))
|
||||
end
|
||||
|
||||
return newstate
|
||||
end)
|
||||
end
|
||||
|
||||
local function updateState()
|
||||
if not state.updating then
|
||||
state.updating = true
|
||||
return getState():thenCall(function(newstate)
|
||||
state.workspaces = newstate.workspaces
|
||||
state.updating = false
|
||||
end)
|
||||
end
|
||||
return Promise.reject 'State is already updating'
|
||||
end
|
||||
|
||||
local function highlightSpace(space, space_padding, space_bracket, selected)
|
||||
space:set {
|
||||
drawing = true,
|
||||
icon = { highlight = selected },
|
||||
label = { highlight = selected },
|
||||
-- background = { border_color = selected and colors.white or colors.bg2 }
|
||||
}
|
||||
space_padding:set {
|
||||
drawing = true,
|
||||
}
|
||||
if space_bracket then
|
||||
space_bracket:set {
|
||||
-- background = { border_color = selected and colors.grey or colors.bg2 },
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function onActiveSpaceChange(env)
|
||||
local focused_workspace = env.FOCUSED_WORKSPACE
|
||||
local last_workspace = env.PREV_WORKSPACE
|
||||
-- print("aerospace_workspace_change from " .. last_workspace .. " to " .. focused_workspace)
|
||||
|
||||
local space = spaces[focused_workspace]
|
||||
local space_padding = space_paddings[focused_workspace]
|
||||
|
||||
local prev_space = spaces[last_workspace]
|
||||
local prev_space_padding = space_paddings[last_workspace]
|
||||
|
||||
sbar.animate('tanh', 10, function()
|
||||
highlightSpace(space, space_padding, nil, true)
|
||||
if state.workspaces[last_workspace]['monitor'] == state.workspaces[focused_workspace]['monitor'] then
|
||||
highlightSpace(prev_space, prev_space_padding, nil, false)
|
||||
end
|
||||
end)
|
||||
|
||||
updateState()
|
||||
end
|
||||
|
||||
local function syncState()
|
||||
sbar.animate('tanh', 10, function()
|
||||
for workspaceid, workspacestate in pairs(state.workspaces) do
|
||||
if not workspacestate['empty'] then
|
||||
spaces[workspaceid]:set {
|
||||
drawing = true,
|
||||
display = workspacestate['monitor'],
|
||||
-- label = {
|
||||
-- string = workspaceid,
|
||||
-- highlight = workspacestate["active"],
|
||||
-- },
|
||||
-- icon = {
|
||||
-- string = workspaceid,
|
||||
-- color = colors.white,
|
||||
-- highlight = workspacestate["active"],
|
||||
-- },
|
||||
label = {
|
||||
string = workspacestate['appicons'],
|
||||
highlight = workspacestate['active'],
|
||||
},
|
||||
icon = {
|
||||
highlight = workspacestate['active'],
|
||||
},
|
||||
}
|
||||
space_paddings[workspaceid]:set { drawing = true }
|
||||
else
|
||||
-- These should be hidden
|
||||
spaces[workspaceid]:set {
|
||||
drawing = false,
|
||||
display = workspacestate['monitor'],
|
||||
label = workspacestate['appicons'],
|
||||
}
|
||||
space_paddings[workspaceid]:set { drawing = false }
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function updateStateAndSync() return updateState():thenCall(syncState) end
|
||||
|
||||
function setup()
|
||||
getAllWorkspaces()
|
||||
:thenCall(function(workspaces)
|
||||
for _, workspace in ipairs(workspaces) do
|
||||
local workspaceid = workspace['workspace']
|
||||
local display = getMonitorId(workspace)
|
||||
|
||||
local space = sbar.add('item', 'space.' .. workspaceid, {
|
||||
drawing = false, -- default to not showing the space -- we'll show if it has windows or is activated
|
||||
updates = 'when_shown',
|
||||
display = display,
|
||||
icon = {
|
||||
string = workspaceid,
|
||||
color = colors.fg,
|
||||
highlight_color = colors.red,
|
||||
},
|
||||
label = {
|
||||
padding_right = 12,
|
||||
color = colors.fg,
|
||||
highlight_color = colors.blue,
|
||||
font = 'sketchybar-app-font:Regular:14.0',
|
||||
y_offset = -1,
|
||||
-- drawing = false
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = 'aerospace workspace ' .. workspaceid,
|
||||
})
|
||||
|
||||
spaces[workspaceid] = space
|
||||
|
||||
local padding = sbar.add('space', 'space.padding.' .. space.name, {
|
||||
drawing = false,
|
||||
updates = 'when_shown',
|
||||
display = display,
|
||||
script = '',
|
||||
width = settings.space_paddings,
|
||||
})
|
||||
space_paddings[workspaceid] = padding
|
||||
end
|
||||
end)
|
||||
:thenCall(function()
|
||||
local space_window_observer = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
space_window_observer:subscribe('aerospace_workspace_change', onActiveSpaceChange)
|
||||
space_window_observer:subscribe('space_windows_change', updateStateAndSync)
|
||||
space_window_observer:subscribe('system_woke', updateStateAndSync)
|
||||
space_window_observer:subscribe('front_app_switched', updateStateAndSync)
|
||||
end)
|
||||
:thenCall(updateStateAndSync)
|
||||
end
|
||||
|
||||
setup()
|
||||
37
config/sketchybar/items/apple.lua
Normal file
37
config/sketchybar/items/apple.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
local colors = require 'colors'
|
||||
local icons = require 'icons'
|
||||
local settings = require 'settings'
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add('item', { width = 5 })
|
||||
|
||||
local apple = sbar.add('item', {
|
||||
icon = {
|
||||
font = { size = 16.0 },
|
||||
string = icons.apple,
|
||||
padding_right = settings.paddings,
|
||||
padding_left = 0,
|
||||
color = colors.fg,
|
||||
},
|
||||
label = { drawing = false },
|
||||
background = {
|
||||
color = colors.bar.bg,
|
||||
-- border_color = colors.black,
|
||||
-- border_width = 1
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = 'sk-menus -s 0',
|
||||
})
|
||||
|
||||
-- Double border for apple using a single item bracket
|
||||
-- sbar.add("bracket", { apple.name }, {
|
||||
-- background = {
|
||||
-- color = colors.transparent,
|
||||
-- height = 30,
|
||||
-- -- border_color = colors.grey,
|
||||
-- }
|
||||
-- })
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add('item', { width = 7 })
|
||||
42
config/sketchybar/items/battery.lua
Normal file
42
config/sketchybar/items/battery.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
local icons = require 'icons'
|
||||
|
||||
local battery = sbar.add('item', {
|
||||
position = 'right',
|
||||
icon = {
|
||||
font = {
|
||||
style = 'Regular',
|
||||
size = 19.0,
|
||||
},
|
||||
},
|
||||
label = { drawing = false },
|
||||
update_freq = 120,
|
||||
})
|
||||
|
||||
local function battery_update()
|
||||
sbar.exec('pmset -g batt', function(batt_info)
|
||||
local icon = '!'
|
||||
|
||||
if string.find(batt_info, 'AC Power') then
|
||||
icon = icons.battery.charging
|
||||
else
|
||||
local found, _, charge = batt_info:find '(%d+)%%'
|
||||
if found then charge = tonumber(charge) end
|
||||
|
||||
if found and charge > 80 then
|
||||
icon = icons.battery._100
|
||||
elseif found and charge > 60 then
|
||||
icon = icons.battery._75
|
||||
elseif found and charge > 40 then
|
||||
icon = icons.battery._50
|
||||
elseif found and charge > 20 then
|
||||
icon = icons.battery._25
|
||||
else
|
||||
icon = icons.battery._0
|
||||
end
|
||||
end
|
||||
|
||||
battery:set { icon = icon }
|
||||
end)
|
||||
end
|
||||
|
||||
battery:subscribe({ 'routine', 'power_source_change', 'system_woke' }, battery_update)
|
||||
50
config/sketchybar/items/cal.lua
Normal file
50
config/sketchybar/items/cal.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add('item', { position = 'right', width = settings.group_paddings })
|
||||
|
||||
local cal = sbar.add('item', {
|
||||
icon = {
|
||||
color = colors.fg,
|
||||
padding_left = 0,
|
||||
font = { size = 13 },
|
||||
},
|
||||
label = {
|
||||
color = colors.fg,
|
||||
padding_right = 0,
|
||||
align = 'right',
|
||||
},
|
||||
position = 'right',
|
||||
update_freq = 30,
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
click_script = 'open -n -a Calendar',
|
||||
-- background = {
|
||||
-- color = colors.bg1,
|
||||
-- border_color = colors.bar.border,
|
||||
-- border_width = 1,
|
||||
-- },
|
||||
})
|
||||
|
||||
-- Double border for calendar using a single item bracket
|
||||
-- sbar.add("bracket", { cal.name }, {
|
||||
-- background = {
|
||||
-- color = colors.transparent,
|
||||
-- height = 30,
|
||||
-- border_color = colors.bar.bg,
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add('item', { position = 'right', width = settings.group_paddings })
|
||||
|
||||
-- cal:subscribe({ "forced", "routine", "system_woke" }, function(env)
|
||||
-- cal:set({ icon = os.date(" %B %d %a"), label = os.date(" %H:%M") })
|
||||
-- end)
|
||||
cal:subscribe({ 'forced', 'routine', 'system_woke' }, function(env)
|
||||
cal:set {
|
||||
icon = os.date ' %B %d %a',
|
||||
label = os.date ' %I:%M %p', -- 12-hour format with AM/PM
|
||||
}
|
||||
end)
|
||||
67
config/sketchybar/items/cpu.lua
Normal file
67
config/sketchybar/items/cpu.lua
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
local icons = require 'icons'
|
||||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
-- Execute the event provider binary which provides the event "cpu_update" for
|
||||
-- the cpu load data, which is fired every 2.0 seconds.
|
||||
sbar.exec 'killall sk-cpu-load >/dev/null; sk-cpu-load cpu_update 2.0'
|
||||
|
||||
local cpu = sbar.add('graph', 'widgets.cpu', 42, {
|
||||
position = 'right',
|
||||
graph = { color = colors.blue },
|
||||
background = {
|
||||
height = 22,
|
||||
color = { alpha = 0 },
|
||||
border_color = { alpha = 0 },
|
||||
drawing = true,
|
||||
},
|
||||
icon = { string = icons.cpu },
|
||||
label = {
|
||||
string = 'cpu ??%',
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 9.0,
|
||||
},
|
||||
align = 'right',
|
||||
padding_right = 0,
|
||||
width = 0,
|
||||
y_offset = 4,
|
||||
},
|
||||
padding_right = settings.paddings + 6,
|
||||
})
|
||||
|
||||
cpu:subscribe('cpu_update', function(env)
|
||||
-- Also available: env.user_load, env.sys_load
|
||||
local load = tonumber(env.total_load)
|
||||
cpu:push { load / 100. }
|
||||
|
||||
local color = colors.blue
|
||||
if load > 30 then
|
||||
if load < 60 then
|
||||
color = colors.yellow
|
||||
elseif load < 80 then
|
||||
color = colors.orange
|
||||
else
|
||||
color = colors.red
|
||||
end
|
||||
end
|
||||
|
||||
cpu:set {
|
||||
graph = { color = color },
|
||||
label = 'cpu ' .. env.total_load .. '%',
|
||||
}
|
||||
end)
|
||||
|
||||
cpu:subscribe('mouse.clicked', function(env) sbar.exec "open -a 'Activity Monitor'" end)
|
||||
|
||||
-- Background around the cpu item
|
||||
sbar.add('bracket', 'widgets.cpu.bracket', { cpu.name }, {
|
||||
background = { color = colors.bg1 },
|
||||
})
|
||||
|
||||
-- Background around the cpu item
|
||||
sbar.add('item', 'widgets.cpu.padding', {
|
||||
position = 'right',
|
||||
width = settings.group_paddings,
|
||||
})
|
||||
31
config/sketchybar/items/front_app.lua
Normal file
31
config/sketchybar/items/front_app.lua
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
local settings = require 'settings'
|
||||
local app_icons = require 'app_icons'
|
||||
|
||||
local front_app = sbar.add('item', 'front_app', {
|
||||
icon = {
|
||||
font = 'sketchybar-app-font:Regular:16.0',
|
||||
padding_left = 8,
|
||||
padding_right = 8,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 12.0,
|
||||
},
|
||||
padding_right = 8,
|
||||
},
|
||||
})
|
||||
|
||||
front_app:subscribe('front_app_switched', function(env)
|
||||
local app_name = env.INFO
|
||||
local icon = app_icons[app_name] or app_icons['Default']
|
||||
|
||||
front_app:set {
|
||||
icon = {
|
||||
string = icon,
|
||||
},
|
||||
label = {
|
||||
string = app_name,
|
||||
},
|
||||
}
|
||||
end)
|
||||
33
config/sketchybar/items/init.lua
Normal file
33
config/sketchybar/items/init.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
local function file_exists(path)
|
||||
local f = io.open(path, 'r')
|
||||
if f then
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function load_module_if_program_exists(module_name, binary_path)
|
||||
if file_exists(binary_path) then
|
||||
print('Loading ' .. module_name .. ' (found at ' .. binary_path .. ')')
|
||||
local ok, err = pcall(require, module_name)
|
||||
if not ok then
|
||||
print('ERROR loading ' .. module_name .. ' module: ' .. tostring(err))
|
||||
else
|
||||
print('Successfully loaded ' .. module_name)
|
||||
end
|
||||
else
|
||||
print('Skipping ' .. module_name .. ' (binary not found at ' .. binary_path .. ')')
|
||||
end
|
||||
end
|
||||
|
||||
require 'items.apple'
|
||||
load_module_if_program_exists('items.aerospace', '/opt/homebrew/bin/aerospace')
|
||||
load_module_if_program_exists('items.yabai', '/etc/profiles/per-user/rayandrew/bin/yabai')
|
||||
require 'items.front_app'
|
||||
require 'items.menu'
|
||||
require 'items.battery'
|
||||
require 'items.cal'
|
||||
require 'items.volume'
|
||||
require 'items.cpu'
|
||||
require 'items.wifi'
|
||||
78
config/sketchybar/items/menu.lua
Normal file
78
config/sketchybar/items/menu.lua
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
local colors = require 'colors'
|
||||
local icons = require 'icons'
|
||||
local settings = require 'settings'
|
||||
|
||||
local menu_watcher = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = false,
|
||||
})
|
||||
local space_menu_swap = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
sbar.add('event', 'swap_menus_and_spaces')
|
||||
|
||||
local max_items = 15
|
||||
local menu_items = {}
|
||||
for i = 1, max_items, 1 do
|
||||
local menu = sbar.add('item', 'menu.' .. i, {
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
drawing = false,
|
||||
icon = { drawing = false },
|
||||
label = {
|
||||
font = {
|
||||
style = settings.font.style_map[i == 1 and 'Heavy' or 'Semibold'],
|
||||
},
|
||||
padding_left = 6,
|
||||
padding_right = 6,
|
||||
},
|
||||
click_script = 'sk-menus -s ' .. i,
|
||||
})
|
||||
|
||||
menu_items[i] = menu
|
||||
end
|
||||
|
||||
sbar.add('bracket', { '/menu\\..*/' }, {
|
||||
background = { color = colors.bg1 },
|
||||
})
|
||||
|
||||
local menu_padding = sbar.add('item', 'menu.padding', {
|
||||
drawing = false,
|
||||
width = 5,
|
||||
})
|
||||
|
||||
local function update_menus(env)
|
||||
sbar.exec('sk-menus -l', function(menus)
|
||||
sbar.set('/menu\\..*/', { drawing = false })
|
||||
menu_padding:set { drawing = true }
|
||||
id = 1
|
||||
for menu in string.gmatch(menus, '[^\r\n]+') do
|
||||
if id < max_items then
|
||||
menu_items[id]:set { label = menu, drawing = true }
|
||||
else
|
||||
break
|
||||
end
|
||||
id = id + 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
menu_watcher:subscribe('front_app_switched', update_menus)
|
||||
|
||||
space_menu_swap:subscribe('swap_menus_and_spaces', function(env)
|
||||
local drawing = menu_items[1]:query().geometry.drawing == 'on'
|
||||
if drawing then
|
||||
menu_watcher:set { updates = false }
|
||||
sbar.set('/menu\\..*/', { drawing = false })
|
||||
sbar.set('/space\\..*/', { drawing = true })
|
||||
sbar.set('front_app', { drawing = true })
|
||||
else
|
||||
menu_watcher:set { updates = true }
|
||||
sbar.set('/space\\..*/', { drawing = false })
|
||||
sbar.set('front_app', { drawing = false })
|
||||
update_menus()
|
||||
end
|
||||
end)
|
||||
|
||||
return menu_watcher
|
||||
75
config/sketchybar/items/volume.lua
Normal file
75
config/sketchybar/items/volume.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
local colors = require 'colors'
|
||||
local icons = require 'icons'
|
||||
|
||||
local volume_slider = sbar.add('slider', 100, {
|
||||
position = 'right',
|
||||
updates = true,
|
||||
label = { drawing = false },
|
||||
icon = { drawing = false },
|
||||
slider = {
|
||||
highlight_color = colors.blue,
|
||||
width = 0,
|
||||
background = {
|
||||
height = 6,
|
||||
corner_radius = 3,
|
||||
color = colors.bg2,
|
||||
},
|
||||
knob = {
|
||||
string = '',
|
||||
drawing = false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
local volume_icon = sbar.add('item', {
|
||||
position = 'right',
|
||||
icon = {
|
||||
string = icons.volume._100,
|
||||
width = 0,
|
||||
align = 'left',
|
||||
color = colors.grey,
|
||||
font = {
|
||||
style = 'Regular',
|
||||
size = 14.0,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
width = 25,
|
||||
align = 'left',
|
||||
font = {
|
||||
style = 'Regular',
|
||||
size = 14.0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
volume_slider:subscribe('mouse.clicked', function(env) sbar.exec("osascript -e 'set volume output volume " .. env['PERCENTAGE'] .. "'") end)
|
||||
|
||||
volume_slider:subscribe('volume_change', function(env)
|
||||
local volume = tonumber(env.INFO)
|
||||
local icon = icons.volume._0
|
||||
if volume > 60 then
|
||||
icon = icons.volume._100
|
||||
elseif volume > 30 then
|
||||
icon = icons.volume._66
|
||||
elseif volume > 10 then
|
||||
icon = icons.volume._33
|
||||
elseif volume > 0 then
|
||||
icon = icons.volume._10
|
||||
end
|
||||
|
||||
volume_icon:set { label = icon }
|
||||
volume_slider:set { slider = { percentage = volume } }
|
||||
end)
|
||||
|
||||
local function animate_slider_width(width)
|
||||
sbar.animate('tanh', 30.0, function() volume_slider:set { slider = { width = width } } end)
|
||||
end
|
||||
|
||||
volume_icon:subscribe('mouse.clicked', function()
|
||||
if tonumber(volume_slider:query().slider.width) > 0 then
|
||||
animate_slider_width(0)
|
||||
else
|
||||
animate_slider_width(100)
|
||||
end
|
||||
end)
|
||||
219
config/sketchybar/items/wifi.lua
Normal file
219
config/sketchybar/items/wifi.lua
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
local icons = require 'icons'
|
||||
local colors = require 'colors'
|
||||
local settings = require 'settings'
|
||||
|
||||
-- Execute the event provider binary which provides the event "network_update"
|
||||
-- for the network interface "en0", which is fired every 2.0 seconds.
|
||||
sbar.exec 'killall sk-network-load >/dev/null; sk-network-load en0 network_update 2.0'
|
||||
|
||||
local popup_width = 250
|
||||
|
||||
local wifi_up = sbar.add('item', 'widgets.wifi1', {
|
||||
position = 'right',
|
||||
padding_left = -5,
|
||||
width = 0,
|
||||
icon = {
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 9.0,
|
||||
},
|
||||
string = icons.wifi.upload,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 9.0,
|
||||
},
|
||||
color = colors.red,
|
||||
string = '??? Bps',
|
||||
},
|
||||
y_offset = 4,
|
||||
})
|
||||
|
||||
local wifi_down = sbar.add('item', 'widgets.wifi2', {
|
||||
position = 'right',
|
||||
padding_left = -5,
|
||||
icon = {
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 9.0,
|
||||
},
|
||||
string = icons.wifi.download,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map['Bold'],
|
||||
size = 9.0,
|
||||
},
|
||||
color = colors.blue,
|
||||
string = '??? Bps',
|
||||
},
|
||||
y_offset = -4,
|
||||
})
|
||||
|
||||
local wifi = sbar.add('item', 'widgets.wifi.padding', {
|
||||
position = 'right',
|
||||
label = { drawing = false },
|
||||
})
|
||||
|
||||
-- Background around the item
|
||||
local wifi_bracket = sbar.add('bracket', 'widgets.wifi.bracket', {
|
||||
wifi.name,
|
||||
wifi_up.name,
|
||||
wifi_down.name,
|
||||
}, {
|
||||
-- background = { color = colors.bar.bg },
|
||||
popup = { align = 'center', height = 30 },
|
||||
})
|
||||
|
||||
local ssid = sbar.add('item', {
|
||||
position = 'popup.' .. wifi_bracket.name,
|
||||
icon = {
|
||||
font = {
|
||||
style = settings.font.style_map['Bold'],
|
||||
},
|
||||
string = icons.wifi.router,
|
||||
},
|
||||
width = popup_width,
|
||||
align = 'center',
|
||||
label = {
|
||||
font = {
|
||||
size = 15,
|
||||
style = settings.font.style_map['Bold'],
|
||||
},
|
||||
max_chars = 18,
|
||||
string = '????????????',
|
||||
},
|
||||
background = {
|
||||
height = 2,
|
||||
color = colors.fg,
|
||||
y_offset = -15,
|
||||
},
|
||||
})
|
||||
|
||||
local hostname = sbar.add('item', {
|
||||
position = 'popup.' .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'Hostname:',
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
max_chars = 20,
|
||||
string = '????????????',
|
||||
width = popup_width / 2,
|
||||
align = 'right',
|
||||
},
|
||||
})
|
||||
local ip = sbar.add('item', {
|
||||
position = 'popup.' .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'IP:',
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = '???.???.???.???',
|
||||
width = popup_width / 2,
|
||||
align = 'right',
|
||||
},
|
||||
})
|
||||
|
||||
local mask = sbar.add('item', {
|
||||
position = 'popup.' .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'Subnet mask:',
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = '???.???.???.???',
|
||||
width = popup_width / 2,
|
||||
align = 'right',
|
||||
},
|
||||
})
|
||||
|
||||
local router = sbar.add('item', {
|
||||
position = 'popup.' .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = 'left',
|
||||
string = 'Router:',
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = '???.???.???.???',
|
||||
width = popup_width / 2,
|
||||
align = 'right',
|
||||
},
|
||||
})
|
||||
|
||||
sbar.add('item', { position = 'right', width = settings.group_paddings })
|
||||
|
||||
wifi_up:subscribe('network_update', function(env)
|
||||
local up_color = (env.upload == '000 Bps') and colors.fg or colors.red
|
||||
local down_color = (env.download == '000 Bps') and colors.fg or colors.blue
|
||||
wifi_up:set {
|
||||
icon = { color = up_color },
|
||||
label = {
|
||||
string = env.upload,
|
||||
color = up_color,
|
||||
},
|
||||
}
|
||||
wifi_down:set {
|
||||
icon = { color = down_color },
|
||||
label = {
|
||||
string = env.download,
|
||||
color = down_color,
|
||||
},
|
||||
}
|
||||
end)
|
||||
|
||||
wifi:subscribe({ 'wifi_change', 'system_woke' }, function(env)
|
||||
sbar.exec('ipconfig getifaddr en0', function(ip)
|
||||
local connected = not (ip == '')
|
||||
wifi:set {
|
||||
icon = {
|
||||
string = connected and icons.wifi.connected or icons.wifi.disconnected,
|
||||
color = connected and colors.fg or colors.red,
|
||||
},
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
local function hide_details() wifi_bracket:set { popup = { drawing = false } } end
|
||||
|
||||
local function toggle_details()
|
||||
local should_draw = wifi_bracket:query().popup.drawing == 'off'
|
||||
if should_draw then
|
||||
wifi_bracket:set { popup = { drawing = true } }
|
||||
sbar.exec('networksetup -getcomputername', function(result) hostname:set { label = result } end)
|
||||
sbar.exec('ipconfig getifaddr en0', function(result) ip:set { label = result } end)
|
||||
sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(result) ssid:set { label = result } end)
|
||||
sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Subnet mask: ' '/^Subnet mask: / {print $2}'", function(result) mask:set { label = result } end)
|
||||
sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Router: ' '/^Router: / {print $2}'", function(result) router:set { label = result } end)
|
||||
else
|
||||
hide_details()
|
||||
end
|
||||
end
|
||||
|
||||
wifi_up:subscribe('mouse.clicked', toggle_details)
|
||||
wifi_down:subscribe('mouse.clicked', toggle_details)
|
||||
wifi:subscribe('mouse.clicked', toggle_details)
|
||||
wifi:subscribe('mouse.exited.global', hide_details)
|
||||
|
||||
local function copy_label_to_clipboard(env)
|
||||
local label = sbar.query(env.NAME).label.value
|
||||
sbar.exec('echo "' .. label .. '" | pbcopy')
|
||||
sbar.set(env.NAME, { label = { string = icons.clipboard, align = 'center' } })
|
||||
sbar.delay(1, function() sbar.set(env.NAME, { label = { string = label, align = 'right' } }) end)
|
||||
end
|
||||
|
||||
ssid:subscribe('mouse.clicked', copy_label_to_clipboard)
|
||||
hostname:subscribe('mouse.clicked', copy_label_to_clipboard)
|
||||
ip:subscribe('mouse.clicked', copy_label_to_clipboard)
|
||||
mask:subscribe('mouse.clicked', copy_label_to_clipboard)
|
||||
router:subscribe('mouse.clicked', copy_label_to_clipboard)
|
||||
190
config/sketchybar/items/yabai.lua
Normal file
190
config/sketchybar/items/yabai.lua
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
local colors = require 'colors'
|
||||
-- local icons = require("icons")
|
||||
local settings = require 'settings'
|
||||
local app_icons = require 'app_icons'
|
||||
|
||||
local spaces = {}
|
||||
local space_has_windows = {}
|
||||
|
||||
local yabai_cmd = '/etc/profiles/per-user/rayandrew/bin/yabai'
|
||||
|
||||
for i = 1, 10, 1 do
|
||||
local space = sbar.add('space', 'space.' .. i, {
|
||||
space = i,
|
||||
icon = {
|
||||
font = { family = settings.font.numbers },
|
||||
string = i,
|
||||
padding_left = 15,
|
||||
padding_right = 8,
|
||||
color = colors.white,
|
||||
highlight_color = colors.red,
|
||||
},
|
||||
label = {
|
||||
padding_right = 20,
|
||||
color = colors.grey,
|
||||
highlight_color = colors.white,
|
||||
font = 'sketchybar-app-font:Regular:16.0',
|
||||
y_offset = -1,
|
||||
},
|
||||
padding_right = 1,
|
||||
padding_left = 1,
|
||||
background = {
|
||||
color = colors.bg1,
|
||||
border_width = 1,
|
||||
height = 26,
|
||||
border_color = colors.black,
|
||||
},
|
||||
popup = { background = { border_width = 5, border_color = colors.black } },
|
||||
})
|
||||
|
||||
spaces[i] = space
|
||||
|
||||
-- Single item bracket for space items to achieve double border on highlight
|
||||
local space_bracket = sbar.add('bracket', { space.name }, {
|
||||
background = {
|
||||
color = colors.transparent,
|
||||
border_color = colors.bg2,
|
||||
height = 28,
|
||||
border_width = 2,
|
||||
},
|
||||
})
|
||||
|
||||
-- Padding space
|
||||
sbar.add('space', 'space.padding.' .. i, {
|
||||
space = i,
|
||||
script = '',
|
||||
width = settings.group_paddings,
|
||||
})
|
||||
|
||||
local space_popup = sbar.add('item', 'space.popup.' .. i, {
|
||||
position = 'popup.space.' .. i,
|
||||
padding_left = 5,
|
||||
padding_right = 0,
|
||||
background = {
|
||||
drawing = true,
|
||||
image = {
|
||||
corner_radius = 9,
|
||||
scale = 0.2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
space:subscribe('space_change', function(env)
|
||||
local selected = env.SELECTED == 'true'
|
||||
local color = selected and colors.grey or colors.bg2
|
||||
local has_windows = space_has_windows[i] or false
|
||||
|
||||
space:set {
|
||||
icon = { highlight = selected },
|
||||
label = { highlight = selected },
|
||||
background = { border_color = selected and colors.black or colors.bg2 },
|
||||
drawing = selected or has_windows,
|
||||
}
|
||||
space_bracket:set {
|
||||
background = { border_color = selected and colors.grey or colors.bg2 },
|
||||
}
|
||||
end)
|
||||
|
||||
space:subscribe('mouse.clicked', function(env)
|
||||
if env.BUTTON == 'other' then
|
||||
space_popup:set { background = { image = 'space.' .. env.SID } }
|
||||
space:set { popup = { drawing = 'toggle' } }
|
||||
else
|
||||
local op = (env.BUTTON == 'right') and '--destroy' or '--focus'
|
||||
sbar.exec(yabai_cmd .. ' -m space ' .. op .. ' ' .. env.SID)
|
||||
end
|
||||
end)
|
||||
|
||||
space:subscribe('mouse.exited', function(_) space:set { popup = { drawing = false } } end)
|
||||
end
|
||||
|
||||
local space_window_observer = sbar.add('item', {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
-- local spaces_indicator = sbar.add("item", {
|
||||
-- padding_left = -3,
|
||||
-- padding_right = 0,
|
||||
-- icon = {
|
||||
-- padding_left = 8,
|
||||
-- padding_right = 9,
|
||||
-- color = colors.grey,
|
||||
-- string = icons.switch.on,
|
||||
-- },
|
||||
-- label = {
|
||||
-- width = 0,
|
||||
-- padding_left = 0,
|
||||
-- padding_right = 8,
|
||||
-- string = "Spaces",
|
||||
-- color = colors.bg1,
|
||||
-- },
|
||||
-- background = {
|
||||
-- color = colors.with_alpha(colors.grey, 0.0),
|
||||
-- border_color = colors.with_alpha(colors.bg1, 0.0),
|
||||
-- }
|
||||
-- })
|
||||
|
||||
space_window_observer:subscribe('space_windows_change', function(env)
|
||||
local icon_line = ''
|
||||
local no_app = true
|
||||
for app, count in pairs(env.INFO.apps) do
|
||||
no_app = false
|
||||
local lookup = app_icons[app]
|
||||
local icon = ((lookup == nil) and app_icons['Default'] or lookup)
|
||||
icon_line = icon_line .. icon
|
||||
end
|
||||
|
||||
if no_app then icon_line = ' —' end
|
||||
|
||||
-- Track window state
|
||||
space_has_windows[env.INFO.space] = not no_app
|
||||
|
||||
-- Query if this space is currently selected
|
||||
local space_info = spaces[env.INFO.space]:query()
|
||||
local is_selected = space_info and space_info.icon and space_info.icon.highlight or false
|
||||
|
||||
sbar.animate('tanh', 10, function()
|
||||
spaces[env.INFO.space]:set {
|
||||
label = icon_line,
|
||||
drawing = is_selected or not no_app,
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
-- spaces_indicator:subscribe("swap_menus_and_spaces", function(env)
|
||||
-- local currently_on = spaces_indicator:query().icon.value == icons.switch.on
|
||||
-- spaces_indicator:set({
|
||||
-- icon = currently_on and icons.switch.off or icons.switch.on
|
||||
-- })
|
||||
-- end)
|
||||
--
|
||||
-- spaces_indicator:subscribe("mouse.entered", function(env)
|
||||
-- sbar.animate("tanh", 30, function()
|
||||
-- spaces_indicator:set({
|
||||
-- background = {
|
||||
-- color = { alpha = 1.0 },
|
||||
-- border_color = { alpha = 1.0 },
|
||||
-- },
|
||||
-- icon = { color = colors.bg1 },
|
||||
-- label = { width = "dynamic" }
|
||||
-- })
|
||||
-- end)
|
||||
-- end)
|
||||
--
|
||||
-- spaces_indicator:subscribe("mouse.exited", function(env)
|
||||
-- sbar.animate("tanh", 30, function()
|
||||
-- spaces_indicator:set({
|
||||
-- background = {
|
||||
-- color = { alpha = 0.0 },
|
||||
-- border_color = { alpha = 0.0 },
|
||||
-- },
|
||||
-- icon = { color = colors.grey },
|
||||
-- label = { width = 0, }
|
||||
-- })
|
||||
-- end)
|
||||
-- end)
|
||||
--
|
||||
-- spaces_indicator:subscribe("mouse.clicked", function(env)
|
||||
-- sbar.trigger("swap_menus_and_spaces")
|
||||
-- end)
|
||||
19
config/sketchybar/settings.lua
Normal file
19
config/sketchybar/settings.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
return {
|
||||
icons = 'sf-symbols',
|
||||
font = {
|
||||
text = 'SF Pro',
|
||||
numbers = 'SF Pro',
|
||||
style_map = {
|
||||
['Regular'] = 'Regular',
|
||||
['Semibold'] = 'Semibold',
|
||||
['Bold'] = 'Bold',
|
||||
['Heavy'] = 'Heavy',
|
||||
['Black'] = 'Black',
|
||||
},
|
||||
},
|
||||
paddings = 3,
|
||||
group_paddings = 0,
|
||||
space_paddings = 5,
|
||||
}
|
||||
33
config/sketchybar/utils.lua
Normal file
33
config/sketchybar/utils.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
local Promise = require 'promise'
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.dump(o)
|
||||
if type(o) == 'table' then
|
||||
local s = '{'
|
||||
for k, v in pairs(o) do
|
||||
if type(k) ~= 'number' then k = '"' .. k .. '"' end
|
||||
s = s .. ' [' .. k .. '] = ' .. M.dump(v) .. ','
|
||||
end
|
||||
return s .. '} '
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
local function onErrorP(reason) print('Error found: ' .. (reason and M.dump(reason) or 'unknown')) end
|
||||
|
||||
-- https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/sbar-config-libs/items/aerospaces.lua
|
||||
function M.sbarExecP(cmd)
|
||||
return Promise.new(function(resolve, failfunc)
|
||||
sbar.exec(cmd, function(result, exit_code)
|
||||
if exit_code ~= 0 then
|
||||
if failfunc ~= nil then failfunc(string.format('Exit Code: %s Message: %s', tostring(exit_code), M.dump(result))) end
|
||||
else
|
||||
if resolve ~= nil then resolve(result) end
|
||||
end
|
||||
end)
|
||||
end):catch(onErrorP)
|
||||
end
|
||||
|
||||
return M
|
||||
49
config/yabai/yabairc
Normal file
49
config/yabai/yabairc
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
sudo $(readlink -f $(which yabai)) --load-sa
|
||||
yabai -m signal --add event=dock_did_restart action="sudo $(readlink -f $(which yabai)) --load-sa"
|
||||
|
||||
yabai -m config layout bsp
|
||||
yabai -m config top_padding 5
|
||||
yabai -m config bottom_padding 5
|
||||
yabai -m config left_padding 15
|
||||
yabai -m config right_padding 15
|
||||
yabai -m config window_gap 15
|
||||
|
||||
yabai -m config auto_balance off
|
||||
|
||||
yabai -m config mouse_follows_focus off
|
||||
yabai -m config focus_follows_mouse autofocus
|
||||
yabai -m config mouse_modifier fn
|
||||
yabai -m config mouse_action1 move
|
||||
yabai -m config mouse_action2 resize
|
||||
yabai -m config mouse_drop_action swap
|
||||
|
||||
yabai -m config external_bar all:45:0
|
||||
yabai -m config window_shadow float
|
||||
|
||||
yabai -m config split_ratio 0.50
|
||||
yabai -m config window_placement second_child
|
||||
|
||||
yabai -m config window_opacity on
|
||||
yabai -m config active_window_opacity 1.0
|
||||
yabai -m config normal_window_opacity 0.9
|
||||
|
||||
yabai -m config window_border off
|
||||
yabai -m config window_border_width 6
|
||||
yabai -m config active_window_border_color 0xff775759
|
||||
yabai -m config normal_window_border_color 0xff555555
|
||||
yabai -m config insert_feedback_color 0xffd75f5f
|
||||
|
||||
yabai -m rule --add app="^System Settings$" manage=off
|
||||
yabai -m rule --add app="^Archive Utility$" manage=off
|
||||
yabai -m rule --add app="^Wally$" manage=off
|
||||
yabai -m rule --add app="^Pika$" manage=off
|
||||
yabai -m rule --add app="^balenaEtcher$" manage=off
|
||||
yabai -m rule --add app="^Creative Cloud$" manage=off
|
||||
yabai -m rule --add app="^Logi Options$" manage=off
|
||||
yabai -m rule --add app="^Alfred Preferences$" manage=off
|
||||
yabai -m rule --add app="Raycast" manage=off
|
||||
yabai -m rule --add app="^Music$" manage=off
|
||||
|
||||
yabai-create-space
|
||||
|
||||
echo "yabai configuration loaded..."
|
||||
|
|
@ -7,10 +7,10 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.custom.aerospace;
|
||||
cfg = config.custom.gui.aerospace;
|
||||
in
|
||||
{
|
||||
options.custom = with lib; {
|
||||
options.custom.gui = with lib; {
|
||||
aerospace = {
|
||||
enable = mkEnableOption "Enable aerospace";
|
||||
logFile = mkOption {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
./keyboard.nix
|
||||
./sketchybar
|
||||
./nix.nix
|
||||
./yabai.nix
|
||||
];
|
||||
|
||||
options.custom = with lib; {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
clang-format = mkEnableOption "Enable clang-format";
|
||||
marta = mkEnableOption "Enable marta";
|
||||
valgrind = mkEnableOption "Enable valgrind";
|
||||
hammerspoon = mkEnableOption "Enable hammerspoon";
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
|
|
@ -215,7 +216,7 @@
|
|||
})
|
||||
(lib.mkIf config.custom.brew.flux {
|
||||
homebrew.casks = [
|
||||
"flux"
|
||||
"flux-app"
|
||||
];
|
||||
})
|
||||
(lib.mkIf config.custom.brew.cleanshot {
|
||||
|
|
@ -376,5 +377,10 @@
|
|||
# }
|
||||
# ];
|
||||
})
|
||||
(lib.mkIf config.custom.brew.hammerspoon {
|
||||
homebrew.casks = [
|
||||
"hammerspoon"
|
||||
];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
dots,
|
||||
home-dir,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.custom.jankyborders;
|
||||
cfg = config.custom.gui.jankyborders;
|
||||
in
|
||||
{
|
||||
options.custom = with lib; {
|
||||
options.custom.gui = with lib; {
|
||||
jankyborders = {
|
||||
enable = mkEnableOption "Enable jankyborders";
|
||||
logFile = mkOption {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ config, ... }:
|
||||
{ ... }:
|
||||
{
|
||||
system.keyboard = {
|
||||
enableKeyMapping = true;
|
||||
|
|
|
|||
|
|
@ -1,321 +0,0 @@
|
|||
-- these seem to get disentangled to https://github.com/kvndrsslr/sketchybar-app-font/tree/main/mappings
|
||||
return {
|
||||
["Live"] = ":ableton:",
|
||||
["Activity Monitor"] = ":numbers:", -- no pre-existing, sadly
|
||||
["Adobe Bridge"] = ":adobe_bridge:",
|
||||
["Affinity Designer"] = ":affinity_designer:",
|
||||
["Affinity Designer 2"] = ":affinity_designer_2:",
|
||||
["Affinity Photo"] = ":affinity_photo:",
|
||||
["Affinity Photo 2"] = ":affinity_photo_2:",
|
||||
["Affinity Publisher"] = ":affinity_publisher:",
|
||||
["Affinity Publisher 2"] = ":affinity_publisher_2:",
|
||||
["Airmail"] = ":airmail:",
|
||||
["Alacritty"] = ":alacritty:",
|
||||
["Alfred"] = ":alfred:",
|
||||
["Android Messages"] = ":android_messages:",
|
||||
["Android Studio"] = ":android_studio:",
|
||||
["Anki"] = ":anki:",
|
||||
["Anytype"] = ":anytype:",
|
||||
["App Eraser"] = ":app_eraser:",
|
||||
["App Store"] = ":app_store:",
|
||||
["Arc"] = ":arc:",
|
||||
["Arduino"] = ":arduino:",
|
||||
["Arduino IDE"] = ":arduino:",
|
||||
["Atom"] = ":atom:",
|
||||
["Audacity"] = ":audacity:",
|
||||
["Bambu Studio"] = ":bambu_studio:",
|
||||
["MoneyMoney"] = ":bank:",
|
||||
["Battle.net"] = ":battle_net:",
|
||||
["Bear"] = ":bear:",
|
||||
["BetterTouchTool"] = ":bettertouchtool:",
|
||||
["Bilibili"] = ":bilibili:",
|
||||
["哔哩哔哩"] = ":bilibili:",
|
||||
["Bitwarden"] = ":bit_warden:",
|
||||
["Blender"] = ":blender:",
|
||||
["BluOS Controller"] = ":bluos_controller:",
|
||||
["Calibre"] = ":book:",
|
||||
["Brave Browser"] = ":brave_browser:",
|
||||
["BusyCal"] = ":busycal:",
|
||||
["Calculator"] = ":calculator:",
|
||||
["Calculette"] = ":calculator:",
|
||||
["Calendar"] = ":calendar:",
|
||||
["日历"] = ":calendar:",
|
||||
["Fantastical"] = ":calendar:",
|
||||
["Cron"] = ":calendar:",
|
||||
["Amie"] = ":calendar:",
|
||||
["Calendrier"] = ":calendar:",
|
||||
["Notion Calendar"] = ":calendar:",
|
||||
["Caprine"] = ":caprine:",
|
||||
["Amazon Chime"] = ":chime:",
|
||||
["Citrix Workspace"] = ":citrix:",
|
||||
["Citrix Viewer"] = ":citrix:",
|
||||
["Claude"] = ":claude:",
|
||||
["ClickUp"] = ":click_up:",
|
||||
["Code"] = ":code:",
|
||||
["Code - Insiders"] = ":code:",
|
||||
["Cold Turkey Blocker"] = ":cold_turkey_blocker:",
|
||||
["Color Picker"] = ":color_picker:",
|
||||
["数码测色计"] = ":color_picker:",
|
||||
["Copilot"] = ":copilot:",
|
||||
["CotEditor"] = ":coteditor:",
|
||||
["Creative Cloud"] = ":creative_cloud:",
|
||||
["Cursor"] = ":cursor:",
|
||||
["Cypress"] = ":cypress:",
|
||||
["DataGrip"] = ":datagrip:",
|
||||
["DataSpell"] = ":dataspell:",
|
||||
["DaVinci Resolve"] = ":davinciresolve:",
|
||||
["Deezer"] = ":deezer:",
|
||||
["Default"] = ":default:",
|
||||
["CleanMyMac X"] = ":desktop:",
|
||||
["DEVONthink 3"] = ":devonthink3:",
|
||||
["DingTalk"] = ":dingtalk:",
|
||||
["钉钉"] = ":dingtalk:",
|
||||
["阿里钉"] = ":dingtalk:",
|
||||
["Discord"] = ":discord:",
|
||||
["Discord Canary"] = ":discord:",
|
||||
["Discord PTB"] = ":discord:",
|
||||
["Vesktop"] = ":discord:",
|
||||
["Docker"] = ":docker:",
|
||||
["Docker Desktop"] = ":docker:",
|
||||
["GrandTotal"] = ":dollar:",
|
||||
["Receipts"] = ":dollar:",
|
||||
["Double Commander"] = ":doublecmd:",
|
||||
["Drafts"] = ":drafts:",
|
||||
["draw.io"] = ":draw_io:",
|
||||
["Dropbox"] = ":dropbox:",
|
||||
["Element"] = ":element:",
|
||||
["Emacs"] = ":emacs:",
|
||||
["Evernote Legacy"] = ":evernote_legacy:",
|
||||
["FaceTime"] = ":face_time:",
|
||||
["FaceTime 通话"] = ":face_time:",
|
||||
["Figma"] = ":figma:",
|
||||
["Final Cut Pro"] = ":final_cut_pro:",
|
||||
["Finder"] = ":finder:",
|
||||
["访达"] = ":finder:",
|
||||
["Firefox"] = ":firefox:",
|
||||
["Firefox Developer Edition"] = ":firefox_developer_edition:",
|
||||
["Firefox Nightly"] = ":firefox_developer_edition:",
|
||||
["Folx"] = ":folx:",
|
||||
["Fork"] = ":fork:",
|
||||
["FreeTube"] = ":freetube:",
|
||||
["Fusion"] = ":fusion:",
|
||||
["System Preferences"] = ":gear:",
|
||||
["System Settings"] = ":gear:",
|
||||
["系统设置"] = ":gear:",
|
||||
["Réglages Système"] = ":gear:",
|
||||
["GitHub Desktop"] = ":git_hub:",
|
||||
["Godot"] = ":godot:",
|
||||
["GoLand"] = ":goland:",
|
||||
["Chromium"] = ":google_chrome:",
|
||||
["Google Chrome"] = ":google_chrome:",
|
||||
["Google Chrome Canary"] = ":google_chrome:",
|
||||
["Grammarly Editor"] = ":grammarly:",
|
||||
["Home Assistant"] = ":home_assistant:",
|
||||
["Hyper"] = ":hyper:",
|
||||
["IntelliJ IDEA"] = ":idea:",
|
||||
["IINA"] = ":iina:",
|
||||
["Adobe Illustrator"] = ":illustrator:",
|
||||
["Illustrator"] = ":illustrator:",
|
||||
["Adobe InDesign"] = ":indesign:",
|
||||
["InDesign"] = ":indesign:",
|
||||
["Inkdrop"] = ":inkdrop:",
|
||||
["Inkscape"] = ":inkscape:",
|
||||
["Insomnia"] = ":insomnia:",
|
||||
["Iris"] = ":iris:",
|
||||
["iTerm"] = ":iterm:",
|
||||
["iTerm2"] = ":iterm:",
|
||||
["Jellyfin Media Player"] = ":jellyfin:",
|
||||
["Joplin"] = ":joplin:",
|
||||
["카카오톡"] = ":kakaotalk:",
|
||||
["KakaoTalk"] = ":kakaotalk:",
|
||||
["Kakoune"] = ":kakoune:",
|
||||
["KeePassXC"] = ":kee_pass_x_c:",
|
||||
["Keyboard Maestro"] = ":keyboard_maestro:",
|
||||
["Keynote"] = ":keynote:",
|
||||
["Keynote 讲演"] = ":keynote:",
|
||||
["kitty"] = ":kitty:",
|
||||
["League of Legends"] = ":league_of_legends:",
|
||||
["LibreWolf"] = ":libre_wolf:",
|
||||
["Adobe Lightroom"] = ":lightroom:",
|
||||
["Lightroom Classic"] = ":lightroomclassic:",
|
||||
["LINE"] = ":line:",
|
||||
["Linear"] = ":linear:",
|
||||
["LM Studio"] = ":lm_studio:",
|
||||
["LocalSend"] = ":localsend:",
|
||||
["Logic Pro"] = ":logicpro:",
|
||||
["Logseq"] = ":logseq:",
|
||||
["Canary Mail"] = ":mail:",
|
||||
["HEY"] = ":mail:",
|
||||
["Mail"] = ":mail:",
|
||||
["Mailspring"] = ":mail:",
|
||||
["MailMate"] = ":mail:",
|
||||
["Superhuman"] = ":mail:",
|
||||
["Spark"] = ":mail:",
|
||||
["邮件"] = ":mail:",
|
||||
["MAMP"] = ":mamp:",
|
||||
["MAMP PRO"] = ":mamp:",
|
||||
["Maps"] = ":maps:",
|
||||
["News"] = ":sioyek:",
|
||||
["Ghostty"] = ":terminal:",
|
||||
["Google Maps"] = ":maps:",
|
||||
["Marta"] = ":marta:",
|
||||
["Matlab"] = ":matlab:",
|
||||
["Mattermost"] = ":mattermost:",
|
||||
["Messages"] = ":messages:",
|
||||
["信息"] = ":messages:",
|
||||
["Nachrichten"] = ":messages:",
|
||||
["Messenger"] = ":messenger:",
|
||||
["Microsoft Edge"] = ":microsoft_edge:",
|
||||
["Microsoft Excel"] = ":microsoft_excel:",
|
||||
["Microsoft Outlook"] = ":microsoft_outlook:",
|
||||
["Microsoft PowerPoint"] = ":microsoft_power_point:",
|
||||
["Microsoft Remote Desktop"] = ":microsoft_remote_desktop:",
|
||||
["Microsoft Teams"] = ":microsoft_teams:",
|
||||
["Microsoft Teams (work or school)"] = ":microsoft_teams:",
|
||||
["Microsoft Word"] = ":microsoft_word:",
|
||||
["Min"] = ":min_browser:",
|
||||
["Miro"] = ":miro:",
|
||||
["MongoDB Compass"] = ":mongodb:",
|
||||
["mpv"] = ":mpv:",
|
||||
["Mullvad Browser"] = ":mullvad_browser:",
|
||||
["Music"] = ":music:",
|
||||
["音乐"] = ":music:",
|
||||
["Musique"] = ":music:",
|
||||
["PWNeovide"] = ":neovide:",
|
||||
["Neovide"] = ":neovide:",
|
||||
["neovide"] = ":neovide:",
|
||||
["Neovim"] = ":neovim:",
|
||||
["neovim"] = ":neovim:",
|
||||
["nvim"] = ":neovim:",
|
||||
["网易云音乐"] = ":netease_music:",
|
||||
["Noodl"] = ":noodl:",
|
||||
["Noodl Editor"] = ":noodl:",
|
||||
["NordVPN"] = ":nord_vpn:",
|
||||
["Notability"] = ":notability:",
|
||||
["Notes"] = ":notes:",
|
||||
["备忘录"] = ":notes:",
|
||||
["Notion"] = ":notion:",
|
||||
["Nova"] = ":nova:",
|
||||
["Numbers"] = ":numbers:",
|
||||
["Numbers 表格"] = ":numbers:",
|
||||
["Obsidian"] = ":obsidian:",
|
||||
["OBS"] = ":obsstudio:",
|
||||
["OmniFocus"] = ":omni_focus:",
|
||||
["1Password"] = ":one_password:",
|
||||
["Open Video Downloader"] = ":open_video_downloader:",
|
||||
["ChatGPT"] = ":openai:",
|
||||
["OpenVPN Connect"] = ":openvpn_connect:",
|
||||
["Opera"] = ":opera:",
|
||||
["OrbStack"] = ":orbstack:",
|
||||
["OrcaSlicer"] = ":orcaslicer:",
|
||||
["Orion"] = ":orion:",
|
||||
["Orion RC"] = ":orion:",
|
||||
["Pages"] = ":pages:",
|
||||
["Pages 文稿"] = ":pages:",
|
||||
["Parallels Desktop"] = ":parallels:",
|
||||
["Parsec"] = ":parsec:",
|
||||
["Preview"] = ":pdf:",
|
||||
["预览"] = ":pdf:",
|
||||
["Skim"] = ":pdf:",
|
||||
["zathura"] = ":pdf:",
|
||||
["Aperçu"] = ":pdf:",
|
||||
["PDF Expert"] = ":pdf_expert:",
|
||||
["Pearcleaner"] = ":pearcleaner:",
|
||||
["Phoenix Slides"] = ":phoenix_slides:",
|
||||
["Adobe Photoshop"] = ":photoshop:",
|
||||
["PhpStorm"] = ":php_storm:",
|
||||
["Pi-hole Remote"] = ":pihole:",
|
||||
["Pine"] = ":pine:",
|
||||
["Plex"] = ":plex:",
|
||||
["Plexamp"] = ":plexamp:",
|
||||
["Podcasts"] = ":podcasts:",
|
||||
["播客"] = ":podcasts:",
|
||||
["PomoDone App"] = ":pomodone:",
|
||||
["Postman"] = ":postman:",
|
||||
["Proton Mail"] = ":proton_mail:",
|
||||
["Proton Mail Bridge"] = ":proton_mail:",
|
||||
["PrusaSlicer"] = ":prusaslicer:",
|
||||
["SuperSlicer"] = ":prusaslicer:",
|
||||
["PyCharm"] = ":pycharm:",
|
||||
["QQ"] = ":qq:",
|
||||
["QQ音乐"] = ":qqmusic:",
|
||||
["QQMusic"] = ":qqmusic:",
|
||||
["Quantumult X"] = ":quantumult_x:",
|
||||
["qutebrowser"] = ":qute_browser:",
|
||||
["Raindrop.io"] = ":raindrop_io:",
|
||||
["Reeder"] = ":reeder5:",
|
||||
["Reminders"] = ":reminders:",
|
||||
["提醒事项"] = ":reminders:",
|
||||
["Rappels"] = ":reminders:",
|
||||
["Replit"] = ":replit:",
|
||||
["Rider"] = ":rider:",
|
||||
["JetBrains Rider"] = ":rider:",
|
||||
["Rio"] = ":rio:",
|
||||
["Royal TSX"] = ":royaltsx:",
|
||||
["Safari"] = ":safari:",
|
||||
["Safari浏览器"] = ":safari:",
|
||||
["Safari Technology Preview"] = ":safari:",
|
||||
["Sequel Ace"] = ":sequel_ace:",
|
||||
["Sequel Pro"] = ":sequel_pro:",
|
||||
["Setapp"] = ":setapp:",
|
||||
["SF Symbols"] = ":sf_symbols:",
|
||||
["Signal"] = ":signal:",
|
||||
["sioyek"] = ":sioyek:",
|
||||
["Sketch"] = ":sketch:",
|
||||
["Skype"] = ":skype:",
|
||||
["Slack"] = ":slack:",
|
||||
["Spark Desktop"] = ":spark:",
|
||||
["Spotify"] = ":spotify:",
|
||||
["Spotlight"] = ":spotlight:",
|
||||
["Sublime Text"] = ":sublime_text:",
|
||||
["Strongbox"] = ":one_password:",
|
||||
["superProductivity"] = ":superproductivity:",
|
||||
["Tana"] = ":tana:",
|
||||
["TeamSpeak 3"] = ":team_speak:",
|
||||
["Telegram"] = ":telegram:",
|
||||
["Terminal"] = ":terminal:",
|
||||
["终端"] = ":terminal:",
|
||||
["Typora"] = ":text:",
|
||||
["Microsoft To Do"] = ":things:",
|
||||
["Things"] = ":things:",
|
||||
["Thunderbird"] = ":thunderbird:",
|
||||
["TickTick"] = ":tick_tick:",
|
||||
["TIDAL"] = ":tidal:",
|
||||
["Tiny RDM"] = ":tinyrdm:",
|
||||
["Todoist"] = ":todoist:",
|
||||
["Toggl Track"] = ":toggl_track:",
|
||||
["Tor Browser"] = ":tor_browser:",
|
||||
["Tower"] = ":tower:",
|
||||
["Transmit"] = ":transmit:",
|
||||
["Trello"] = ":trello:",
|
||||
["Tweetbot"] = ":twitter:",
|
||||
["Twitter"] = ":twitter:",
|
||||
["UTM"] = ":utm:",
|
||||
["MacVim"] = ":vim:",
|
||||
["Vim"] = ":vim:",
|
||||
["VimR"] = ":vim:",
|
||||
["Vivaldi"] = ":vivaldi:",
|
||||
["VLC"] = ":vlc:",
|
||||
["VMware Fusion"] = ":vmware_fusion:",
|
||||
["VSCodium"] = ":vscodium:",
|
||||
["Warp"] = ":warp:",
|
||||
["WebStorm"] = ":web_storm:",
|
||||
["微信"] = ":wechat:",
|
||||
["WeChat"] = ":wechat:",
|
||||
["企业微信"] = ":wecom:",
|
||||
["WeCom"] = ":wecom:",
|
||||
["WezTerm"] = ":wezterm:",
|
||||
["WhatsApp"] = ":whats_app:",
|
||||
["WhatsApp"] = ":whats_app:",
|
||||
["Xcode"] = ":xcode:",
|
||||
["Yandex Music"] = ":yandex_music:",
|
||||
["Yuque"] = ":yuque:",
|
||||
["语雀"] = ":yuque:",
|
||||
["Zed"] = ":zed:",
|
||||
["Zen Browser"] = ":zen_browser:",
|
||||
["Zeplin"] = ":zeplin:",
|
||||
["zoom.us"] = ":zoom:",
|
||||
["Zotero"] = ":zotero:",
|
||||
["Zulip"] = ":zulip:",
|
||||
["Zen"] = ":zen_browser:",
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require("colors")
|
||||
|
||||
local bar_height = 35
|
||||
|
||||
sbar.bar({
|
||||
blur_radius = 20,
|
||||
border_color = colors.bar.border,
|
||||
border_width = 2,
|
||||
color = colors.bar.bg,
|
||||
corner_radius = 5,
|
||||
height = bar_height,
|
||||
margin = 10,
|
||||
notch_width = 0,
|
||||
padding_left = 10,
|
||||
padding_right = 10,
|
||||
position = "top",
|
||||
shadow = true,
|
||||
sticky = true,
|
||||
topmost = false,
|
||||
y_offset = 2,
|
||||
})
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
local function with_alpha(color, alpha)
|
||||
if alpha > 1.0 or alpha < 0.0 then
|
||||
return color
|
||||
end
|
||||
return (color & 0x00ffffff) | (math.floor(alpha * 255.0) << 24)
|
||||
end
|
||||
|
||||
return {
|
||||
fg = 0xffd3b58d,
|
||||
black = 0xff181819,
|
||||
white = 0xffd3b58d,
|
||||
red = 0xffF92672,
|
||||
blue = 0xff66D9EF,
|
||||
grey = 0xff7f8490,
|
||||
transparent = 0x00000000,
|
||||
|
||||
bar = {
|
||||
bg = 0xff072626,
|
||||
border = 0xffFD971F,
|
||||
},
|
||||
popup = {
|
||||
bg = with_alpha(0xff072626, 0.6),
|
||||
border = 0xffFD971F,
|
||||
},
|
||||
|
||||
with_alpha = with_alpha,
|
||||
}
|
||||
|
||||
-- return {
|
||||
-- fg = 0xff181819,
|
||||
-- black = 0xff181819,
|
||||
-- white = 0xffffffff,
|
||||
-- red = 0xffff0000,
|
||||
-- blue = 0xff0000ff,
|
||||
-- grey = 0xff7f8490,
|
||||
-- transparent = 0x00000000,
|
||||
--
|
||||
-- bar = {
|
||||
-- bg = 0xffffffff,
|
||||
-- border = 0xff000000,
|
||||
-- },
|
||||
-- popup = {
|
||||
-- bg = with_alpha(0xffffffff, 0.6),
|
||||
-- border = 0xff000000,
|
||||
-- },
|
||||
--
|
||||
-- with_alpha = with_alpha,
|
||||
-- }
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
local settings = require("settings")
|
||||
|
||||
local icons = {
|
||||
sf_symbols = {
|
||||
plus = "",
|
||||
loading = "",
|
||||
apple = "",
|
||||
gear = "",
|
||||
cpu = "",
|
||||
clipboard = "",
|
||||
|
||||
switch = {
|
||||
on = "",
|
||||
off = "",
|
||||
},
|
||||
volume = {
|
||||
_100 = "",
|
||||
_66 = "",
|
||||
_33 = "",
|
||||
_10 = "",
|
||||
_0 = "",
|
||||
},
|
||||
battery = {
|
||||
_100 = "",
|
||||
_75 = "",
|
||||
_50 = "",
|
||||
_25 = "",
|
||||
_0 = "",
|
||||
charging = "",
|
||||
},
|
||||
wifi = {
|
||||
upload = "",
|
||||
download = "",
|
||||
connected = "",
|
||||
disconnected = "",
|
||||
router = "",
|
||||
},
|
||||
media = {
|
||||
back = "",
|
||||
forward = "",
|
||||
play_pause = "",
|
||||
},
|
||||
},
|
||||
|
||||
-- Alternative NerdFont icons
|
||||
nerdfont = {
|
||||
plus = "",
|
||||
loading = "",
|
||||
apple = "",
|
||||
gear = "",
|
||||
cpu = "",
|
||||
clipboard = "Missing Icon",
|
||||
|
||||
switch = {
|
||||
on = "",
|
||||
off = "",
|
||||
},
|
||||
volume = {
|
||||
_100 = "",
|
||||
_66 = "",
|
||||
_33 = "",
|
||||
_10 = "",
|
||||
_0 = "",
|
||||
},
|
||||
battery = {
|
||||
_100 = "",
|
||||
_75 = "",
|
||||
_50 = "",
|
||||
_25 = "",
|
||||
_0 = "",
|
||||
charging = "",
|
||||
},
|
||||
wifi = {
|
||||
upload = "",
|
||||
download = "",
|
||||
connected = "",
|
||||
disconnected = "",
|
||||
router = "Missing Icon",
|
||||
},
|
||||
media = {
|
||||
back = "",
|
||||
forward = "",
|
||||
play_pause = "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if not (settings.icons == "NerdFont") then
|
||||
return icons.sf_symbols
|
||||
else
|
||||
return icons.nerdfont
|
||||
end
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
local colors = require("colors")
|
||||
local settings = require("settings")
|
||||
|
||||
sbar.default({
|
||||
updates = "when_shown",
|
||||
icon = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = "Bold",
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
background = { image = { corner_radius = 9 } },
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.text,
|
||||
style = "Semibold",
|
||||
size = 13.0,
|
||||
},
|
||||
color = colors.fg,
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
},
|
||||
background = {
|
||||
height = 30,
|
||||
corner_radius = 12,
|
||||
border_width = 1,
|
||||
-- border_color = colors.bar.border,
|
||||
image = {
|
||||
corner_radius = 8,
|
||||
-- border_color = colors.grey,
|
||||
border_width = 1,
|
||||
},
|
||||
},
|
||||
popup = {
|
||||
background = {
|
||||
border_width = 1,
|
||||
corner_radius = 8,
|
||||
border_color = colors.popup.border,
|
||||
color = colors.popup.bg,
|
||||
shadow = { drawing = true },
|
||||
},
|
||||
blur_radius = 20,
|
||||
},
|
||||
padding_left = 5,
|
||||
padding_right = 5,
|
||||
scroll_texts = true,
|
||||
})
|
||||
|
||||
require("bar")
|
||||
require("items")
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
-- https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/sbar-config-libs/items/aerospaces.lua
|
||||
|
||||
local Promise = require("promise")
|
||||
local colors = require("colors")
|
||||
local utils = require("utils")
|
||||
local settings = require("settings")
|
||||
local app_icons = require("app_icons")
|
||||
|
||||
local function getAllWorkspaces()
|
||||
return utils.sbarExecP(
|
||||
"aerospace list-workspaces --all --format '%{workspace}%{monitor-appkit-nsscreen-screens-id}%{monitor-id}%{monitor-name}' --json"
|
||||
)
|
||||
end
|
||||
|
||||
local function getVisibleWorkspaces()
|
||||
return utils.sbarExecP(
|
||||
"aerospace list-workspaces --visible --monitor all --format '%{workspace}%{monitor-appkit-nsscreen-screens-id}%{monitor-id}%{monitor-name}' --json"
|
||||
)
|
||||
end
|
||||
|
||||
local function getAllWindows()
|
||||
return utils.sbarExecP(
|
||||
"aerospace list-windows --all --format '%{app-name}%{window-title}%{workspace}%{monitor-id}%{monitor-appkit-nsscreen-screens-id}%{monitor-name}' --json"
|
||||
)
|
||||
end
|
||||
|
||||
local function getMonitorId(obj)
|
||||
if obj["monitor-name"] then
|
||||
if obj["monitor-name"] == "ZOWIE XL LCD" then
|
||||
return "2"
|
||||
elseif obj["monitor-name"] == "LG ULTRAWIDE" then
|
||||
return "1"
|
||||
end
|
||||
end
|
||||
if obj["monitor-appkit-nsscreen-screens-id"] then
|
||||
return obj["monitor-appkit-nsscreen-screens-id"]
|
||||
end
|
||||
return obj["monitor-id"]
|
||||
end
|
||||
|
||||
local spaces = {}
|
||||
local space_paddings = {}
|
||||
local brackets = {}
|
||||
local state = {
|
||||
workspaces = {},
|
||||
updating = false,
|
||||
}
|
||||
|
||||
function getState()
|
||||
local newstate = {
|
||||
workspaces = {},
|
||||
}
|
||||
|
||||
for workspaceid, space in pairs(spaces) do
|
||||
newstate.workspaces[workspaceid] = {
|
||||
monitor = 0,
|
||||
active = false,
|
||||
empty = true,
|
||||
apps = {},
|
||||
appicons = "",
|
||||
}
|
||||
end
|
||||
|
||||
return Promise.all({ getAllWorkspaces(), getVisibleWorkspaces(), getAllWindows() }):thenCall(function(values)
|
||||
local all, visible, apps = values[1], values[2], values[3]
|
||||
for _, workspace in ipairs(all) do
|
||||
local workspaceid = workspace["workspace"]
|
||||
newstate.workspaces[workspaceid]["id"] = workspaceid
|
||||
newstate.workspaces[workspaceid]["monitor"] = getMonitorId(workspace)
|
||||
end
|
||||
|
||||
for _, workspace in ipairs(visible) do
|
||||
local workspaceid = workspace["workspace"]
|
||||
newstate.workspaces[workspaceid]["active"] = true
|
||||
end
|
||||
|
||||
for _, window in ipairs(apps) do
|
||||
local workspaceid = window["workspace"]
|
||||
local appname = window["app-name"]
|
||||
newstate.workspaces[workspaceid]["apps"][appname] = true
|
||||
newstate.workspaces[workspaceid]["empty"] = false
|
||||
end
|
||||
|
||||
for workspaceid, workspacestate in pairs(newstate.workspaces) do
|
||||
local appkeys = {}
|
||||
for app in pairs(workspacestate["apps"]) do
|
||||
table.insert(appkeys, app)
|
||||
end
|
||||
table.sort(appkeys)
|
||||
if #appkeys > 0 then
|
||||
for _, app in ipairs(appkeys) do
|
||||
local lookup = app_icons[app]
|
||||
local icon = ((lookup == nil) and app_icons["Default"] or lookup)
|
||||
workspacestate["appicons"] = workspacestate["appicons"] .. " " .. icon
|
||||
end
|
||||
else
|
||||
workspacestate["appicons"] = ""
|
||||
end
|
||||
-- print(utils.dump(workspacestate))
|
||||
end
|
||||
|
||||
return newstate
|
||||
end)
|
||||
end
|
||||
|
||||
local function updateState()
|
||||
if not state.updating then
|
||||
state.updating = true
|
||||
return getState():thenCall(function(newstate)
|
||||
state.workspaces = newstate.workspaces
|
||||
state.updating = false
|
||||
end)
|
||||
end
|
||||
return Promise.reject("State is already updating")
|
||||
end
|
||||
|
||||
local function highlightSpace(space, space_padding, space_bracket, selected)
|
||||
space:set({
|
||||
drawing = true,
|
||||
icon = { highlight = selected },
|
||||
label = { highlight = selected },
|
||||
-- background = { border_color = selected and colors.white or colors.bg2 }
|
||||
})
|
||||
space_padding:set({
|
||||
drawing = true,
|
||||
})
|
||||
if space_bracket then
|
||||
space_bracket:set({
|
||||
-- background = { border_color = selected and colors.grey or colors.bg2 },
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function onActiveSpaceChange(env)
|
||||
local focused_workspace = env.FOCUSED_WORKSPACE
|
||||
local last_workspace = env.PREV_WORKSPACE
|
||||
-- print("aerospace_workspace_change from " .. last_workspace .. " to " .. focused_workspace)
|
||||
|
||||
local space = spaces[focused_workspace]
|
||||
local space_padding = space_paddings[focused_workspace]
|
||||
|
||||
local prev_space = spaces[last_workspace]
|
||||
local prev_space_padding = space_paddings[last_workspace]
|
||||
|
||||
sbar.animate("tanh", 10, function()
|
||||
highlightSpace(space, space_padding, nil, true)
|
||||
if state.workspaces[last_workspace]["monitor"] == state.workspaces[focused_workspace]["monitor"] then
|
||||
highlightSpace(prev_space, prev_space_padding, nil, false)
|
||||
end
|
||||
end)
|
||||
|
||||
updateState()
|
||||
end
|
||||
|
||||
local function syncState()
|
||||
sbar.animate("tanh", 10, function()
|
||||
for workspaceid, workspacestate in pairs(state.workspaces) do
|
||||
if not workspacestate["empty"] then
|
||||
spaces[workspaceid]:set({
|
||||
drawing = true,
|
||||
display = workspacestate["monitor"],
|
||||
-- label = {
|
||||
-- string = workspaceid,
|
||||
-- highlight = workspacestate["active"],
|
||||
-- },
|
||||
-- icon = {
|
||||
-- string = workspaceid,
|
||||
-- color = colors.white,
|
||||
-- highlight = workspacestate["active"],
|
||||
-- },
|
||||
label = {
|
||||
string = workspacestate["appicons"],
|
||||
highlight = workspacestate["active"],
|
||||
},
|
||||
icon = {
|
||||
highlight = workspacestate["active"],
|
||||
},
|
||||
})
|
||||
space_paddings[workspaceid]:set({ drawing = true })
|
||||
else
|
||||
-- These should be hidden
|
||||
spaces[workspaceid]:set({
|
||||
drawing = false,
|
||||
display = workspacestate["monitor"],
|
||||
label = workspacestate["appicons"],
|
||||
})
|
||||
space_paddings[workspaceid]:set({ drawing = false })
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function updateStateAndSync()
|
||||
return updateState():thenCall(syncState)
|
||||
end
|
||||
|
||||
function setup()
|
||||
getAllWorkspaces()
|
||||
:thenCall(function(workspaces)
|
||||
for _, workspace in ipairs(workspaces) do
|
||||
local workspaceid = workspace["workspace"]
|
||||
local display = getMonitorId(workspace)
|
||||
|
||||
local space = sbar.add("item", "space." .. workspaceid, {
|
||||
drawing = false, -- default to not showing the space -- we'll show if it has windows or is activated
|
||||
updates = "when_shown",
|
||||
display = display,
|
||||
icon = {
|
||||
string = workspaceid,
|
||||
color = colors.fg,
|
||||
highlight_color = colors.red,
|
||||
},
|
||||
label = {
|
||||
padding_right = 12,
|
||||
color = colors.fg,
|
||||
highlight_color = colors.blue,
|
||||
font = "sketchybar-app-font:Regular:14.0",
|
||||
y_offset = -1,
|
||||
-- drawing = false
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = "aerospace workspace " .. workspaceid,
|
||||
})
|
||||
|
||||
spaces[workspaceid] = space
|
||||
|
||||
local padding = sbar.add("space", "space.padding." .. space.name, {
|
||||
drawing = false,
|
||||
updates = "when_shown",
|
||||
display = display,
|
||||
script = "",
|
||||
width = settings.space_paddings,
|
||||
})
|
||||
space_paddings[workspaceid] = padding
|
||||
end
|
||||
end)
|
||||
:thenCall(function()
|
||||
local space_window_observer = sbar.add("item", {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
|
||||
space_window_observer:subscribe("aerospace_workspace_change", onActiveSpaceChange)
|
||||
space_window_observer:subscribe("space_windows_change", updateStateAndSync)
|
||||
space_window_observer:subscribe("system_woke", updateStateAndSync)
|
||||
space_window_observer:subscribe("front_app_switched", updateStateAndSync)
|
||||
end)
|
||||
:thenCall(updateStateAndSync)
|
||||
end
|
||||
|
||||
setup()
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
local colors = require("colors")
|
||||
local icons = require("icons")
|
||||
local settings = require("settings")
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add("item", { width = 5 })
|
||||
|
||||
local apple = sbar.add("item", {
|
||||
icon = {
|
||||
font = { size = 16.0 },
|
||||
string = icons.apple,
|
||||
padding_right = settings.paddings,
|
||||
padding_left = 0,
|
||||
color = colors.fg,
|
||||
},
|
||||
label = { drawing = false },
|
||||
background = {
|
||||
color = colors.bar.bg,
|
||||
-- border_color = colors.black,
|
||||
-- border_width = 1
|
||||
},
|
||||
padding_left = 1,
|
||||
padding_right = 1,
|
||||
click_script = "sk-menus -s 0",
|
||||
})
|
||||
|
||||
-- Double border for apple using a single item bracket
|
||||
-- sbar.add("bracket", { apple.name }, {
|
||||
-- background = {
|
||||
-- color = colors.transparent,
|
||||
-- height = 30,
|
||||
-- -- border_color = colors.grey,
|
||||
-- }
|
||||
-- })
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add("item", { width = 7 })
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
local icons = require("icons")
|
||||
|
||||
local battery = sbar.add("item", {
|
||||
position = "right",
|
||||
icon = {
|
||||
font = {
|
||||
style = "Regular",
|
||||
size = 19.0,
|
||||
},
|
||||
},
|
||||
label = { drawing = false },
|
||||
update_freq = 120,
|
||||
})
|
||||
|
||||
local function battery_update()
|
||||
sbar.exec("pmset -g batt", function(batt_info)
|
||||
local icon = "!"
|
||||
|
||||
if string.find(batt_info, "AC Power") then
|
||||
icon = icons.battery.charging
|
||||
else
|
||||
local found, _, charge = batt_info:find("(%d+)%%")
|
||||
if found then
|
||||
charge = tonumber(charge)
|
||||
end
|
||||
|
||||
if found and charge > 80 then
|
||||
icon = icons.battery._100
|
||||
elseif found and charge > 60 then
|
||||
icon = icons.battery._75
|
||||
elseif found and charge > 40 then
|
||||
icon = icons.battery._50
|
||||
elseif found and charge > 20 then
|
||||
icon = icons.battery._25
|
||||
else
|
||||
icon = icons.battery._0
|
||||
end
|
||||
end
|
||||
|
||||
battery:set({ icon = icon })
|
||||
end)
|
||||
end
|
||||
|
||||
battery:subscribe({ "routine", "power_source_change", "system_woke" }, battery_update)
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
local colors = require("colors")
|
||||
local settings = require("settings")
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add("item", { position = "right", width = settings.group_paddings })
|
||||
|
||||
local cal = sbar.add("item", {
|
||||
icon = {
|
||||
color = colors.fg,
|
||||
padding_left = 0,
|
||||
font = { size = 13 },
|
||||
},
|
||||
label = {
|
||||
color = colors.fg,
|
||||
padding_right = 0,
|
||||
align = "right",
|
||||
},
|
||||
position = "right",
|
||||
update_freq = 30,
|
||||
padding_left = 0,
|
||||
padding_right = 0,
|
||||
click_script = "open -n -a Calendar",
|
||||
-- background = {
|
||||
-- color = colors.bg1,
|
||||
-- border_color = colors.bar.border,
|
||||
-- border_width = 1,
|
||||
-- },
|
||||
})
|
||||
|
||||
-- Double border for calendar using a single item bracket
|
||||
-- sbar.add("bracket", { cal.name }, {
|
||||
-- background = {
|
||||
-- color = colors.transparent,
|
||||
-- height = 30,
|
||||
-- border_color = colors.bar.bg,
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- Padding item required because of bracket
|
||||
sbar.add("item", { position = "right", width = settings.group_paddings })
|
||||
|
||||
-- cal:subscribe({ "forced", "routine", "system_woke" }, function(env)
|
||||
-- cal:set({ icon = os.date(" %B %d %a"), label = os.date(" %H:%M") })
|
||||
-- end)
|
||||
cal:subscribe({ "forced", "routine", "system_woke" }, function(env)
|
||||
cal:set({
|
||||
icon = os.date(" %B %d %a"),
|
||||
label = os.date(" %I:%M %p"), -- 12-hour format with AM/PM
|
||||
})
|
||||
end)
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
local icons = require("icons")
|
||||
local colors = require("colors")
|
||||
local settings = require("settings")
|
||||
|
||||
-- Execute the event provider binary which provides the event "cpu_update" for
|
||||
-- the cpu load data, which is fired every 2.0 seconds.
|
||||
sbar.exec("killall sk-cpu-load >/dev/null; sk-cpu-load cpu_update 2.0")
|
||||
|
||||
local cpu = sbar.add("graph", "widgets.cpu", 42, {
|
||||
position = "right",
|
||||
graph = { color = colors.blue },
|
||||
background = {
|
||||
height = 22,
|
||||
color = { alpha = 0 },
|
||||
border_color = { alpha = 0 },
|
||||
drawing = true,
|
||||
},
|
||||
icon = { string = icons.cpu },
|
||||
label = {
|
||||
string = "cpu ??%",
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 9.0,
|
||||
},
|
||||
align = "right",
|
||||
padding_right = 0,
|
||||
width = 0,
|
||||
y_offset = 4,
|
||||
},
|
||||
padding_right = settings.paddings + 6,
|
||||
})
|
||||
|
||||
cpu:subscribe("cpu_update", function(env)
|
||||
-- Also available: env.user_load, env.sys_load
|
||||
local load = tonumber(env.total_load)
|
||||
cpu:push({ load / 100. })
|
||||
|
||||
local color = colors.blue
|
||||
if load > 30 then
|
||||
if load < 60 then
|
||||
color = colors.yellow
|
||||
elseif load < 80 then
|
||||
color = colors.orange
|
||||
else
|
||||
color = colors.red
|
||||
end
|
||||
end
|
||||
|
||||
cpu:set({
|
||||
graph = { color = color },
|
||||
label = "cpu " .. env.total_load .. "%",
|
||||
})
|
||||
end)
|
||||
|
||||
cpu:subscribe("mouse.clicked", function(env)
|
||||
sbar.exec("open -a 'Activity Monitor'")
|
||||
end)
|
||||
|
||||
-- Background around the cpu item
|
||||
sbar.add("bracket", "widgets.cpu.bracket", { cpu.name }, {
|
||||
background = { color = colors.bg1 },
|
||||
})
|
||||
|
||||
-- Background around the cpu item
|
||||
sbar.add("item", "widgets.cpu.padding", {
|
||||
position = "right",
|
||||
width = settings.group_paddings,
|
||||
})
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
local settings = require("settings")
|
||||
|
||||
local front_app = sbar.add("item", {
|
||||
icon = {
|
||||
drawing = false,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 12.0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
front_app:subscribe("front_app_switched", function(env)
|
||||
front_app:set({
|
||||
label = {
|
||||
string = env.INFO:upper(),
|
||||
},
|
||||
})
|
||||
|
||||
-- Or equivalently:
|
||||
-- sbar.set(env.NAME, {
|
||||
-- label = {
|
||||
-- string = env.INFO
|
||||
-- }
|
||||
-- })
|
||||
end)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
require("items.aerospace")
|
||||
require("items.apple")
|
||||
require("items.menu")
|
||||
require("items.front_app")
|
||||
require("items.battery")
|
||||
require("items.cal")
|
||||
require("items.volume")
|
||||
require("items.cpu")
|
||||
require("items.wifi")
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
local colors = require("colors")
|
||||
local icons = require("icons")
|
||||
local settings = require("settings")
|
||||
|
||||
local menu_watcher = sbar.add("item", {
|
||||
drawing = false,
|
||||
updates = false,
|
||||
})
|
||||
local space_menu_swap = sbar.add("item", {
|
||||
drawing = false,
|
||||
updates = true,
|
||||
})
|
||||
sbar.add("event", "swap_menus_and_spaces")
|
||||
|
||||
local max_items = 15
|
||||
local menu_items = {}
|
||||
for i = 1, max_items, 1 do
|
||||
local menu = sbar.add("item", "menu." .. i, {
|
||||
padding_left = settings.paddings,
|
||||
padding_right = settings.paddings,
|
||||
drawing = false,
|
||||
icon = { drawing = false },
|
||||
label = {
|
||||
font = {
|
||||
style = settings.font.style_map[i == 1 and "Heavy" or "Semibold"],
|
||||
},
|
||||
padding_left = 6,
|
||||
padding_right = 6,
|
||||
},
|
||||
click_script = "sk-menus -s " .. i,
|
||||
})
|
||||
|
||||
menu_items[i] = menu
|
||||
end
|
||||
|
||||
sbar.add("bracket", { "/menu\\..*/" }, {
|
||||
background = { color = colors.bg1 },
|
||||
})
|
||||
|
||||
local menu_padding = sbar.add("item", "menu.padding", {
|
||||
drawing = false,
|
||||
width = 5,
|
||||
})
|
||||
|
||||
local function update_menus(env)
|
||||
sbar.exec("sk-menus -l", function(menus)
|
||||
sbar.set("/menu\\..*/", { drawing = false })
|
||||
menu_padding:set({ drawing = true })
|
||||
id = 1
|
||||
for menu in string.gmatch(menus, "[^\r\n]+") do
|
||||
if id < max_items then
|
||||
menu_items[id]:set({ label = menu, drawing = true })
|
||||
else
|
||||
break
|
||||
end
|
||||
id = id + 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
menu_watcher:subscribe("front_app_switched", update_menus)
|
||||
|
||||
space_menu_swap:subscribe("swap_menus_and_spaces", function(env)
|
||||
local drawing = menu_items[1]:query().geometry.drawing == "on"
|
||||
if drawing then
|
||||
menu_watcher:set({ updates = false })
|
||||
sbar.set("/menu\\..*/", { drawing = false })
|
||||
sbar.set("/space\\..*/", { drawing = true })
|
||||
sbar.set("front_app", { drawing = true })
|
||||
else
|
||||
menu_watcher:set({ updates = true })
|
||||
sbar.set("/space\\..*/", { drawing = false })
|
||||
sbar.set("front_app", { drawing = false })
|
||||
update_menus()
|
||||
end
|
||||
end)
|
||||
|
||||
return menu_watcher
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
local colors = require("colors")
|
||||
local icons = require("icons")
|
||||
|
||||
local volume_slider = sbar.add("slider", 100, {
|
||||
position = "right",
|
||||
updates = true,
|
||||
label = { drawing = false },
|
||||
icon = { drawing = false },
|
||||
slider = {
|
||||
highlight_color = colors.blue,
|
||||
width = 0,
|
||||
background = {
|
||||
height = 6,
|
||||
corner_radius = 3,
|
||||
color = colors.bg2,
|
||||
},
|
||||
knob = {
|
||||
string = "",
|
||||
drawing = false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
local volume_icon = sbar.add("item", {
|
||||
position = "right",
|
||||
icon = {
|
||||
string = icons.volume._100,
|
||||
width = 0,
|
||||
align = "left",
|
||||
color = colors.grey,
|
||||
font = {
|
||||
style = "Regular",
|
||||
size = 14.0,
|
||||
},
|
||||
},
|
||||
label = {
|
||||
width = 25,
|
||||
align = "left",
|
||||
font = {
|
||||
style = "Regular",
|
||||
size = 14.0,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
volume_slider:subscribe("mouse.clicked", function(env)
|
||||
sbar.exec("osascript -e 'set volume output volume " .. env["PERCENTAGE"] .. "'")
|
||||
end)
|
||||
|
||||
volume_slider:subscribe("volume_change", function(env)
|
||||
local volume = tonumber(env.INFO)
|
||||
local icon = icons.volume._0
|
||||
if volume > 60 then
|
||||
icon = icons.volume._100
|
||||
elseif volume > 30 then
|
||||
icon = icons.volume._66
|
||||
elseif volume > 10 then
|
||||
icon = icons.volume._33
|
||||
elseif volume > 0 then
|
||||
icon = icons.volume._10
|
||||
end
|
||||
|
||||
volume_icon:set({ label = icon })
|
||||
volume_slider:set({ slider = { percentage = volume } })
|
||||
end)
|
||||
|
||||
local function animate_slider_width(width)
|
||||
sbar.animate("tanh", 30.0, function()
|
||||
volume_slider:set({ slider = { width = width } })
|
||||
end)
|
||||
end
|
||||
|
||||
volume_icon:subscribe("mouse.clicked", function()
|
||||
if tonumber(volume_slider:query().slider.width) > 0 then
|
||||
animate_slider_width(0)
|
||||
else
|
||||
animate_slider_width(100)
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,233 +0,0 @@
|
|||
local icons = require("icons")
|
||||
local colors = require("colors")
|
||||
local settings = require("settings")
|
||||
|
||||
-- Execute the event provider binary which provides the event "network_update"
|
||||
-- for the network interface "en0", which is fired every 2.0 seconds.
|
||||
sbar.exec("killall sk-network-load >/dev/null; sk-network-load en0 network_update 2.0")
|
||||
|
||||
local popup_width = 250
|
||||
|
||||
local wifi_up = sbar.add("item", "widgets.wifi1", {
|
||||
position = "right",
|
||||
padding_left = -5,
|
||||
width = 0,
|
||||
icon = {
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 9.0,
|
||||
},
|
||||
string = icons.wifi.upload,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 9.0,
|
||||
},
|
||||
color = colors.red,
|
||||
string = "??? Bps",
|
||||
},
|
||||
y_offset = 4,
|
||||
})
|
||||
|
||||
local wifi_down = sbar.add("item", "widgets.wifi2", {
|
||||
position = "right",
|
||||
padding_left = -5,
|
||||
icon = {
|
||||
padding_right = 0,
|
||||
font = {
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 9.0,
|
||||
},
|
||||
string = icons.wifi.download,
|
||||
},
|
||||
label = {
|
||||
font = {
|
||||
family = settings.font.numbers,
|
||||
style = settings.font.style_map["Bold"],
|
||||
size = 9.0,
|
||||
},
|
||||
color = colors.blue,
|
||||
string = "??? Bps",
|
||||
},
|
||||
y_offset = -4,
|
||||
})
|
||||
|
||||
local wifi = sbar.add("item", "widgets.wifi.padding", {
|
||||
position = "right",
|
||||
label = { drawing = false },
|
||||
})
|
||||
|
||||
-- Background around the item
|
||||
local wifi_bracket = sbar.add("bracket", "widgets.wifi.bracket", {
|
||||
wifi.name,
|
||||
wifi_up.name,
|
||||
wifi_down.name,
|
||||
}, {
|
||||
-- background = { color = colors.bar.bg },
|
||||
popup = { align = "center", height = 30 },
|
||||
})
|
||||
|
||||
local ssid = sbar.add("item", {
|
||||
position = "popup." .. wifi_bracket.name,
|
||||
icon = {
|
||||
font = {
|
||||
style = settings.font.style_map["Bold"],
|
||||
},
|
||||
string = icons.wifi.router,
|
||||
},
|
||||
width = popup_width,
|
||||
align = "center",
|
||||
label = {
|
||||
font = {
|
||||
size = 15,
|
||||
style = settings.font.style_map["Bold"],
|
||||
},
|
||||
max_chars = 18,
|
||||
string = "????????????",
|
||||
},
|
||||
background = {
|
||||
height = 2,
|
||||
color = colors.fg,
|
||||
y_offset = -15,
|
||||
},
|
||||
})
|
||||
|
||||
local hostname = sbar.add("item", {
|
||||
position = "popup." .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = "left",
|
||||
string = "Hostname:",
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
max_chars = 20,
|
||||
string = "????????????",
|
||||
width = popup_width / 2,
|
||||
align = "right",
|
||||
},
|
||||
})
|
||||
local ip = sbar.add("item", {
|
||||
position = "popup." .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = "left",
|
||||
string = "IP:",
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = "???.???.???.???",
|
||||
width = popup_width / 2,
|
||||
align = "right",
|
||||
},
|
||||
})
|
||||
|
||||
local mask = sbar.add("item", {
|
||||
position = "popup." .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = "left",
|
||||
string = "Subnet mask:",
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = "???.???.???.???",
|
||||
width = popup_width / 2,
|
||||
align = "right",
|
||||
},
|
||||
})
|
||||
|
||||
local router = sbar.add("item", {
|
||||
position = "popup." .. wifi_bracket.name,
|
||||
icon = {
|
||||
align = "left",
|
||||
string = "Router:",
|
||||
width = popup_width / 2,
|
||||
},
|
||||
label = {
|
||||
string = "???.???.???.???",
|
||||
width = popup_width / 2,
|
||||
align = "right",
|
||||
},
|
||||
})
|
||||
|
||||
sbar.add("item", { position = "right", width = settings.group_paddings })
|
||||
|
||||
wifi_up:subscribe("network_update", function(env)
|
||||
local up_color = (env.upload == "000 Bps") and colors.fg or colors.red
|
||||
local down_color = (env.download == "000 Bps") and colors.fg or colors.blue
|
||||
wifi_up:set({
|
||||
icon = { color = up_color },
|
||||
label = {
|
||||
string = env.upload,
|
||||
color = up_color,
|
||||
},
|
||||
})
|
||||
wifi_down:set({
|
||||
icon = { color = down_color },
|
||||
label = {
|
||||
string = env.download,
|
||||
color = down_color,
|
||||
},
|
||||
})
|
||||
end)
|
||||
|
||||
wifi:subscribe({ "wifi_change", "system_woke" }, function(env)
|
||||
sbar.exec("ipconfig getifaddr en0", function(ip)
|
||||
local connected = not (ip == "")
|
||||
wifi:set({
|
||||
icon = {
|
||||
string = connected and icons.wifi.connected or icons.wifi.disconnected,
|
||||
color = connected and colors.fg or colors.red,
|
||||
},
|
||||
})
|
||||
end)
|
||||
end)
|
||||
|
||||
local function hide_details()
|
||||
wifi_bracket:set({ popup = { drawing = false } })
|
||||
end
|
||||
|
||||
local function toggle_details()
|
||||
local should_draw = wifi_bracket:query().popup.drawing == "off"
|
||||
if should_draw then
|
||||
wifi_bracket:set({ popup = { drawing = true } })
|
||||
sbar.exec("networksetup -getcomputername", function(result)
|
||||
hostname:set({ label = result })
|
||||
end)
|
||||
sbar.exec("ipconfig getifaddr en0", function(result)
|
||||
ip:set({ label = result })
|
||||
end)
|
||||
sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(result)
|
||||
ssid:set({ label = result })
|
||||
end)
|
||||
sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Subnet mask: ' '/^Subnet mask: / {print $2}'", function(result)
|
||||
mask:set({ label = result })
|
||||
end)
|
||||
sbar.exec("networksetup -getinfo Wi-Fi | awk -F 'Router: ' '/^Router: / {print $2}'", function(result)
|
||||
router:set({ label = result })
|
||||
end)
|
||||
else
|
||||
hide_details()
|
||||
end
|
||||
end
|
||||
|
||||
wifi_up:subscribe("mouse.clicked", toggle_details)
|
||||
wifi_down:subscribe("mouse.clicked", toggle_details)
|
||||
wifi:subscribe("mouse.clicked", toggle_details)
|
||||
wifi:subscribe("mouse.exited.global", hide_details)
|
||||
|
||||
local function copy_label_to_clipboard(env)
|
||||
local label = sbar.query(env.NAME).label.value
|
||||
sbar.exec('echo "' .. label .. '" | pbcopy')
|
||||
sbar.set(env.NAME, { label = { string = icons.clipboard, align = "center" } })
|
||||
sbar.delay(1, function()
|
||||
sbar.set(env.NAME, { label = { string = label, align = "right" } })
|
||||
end)
|
||||
end
|
||||
|
||||
ssid:subscribe("mouse.clicked", copy_label_to_clipboard)
|
||||
hostname:subscribe("mouse.clicked", copy_label_to_clipboard)
|
||||
ip:subscribe("mouse.clicked", copy_label_to_clipboard)
|
||||
mask:subscribe("mouse.clicked", copy_label_to_clipboard)
|
||||
router:subscribe("mouse.clicked", copy_label_to_clipboard)
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
return {
|
||||
icons = "sf-symbols",
|
||||
font = {
|
||||
text = "SF Pro",
|
||||
numbers = "SF Pro",
|
||||
style_map = {
|
||||
["Regular"] = "Regular",
|
||||
["Semibold"] = "Semibold",
|
||||
["Bold"] = "Bold",
|
||||
["Heavy"] = "Heavy",
|
||||
["Black"] = "Black",
|
||||
},
|
||||
},
|
||||
paddings = 3,
|
||||
group_paddings = 0,
|
||||
space_paddings = 5,
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
local Promise = require("promise")
|
||||
|
||||
local M = {}
|
||||
|
||||
function M.dump(o)
|
||||
if type(o) == "table" then
|
||||
local s = "{"
|
||||
for k, v in pairs(o) do
|
||||
if type(k) ~= "number" then
|
||||
k = '"' .. k .. '"'
|
||||
end
|
||||
s = s .. " [" .. k .. "] = " .. M.dump(v) .. ","
|
||||
end
|
||||
return s .. "} "
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
local function onErrorP(reason)
|
||||
print("Error found: " .. (reason and M.dump(reason) or "unknown"))
|
||||
end
|
||||
|
||||
-- https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/sbar-config-libs/items/aerospaces.lua
|
||||
function M.sbarExecP(cmd)
|
||||
return Promise.new(function(resolve, failfunc)
|
||||
sbar.exec(cmd, function(result, exit_code)
|
||||
if exit_code ~= 0 then
|
||||
if failfunc ~= nil then
|
||||
failfunc(string.format("Exit Code: %s Message: %s", tostring(exit_code), M.dump(result)))
|
||||
end
|
||||
else
|
||||
if resolve ~= nil then
|
||||
resolve(result)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end):catch(onErrorP)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
}:
|
||||
|
||||
let
|
||||
cfg = config.custom.sketchybar;
|
||||
cfg = config.custom.gui.sketchybar;
|
||||
sketchybar = lib.getExe pkgs.sketchybar;
|
||||
lua = pkgs.lua5_4.withPackages (
|
||||
ps: with ps; [
|
||||
|
|
@ -19,7 +19,7 @@ let
|
|||
);
|
||||
in
|
||||
{
|
||||
options.custom = with lib; {
|
||||
options.custom.gui = with lib; {
|
||||
sketchybar = {
|
||||
enable = mkEnableOption "Enable sketchybar";
|
||||
logFile = mkOption {
|
||||
|
|
@ -56,7 +56,7 @@ in
|
|||
|
||||
-- Add the sketchybar module to the package cpath (the module could be
|
||||
-- installed into the default search path then this would not be needed)
|
||||
package.path = "${dots}/darwin/sketchybar/config/?.lua;${dots}/darwin/sketchybar/config/?/?.lua;${dots}/darwin/sketchybar/config/?/init.lua;" .. package.path
|
||||
package.path = "${dots}/config/sketchybar/?.lua;${dots}/config/sketchybar/?/?.lua;${dots}/config/sketchybar/?/init.lua;" .. package.path
|
||||
|
||||
sbar = require("sketchybar")
|
||||
sbar.exec("killall sketchyhelper || sketchyhelper git.felix.sketchyhelper >/dev/null 2>&1 &")
|
||||
|
|
|
|||
52
darwin/yabai.nix
Normal file
52
darwin/yabai.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
user,
|
||||
dots,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.custom.gui = with lib; {
|
||||
yabai = {
|
||||
enable = mkEnableOption "Enable yabai";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (config.custom.gui.yabai.enable && pkgs.stdenv.isDarwin) {
|
||||
# csrutil enable --without fs --without debug --without nvram
|
||||
# nvram boot-args=-arm64e_preview_abi
|
||||
|
||||
# Generate sudoers file with SHA256 hash computed at activation time
|
||||
system.activationScripts.yabaiSudoers.text = ''
|
||||
echo "setting up yabai sudoers..." >&2
|
||||
YABAI_BIN="${pkgs.yabai}/bin/yabai"
|
||||
YABAI_HASH=$(shasum -a 256 "$YABAI_BIN" | ${pkgs.gawk}/bin/awk '{print $1}')
|
||||
|
||||
echo "${user} ALL = (root) NOPASSWD: sha256:$YABAI_HASH $YABAI_BIN --load-sa" > /etc/sudoers.d/yabai
|
||||
chmod 0440 /etc/sudoers.d/yabai
|
||||
'';
|
||||
|
||||
system.activationScripts.yabaiScriptingAddition.text = ''
|
||||
echo "loading yabai scripting addition..." >&2
|
||||
sudo ${pkgs.yabai}/bin/yabai --load-sa
|
||||
'';
|
||||
|
||||
hm.home.packages = with pkgs; [
|
||||
yabai
|
||||
];
|
||||
|
||||
hm.xdg.configFile."yabai".source = config.hm.lib.file.mkOutOfStoreSymlink "${dots}/config/yabai";
|
||||
|
||||
hm.home.activation.yabaiService = config.hm.lib.dag.entryAfter [ "writeBoundary" ] ''
|
||||
echo "Restarting yabai service..." >&2
|
||||
$DRY_RUN_CMD ${pkgs.yabai}/bin/yabai --uninstall-service || true
|
||||
$DRY_RUN_CMD ${pkgs.yabai}/bin/yabai --install-service
|
||||
$DRY_RUN_CMD ${pkgs.yabai}/bin/yabai --start-service
|
||||
'';
|
||||
|
||||
hm.home.shellAliases = {
|
||||
restart-yabai = ''${pkgs.yabai}/bin/yabai --uninstall-service || ${pkgs.yabai}/bin/yabai --install-service || ${pkgs.yabai}/bin/yabai --start-service'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
{
|
||||
imports = [
|
||||
./i3
|
||||
./hammerspoon.nix
|
||||
./kitty.nix
|
||||
./ghostty.nix
|
||||
];
|
||||
|
|
|
|||
19
home/hammerspoon.nix
Normal file
19
home/hammerspoon.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
dots,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.custom.gui = with lib; {
|
||||
hammerspoon = {
|
||||
enable = mkEnableOption "Enable hammerspoon";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.custom.gui.hammerspoon.enable {
|
||||
home.file.".hammerspoon".source =
|
||||
config.lib.file.mkOutOfStoreSymlink "${dots}/config/home/.hammerspoon";
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -4,9 +4,12 @@
|
|||
}:
|
||||
{
|
||||
custom = {
|
||||
aerospace.enable = false;
|
||||
sketchybar.enable = false;
|
||||
jankyborders.enable = false;
|
||||
gui = {
|
||||
aerospace.enable = false;
|
||||
sketchybar.enable = true;
|
||||
jankyborders.enable = false;
|
||||
yabai.enable = true;
|
||||
};
|
||||
brew = {
|
||||
zen-browser = false;
|
||||
webex = true;
|
||||
|
|
@ -60,6 +63,7 @@
|
|||
clang-format = true;
|
||||
marta = true;
|
||||
valgrind = true;
|
||||
hammerspoon = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -83,6 +87,7 @@
|
|||
default.enable = true;
|
||||
darwin.enable = true;
|
||||
ghostty.enable = true;
|
||||
hammerspoon.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
# https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/flake.nix
|
||||
{
|
||||
clang,
|
||||
fetchFromGitHub,
|
||||
fetchurl,
|
||||
gcc,
|
||||
readline,
|
||||
lua5_4,
|
||||
lua54Packages,
|
||||
stdenv,
|
||||
darwin,
|
||||
lib,
|
||||
luaPackages,
|
||||
}:
|
||||
lua54Packages.buildLuarocksPackage rec {
|
||||
pname = "promise-lua";
|
||||
|
|
|
|||
|
|
@ -1,47 +1,3 @@
|
|||
# https://github.com/khaneliman/khanelinix/blob/7703e485a2c7431f63004321da9e02ff7e06eb0b/packages/sbarlua/default.nix
|
||||
|
||||
# {
|
||||
# clang,
|
||||
# fetchFromGitHub,
|
||||
# gcc,
|
||||
# readline,
|
||||
# lua,
|
||||
# }:
|
||||
# lua.stdenv.mkDerivation rec {
|
||||
# pname = "SBarLua";
|
||||
# version = "0-unstable-2024-08-12";
|
||||
#
|
||||
# name = "lua${lua.luaversion}-" + pname + "-" + version;
|
||||
#
|
||||
# src = fetchFromGitHub {
|
||||
# owner = "FelixKratz";
|
||||
# repo = "SbarLua";
|
||||
# rev = "437bd2031da38ccda75827cb7548e7baa4aa9978";
|
||||
# hash = "sha256-F0UfNxHM389GhiPQ6/GFbeKQq5EvpiqQdvyf7ygzkPg=";
|
||||
# };
|
||||
#
|
||||
# nativeBuildInputs = [
|
||||
# clang
|
||||
# gcc
|
||||
# ];
|
||||
#
|
||||
# buildInputs = [ readline ];
|
||||
#
|
||||
# propagatedBuildInputs = [ lua ];
|
||||
#
|
||||
# makeFlags = [
|
||||
# "PREFIX=$(out)"
|
||||
# "LUA_INC=-I${lua}/include"
|
||||
# "LUA_LIBDIR=$(out)/lib/lua/${lua.luaversion}"
|
||||
# "LUA_VERSION=${lua.luaversion}"
|
||||
# ];
|
||||
#
|
||||
# installPhase = ''
|
||||
# mkdir -p $out/lib/lua/${lua.luaversion}/
|
||||
# cp -r bin/* "$out/lib/lua/${lua.luaversion}/"
|
||||
# '';
|
||||
# }
|
||||
|
||||
# https://github.com/Tnixc/nix-config/blob/main/home/programs/aerospace-sketchybar/flake.nix
|
||||
{
|
||||
clang,
|
||||
|
|
@ -51,9 +7,8 @@
|
|||
lua5_4,
|
||||
lua54Packages,
|
||||
stdenv,
|
||||
darwin,
|
||||
lib,
|
||||
luaPackages,
|
||||
apple-sdk_12,
|
||||
}:
|
||||
lua54Packages.buildLuaPackage rec {
|
||||
pname = "sbar";
|
||||
|
|
@ -74,5 +29,6 @@ lua54Packages.buildLuaPackage rec {
|
|||
readline
|
||||
clang
|
||||
stdenv
|
||||
] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ CoreFoundation ]);
|
||||
]
|
||||
++ lib.optionals stdenv.isDarwin [ apple-sdk_12 ];
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue