lowkey idk forgor
This commit is contained in:
@@ -99,6 +99,14 @@ vim.keymap.set("i", "jj", "<Esc>", { desc = "Exit insert mode", silent = true })
|
|||||||
-- Keybinds to make split navigation easier.
|
-- Keybinds to make split navigation easier.
|
||||||
-- Use CTRL+<hjkl> to switch between windows
|
-- Use CTRL+<hjkl> to switch between windows
|
||||||
|
|
||||||
|
-- Vertical navigation
|
||||||
|
vim.keymap.set("n", "<S-j>", "10j", { desc = "Jump ten spaces down", silent = true })
|
||||||
|
vim.keymap.set("n", "<S-k>", "10k", { desc = "Jump ten spaces up", silent = true })
|
||||||
|
|
||||||
|
-- Horizontal navigation
|
||||||
|
vim.keymap.set("n", "<C-i>", "^", { desc = "Jump to start of line", silent = true })
|
||||||
|
vim.keymap.set("n", "<C-a>", "$", { desc = "Jump to end of line", silent = true })
|
||||||
|
|
||||||
-- Telescope
|
-- Telescope
|
||||||
vim.keymap.set("n", "<leader>ff", ":Telescope find_files<Return>", { desc = "Find Files", silent = true })
|
vim.keymap.set("n", "<leader>ff", ":Telescope find_files<Return>", { desc = "Find Files", silent = true })
|
||||||
|
|
||||||
@@ -210,6 +218,35 @@ vim.opt.rtp:prepend(lazypath)
|
|||||||
-- PLUGINS
|
-- PLUGINS
|
||||||
|
|
||||||
require("lazy").setup({
|
require("lazy").setup({
|
||||||
|
{
|
||||||
|
"arminveres/md-pdf.nvim",
|
||||||
|
branch = "main", -- you can assume that main is somewhat stable until releases will be made
|
||||||
|
lazy = true,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
"<leader>,",
|
||||||
|
function()
|
||||||
|
require("md-pdf").convert_md_to_pdf()
|
||||||
|
end,
|
||||||
|
desc = "Markdown preview",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opts = {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"MeanderingProgrammer/render-markdown.nvim",
|
||||||
|
opts = {},
|
||||||
|
dependencies = { "nvim-treesitter/nvim-treesitter", "echasnovski/mini.nvim" }, -- if you use the mini.nvim suite
|
||||||
|
-- dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.icons' }, -- if you use standalone mini plugins
|
||||||
|
-- dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, -- if you prefer nvim-web-devicons
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tadmccorkle/markdown.nvim",
|
||||||
|
ft = "markdown", -- or 'event = "VeryLazy"'
|
||||||
|
opts = {
|
||||||
|
-- configuration here or empty for defaults
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"OmniSharp/omnisharp-vim",
|
"OmniSharp/omnisharp-vim",
|
||||||
init = function()
|
init = function()
|
||||||
@@ -736,9 +773,9 @@ require("lazy").setup({
|
|||||||
|
|
||||||
mapping = cmp.mapping.preset.insert({
|
mapping = cmp.mapping.preset.insert({
|
||||||
-- Select the [n]ext item
|
-- Select the [n]ext item
|
||||||
["<S-j>"] = cmp.mapping.select_next_item(),
|
["<C-j>"] = cmp.mapping.select_next_item(),
|
||||||
-- Select the [p]revious item
|
-- Select the [p]revious item
|
||||||
["<S-k>"] = cmp.mapping.select_prev_item(),
|
["<C-k>"] = cmp.mapping.select_prev_item(),
|
||||||
|
|
||||||
-- Scroll the documentation window [b]ack / [f]orward
|
-- Scroll the documentation window [b]ack / [f]orward
|
||||||
["<C-b>"] = cmp.mapping.scroll_docs(-4),
|
["<C-b>"] = cmp.mapping.scroll_docs(-4),
|
||||||
|
|||||||
@@ -1,45 +1,47 @@
|
|||||||
{
|
{
|
||||||
"LuaSnip": { "branch": "master", "commit": "7ad2eaeaca56d6ed63acacbfc114b99f1f67b982" },
|
"LuaSnip": { "branch": "master", "commit": "45db5addf8d0a201e1cf247cae4cdce605ad3768" },
|
||||||
"auto-session": { "branch": "main", "commit": "aa01054d478c6d3efc0188cb2ed4850e9f475664" },
|
"auto-session": { "branch": "main", "commit": "aa01054d478c6d3efc0188cb2ed4850e9f475664" },
|
||||||
"barbar.nvim": { "branch": "master", "commit": "53b5a2f34b68875898f0531032fbf090e3952ad7" },
|
"barbar.nvim": { "branch": "master", "commit": "53b5a2f34b68875898f0531032fbf090e3952ad7" },
|
||||||
"biscuit": { "branch": "main", "commit": "4089be2d6051c41558db55bbcc227c9d0c33bb0f" },
|
"biscuit": { "branch": "main", "commit": "4089be2d6051c41558db55bbcc227c9d0c33bb0f" },
|
||||||
"cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" },
|
"cmp-nvim-lsp": { "branch": "main", "commit": "39e2eda76828d88b773cc27a3f61d2ad782c922d" },
|
||||||
"cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
|
"cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
|
||||||
"cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
|
"cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
|
||||||
"coc.nvim": { "branch": "master", "commit": "f3406e06421eae672f1e990d8ac5a8b32b3190b9" },
|
"conform.nvim": { "branch": "master", "commit": "0ebe875d9c306f5fc829db38492ffff2a70d8e9d" },
|
||||||
"conform.nvim": { "branch": "master", "commit": "62eba813b7501b39612146cbf29cd07f1d4ac29c" },
|
|
||||||
"fidget.nvim": { "branch": "main", "commit": "d855eed8a06531a7e8fd0684889b2943f373c469" },
|
"fidget.nvim": { "branch": "main", "commit": "d855eed8a06531a7e8fd0684889b2943f373c469" },
|
||||||
"gitsigns.nvim": { "branch": "main", "commit": "562dc47189ad3c8696dbf460d38603a74d544849" },
|
"gitsigns.nvim": { "branch": "main", "commit": "1ef74b546732f185d0f806860fa5404df7614f28" },
|
||||||
"gruvbox-baby": { "branch": "main", "commit": "bd52e62d8134647090108189e69c8b3cd18bdbbf" },
|
"gruvbox-baby": { "branch": "main", "commit": "bd52e62d8134647090108189e69c8b3cd18bdbbf" },
|
||||||
"kanagawa.nvim": { "branch": "master", "commit": "e5f7b8a804360f0a48e40d0083a97193ee4fcc87" },
|
"kanagawa.nvim": { "branch": "master", "commit": "f491b0fe68fffbece7030181073dfe51f45cda81" },
|
||||||
"lazy.nvim": { "branch": "main", "commit": "077102c5bfc578693f12377846d427f49bc50076" },
|
"lazy.nvim": { "branch": "main", "commit": "077102c5bfc578693f12377846d427f49bc50076" },
|
||||||
"lazydev.nvim": { "branch": "main", "commit": "491452cf1ca6f029e90ad0d0368848fac717c6d2" },
|
"lazydev.nvim": { "branch": "main", "commit": "491452cf1ca6f029e90ad0d0368848fac717c6d2" },
|
||||||
"love2d.nvim": { "branch": "main", "commit": "9e3927836391a6147247411802917e2da6844042" },
|
"love2d.nvim": { "branch": "main", "commit": "b151657fbea8c37e734d68916215262e76dcabf2" },
|
||||||
"lualine.nvim": { "branch": "master", "commit": "b431d228b7bbcdaea818bdc3e25b8cdbe861f056" },
|
"lualine.nvim": { "branch": "master", "commit": "b431d228b7bbcdaea818bdc3e25b8cdbe861f056" },
|
||||||
"luvit-meta": { "branch": "main", "commit": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60" },
|
"luvit-meta": { "branch": "main", "commit": "ce76f6f6cdc9201523a5875a4471dcfe0186eb60" },
|
||||||
|
"markdown.nvim": { "branch": "master", "commit": "dfa0d2def6dbf77e9206b16dc90cad4dd23d55d2" },
|
||||||
"mason-lspconfig.nvim": { "branch": "main", "commit": "482350b050bd413931c2cdd4857443c3da7d57cb" },
|
"mason-lspconfig.nvim": { "branch": "main", "commit": "482350b050bd413931c2cdd4857443c3da7d57cb" },
|
||||||
"mason-tool-installer.nvim": { "branch": "main", "commit": "c5e07b8ff54187716334d585db34282e46fa2932" },
|
"mason-tool-installer.nvim": { "branch": "main", "commit": "c5e07b8ff54187716334d585db34282e46fa2932" },
|
||||||
"mason.nvim": { "branch": "main", "commit": "e2f7f9044ec30067bc11800a9e266664b88cda22" },
|
"mason.nvim": { "branch": "main", "commit": "e2f7f9044ec30067bc11800a9e266664b88cda22" },
|
||||||
"mini.nvim": { "branch": "main", "commit": "0bd6c4d25f2b0cc1ecb8b1a0f659cce54627e218" },
|
"md-pdf.nvim": { "branch": "main", "commit": "0da0bf9a6e85855762c68b40019851a75543d82b" },
|
||||||
"neovim": { "branch": "main", "commit": "256d086c218a282ae5de79d2c091b1e592a65367" },
|
"mini.nvim": { "branch": "main", "commit": "8413efde2546be4dec9ea424bc6af346a14dffbe" },
|
||||||
|
"neovim": { "branch": "main", "commit": "8b1fd252255a7f2c41b4192a787ab62660b29f72" },
|
||||||
"nvim": { "branch": "main", "commit": "4fd72a9ab64b393c2c22b168508fd244877fec96" },
|
"nvim": { "branch": "main", "commit": "4fd72a9ab64b393c2c22b168508fd244877fec96" },
|
||||||
"nvim-autopairs": { "branch": "master", "commit": "19606af7c039271d5aa96bceff101e7523af3136" },
|
"nvim-autopairs": { "branch": "master", "commit": "fd2badc24e675f947162a16c124d395bde80dbd6" },
|
||||||
"nvim-cmp": { "branch": "main", "commit": "ae644feb7b67bf1ce4260c231d1d4300b19c6f30" },
|
"nvim-cmp": { "branch": "main", "commit": "ae644feb7b67bf1ce4260c231d1d4300b19c6f30" },
|
||||||
"nvim-lspconfig": { "branch": "master", "commit": "911167921d49cd5c1c9b2436031d0da3945e787f" },
|
"nvim-lspconfig": { "branch": "master", "commit": "bdbc65aadc708ce528efb22bca5f82a7cca6b54d" },
|
||||||
"nvim-numbertoggle": { "branch": "main", "commit": "c5827153f8a955886f1b38eaea6998c067d2992f" },
|
"nvim-numbertoggle": { "branch": "main", "commit": "c5827153f8a955886f1b38eaea6998c067d2992f" },
|
||||||
"nvim-tree.lua": { "branch": "master", "commit": "ad0b95dee55955817af635fa121f6e2486b10583" },
|
"nvim-tree.lua": { "branch": "master", "commit": "ad0b95dee55955817af635fa121f6e2486b10583" },
|
||||||
"nvim-treesitter": { "branch": "master", "commit": "04401b5dd17c3419dae5141677bd256f52d54733" },
|
"nvim-treesitter": { "branch": "master", "commit": "4770d9a1a77b0cc2b723c646c3dbe43a9133e5db" },
|
||||||
"nvim-web-devicons": { "branch": "master", "commit": "3722e3d1fb5fe1896a104eb489e8f8651260b520" },
|
"nvim-web-devicons": { "branch": "master", "commit": "9793801f974bba70e4ac5d7eae6c4f5659993d8e" },
|
||||||
"omnisharp-vim": { "branch": "master", "commit": "f9c5d3e3375e8b5688a4506e813cb21bdc7329b1" },
|
"omnisharp-vim": { "branch": "master", "commit": "f9c5d3e3375e8b5688a4506e813cb21bdc7329b1" },
|
||||||
"plenary.nvim": { "branch": "master", "commit": "ec289423a1693aeae6cd0d503bac2856af74edaa" },
|
"plenary.nvim": { "branch": "master", "commit": "ec289423a1693aeae6cd0d503bac2856af74edaa" },
|
||||||
|
"render-markdown.nvim": { "branch": "main", "commit": "e91b042b3865d2d040a0e21e0a3b13fb57f24094" },
|
||||||
"sg.nvim": { "branch": "master", "commit": "8bdd4d19da2268072708d5fe18fda9c23e16509d" },
|
"sg.nvim": { "branch": "master", "commit": "8bdd4d19da2268072708d5fe18fda9c23e16509d" },
|
||||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "cf48d4dfce44e0b9a2e19a008d6ec6ea6f01a83b" },
|
"telescope-fzf-native.nvim": { "branch": "main", "commit": "cf48d4dfce44e0b9a2e19a008d6ec6ea6f01a83b" },
|
||||||
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
|
"telescope-ui-select.nvim": { "branch": "master", "commit": "6e51d7da30bd139a6950adf2a47fda6df9fa06d2" },
|
||||||
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
||||||
"todo-comments.nvim": { "branch": "main", "commit": "8f45f353dc3649cb9b44cecda96827ea88128584" },
|
"todo-comments.nvim": { "branch": "main", "commit": "319c01b99b7a8c9ac2066bf0efd4d6ec68fef444" },
|
||||||
"tokyonight.nvim": { "branch": "main", "commit": "b0e7c7382a7e8f6456f2a95655983993ffda745e" },
|
"tokyonight.nvim": { "branch": "main", "commit": "4b386e66a9599057587c30538d5e6192e3d1c181" },
|
||||||
"vim-sleuth": { "branch": "master", "commit": "1cc4557420f215d02c4d2645a748a816c220e99b" },
|
"vim-sleuth": { "branch": "master", "commit": "cd9d382e33bb817abe7f10cdc3a606bf1d491d75" },
|
||||||
"vim-tmux-navigator": { "branch": "master", "commit": "5b3c701686fb4e6629c100ed32e827edf8dad01e" },
|
"vim-tmux-navigator": { "branch": "master", "commit": "5b3c701686fb4e6629c100ed32e827edf8dad01e" },
|
||||||
"which-key.nvim": { "branch": "main", "commit": "6c1584eb76b55629702716995cca4ae2798a9cca" },
|
"which-key.nvim": { "branch": "main", "commit": "bfec3d6bc0a9b0b2cb11644642f78c2c3915eef0" },
|
||||||
"yazi.nvim": { "branch": "main", "commit": "ac97d7c5e47490ecd179647bc0d0ea04c9ce3329" }
|
"yazi.nvim": { "branch": "main", "commit": "ac97d7c5e47490ecd179647bc0d0ea04c9ce3329" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
local colors = require("colors")
|
||||||
|
|
||||||
|
-- Equivalent to the --bar domain
|
||||||
|
sbar.bar({
|
||||||
|
topmost = "window",
|
||||||
|
height = 50,
|
||||||
|
color = colors.bar.bg,
|
||||||
|
padding_right = 3,
|
||||||
|
padding_left = 3,
|
||||||
|
})
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
return {
|
||||||
|
black = 0xff25273A,
|
||||||
|
white = 0xffb5c9ff,
|
||||||
|
red = 0xffFF6C8D,
|
||||||
|
green = 0xff90D05A,
|
||||||
|
blue = 0xff6EA3FE,
|
||||||
|
yellow = 0xffE9AD5B,
|
||||||
|
orange = 0xffFF9856,
|
||||||
|
magenta = 0xffC198FD,
|
||||||
|
grey = 0xff9AA9D9,
|
||||||
|
transparent = 0x00000000,
|
||||||
|
|
||||||
|
bar = {
|
||||||
|
bg = 0x00ffffff,
|
||||||
|
border = 0x00ffffff,
|
||||||
|
},
|
||||||
|
popup = {
|
||||||
|
bg = 0xee25273A,
|
||||||
|
border = 0xff1E2030,
|
||||||
|
},
|
||||||
|
bg1 = 0xff25273A,
|
||||||
|
bg2 = 0xff1E2030,
|
||||||
|
|
||||||
|
with_alpha = function(color, alpha)
|
||||||
|
if alpha > 1.0 or alpha < 0.0 then return color end
|
||||||
|
return (color & 0x00ffffff) | (math.floor(alpha * 255.0) << 24)
|
||||||
|
end,
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
local settings = require("settings")
|
||||||
|
local colors = require("colors")
|
||||||
|
|
||||||
|
-- Equivalent to the --default domain
|
||||||
|
sbar.default({
|
||||||
|
updates = "when_shown",
|
||||||
|
icon = {
|
||||||
|
font = {
|
||||||
|
family = settings.font.text,
|
||||||
|
style = settings.font.style_map["Bold"],
|
||||||
|
size = 14.0
|
||||||
|
},
|
||||||
|
color = colors.white,
|
||||||
|
padding_left = settings.paddings,
|
||||||
|
padding_right = settings.paddings,
|
||||||
|
background = { image = { corner_radius = 9 } },
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
font = {
|
||||||
|
family = settings.font.text,
|
||||||
|
style = settings.font.style_map["Semibold"],
|
||||||
|
size = 13.0
|
||||||
|
},
|
||||||
|
color = colors.white,
|
||||||
|
padding_left = settings.paddings,
|
||||||
|
padding_right = settings.paddings,
|
||||||
|
},
|
||||||
|
background = {
|
||||||
|
height = 34,
|
||||||
|
corner_radius = 12,
|
||||||
|
border_width = 0,
|
||||||
|
border_color = colors.bg2,
|
||||||
|
image = {
|
||||||
|
corner_radius = 9,
|
||||||
|
border_color = colors.grey,
|
||||||
|
border_width = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
popup = {
|
||||||
|
background = {
|
||||||
|
border_width = 0,
|
||||||
|
corner_radius = 9,
|
||||||
|
border_color = colors.popup.border,
|
||||||
|
color = colors.popup.bg,
|
||||||
|
shadow = { drawing = true },
|
||||||
|
},
|
||||||
|
blur_radius = 50,
|
||||||
|
},
|
||||||
|
padding_left = 5,
|
||||||
|
padding_right = 5,
|
||||||
|
scroll_texts = true,
|
||||||
|
})
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
bin
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
return {
|
||||||
|
["Typora"] = ":text:",
|
||||||
|
["Orion"] = ":orion:",
|
||||||
|
["Orion RC"] = ":orion:",
|
||||||
|
["Grammarly Editor"] = ":grammarly:",
|
||||||
|
["kitty"] = ":kitty:",
|
||||||
|
["ClickUp"] = ":click_up:",
|
||||||
|
["Iris"] = ":iris:",
|
||||||
|
["PomoDone App"] = ":pomodone:",
|
||||||
|
["qutebrowser"] = ":qute_browser:",
|
||||||
|
["Raindrop.io"] = ":raindrop_io:",
|
||||||
|
["Airmail"] = ":airmail:",
|
||||||
|
["Affinity Publisher 2"] = ":affinity_publisher_2:",
|
||||||
|
["Calendar"] = ":calendar:",
|
||||||
|
["日历"] = ":calendar:",
|
||||||
|
["Fantastical"] = ":calendar:",
|
||||||
|
["Cron"] = ":calendar:",
|
||||||
|
["Amie"] = ":calendar:",
|
||||||
|
["Figma"] = ":figma:",
|
||||||
|
["Element"] = ":element:",
|
||||||
|
["Signal"] = ":signal:",
|
||||||
|
["Mattermost"] = ":mattermost:",
|
||||||
|
["Caprine"] = ":caprine:",
|
||||||
|
["Microsoft To Do"] = ":things:",
|
||||||
|
["Things"] = ":things:",
|
||||||
|
["Godot"] = ":godot:",
|
||||||
|
["Android Messages"] = ":android_messages:",
|
||||||
|
["Zed"] = ":zed:",
|
||||||
|
["Anytype"] = ":anytype:",
|
||||||
|
["TeamSpeak 3"] = ":team_speak:",
|
||||||
|
["LibreWolf"] = ":libre_wolf:",
|
||||||
|
["Neovide"] = ":neovide:",
|
||||||
|
["neovide"] = ":neovide:",
|
||||||
|
["Spotlight"] = ":spotlight:",
|
||||||
|
["微信"] = ":wechat:",
|
||||||
|
["Dropbox"] = ":dropbox:",
|
||||||
|
["Transmit"] = ":transmit:",
|
||||||
|
["TickTick"] = ":tick_tick:",
|
||||||
|
["Parallels Desktop"] = ":parallels:",
|
||||||
|
["Audacity"] = ":audacity:",
|
||||||
|
["Rider"] = ":rider:",
|
||||||
|
["JetBrains Rider"] = ":rider:",
|
||||||
|
["DEVONthink 3"] = ":devonthink3:",
|
||||||
|
["Docker"] = ":docker:",
|
||||||
|
["Docker Desktop"] = ":docker:",
|
||||||
|
["Matlab"] = ":matlab:",
|
||||||
|
["VLC"] = ":vlc:",
|
||||||
|
["Alacritty"] = ":alacritty:",
|
||||||
|
["Pages"] = ":pages:",
|
||||||
|
["Pages 文稿"] = ":pages:",
|
||||||
|
["Bear"] = ":bear:",
|
||||||
|
["Pine"] = ":pine:",
|
||||||
|
["Affinity Designer 2"] = ":affinity_designer_2:",
|
||||||
|
["Keyboard Maestro"] = ":keyboard_maestro:",
|
||||||
|
["Joplin"] = ":joplin:",
|
||||||
|
["mpv"] = ":mpv:",
|
||||||
|
["zoom.us"] = ":zoom:",
|
||||||
|
["Affinity Photo 2"] = ":affinity_photo_2:",
|
||||||
|
["Music"] = ":music:",
|
||||||
|
["音乐"] = ":music:",
|
||||||
|
["League of Legends"] = ":league_of_legends:",
|
||||||
|
["Tor Browser"] = ":tor_browser:",
|
||||||
|
["Hyper"] = ":hyper:",
|
||||||
|
["WhatsApp"] = ":whats_app:",
|
||||||
|
["카카오톡"] = ":kakaotalk:",
|
||||||
|
["Discord"] = ":discord:",
|
||||||
|
["Discord Canary"] = ":discord:",
|
||||||
|
["Discord PTB"] = ":discord:",
|
||||||
|
["Neovide"] = ":vim:",
|
||||||
|
["MacVim"] = ":vim:",
|
||||||
|
["Vim"] = ":vim:",
|
||||||
|
["VimR"] = ":vim:",
|
||||||
|
["Keynote"] = ":keynote:",
|
||||||
|
["Keynote 讲演"] = ":keynote:",
|
||||||
|
["iTerm"] = ":iterm:",
|
||||||
|
["IntelliJ IDEA"] = ":idea:",
|
||||||
|
["Finder"] = ":finder:",
|
||||||
|
["访达"] = ":finder:",
|
||||||
|
["Xcode"] = ":xcode:",
|
||||||
|
["GoLand"] = ":goland:",
|
||||||
|
["Android Studio"] = ":android_studio:",
|
||||||
|
["MoneyMoney"] = ":bank:",
|
||||||
|
["Spotify"] = ":spotify:",
|
||||||
|
["KeePassXC"] = ":kee_pass_x_c:",
|
||||||
|
["Alfred"] = ":alfred:",
|
||||||
|
["Color Picker"] = ":color_picker:",
|
||||||
|
["数码测色计"] = ":color_picker:",
|
||||||
|
["Microsoft Word"] = ":microsoft_word:",
|
||||||
|
["Microsoft PowerPoint"] = ":microsoft_power_point:",
|
||||||
|
["Notes"] = ":notes:",
|
||||||
|
["备忘录"] = ":notes:",
|
||||||
|
["Microsoft Edge"] = ":microsoft_edge:",
|
||||||
|
["Sublime Text"] = ":sublime_text:",
|
||||||
|
["Sequel Ace"] = ":sequel_ace:",
|
||||||
|
["Folx"] = ":folx:",
|
||||||
|
["DingTalk"] = ":dingtalk:",
|
||||||
|
["钉钉"] = ":dingtalk:",
|
||||||
|
["阿里钉"] = ":dingtalk:",
|
||||||
|
["WebStorm"] = ":web_storm:",
|
||||||
|
["Sequel Pro"] = ":sequel_pro:",
|
||||||
|
["Skype"] = ":skype:",
|
||||||
|
["网易云音乐"] = ":netease_music:",
|
||||||
|
["PyCharm"] = ":pycharm:",
|
||||||
|
["Canary Mail"] = ":mail:",
|
||||||
|
["HEY"] = ":mail:",
|
||||||
|
["Mail"] = ":mail:",
|
||||||
|
["Mailspring"] = ":mail:",
|
||||||
|
["MailMate"] = ":mail:",
|
||||||
|
["邮件"] = ":mail:",
|
||||||
|
["Default"] = ":default:",
|
||||||
|
["App Store"] = ":app_store:",
|
||||||
|
["Calibre"] = ":book:",
|
||||||
|
["Todoist"] = ":todoist:",
|
||||||
|
["Emacs"] = ":emacs:",
|
||||||
|
["Messenger"] = ":messenger:",
|
||||||
|
["Tower"] = ":tower:",
|
||||||
|
["VSCodium"] = ":vscodium:",
|
||||||
|
["Drafts"] = ":drafts:",
|
||||||
|
["Cypress"] = ":cypress:",
|
||||||
|
["GitHub Desktop"] = ":git_hub:",
|
||||||
|
["Telegram"] = ":telegram:",
|
||||||
|
["Firefox Developer Edition"] = ":firefox_developer_edition:",
|
||||||
|
["Firefox Nightly"] = ":firefox_developer_edition:",
|
||||||
|
["Min"] = ":min_browser:",
|
||||||
|
["Sketch"] = ":sketch:",
|
||||||
|
["Affinity Photo"] = ":affinity_photo:",
|
||||||
|
["MAMP"] = ":mamp:",
|
||||||
|
["MAMP PRO"] = ":mamp:",
|
||||||
|
["Insomnia"] = ":insomnia:",
|
||||||
|
["Bitwarden"] = ":bit_warden:",
|
||||||
|
["Warp"] = ":warp:",
|
||||||
|
["System Preferences"] = ":gear:",
|
||||||
|
["System Settings"] = ":gear:",
|
||||||
|
["系统设置"] = ":gear:",
|
||||||
|
["Affinity Designer"] = ":affinity_designer:",
|
||||||
|
["Live"] = ":ableton:",
|
||||||
|
["Arc"] = ":arc:",
|
||||||
|
["Chromium"] = ":google_chrome:",
|
||||||
|
["Google Chrome"] = ":google_chrome:",
|
||||||
|
["Google Chrome Canary"] = ":google_chrome:",
|
||||||
|
["Jellyfin Media Player"] = ":jellyfin:",
|
||||||
|
["Zulip"] = ":zulip:",
|
||||||
|
["1Password"] = ":one_password:",
|
||||||
|
["FaceTime"] = ":face_time:",
|
||||||
|
["FaceTime 通话"] = ":face_time:",
|
||||||
|
["Citrix Workspace"] = ":citrix:",
|
||||||
|
["Citrix Viewer"] = ":citrix:",
|
||||||
|
["Logseq"] = ":logseq:",
|
||||||
|
["Reeder"] = ":reeder5:",
|
||||||
|
["Code"] = ":code:",
|
||||||
|
["Code - Insiders"] = ":code:",
|
||||||
|
["Notion"] = ":notion:",
|
||||||
|
["Final Cut Pro"] = ":final_cut_pro:",
|
||||||
|
["Zotero"] = ":zotero:",
|
||||||
|
["Safari"] = ":safari:",
|
||||||
|
["Safari浏览器"] = ":safari:",
|
||||||
|
["Safari Technology Preview"] = ":safari:",
|
||||||
|
["Blender"] = ":blender:",
|
||||||
|
["Affinity Publisher"] = ":affinity_publisher:",
|
||||||
|
["Spark Desktop"] = ":spark:",
|
||||||
|
["Zeplin"] = ":zeplin:",
|
||||||
|
["Replit"] = ":replit:",
|
||||||
|
["Podcasts"] = ":podcasts:",
|
||||||
|
["播客"] = ":podcasts:",
|
||||||
|
["NordVPN"] = ":nord_vpn:",
|
||||||
|
["Notability"] = ":notability:",
|
||||||
|
["Numbers"] = ":numbers:",
|
||||||
|
["Numbers 表格"] = ":numbers:",
|
||||||
|
["Nova"] = ":nova:",
|
||||||
|
["Microsoft Excel"] = ":microsoft_excel:",
|
||||||
|
["Trello"] = ":trello:",
|
||||||
|
["Pi-hole Remote"] = ":pihole:",
|
||||||
|
["Linear"] = ":linear:",
|
||||||
|
["CleanMyMac X"] = ":desktop:",
|
||||||
|
["GrandTotal"] = ":dollar:",
|
||||||
|
["Receipts"] = ":dollar:",
|
||||||
|
["Evernote Legacy"] = ":evernote_legacy:",
|
||||||
|
["OmniFocus"] = ":omni_focus:",
|
||||||
|
["Terminal"] = ":terminal:",
|
||||||
|
["终端"] = ":terminal:",
|
||||||
|
["Atom"] = ":atom:",
|
||||||
|
["Kakoune"] = ":kakoune:",
|
||||||
|
["Reminders"] = ":reminders:",
|
||||||
|
["提醒事项"] = ":reminders:",
|
||||||
|
["Tana"] = ":tana:",
|
||||||
|
["OBS"] = ":obsstudio:",
|
||||||
|
["VMware Fusion"] = ":vmware_fusion:",
|
||||||
|
["Tweetbot"] = ":twitter:",
|
||||||
|
["Twitter"] = ":twitter:",
|
||||||
|
["Microsoft Teams"] = ":microsoft_teams:",
|
||||||
|
["Yuque"] = ":yuque:",
|
||||||
|
["语雀"] = ":yuque:",
|
||||||
|
["Slack"] = ":slack:",
|
||||||
|
["Vivaldi"] = ":vivaldi:",
|
||||||
|
["Setapp"] = ":setapp:",
|
||||||
|
["TIDAL"] = ":tidal:",
|
||||||
|
["Miro"] = ":miro:",
|
||||||
|
["Messages"] = ":messages:",
|
||||||
|
["信息"] = ":messages:",
|
||||||
|
["Nachrichten"] = ":messages:",
|
||||||
|
["Brave Browser"] = ":brave_browser:",
|
||||||
|
["Preview"] = ":pdf:",
|
||||||
|
["预览"] = ":pdf:",
|
||||||
|
["Skim"] = ":pdf:",
|
||||||
|
["zathura"] = ":pdf:",
|
||||||
|
["Obsidian"] = ":obsidian:",
|
||||||
|
["Thunderbird"] = ":thunderbird:",
|
||||||
|
["Firefox"] = ":firefox:",
|
||||||
|
["WezTerm"] = ":wezterm:",
|
||||||
|
["default"] = ":default:",
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
return {
|
||||||
|
text = "SF Pro", -- Used for text
|
||||||
|
numbers = "SF Pro", -- Used for numbers
|
||||||
|
mono = "BerkeleyMono Nerd Font",
|
||||||
|
|
||||||
|
-- Unified font style map
|
||||||
|
style_map = {
|
||||||
|
["Regular"] = "Regular",
|
||||||
|
["Semibold"] = "Semibold",
|
||||||
|
["Bold"] = "Bold",
|
||||||
|
["Heavy"] = "Heavy",
|
||||||
|
["Black"] = "Black",
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include <mach/mach.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct cpu {
|
||||||
|
host_t host;
|
||||||
|
mach_msg_type_number_t count;
|
||||||
|
host_cpu_load_info_data_t load;
|
||||||
|
host_cpu_load_info_data_t prev_load;
|
||||||
|
bool has_prev_load;
|
||||||
|
|
||||||
|
int user_load;
|
||||||
|
int sys_load;
|
||||||
|
int total_load;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void cpu_init(struct cpu* cpu) {
|
||||||
|
cpu->host = mach_host_self();
|
||||||
|
cpu->count = HOST_CPU_LOAD_INFO_COUNT;
|
||||||
|
cpu->has_prev_load = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cpu_update(struct cpu* cpu) {
|
||||||
|
kern_return_t error = host_statistics(cpu->host,
|
||||||
|
HOST_CPU_LOAD_INFO,
|
||||||
|
(host_info_t)&cpu->load,
|
||||||
|
&cpu->count );
|
||||||
|
|
||||||
|
if (error != KERN_SUCCESS) {
|
||||||
|
printf("Error: Could not read cpu host statistics.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpu->has_prev_load) {
|
||||||
|
uint32_t delta_user = cpu->load.cpu_ticks[CPU_STATE_USER]
|
||||||
|
- cpu->prev_load.cpu_ticks[CPU_STATE_USER];
|
||||||
|
|
||||||
|
uint32_t delta_system = cpu->load.cpu_ticks[CPU_STATE_SYSTEM]
|
||||||
|
- cpu->prev_load.cpu_ticks[CPU_STATE_SYSTEM];
|
||||||
|
|
||||||
|
uint32_t delta_idle = cpu->load.cpu_ticks[CPU_STATE_IDLE]
|
||||||
|
- cpu->prev_load.cpu_ticks[CPU_STATE_IDLE];
|
||||||
|
|
||||||
|
cpu->user_load = (double)delta_user / (double)(delta_system
|
||||||
|
+ delta_user
|
||||||
|
+ delta_idle) * 100.0;
|
||||||
|
|
||||||
|
cpu->sys_load = (double)delta_system / (double)(delta_system
|
||||||
|
+ delta_user
|
||||||
|
+ delta_idle) * 100.0;
|
||||||
|
|
||||||
|
cpu->total_load = cpu->user_load + cpu->sys_load;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu->prev_load = cpu->load;
|
||||||
|
cpu->has_prev_load = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "cpu.h"
|
||||||
|
#include "../sketchybar.h"
|
||||||
|
|
||||||
|
int main (int argc, char** argv) {
|
||||||
|
float update_freq;
|
||||||
|
if (argc < 3 || (sscanf(argv[2], "%f", &update_freq) != 1)) {
|
||||||
|
printf("Usage: %s \"<event-name>\" \"<event_freq>\"\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(0);
|
||||||
|
struct cpu cpu;
|
||||||
|
cpu_init(&cpu);
|
||||||
|
|
||||||
|
// Setup the event in sketchybar
|
||||||
|
char event_message[512];
|
||||||
|
snprintf(event_message, 512, "--add event '%s'", argv[1]);
|
||||||
|
sketchybar(event_message);
|
||||||
|
|
||||||
|
char trigger_message[512];
|
||||||
|
for (;;) {
|
||||||
|
// Acquire new info
|
||||||
|
cpu_update(&cpu);
|
||||||
|
|
||||||
|
// Prepare the event message
|
||||||
|
snprintf(trigger_message,
|
||||||
|
512,
|
||||||
|
"--trigger '%s' user_load='%d' sys_load='%02d' total_load='%02d'",
|
||||||
|
argv[1],
|
||||||
|
cpu.user_load,
|
||||||
|
cpu.sys_load,
|
||||||
|
cpu.total_load );
|
||||||
|
|
||||||
|
// Trigger the event
|
||||||
|
sketchybar(trigger_message);
|
||||||
|
|
||||||
|
// Wait
|
||||||
|
usleep(update_freq * 1000000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
bin/cpu_load: cpu_load.c cpu.h ../sketchybar.h | bin
|
||||||
|
clang -std=c99 -O3 $< -o $@
|
||||||
|
|
||||||
|
bin:
|
||||||
|
mkdir bin
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
all:
|
||||||
|
(cd cpu_load && $(MAKE))
|
||||||
|
(cd network_load && $(MAKE))
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
bin/network_load: network_load.c network.h ../sketchybar.h | bin
|
||||||
|
clang -std=c99 -O3 $< -o $@
|
||||||
|
|
||||||
|
bin:
|
||||||
|
mkdir bin
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <net/if_mib.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
static char unit_str[3][6] = { { " Bps" }, { "KBps" }, { "MBps" }, };
|
||||||
|
|
||||||
|
enum unit {
|
||||||
|
UNIT_BPS,
|
||||||
|
UNIT_KBPS,
|
||||||
|
UNIT_MBPS
|
||||||
|
};
|
||||||
|
struct network {
|
||||||
|
uint32_t row;
|
||||||
|
struct ifmibdata data;
|
||||||
|
struct timeval tv_nm1, tv_n, tv_delta;
|
||||||
|
|
||||||
|
int up;
|
||||||
|
int down;
|
||||||
|
enum unit up_unit, down_unit;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void ifdata(uint32_t net_row, struct ifmibdata* data) {
|
||||||
|
static size_t size = sizeof(struct ifmibdata);
|
||||||
|
static int32_t data_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL };
|
||||||
|
data_option[4] = net_row;
|
||||||
|
sysctl(data_option, 6, data, &size, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void network_init(struct network* net, char* ifname) {
|
||||||
|
memset(net, 0, sizeof(struct network));
|
||||||
|
|
||||||
|
static int count_option[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
|
||||||
|
uint32_t interface_count = 0;
|
||||||
|
size_t size = sizeof(uint32_t);
|
||||||
|
sysctl(count_option, 5, &interface_count, &size, NULL, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < interface_count; i++) {
|
||||||
|
ifdata(i, &net->data);
|
||||||
|
if (strcmp(net->data.ifmd_name, ifname) == 0) {
|
||||||
|
net->row = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void network_update(struct network* net) {
|
||||||
|
gettimeofday(&net->tv_n, NULL);
|
||||||
|
timersub(&net->tv_n, &net->tv_nm1, &net->tv_delta);
|
||||||
|
net->tv_nm1 = net->tv_n;
|
||||||
|
|
||||||
|
uint64_t ibytes_nm1 = net->data.ifmd_data.ifi_ibytes;
|
||||||
|
uint64_t obytes_nm1 = net->data.ifmd_data.ifi_obytes;
|
||||||
|
ifdata(net->row, &net->data);
|
||||||
|
|
||||||
|
double time_scale = (net->tv_delta.tv_sec + 1e-6*net->tv_delta.tv_usec);
|
||||||
|
if (time_scale < 1e-6 || time_scale > 1e2) return;
|
||||||
|
double delta_ibytes = (double)(net->data.ifmd_data.ifi_ibytes - ibytes_nm1)
|
||||||
|
/ time_scale;
|
||||||
|
double delta_obytes = (double)(net->data.ifmd_data.ifi_obytes - obytes_nm1)
|
||||||
|
/ time_scale;
|
||||||
|
|
||||||
|
double exponent_ibytes = log10(delta_ibytes);
|
||||||
|
double exponent_obytes = log10(delta_obytes);
|
||||||
|
|
||||||
|
if (exponent_ibytes < 3) {
|
||||||
|
net->down_unit = UNIT_BPS;
|
||||||
|
net->down = delta_ibytes;
|
||||||
|
} else if (exponent_ibytes < 6) {
|
||||||
|
net->down_unit = UNIT_KBPS;
|
||||||
|
net->down = delta_ibytes / 1000.0;
|
||||||
|
} else if (exponent_ibytes < 9) {
|
||||||
|
net->down_unit = UNIT_MBPS;
|
||||||
|
net->down = delta_ibytes / 1000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exponent_obytes < 3) {
|
||||||
|
net->up_unit = UNIT_BPS;
|
||||||
|
net->up = delta_obytes;
|
||||||
|
} else if (exponent_obytes < 6) {
|
||||||
|
net->up_unit = UNIT_KBPS;
|
||||||
|
net->up = delta_obytes / 1000.0;
|
||||||
|
} else if (exponent_obytes < 9) {
|
||||||
|
net->up_unit = UNIT_MBPS;
|
||||||
|
net->up = delta_obytes / 1000000.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#include <unistd.h>
|
||||||
|
#include "network.h"
|
||||||
|
#include "../sketchybar.h"
|
||||||
|
|
||||||
|
int main (int argc, char** argv) {
|
||||||
|
float update_freq;
|
||||||
|
if (argc < 4 || (sscanf(argv[3], "%f", &update_freq) != 1)) {
|
||||||
|
printf("Usage: %s \"<interface>\" \"<event-name>\" \"<event_freq>\"\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(0);
|
||||||
|
// Setup the event in sketchybar
|
||||||
|
char event_message[512];
|
||||||
|
snprintf(event_message, 512, "--add event '%s'", argv[2]);
|
||||||
|
sketchybar(event_message);
|
||||||
|
|
||||||
|
struct network network;
|
||||||
|
network_init(&network, argv[1]);
|
||||||
|
char trigger_message[512];
|
||||||
|
for (;;) {
|
||||||
|
// Acquire new info
|
||||||
|
network_update(&network);
|
||||||
|
|
||||||
|
// Prepare the event message
|
||||||
|
snprintf(trigger_message,
|
||||||
|
512,
|
||||||
|
"--trigger '%s' upload='%03d%s' download='%03d%s'",
|
||||||
|
argv[2],
|
||||||
|
network.up,
|
||||||
|
unit_str[network.up_unit],
|
||||||
|
network.down,
|
||||||
|
unit_str[network.down_unit]);
|
||||||
|
|
||||||
|
// Trigger the event
|
||||||
|
sketchybar(trigger_message);
|
||||||
|
|
||||||
|
// Wait
|
||||||
|
usleep(update_freq * 1000000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mach/arm/kern_return.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/mach_port.h>
|
||||||
|
#include <mach/message.h>
|
||||||
|
#include <bootstrap.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef char* env;
|
||||||
|
|
||||||
|
#define MACH_HANDLER(name) void name(env env)
|
||||||
|
typedef MACH_HANDLER(mach_handler);
|
||||||
|
|
||||||
|
struct mach_message {
|
||||||
|
mach_msg_header_t header;
|
||||||
|
mach_msg_size_t msgh_descriptor_count;
|
||||||
|
mach_msg_ool_descriptor_t descriptor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mach_buffer {
|
||||||
|
struct mach_message message;
|
||||||
|
mach_msg_trailer_t trailer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static mach_port_t g_mach_port = 0;
|
||||||
|
|
||||||
|
static inline mach_port_t mach_get_bs_port() {
|
||||||
|
mach_port_name_t task = mach_task_self();
|
||||||
|
|
||||||
|
mach_port_t bs_port;
|
||||||
|
if (task_get_special_port(task,
|
||||||
|
TASK_BOOTSTRAP_PORT,
|
||||||
|
&bs_port ) != KERN_SUCCESS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* name = getenv("BAR_NAME");
|
||||||
|
if (!name) name = "sketchybar";
|
||||||
|
uint32_t lookup_len = 16 + strlen(name);
|
||||||
|
|
||||||
|
char buffer[lookup_len];
|
||||||
|
snprintf(buffer, lookup_len, "git.felix.%s", name);
|
||||||
|
|
||||||
|
mach_port_t port;
|
||||||
|
if (bootstrap_look_up(bs_port, buffer, &port) != KERN_SUCCESS) return 0;
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool mach_send_message(mach_port_t port, char* message, uint32_t len) {
|
||||||
|
if (!message || !port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mach_message msg = { 0 };
|
||||||
|
msg.header.msgh_remote_port = port;
|
||||||
|
msg.header.msgh_local_port = 0;
|
||||||
|
msg.header.msgh_id = 0;
|
||||||
|
msg.header.msgh_bits = MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND,
|
||||||
|
MACH_MSG_TYPE_MAKE_SEND,
|
||||||
|
0,
|
||||||
|
MACH_MSGH_BITS_COMPLEX );
|
||||||
|
|
||||||
|
msg.header.msgh_size = sizeof(struct mach_message);
|
||||||
|
msg.msgh_descriptor_count = 1;
|
||||||
|
msg.descriptor.address = message;
|
||||||
|
msg.descriptor.size = len * sizeof(char);
|
||||||
|
msg.descriptor.copy = MACH_MSG_VIRTUAL_COPY;
|
||||||
|
msg.descriptor.deallocate = false;
|
||||||
|
msg.descriptor.type = MACH_MSG_OOL_DESCRIPTOR;
|
||||||
|
|
||||||
|
kern_return_t err = mach_msg(&msg.header,
|
||||||
|
MACH_SEND_MSG,
|
||||||
|
sizeof(struct mach_message),
|
||||||
|
0,
|
||||||
|
MACH_PORT_NULL,
|
||||||
|
MACH_MSG_TIMEOUT_NONE,
|
||||||
|
MACH_PORT_NULL );
|
||||||
|
|
||||||
|
return err == KERN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t format_message(char* message, char* formatted_message) {
|
||||||
|
// This is not actually robust, switch to stack based messaging.
|
||||||
|
char outer_quote = 0;
|
||||||
|
uint32_t caret = 0;
|
||||||
|
uint32_t message_length = strlen(message) + 1;
|
||||||
|
for (int i = 0; i < message_length; ++i) {
|
||||||
|
if (message[i] == '"' || message[i] == '\'') {
|
||||||
|
if (outer_quote && outer_quote == message[i]) outer_quote = 0;
|
||||||
|
else if (!outer_quote) outer_quote = message[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
formatted_message[caret] = message[i];
|
||||||
|
if (message[i] == ' ' && !outer_quote) formatted_message[caret] = '\0';
|
||||||
|
caret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caret > 0 && formatted_message[caret] == '\0'
|
||||||
|
&& formatted_message[caret - 1] == '\0') {
|
||||||
|
caret--;
|
||||||
|
}
|
||||||
|
formatted_message[caret] = '\0';
|
||||||
|
return caret + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void sketchybar(char* message) {
|
||||||
|
char formatted_message[strlen(message) + 2];
|
||||||
|
uint32_t length = format_message(message, formatted_message);
|
||||||
|
if (!length) return;
|
||||||
|
|
||||||
|
if (!g_mach_port) g_mach_port = mach_get_bs_port();
|
||||||
|
if (!mach_send_message(g_mach_port, formatted_message, length)) {
|
||||||
|
g_mach_port = mach_get_bs_port();
|
||||||
|
if (!mach_send_message(g_mach_port, formatted_message, length)) {
|
||||||
|
// No sketchybar instance running, exit.
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Add the sketchybar module to the package cpath
|
||||||
|
package.cpath = package.cpath .. ";/Users/" .. os.getenv("USER") .. "/.local/share/sketchybar_lua/?.so"
|
||||||
|
|
||||||
|
os.execute("(cd helpers && make)")
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
# Packages
|
||||||
|
brew install lua
|
||||||
|
brew install switchaudio-osx
|
||||||
|
brew install nowplaying-cli
|
||||||
|
|
||||||
|
brew tap FelixKratz/formulae
|
||||||
|
brew install sketchybar
|
||||||
|
|
||||||
|
# Fonts
|
||||||
|
brew install --cask sf-symbols
|
||||||
|
brew install --cask homebrew/cask-fonts/font-sf-mono
|
||||||
|
brew install --cask homebrew/cask-fonts/font-sf-pro
|
||||||
|
|
||||||
|
curl -L https://github.com/kvndrsslr/sketchybar-app-font/releases/download/v2.0.5/sketchybar-app-font.ttf -o $HOME/Library/Fonts/sketchybar-app-font.ttf
|
||||||
|
|
||||||
|
# SbarLua
|
||||||
|
(git clone https://github.com/FelixKratz/SbarLua.git /tmp/SbarLua && cd /tmp/SbarLua/ && make install && rm -rf /tmp/SbarLua/)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
all:
|
||||||
|
(cd event_providers && $(MAKE)) >/dev/null
|
||||||
|
(cd menus && $(MAKE)) >/dev/null
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
bin/menus: menus.c | bin
|
||||||
|
clang -std=c99 -O3 -F/System/Library/PrivateFrameworks/ -framework Carbon -framework SkyLight $< -o $@
|
||||||
|
|
||||||
|
bin:
|
||||||
|
mkdir bin
|
||||||
@@ -0,0 +1,248 @@
|
|||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
void ax_init() {
|
||||||
|
const void *keys[] = { kAXTrustedCheckOptionPrompt };
|
||||||
|
const void *values[] = { kCFBooleanTrue };
|
||||||
|
|
||||||
|
CFDictionaryRef options;
|
||||||
|
options = CFDictionaryCreate(kCFAllocatorDefault,
|
||||||
|
keys,
|
||||||
|
values,
|
||||||
|
sizeof(keys) / sizeof(*keys),
|
||||||
|
&kCFCopyStringDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks );
|
||||||
|
|
||||||
|
bool trusted = AXIsProcessTrustedWithOptions(options);
|
||||||
|
CFRelease(options);
|
||||||
|
if (!trusted) exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ax_perform_click(AXUIElementRef element) {
|
||||||
|
if (!element) return;
|
||||||
|
AXUIElementPerformAction(element, kAXCancelAction);
|
||||||
|
usleep(150000);
|
||||||
|
AXUIElementPerformAction(element, kAXPressAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFStringRef ax_get_title(AXUIElementRef element) {
|
||||||
|
CFTypeRef title = NULL;
|
||||||
|
AXError error = AXUIElementCopyAttributeValue(element,
|
||||||
|
kAXTitleAttribute,
|
||||||
|
&title );
|
||||||
|
|
||||||
|
if (error != kAXErrorSuccess) return NULL;
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ax_select_menu_option(AXUIElementRef app, int id) {
|
||||||
|
AXUIElementRef menubars_ref = NULL;
|
||||||
|
CFArrayRef children_ref = NULL;
|
||||||
|
|
||||||
|
AXError error = AXUIElementCopyAttributeValue(app,
|
||||||
|
kAXMenuBarAttribute,
|
||||||
|
(CFTypeRef*)&menubars_ref);
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
error = AXUIElementCopyAttributeValue(menubars_ref,
|
||||||
|
kAXVisibleChildrenAttribute,
|
||||||
|
(CFTypeRef*)&children_ref );
|
||||||
|
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
uint32_t count = CFArrayGetCount(children_ref);
|
||||||
|
if (id < count) {
|
||||||
|
AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, id);
|
||||||
|
ax_perform_click(item);
|
||||||
|
}
|
||||||
|
if (children_ref) CFRelease(children_ref);
|
||||||
|
}
|
||||||
|
if (menubars_ref) CFRelease(menubars_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ax_print_menu_options(AXUIElementRef app) {
|
||||||
|
AXUIElementRef menubars_ref = NULL;
|
||||||
|
CFTypeRef menubar = NULL;
|
||||||
|
CFArrayRef children_ref = NULL;
|
||||||
|
|
||||||
|
AXError error = AXUIElementCopyAttributeValue(app,
|
||||||
|
kAXMenuBarAttribute,
|
||||||
|
(CFTypeRef*)&menubars_ref);
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
error = AXUIElementCopyAttributeValue(menubars_ref,
|
||||||
|
kAXVisibleChildrenAttribute,
|
||||||
|
(CFTypeRef*)&children_ref );
|
||||||
|
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
uint32_t count = CFArrayGetCount(children_ref);
|
||||||
|
|
||||||
|
for (int i = 1; i < count; i++) {
|
||||||
|
AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
|
||||||
|
CFTypeRef title = ax_get_title(item);
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
uint32_t buffer_len = 2*CFStringGetLength(title);
|
||||||
|
char buffer[2*CFStringGetLength(title)];
|
||||||
|
CFStringGetCString(title, buffer, buffer_len, kCFStringEncodingUTF8);
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
CFRelease(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (menubars_ref) CFRelease(menubars_ref);
|
||||||
|
if (children_ref) CFRelease(children_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AXUIElementRef ax_get_extra_menu_item(char* alias) {
|
||||||
|
pid_t pid = 0;
|
||||||
|
CGRect bounds = CGRectNull;
|
||||||
|
CFArrayRef window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll,
|
||||||
|
kCGNullWindowID );
|
||||||
|
char owner_buffer[256];
|
||||||
|
char name_buffer[256];
|
||||||
|
char buffer[512];
|
||||||
|
int window_count = CFArrayGetCount(window_list);
|
||||||
|
for (int i = 0; i < window_count; ++i) {
|
||||||
|
CFDictionaryRef dictionary = CFArrayGetValueAtIndex(window_list, i);
|
||||||
|
if (!dictionary) continue;
|
||||||
|
|
||||||
|
CFStringRef owner_ref = CFDictionaryGetValue(dictionary,
|
||||||
|
kCGWindowOwnerName);
|
||||||
|
|
||||||
|
CFNumberRef owner_pid_ref = CFDictionaryGetValue(dictionary,
|
||||||
|
kCGWindowOwnerPID);
|
||||||
|
|
||||||
|
CFStringRef name_ref = CFDictionaryGetValue(dictionary, kCGWindowName);
|
||||||
|
CFNumberRef layer_ref = CFDictionaryGetValue(dictionary, kCGWindowLayer);
|
||||||
|
CFDictionaryRef bounds_ref = CFDictionaryGetValue(dictionary,
|
||||||
|
kCGWindowBounds);
|
||||||
|
|
||||||
|
if (!name_ref || !owner_ref || !owner_pid_ref || !layer_ref || !bounds_ref)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
long long int layer = 0;
|
||||||
|
CFNumberGetValue(layer_ref, CFNumberGetType(layer_ref), &layer);
|
||||||
|
uint64_t owner_pid = 0;
|
||||||
|
CFNumberGetValue(owner_pid_ref,
|
||||||
|
CFNumberGetType(owner_pid_ref),
|
||||||
|
&owner_pid );
|
||||||
|
|
||||||
|
if (layer != 0x19) continue;
|
||||||
|
bounds = CGRectNull;
|
||||||
|
if (!CGRectMakeWithDictionaryRepresentation(bounds_ref, &bounds)) continue;
|
||||||
|
CFStringGetCString(owner_ref,
|
||||||
|
owner_buffer,
|
||||||
|
sizeof(owner_buffer),
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
|
||||||
|
CFStringGetCString(name_ref,
|
||||||
|
name_buffer,
|
||||||
|
sizeof(name_buffer),
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s,%s", owner_buffer, name_buffer);
|
||||||
|
|
||||||
|
if (strcmp(buffer, alias) == 0) {
|
||||||
|
pid = owner_pid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CFRelease(window_list);
|
||||||
|
if (!pid) return NULL;
|
||||||
|
|
||||||
|
AXUIElementRef app = AXUIElementCreateApplication(pid);
|
||||||
|
if (!app) return NULL;
|
||||||
|
AXUIElementRef result = NULL;
|
||||||
|
CFTypeRef extras = NULL;
|
||||||
|
CFArrayRef children_ref = NULL;
|
||||||
|
AXError error = AXUIElementCopyAttributeValue(app,
|
||||||
|
kAXExtrasMenuBarAttribute,
|
||||||
|
&extras );
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
error = AXUIElementCopyAttributeValue(extras,
|
||||||
|
kAXVisibleChildrenAttribute,
|
||||||
|
(CFTypeRef*)&children_ref );
|
||||||
|
|
||||||
|
if (error == kAXErrorSuccess) {
|
||||||
|
uint32_t count = CFArrayGetCount(children_ref);
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
AXUIElementRef item = CFArrayGetValueAtIndex(children_ref, i);
|
||||||
|
CFTypeRef position_ref = NULL;
|
||||||
|
CFTypeRef size_ref = NULL;
|
||||||
|
AXUIElementCopyAttributeValue(item, kAXPositionAttribute,
|
||||||
|
&position_ref );
|
||||||
|
AXUIElementCopyAttributeValue(item, kAXSizeAttribute,
|
||||||
|
&size_ref );
|
||||||
|
if (!position_ref || !size_ref) continue;
|
||||||
|
|
||||||
|
CGPoint position = CGPointZero;
|
||||||
|
AXValueGetValue(position_ref, kAXValueCGPointType, &position);
|
||||||
|
CGSize size = CGSizeZero;
|
||||||
|
AXValueGetValue(size_ref, kAXValueCGSizeType, &size);
|
||||||
|
CFRelease(position_ref);
|
||||||
|
CFRelease(size_ref);
|
||||||
|
// The offset is exactly 8 on macOS Sonoma...
|
||||||
|
// printf("%f %f\n", position.x, bounds.origin.x);
|
||||||
|
if (error == kAXErrorSuccess
|
||||||
|
&& fabs(position.x - bounds.origin.x) <= 10) {
|
||||||
|
result = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(app);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int SLSMainConnectionID();
|
||||||
|
extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
|
||||||
|
extern void SLSSetMenuBarVisibilityOverrideOnDisplay(int cid, int did, bool enabled);
|
||||||
|
extern void SLSSetMenuBarInsetAndAlpha(int cid, double u1, double u2, float alpha);
|
||||||
|
void ax_select_menu_extra(char* alias) {
|
||||||
|
AXUIElementRef item = ax_get_extra_menu_item(alias);
|
||||||
|
if (!item) return;
|
||||||
|
SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
|
||||||
|
SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, true);
|
||||||
|
SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 0.0);
|
||||||
|
ax_perform_click(item);
|
||||||
|
SLSSetMenuBarVisibilityOverrideOnDisplay(SLSMainConnectionID(), 0, false);
|
||||||
|
SLSSetMenuBarInsetAndAlpha(SLSMainConnectionID(), 0, 1, 1.0);
|
||||||
|
CFRelease(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void _SLPSGetFrontProcess(ProcessSerialNumber* psn);
|
||||||
|
extern void SLSGetConnectionIDForPSN(int cid, ProcessSerialNumber* psn, int* cid_out);
|
||||||
|
extern void SLSConnectionGetPID(int cid, pid_t* pid_out);
|
||||||
|
AXUIElementRef ax_get_front_app() {
|
||||||
|
ProcessSerialNumber psn;
|
||||||
|
_SLPSGetFrontProcess(&psn);
|
||||||
|
int target_cid;
|
||||||
|
SLSGetConnectionIDForPSN(SLSMainConnectionID(), &psn, &target_cid);
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
SLSConnectionGetPID(target_cid, &pid);
|
||||||
|
return AXUIElementCreateApplication(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char **argv) {
|
||||||
|
if (argc == 1) {
|
||||||
|
printf("Usage: %s [-l | -s id/alias ]\n", argv[0]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
ax_init();
|
||||||
|
if (strcmp(argv[1], "-l") == 0) {
|
||||||
|
AXUIElementRef app = ax_get_front_app();
|
||||||
|
if (!app) return 1;
|
||||||
|
ax_print_menu_options(app);
|
||||||
|
CFRelease(app);
|
||||||
|
} else if (argc == 3 && strcmp(argv[1], "-s") == 0) {
|
||||||
|
int id = 0;
|
||||||
|
if (sscanf(argv[2], "%d", &id) == 1) {
|
||||||
|
AXUIElementRef app = ax_get_front_app();
|
||||||
|
if (!app) return 1;
|
||||||
|
ax_select_menu_option(app, id);
|
||||||
|
CFRelease(app);
|
||||||
|
} else ax_select_menu_extra(argv[2]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
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 = "■■■■■■",
|
||||||
|
_80 = "■■■■□",
|
||||||
|
_60 = "■■■□□",
|
||||||
|
_40 = "■■□□□",
|
||||||
|
_20 = "■□□□□",
|
||||||
|
_0 = "◧□□□□",
|
||||||
|
charging = "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
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- Require the sketchybar module
|
||||||
|
sbar = require("sketchybar")
|
||||||
|
|
||||||
|
-- Set the bar name, if you are using another bar instance than sketchybar
|
||||||
|
-- sbar.set_bar_name("bottom_bar")
|
||||||
|
|
||||||
|
-- Bundle the entire initial configuration into a single message to sketchybar
|
||||||
|
sbar.begin_config()
|
||||||
|
require("bar")
|
||||||
|
require("default")
|
||||||
|
require("items")
|
||||||
|
sbar.end_config()
|
||||||
|
|
||||||
|
-- Run the event loop of the sketchybar module (without this there will be no
|
||||||
|
-- callback functions executed in the lua module)
|
||||||
|
sbar.event_loop()
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
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 = 12,
|
||||||
|
padding_left = 10,
|
||||||
|
},
|
||||||
|
label = { drawing = false },
|
||||||
|
background = {
|
||||||
|
color = colors.bg2,
|
||||||
|
border_color = colors.black,
|
||||||
|
border_width = 3
|
||||||
|
},
|
||||||
|
padding_left = 1,
|
||||||
|
padding_right = 1,
|
||||||
|
click_script = "$CONFIG_DIR/helpers/menus/bin/menus -s 0"
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Padding item required because of bracket
|
||||||
|
sbar.add("item", { width = 7 })
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
local settings = require("settings")
|
||||||
|
local colors = require("colors")
|
||||||
|
|
||||||
|
-- Padding item required because of bracket
|
||||||
|
sbar.add("item", { position = "right", width = settings.group_paddings })
|
||||||
|
|
||||||
|
local cal = sbar.add("item", {
|
||||||
|
icon = {
|
||||||
|
color = colors.white,
|
||||||
|
padding_left = 12,
|
||||||
|
font = {
|
||||||
|
style = settings.font.style_map["Bold"],
|
||||||
|
size = 14.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
color = colors.white,
|
||||||
|
padding_right = 16,
|
||||||
|
width = 70,
|
||||||
|
align = "right",
|
||||||
|
font = { family = settings.font.numbers },
|
||||||
|
},
|
||||||
|
position = "right",
|
||||||
|
update_freq = 30,
|
||||||
|
padding_left = 1,
|
||||||
|
padding_right = 1,
|
||||||
|
background = {
|
||||||
|
color = colors.bg2,
|
||||||
|
border_color = colors.black,
|
||||||
|
border_width = 3
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Double border for calendar using a single item bracket
|
||||||
|
sbar.add("bracket", { cal.name }, {
|
||||||
|
background = {
|
||||||
|
color = colors.transparent,
|
||||||
|
border_color = colors.grey,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
-- 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(" %A %d %B"), label = os.date(" %H:%M") })
|
||||||
|
end)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
require("items.apple")
|
||||||
|
require("items.menus")
|
||||||
|
require("items.spaces")
|
||||||
|
-- require("items.space_mode")
|
||||||
|
require("items.calendar")
|
||||||
|
require("items.widgets")
|
||||||
|
require("items.media")
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
local icons = require("icons")
|
||||||
|
local colors = require("colors")
|
||||||
|
|
||||||
|
local whitelist = { ["Spotify"] = true,
|
||||||
|
["Music"] = true };
|
||||||
|
|
||||||
|
local media_cover = sbar.add("item", {
|
||||||
|
position = "right",
|
||||||
|
background = {
|
||||||
|
image = {
|
||||||
|
string = "media.artwork",
|
||||||
|
scale = 0.85,
|
||||||
|
},
|
||||||
|
color = colors.transparent,
|
||||||
|
},
|
||||||
|
label = { drawing = false },
|
||||||
|
icon = { drawing = false },
|
||||||
|
drawing = false,
|
||||||
|
updates = true,
|
||||||
|
popup = {
|
||||||
|
align = "center",
|
||||||
|
horizontal = true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
local media_artist = sbar.add("item", {
|
||||||
|
position = "right",
|
||||||
|
drawing = false,
|
||||||
|
padding_left = 3,
|
||||||
|
padding_right = 0,
|
||||||
|
width = 0,
|
||||||
|
icon = { drawing = false },
|
||||||
|
label = {
|
||||||
|
width = 0,
|
||||||
|
font = { size = 9 },
|
||||||
|
color = colors.with_alpha(colors.white, 0.6),
|
||||||
|
max_chars = 18,
|
||||||
|
y_offset = 6,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
local media_title = sbar.add("item", {
|
||||||
|
position = "right",
|
||||||
|
drawing = false,
|
||||||
|
padding_left = 3,
|
||||||
|
padding_right = 0,
|
||||||
|
icon = { drawing = false },
|
||||||
|
label = {
|
||||||
|
font = { size = 11 },
|
||||||
|
width = 0,
|
||||||
|
max_chars = 16,
|
||||||
|
y_offset = -5,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
sbar.add("item", {
|
||||||
|
position = "popup." .. media_cover.name,
|
||||||
|
icon = { string = icons.media.back },
|
||||||
|
label = { drawing = false },
|
||||||
|
click_script = "nowplaying-cli previous",
|
||||||
|
})
|
||||||
|
sbar.add("item", {
|
||||||
|
position = "popup." .. media_cover.name,
|
||||||
|
icon = { string = icons.media.play_pause },
|
||||||
|
label = { drawing = false },
|
||||||
|
click_script = "nowplaying-cli togglePlayPause",
|
||||||
|
})
|
||||||
|
sbar.add("item", {
|
||||||
|
position = "popup." .. media_cover.name,
|
||||||
|
icon = { string = icons.media.forward },
|
||||||
|
label = { drawing = false },
|
||||||
|
click_script = "nowplaying-cli next",
|
||||||
|
})
|
||||||
|
|
||||||
|
local interrupt = 0
|
||||||
|
local function animate_detail(detail)
|
||||||
|
if (not detail) then interrupt = interrupt - 1 end
|
||||||
|
if interrupt > 0 and (not detail) then return end
|
||||||
|
|
||||||
|
sbar.animate("tanh", 30, function()
|
||||||
|
media_artist:set({ label = { width = detail and "dynamic" or 0 } })
|
||||||
|
media_title:set({ label = { width = detail and "dynamic" or 0 } })
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
media_cover:subscribe("media_change", function(env)
|
||||||
|
if whitelist[env.INFO.app] then
|
||||||
|
local drawing = (env.INFO.state == "playing")
|
||||||
|
media_artist:set({ drawing = drawing, label = env.INFO.artist, })
|
||||||
|
media_title:set({ drawing = drawing, label = env.INFO.title, })
|
||||||
|
media_cover:set({ drawing = drawing })
|
||||||
|
|
||||||
|
if drawing then
|
||||||
|
animate_detail(true)
|
||||||
|
interrupt = interrupt + 1
|
||||||
|
sbar.delay(5, animate_detail)
|
||||||
|
else
|
||||||
|
media_cover:set({ popup = { drawing = false } })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
media_cover:subscribe("mouse.entered", function(env)
|
||||||
|
interrupt = interrupt + 1
|
||||||
|
animate_detail(true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
media_cover:subscribe("mouse.exited", function(env)
|
||||||
|
animate_detail(false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
media_cover:subscribe("mouse.clicked", function(env)
|
||||||
|
media_cover:set({ popup = { drawing = "toggle" }})
|
||||||
|
end)
|
||||||
|
|
||||||
|
media_title:subscribe("mouse.exited.global", function(env)
|
||||||
|
media_cover:set({ popup = { drawing = false }})
|
||||||
|
end)
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
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 = "$CONFIG_DIR/helpers/menus/bin/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("$CONFIG_DIR/helpers/menus/bin/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
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
local colors = require("colors")
|
||||||
|
local icons = require("icons")
|
||||||
|
local settings = require("settings")
|
||||||
|
local app_icons = require("helpers.app_icons")
|
||||||
|
|
||||||
|
local spaces = {}
|
||||||
|
|
||||||
|
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 = 3,
|
||||||
|
border_color = colors.transparent,
|
||||||
|
},
|
||||||
|
popup = { background = { border_width = 5, border_color = colors.black } }
|
||||||
|
})
|
||||||
|
|
||||||
|
spaces[i] = space
|
||||||
|
|
||||||
|
-- Padding space
|
||||||
|
sbar.add("space", "space.padding." .. i, {
|
||||||
|
space = i,
|
||||||
|
script = "",
|
||||||
|
width = settings.group_paddings,
|
||||||
|
})
|
||||||
|
|
||||||
|
local space_popup = sbar.add("item", {
|
||||||
|
position = "popup." .. space.name,
|
||||||
|
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.red or colors.bg2
|
||||||
|
space:set({
|
||||||
|
icon = { highlight = selected, },
|
||||||
|
label = { highlight = selected },
|
||||||
|
background = { border_color = selected and colors.black or colors.bg2 }
|
||||||
|
})
|
||||||
|
space_bracket:set({
|
||||||
|
background = { border_color = selected and colors.black 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 -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,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
sbar.animate("tanh", 10, function()
|
||||||
|
spaces[env.INFO.space]:set({ label = icon_line })
|
||||||
|
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)
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
local icons = require("icons")
|
||||||
|
local colors = require("colors")
|
||||||
|
local settings = require("settings")
|
||||||
|
|
||||||
|
local battery = sbar.add("item", "widgets.battery", {
|
||||||
|
position = "right",
|
||||||
|
icon = {
|
||||||
|
font = {
|
||||||
|
style = settings.font.style_map["Regular"],
|
||||||
|
size = 12.0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label = { font = { family = settings.font.numbers } },
|
||||||
|
update_freq = 180,
|
||||||
|
popup = { align = "center" }
|
||||||
|
})
|
||||||
|
|
||||||
|
local remaining_time = sbar.add("item", {
|
||||||
|
position = "popup." .. battery.name,
|
||||||
|
icon = {
|
||||||
|
string = "Time remaining:",
|
||||||
|
width = 100,
|
||||||
|
align = "left"
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
string = "??:??h",
|
||||||
|
width = 100,
|
||||||
|
align = "right"
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
battery:subscribe({"routine", "power_source_change", "system_woke"}, function()
|
||||||
|
sbar.exec("pmset -g batt", function(batt_info)
|
||||||
|
local icon = "!"
|
||||||
|
local label = "?"
|
||||||
|
|
||||||
|
local found, _, charge = batt_info:find("(%d+)%%")
|
||||||
|
if found then
|
||||||
|
charge = tonumber(charge)
|
||||||
|
label = charge .. "%"
|
||||||
|
end
|
||||||
|
|
||||||
|
local color = colors.green
|
||||||
|
local charging, _, _ = batt_info:find("AC Power")
|
||||||
|
|
||||||
|
if charging then
|
||||||
|
icon = icons.battery.charging
|
||||||
|
else
|
||||||
|
if found and charge == 0 then
|
||||||
|
icon = icons.battery._0
|
||||||
|
color = colors.red
|
||||||
|
elseif found and charge <= 20 then
|
||||||
|
icon = icons.battery._20
|
||||||
|
color = colors.orange
|
||||||
|
elseif found and charge <= 40 then
|
||||||
|
icon = icons.battery._40
|
||||||
|
elseif found and charge <= 60 then
|
||||||
|
icon = icons.battery._60
|
||||||
|
elseif found and charge <= 80 then
|
||||||
|
icon = icons.battery._80
|
||||||
|
elseif found and charge <= 100 then
|
||||||
|
icon = icons.battery._100
|
||||||
|
else
|
||||||
|
icon = icons.battery._0
|
||||||
|
color = colors.red
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local lead = ""
|
||||||
|
if found and charge < 10 then
|
||||||
|
lead = "0"
|
||||||
|
end
|
||||||
|
|
||||||
|
battery:set({
|
||||||
|
icon = {
|
||||||
|
string = icon,
|
||||||
|
color = color
|
||||||
|
},
|
||||||
|
label = { string = lead .. label },
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
battery:subscribe("mouse.clicked", function(env)
|
||||||
|
local drawing = battery:query().popup.drawing
|
||||||
|
battery:set( { popup = { drawing = "toggle" } })
|
||||||
|
|
||||||
|
if drawing == "off" then
|
||||||
|
sbar.exec("pmset -g batt", function(batt_info)
|
||||||
|
local found, _, remaining = batt_info:find(" (%d+:%d+) remaining")
|
||||||
|
local label = found and remaining .. "h" or "No estimate"
|
||||||
|
remaining_time:set( { label = label })
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
sbar.add("bracket", "widgets.battery.bracket", { battery.name }, {
|
||||||
|
background = { color = colors.bg1 }
|
||||||
|
})
|
||||||
|
|
||||||
|
sbar.add("item", "widgets.battery.padding", {
|
||||||
|
position = "right",
|
||||||
|
width = settings.group_paddings
|
||||||
|
})
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
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 cpu_load >/dev/null; $CONFIG_DIR/helpers/event_providers/cpu_load/bin/cpu_load cpu_update 2.0")
|
||||||
|
|
||||||
|
local cpu = sbar.add("graph", "widgets.cpu" , 62, {
|
||||||
|
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
|
||||||
|
})
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
require("items.widgets.battery")
|
||||||
|
require("items.widgets.volume")
|
||||||
|
require("items.widgets.wifi")
|
||||||
|
require("items.widgets.cpu")
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
local colors = require("colors")
|
||||||
|
local icons = require("icons")
|
||||||
|
local settings = require("settings")
|
||||||
|
|
||||||
|
local popup_width = 250
|
||||||
|
|
||||||
|
local volume_percent = sbar.add("item", "widgets.volume1", {
|
||||||
|
position = "right",
|
||||||
|
icon = { drawing = false },
|
||||||
|
label = {
|
||||||
|
string = "??%",
|
||||||
|
padding_left = -1,
|
||||||
|
font = { family = settings.font.numbers }
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
local volume_icon = sbar.add("item", "widgets.volume2", {
|
||||||
|
position = "right",
|
||||||
|
padding_right = -1,
|
||||||
|
icon = {
|
||||||
|
string = icons.volume._100,
|
||||||
|
width = 0,
|
||||||
|
align = "left",
|
||||||
|
color = colors.grey,
|
||||||
|
font = {
|
||||||
|
style = settings.font.style_map["Regular"],
|
||||||
|
size = 14.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
label = {
|
||||||
|
width = 25,
|
||||||
|
align = "left",
|
||||||
|
font = {
|
||||||
|
style = settings.font.style_map["Regular"],
|
||||||
|
size = 14.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
local volume_bracket = sbar.add("bracket", "widgets.volume.bracket", {
|
||||||
|
volume_icon.name,
|
||||||
|
volume_percent.name
|
||||||
|
}, {
|
||||||
|
background = { color = colors.bg1 },
|
||||||
|
popup = { align = "center" }
|
||||||
|
})
|
||||||
|
|
||||||
|
sbar.add("item", "widgets.volume.padding", {
|
||||||
|
position = "right",
|
||||||
|
width = settings.group_paddings
|
||||||
|
})
|
||||||
|
|
||||||
|
local volume_slider = sbar.add("slider", popup_width, {
|
||||||
|
position = "popup." .. volume_bracket.name,
|
||||||
|
slider = {
|
||||||
|
highlight_color = colors.blue,
|
||||||
|
background = {
|
||||||
|
height = 6,
|
||||||
|
corner_radius = 3,
|
||||||
|
color = colors.bg2,
|
||||||
|
},
|
||||||
|
knob= {
|
||||||
|
string = "",
|
||||||
|
drawing = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
background = { color = colors.bg1, height = 2, y_offset = -20 },
|
||||||
|
click_script = 'osascript -e "set volume output volume $PERCENTAGE"'
|
||||||
|
})
|
||||||
|
|
||||||
|
volume_percent: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
|
||||||
|
|
||||||
|
local lead = ""
|
||||||
|
if volume < 10 then
|
||||||
|
lead = "0"
|
||||||
|
end
|
||||||
|
|
||||||
|
volume_icon:set({ label = icon })
|
||||||
|
volume_percent:set({ label = lead .. volume .. "%" })
|
||||||
|
volume_slider:set({ slider = { percentage = volume } })
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function volume_collapse_details()
|
||||||
|
local drawing = volume_bracket:query().popup.drawing == "on"
|
||||||
|
if not drawing then return end
|
||||||
|
volume_bracket:set({ popup = { drawing = false } })
|
||||||
|
sbar.remove('/volume.device\\.*/')
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_audio_device = "None"
|
||||||
|
local function volume_toggle_details(env)
|
||||||
|
if env.BUTTON == "right" then
|
||||||
|
sbar.exec("open /System/Library/PreferencePanes/Sound.prefpane")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local should_draw = volume_bracket:query().popup.drawing == "off"
|
||||||
|
if should_draw then
|
||||||
|
volume_bracket:set({ popup = { drawing = true } })
|
||||||
|
sbar.exec("SwitchAudioSource -t output -c", function(result)
|
||||||
|
current_audio_device = result:sub(1, -2)
|
||||||
|
sbar.exec("SwitchAudioSource -a -t output", function(available)
|
||||||
|
current = current_audio_device
|
||||||
|
local color = colors.grey
|
||||||
|
local counter = 0
|
||||||
|
|
||||||
|
for device in string.gmatch(available, '[^\r\n]+') do
|
||||||
|
local color = colors.grey
|
||||||
|
if current == device then
|
||||||
|
color = colors.white
|
||||||
|
end
|
||||||
|
sbar.add("item", "volume.device." .. counter, {
|
||||||
|
position = "popup." .. volume_bracket.name,
|
||||||
|
width = popup_width,
|
||||||
|
align = "center",
|
||||||
|
label = { string = device, color = color },
|
||||||
|
click_script = 'SwitchAudioSource -s "' .. device .. '" && sketchybar --set /volume.device\\.*/ label.color=' .. colors.grey .. ' --set $NAME label.color=' .. colors.white
|
||||||
|
|
||||||
|
})
|
||||||
|
counter = counter + 1
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
volume_collapse_details()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function volume_scroll(env)
|
||||||
|
local delta = env.SCROLL_DELTA
|
||||||
|
sbar.exec('osascript -e "set volume output volume (output volume of (get volume settings) + ' .. delta .. ')"')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- volume_icon:subscribe("mouse.clicked", volume_toggle_details)
|
||||||
|
-- volume_icon:subscribe("mouse.scrolled", volume_scroll)
|
||||||
|
-- volume_percent:subscribe("mouse.clicked", volume_toggle_details)
|
||||||
|
-- volume_percent:subscribe("mouse.exited.global", volume_collapse_details)
|
||||||
|
-- volume_percent:subscribe("mouse.scrolled", volume_scroll)
|
||||||
|
|
||||||
@@ -0,0 +1,245 @@
|
|||||||
|
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 network_load >/dev/null; $CONFIG_DIR/helpers/event_providers/network_load/bin/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.mono,
|
||||||
|
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.mono,
|
||||||
|
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 = true, string = [[HERE]] },
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Background around the item
|
||||||
|
local wifi_bracket = sbar.add("bracket", "widgets.wifi.bracket", {
|
||||||
|
wifi.name,
|
||||||
|
wifi_up.name,
|
||||||
|
wifi_down.name
|
||||||
|
}, {
|
||||||
|
background = { color = colors.bg1 },
|
||||||
|
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.grey,
|
||||||
|
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.grey or colors.red
|
||||||
|
local down_color = (env.download == "000 Bps") and colors.grey 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.white or colors.red,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if connected then
|
||||||
|
sbar.exec("ipconfig getsummary en0 | awk -F ' SSID : ' '/ SSID : / {print $2}'", function(ssid_result)
|
||||||
|
wifi:set({
|
||||||
|
label = { string = ssid_result }
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
wifi:set({
|
||||||
|
label = { string = "Disconnected" }
|
||||||
|
})
|
||||||
|
end
|
||||||
|
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)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
return {
|
||||||
|
paddings = 3,
|
||||||
|
group_paddings = 5,
|
||||||
|
|
||||||
|
icons = "sf-symbols", -- alternatively available: NerdFont
|
||||||
|
|
||||||
|
-- This is a font configuration for SF Pro and SF Mono (installed manually)
|
||||||
|
font = require("helpers.default_font"),
|
||||||
|
|
||||||
|
-- Alternatively, this is a font config for JetBrainsMono Nerd Font
|
||||||
|
-- font = {
|
||||||
|
-- text = "JetBrainsMono Nerd Font", -- Used for text
|
||||||
|
-- numbers = "JetBrainsMono Nerd Font", -- Used for numbers
|
||||||
|
-- style_map = {
|
||||||
|
-- ["Regular"] = "Regular",
|
||||||
|
-- ["Semibold"] = "Medium",
|
||||||
|
-- ["Bold"] = "SemiBold",
|
||||||
|
-- ["Heavy"] = "Bold",
|
||||||
|
-- ["Black"] = "ExtraBold",
|
||||||
|
-- },
|
||||||
|
-- },
|
||||||
|
}
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env lua
|
||||||
|
|
||||||
|
-- Load the sketchybar-package and prepare the helper binaries
|
||||||
|
require("helpers")
|
||||||
|
require("init")
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# change window focus
|
||||||
|
cmd - j : yabai -m window --focus south
|
||||||
|
cmd - k : yabai -m window --focus north
|
||||||
|
cmd - h : yabai -m window --focus west
|
||||||
|
cmd - l : yabai -m window --focus east
|
||||||
|
|
||||||
|
# modify layout
|
||||||
|
shift + cmd - r : yabai -m space --rotate 270
|
||||||
|
shift + cmd - y : yabai -m space --mirror y-axis
|
||||||
|
shift + cmd - x : yabai -m space --mirror x-axis
|
||||||
|
shift + cmd - t : yabai -m window --toggle float --grid 4:4:1:1:2:2
|
||||||
|
|
||||||
|
# maximize a window
|
||||||
|
shift + cmd - f : yabai -m window --toggle zoom-fullscreen
|
||||||
|
|
||||||
|
# balance windows
|
||||||
|
shift + cmd - b : yabai -m space --balance
|
||||||
@@ -13,9 +13,10 @@ end
|
|||||||
|
|
||||||
-- For example, changing the color scheme:
|
-- For example, changing the color scheme:
|
||||||
config.color_scheme = "Catppuccin Mocha"
|
config.color_scheme = "Catppuccin Mocha"
|
||||||
config.font_size = 11
|
config.font_size = 14
|
||||||
|
|
||||||
config.window_decorations = "TITLE | RESIZE"
|
-- config.window_decorations = "TITLE | RESIZE"
|
||||||
|
config.window_decorations = "RESIZE"
|
||||||
|
|
||||||
-- tmux
|
-- tmux
|
||||||
config.keys = {
|
config.keys = {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
yabai -m config layout bsp
|
||||||
|
|
||||||
|
yabai -m config window_placement second_child
|
||||||
|
|
||||||
|
# padding
|
||||||
|
yabai -m config top_padding 16
|
||||||
|
yabai -m config bottom_padding 16
|
||||||
|
yabai -m config left_padding 16
|
||||||
|
yabai -m config right_padding 16
|
||||||
|
yabai -m config window_gap 18
|
||||||
|
|
||||||
|
# mouse settings
|
||||||
|
#yabai -m config focus_follows_mouse autoraise
|
||||||
|
yabai -m config focus_follows_mouse on
|
||||||
|
|
||||||
|
yabai -m config mouse_modifier cmd
|
||||||
|
yabai -m config mouse_action1 move
|
||||||
|
yabai -m mouse_action2 resize
|
||||||
|
|
||||||
|
yabai -m mouse_drop_action swap
|
||||||
|
|
||||||
|
# ignore apps
|
||||||
|
yabai -m rule --add app="^System Settings$" manage=off
|
||||||
|
yabai -m rule --add app="^Calculator$" manage=off
|
||||||
|
yabai -m rule --add app="^love$" manage=off
|
||||||
|
yabai -m rule --add app="^Messages$" manage=off
|
||||||
|
|
||||||
|
# include apps
|
||||||
|
yabai -m rule --add app="^Unity$" manage=on
|
||||||
|
|
||||||
|
# yabai -m config external_bar all:8:0
|
||||||
|
|
||||||
|
borders active_color=0xffc6a0f6 inactive_color=0xff24273a width=10.0 blacklist="iPhone Mirroring"&
|
||||||
Reference in New Issue
Block a user