diff --git a/README.html b/README.html
new file mode 100644
index 0000000..4323759
--- /dev/null
+++ b/README.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+ README
+
+
+
+
+nix
+my nix configuration
+
+
diff --git a/config/cp/template.py b/config/cp/template.py
new file mode 100644
index 0000000..58aed8b
--- /dev/null
+++ b/config/cp/template.py
@@ -0,0 +1,6 @@
+def main() -> None:
+ <++>
+
+
+if __name__ == '__main__':
+ main()
diff --git a/config/cp/template_multi.cc b/config/cp/template_multi.cc
new file mode 100644
index 0000000..fa04a3e
--- /dev/null
+++ b/config/cp/template_multi.cc
@@ -0,0 +1,58 @@
+#include // {{{
+
+#include
+#ifdef __cpp_lib_ranges_enumerate
+#include
+namespace rv = std::views;
+namespace rs = std::ranges;
+#endif
+
+#pragma GCC optimize("O2,unroll-loops")
+#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
+
+using namespace std;
+
+using i32 = int32_t;
+using u32 = uint32_t;
+using i64 = int64_t;
+using u64 = uint64_t;
+using f64 = double;
+using f128 = long double;
+
+#if __cplusplus >= 202002L
+template
+constexpr T MIN = std::numeric_limits::min();
+
+template
+constexpr T MAX = std::numeric_limits::max();
+#endif
+
+#ifdef LOCAL
+#define db(...) std::print(__VA_ARGS__)
+#define dbln(...) std::println(__VA_ARGS__)
+#else
+#define db(...)
+#define dbln(...)
+#endif
+// }}}
+
+void solve() {
+ <++>
+}
+
+int main() { // {{{
+ std::cin.exceptions(std::cin.failbit);
+#ifdef LOCAL
+ std::cerr.rdbuf(std::cout.rdbuf());
+ std::cout.setf(std::ios::unitbuf);
+ std::cerr.setf(std::ios::unitbuf);
+#else
+ std::cin.tie(nullptr)->sync_with_stdio(false);
+#endif
+ u32 tc = 1;
+ std::cin >> tc;
+ for (u32 t = 0; t < tc; ++t) {
+ solve();
+ }
+ return 0;
+} // }}}
diff --git a/config/cp/template_single.cc b/config/cp/template_single.cc
new file mode 100644
index 0000000..4d1b572
--- /dev/null
+++ b/config/cp/template_single.cc
@@ -0,0 +1,54 @@
+#include // {{{
+
+#include
+#ifdef __cpp_lib_ranges_enumerate
+#include
+namespace rv = std::views;
+namespace rs = std::ranges;
+#endif
+
+#pragma GCC optimize("O2,unroll-loops")
+#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
+
+using namespace std;
+
+using i32 = int32_t;
+using u32 = uint32_t;
+using i64 = int64_t;
+using u64 = uint64_t;
+using f64 = double;
+using f128 = long double;
+
+#if __cplusplus >= 202002L
+template
+constexpr T MIN = std::numeric_limits::min();
+
+template
+constexpr T MAX = std::numeric_limits::max();
+#endif
+
+#ifdef LOCAL
+#define db(...) std::print(__VA_ARGS__)
+#define dbln(...) std::println(__VA_ARGS__)
+#else
+#define db(...)
+#define dbln(...)
+#endif
+// }}}
+
+void solve() {
+ <++>
+}
+
+int main() { // {{{
+ std::cin.exceptions(std::cin.failbit);
+#ifdef LOCAL
+ std::cerr.rdbuf(std::cout.rdbuf());
+ std::cout.setf(std::ios::unitbuf);
+ std::cerr.setf(std::ios::unitbuf);
+#else
+ std::cin.tie(nullptr)->sync_with_stdio(false);
+#endif
+ solve();
+ return 0;
+} // }}}
diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf
index 221c521..6d53be1 100644
--- a/config/hypr/hyprland.conf
+++ b/config/hypr/hyprland.conf
@@ -128,7 +128,7 @@ bind = ALT SHIFT, E, exec, hypr spawnfocus --ws 8 element-desktop
bind = , XF86Tools, submap, scripts
submap = scripts
-bind = , A, exec, hyprctl dispatch submap reset; ctl audio out
+bind = , A, exec, hyprctl dispatch submap reset; ctl audio sink
bind = , C, exec, hyprctl dispatch submap reset; sh -lc 'cliphist list | fuzzel --width 65 --dmenu --prompt="copy: " | cliphist decode | wl-copy'
bind = , I, exec, hyprctl dispatch submap reset; ctl idle
bind = , K, exec, hyprctl dispatch submap reset; ctl keyboard next
@@ -192,7 +192,5 @@ windowrule = match:class ^(xdg-desktop-portal-kde)$, size monitor_w * 0.5 monito
windowrule = match:class ^(xdg-desktop-portal-hyprland)$, float on
windowrule = match:class ^(xdg-desktop-portal-hyprland)$, size monitor_w * 0.5 monitor_h * 0.6
-windowrule = match:class ^(org.pulseaudio.pavucontrol)$, float on
-windowrule = match:class ^(org.pulseaudio.pavucontrol)$, size 600 450
windowrule = match:class ^([Ss]ioyek)$, tile on
diff --git a/config/nvim/after/ftplugin/markdown.lua b/config/nvim/after/ftplugin/markdown.lua
index c89492d..570d861 100644
--- a/config/nvim/after/ftplugin/markdown.lua
+++ b/config/nvim/after/ftplugin/markdown.lua
@@ -1,33 +1,2 @@
vim.o.conceallevel = 1
vim.o.textwidth = 80
-
-local buf = vim.api.nvim_get_current_buf()
-local opened = false
-
-vim.api.nvim_create_autocmd('User', {
- pattern = 'RenderCompileSuccess',
- callback = function(args)
- if args.data.bufnr ~= buf then
- return
- end
- local html = args.data.output
- if not opened and html and html ~= '' then
- opened = true
- vim.system({ 'xdg-open', html })
- end
- end,
-})
-
-vim.api.nvim_create_autocmd('BufWritePost', {
- buffer = buf,
- callback = function()
- local ok, render = pcall(require, 'render')
- if ok then
- render.compile(buf)
- end
- end,
-})
-
-vim.keymap.set('n', 't', function()
- require('render').compile(buf)
-end, { buffer = true })
diff --git a/config/nvim/after/ftplugin/typst.lua b/config/nvim/after/ftplugin/typst.lua
deleted file mode 100644
index 24f54e5..0000000
--- a/config/nvim/after/ftplugin/typst.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-vim.keymap.set('n', 't', function()
- require('render').compile()
- vim.api.nvim_create_autocmd('User', {
- pattern = 'RenderCompileSuccess',
- once = true,
- callback = function(args)
- local pdf = args.data.output
- if not pdf or pdf == '' then
- return
- end
- if vim.fn.executable('sioyek') ~= 1 then
- return vim.notify('sioyek not found', vim.log.levels.ERROR)
- end
- vim.system({ 'sioyek', '--new-instance', pdf })
- end,
- })
-end, { buffer = true })
diff --git a/config/nvim/lua/plugins/dev.lua b/config/nvim/lua/plugins/dev.lua
index 796e0ad..375cf6f 100644
--- a/config/nvim/lua/plugins/dev.lua
+++ b/config/nvim/lua/plugins/dev.lua
@@ -1,12 +1,12 @@
local dev_plugins = {
'midnight.nvim',
'live-server.nvim',
- 'nonicons.nvim',
'canola.nvim',
'pending.nvim',
'cp.nvim',
'diffs.nvim',
- 'render.nvim',
+ 'preview.nvim',
+ 'fzf-lua',
}
local opt_dir = vim.fn.stdpath('data') .. '/site/pack/dev/opt/'
@@ -76,116 +76,6 @@ AlignAfterOpenBracket: Align
BinPackArguments: false
BinPackParameters: false]]
-local cpp_base = [[#include // {{{
-
-#include
-#ifdef __cpp_lib_ranges_enumerate
-#include
-namespace rv = std::views;
-namespace rs = std::ranges;
-#endif
-
-#pragma GCC optimize("O2,unroll-loops")
-#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
-
-using namespace std;
-
-using i32 = int32_t;
-using u32 = uint32_t;
-using i64 = int64_t;
-using u64 = uint64_t;
-using f64 = double;
-using f128 = long double;
-
-#if __cplusplus >= 202002L
-template
-constexpr T MIN = std::numeric_limits::min();
-
-template
-constexpr T MAX = std::numeric_limits::max();
-#endif
-
-#ifdef LOCAL
-#define db(...) std::print(__VA_ARGS__)
-#define dbln(...) std::println(__VA_ARGS__)
-#else
-#define db(...)
-#define dbln(...)
-#endif
-// }}}
-
-void solve() {
- <++>
-}
-
-int main() { // {{{
- std::cin.exceptions(std::cin.failbit);
-#ifdef LOCAL
- std::cerr.rdbuf(std::cout.rdbuf());
- std::cout.setf(std::ios::unitbuf);
- std::cerr.setf(std::ios::unitbuf);
-#else
- std::cin.tie(nullptr)->sync_with_stdio(false);
-#endif
-]]
-
-local cpp_single = cpp_base .. [[ solve();
- return 0;
-} // }}}]]
-
-local cpp_multi = cpp_base
- .. [[ u32 tc = 1;
- std::cin >> tc;
- for (u32 t = 0; t < tc; ++t) {
- solve();
- }
- return 0;
-} // }}}]]
-
-local templates = {
- cpp = {
- default = cpp_multi,
- codeforces = cpp_multi,
- atcoder = cpp_single,
- cses = cpp_single,
- },
- python = {
- default = [[def main() -> None:
- <++>
-
-
-if __name__ == '__main__':
- main()]],
- },
-}
-
-local function insert_template(buf, lang, platform)
- local lang_templates = templates[lang]
- if not lang_templates then
- return false
- end
-
- local template = lang_templates[platform] or lang_templates.default
- if not template then
- return false
- end
-
- local lines = vim.split(template, '\n')
- vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
-
- for lnum, line in ipairs(lines) do
- local col = line:find('<++>', 1, true)
- if col then
- local new_line = line:sub(1, col - 1) .. line:sub(col + 4)
- vim.api.nvim_buf_set_lines(buf, lnum - 1, lnum, false, { new_line })
- vim.api.nvim_win_set_cursor(0, { lnum, col - 1 })
- break
- end
- end
-
- return true
-end
-
return {
{
'barrettruth/midnight.nvim',
@@ -196,7 +86,7 @@ return {
},
{
'barrettruth/live-server.nvim',
- enabled = false,
+ enabled = true,
before = function()
vim.g.live_server = {
debug = false,
@@ -204,10 +94,6 @@ return {
end,
keys = { { 'l', 'LiveServerToggle' } },
},
- {
- 'barrettruth/nonicons.nvim',
- enabled = true,
- },
{
'barrettruth/canola.nvim',
enabled = true,
@@ -281,7 +167,7 @@ return {
before = function()
vim.g.pending = { debug = true }
end,
- keys = { { 'p', 'Pending' } },
+ keys = { { 'P', 'Pending' } },
},
{
'barrettruth/cp.nvim',
@@ -301,6 +187,7 @@ return {
languages = {
cpp = {
extension = 'cc',
+ template = '~/.config/nix/config/cp/template_multi.cc',
commands = {
build = {
'g++',
@@ -338,6 +225,7 @@ return {
},
python = {
extension = 'py',
+ template = '~/.config/nix/config/cp/template.py',
commands = {
run = { 'python', '{source}' },
debug = { 'python', '{source}' },
@@ -352,8 +240,15 @@ return {
atcoder = {
enabled_languages = { 'cpp', 'python' },
default_language = 'cpp',
+ overrides = {
+ cpp = { template = '~/.config/nix/config/cp/template_single.cc' },
+ },
+ },
+ cses = {
+ overrides = {
+ cpp = { template = '~/.config/nix/config/cp/template_single.cc' },
+ },
},
- cses = {},
},
ui = {
picker = 'fzf-lua',
@@ -372,7 +267,7 @@ return {
before_debug = function(_)
require('config.lsp').format()
end,
- setup_code = function(state)
+ setup_code = function(_)
vim.opt_local.winbar = ''
vim.opt_local.foldlevel = 0
vim.opt_local.foldmethod = 'marker'
@@ -381,18 +276,18 @@ return {
vim.diagnostic.enable(false)
local buf = vim.api.nvim_get_current_buf()
- local lines =
- vim.api.nvim_buf_get_lines(buf, 0, 1, true)
- if #lines > 1 or (#lines == 1 and lines[1] ~= '') then
- return
+ local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
+ for lnum, line in ipairs(lines) do
+ local col = line:find('<++>', 1, true)
+ if col then
+ local new_line = line:sub(1, col - 1) .. line:sub(col + 4)
+ vim.api.nvim_buf_set_lines(buf, lnum - 1, lnum, false, { new_line })
+ vim.api.nvim_win_set_cursor(0, { lnum, col - 1 })
+ break
+ end
end
- local lang = state.get_language()
- local platform = state.get_platform()
- insert_template(buf, lang, platform)
-
- local clang_format_path = vim.fn.getcwd()
- .. '/.clang-format'
+ local clang_format_path = vim.fn.getcwd() .. '/.clang-format'
if vim.fn.filereadable(clang_format_path) == 0 then
vim.fn.writefile(
vim.split(clang_format, '\n'),
@@ -408,55 +303,20 @@ return {
end,
},
{
- 'barrettruth/render.nvim',
+ 'barrettruth/preview.nvim',
ft = { 'typst', 'tex', 'markdown' },
- before = function()
- vim.g.render = {
- providers = {
- typst = {
- cmd = { 'typst', 'compile' },
- args = function(ctx)
- return { ctx.file }
- end,
- output = function(ctx)
- return ctx.file:gsub('%.typ$', '.pdf')
- end,
- },
- latexmk = {
- cmd = { 'latexmk' },
- args = function(ctx)
- return { '-pdf', '-interaction=nonstopmode', ctx.file }
- end,
- output = function(ctx)
- return ctx.file:gsub('%.tex$', '.pdf')
- end,
- clean = { 'latexmk', '-c' },
- },
- pandoc = {
- cmd = { 'pandoc' },
- args = function(ctx)
- local output = ctx.file:gsub('%.md$', '.html')
- return { ctx.file, '-s', '--embed-resources', '-o', output }
- end,
- output = function(ctx)
- return ctx.file:gsub('%.md$', '.html')
- end,
- clean = function(ctx)
- return { 'rm', '-f', ctx.file:gsub('%.md$', '.html') }
- end,
- },
- },
- providers_by_ft = {
- typst = 'typst',
- tex = 'latexmk',
- markdown = 'pandoc',
- },
- }
+ after = function()
+ local presets = require('preview.presets')
+ require('preview').setup({
+ 'github',
+ typst = vim.tbl_deep_extend('force', presets.typst, {
+ open = { 'sioyek', '--new-instance' },
+ }),
+ tex = vim.tbl_deep_extend('force', presets.latex, {
+ open = { 'sioyek', '--new-instance' },
+ }),
+ })
end,
- keys = {
- { 'rr', 'Render compile' },
- { 'rs', 'Render stop' },
- { 'rc', 'Render clean' },
- },
+ keys = { { 'p', 'Preview toggle' } },
},
}
diff --git a/config/nvim/lua/plugins/fzf.lua b/config/nvim/lua/plugins/fzf.lua
index 05c25d9..2ed043a 100644
--- a/config/nvim/lua/plugins/fzf.lua
+++ b/config/nvim/lua/plugins/fzf.lua
@@ -1,12 +1,8 @@
-vim.pack.add({
- 'https://github.com/ibhagwan/fzf-lua',
-}, { load = function() end })
-
return {
- 'ibhagwan/fzf-lua',
+ 'barrettruth/fzf-lua',
after = function()
local fzf = require('fzf-lua')
- local has_icons = pcall(require, 'nonicons')
+ local has_nonicons = pcall(require, 'nonicons')
local opts = {
file_icon_padding = ' ',
@@ -85,8 +81,8 @@ return {
},
}
- opts.files.file_icons = has_icons
- opts.grep.file_icons = has_icons
+ opts.files.file_icons = has_nonicons and 'nonicons' or false
+ opts.grep.file_icons = has_nonicons and 'nonicons' or false
opts.grep.rg_opts =
fzf.defaults.grep.rg_opts:gsub('%-e$', "--glob='!.git/' -e")
diff --git a/config/nvim/lua/plugins/git.lua b/config/nvim/lua/plugins/git.lua
index b6a95cd..7423dd5 100644
--- a/config/nvim/lua/plugins/git.lua
+++ b/config/nvim/lua/plugins/git.lua
@@ -242,25 +242,4 @@ return {
}
end,
},
- {
- 'lewis6991/gitsigns.nvim',
- enabled = false,
- event = 'DeferredUIEnter',
- after = function()
- require('gitsigns').setup({
- signs = {
- add = { text = '│' },
- change = { text = '│' },
- delete = { text = '_' },
- topdelete = { text = '‾' },
- changedelete = { text = '│' },
- },
- })
- end,
- keys = {
- { ']g', 'Gitsigns next_hunk' },
- { '[g', 'Gitsigns prev_hunk' },
- { 'gB', 'Gitsigns toggle_current_line_blame' },
- },
- },
}
diff --git a/config/nvim/nvim-pack-lock.json b/config/nvim/nvim-pack-lock.json
index 5ee9692..ed1bee4 100644
--- a/config/nvim/nvim-pack-lock.json
+++ b/config/nvim/nvim-pack-lock.json
@@ -32,10 +32,6 @@
"rev": "f2634758455cfa52a8acea6f142dcd6271a1bf57",
"src": "https://github.com/monaqa/dial.nvim"
},
- "fzf-lua": {
- "rev": "d637241b34f2cb012309baebb2e35e440a946d8b",
- "src": "https://github.com/ibhagwan/fzf-lua"
- },
"gitsigns.nvim": {
"rev": "9f3c6dd7868bcc116e9c1c1929ce063b978fa519",
"src": "https://github.com/lewis6991/gitsigns.nvim"
diff --git a/home/modules/ui.nix b/home/modules/ui.nix
index 170fc0e..2b4f659 100644
--- a/home/modules/ui.nix
+++ b/home/modules/ui.nix
@@ -17,6 +17,8 @@ let
#workspaces button:hover { background: ${palette.bgAlt}; }
#window { color: ${palette.fgAlt}; }
tooltip { background: ${palette.bgAlt}; color: ${palette.fg}; border: 1px solid ${palette.border}; }
+ #pulseaudio-slider trough { background: ${palette.bgAlt}; }
+ #pulseaudio-slider highlight { background: ${palette.accent}; }
'';
hexToFuzzel = hex: "${builtins.substring 1 6 hex}ff";
@@ -91,7 +93,6 @@ in
glib.bin
gsettings-desktop-schemas
(python3.withPackages (ps: [ ps.pillow ]))
- pavucontrol
];
programs.waybar = {
@@ -158,7 +159,7 @@ in
return-type = "json";
interval = 1;
signal = 2;
- on-click = "pgrep pavucontrol && pkill pavucontrol || pavucontrol --tab=4";
+ on-click = "ctl audio source";
on-click-middle = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle";
on-scroll-up = "wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%+ --limit 1.0";
on-scroll-down = "wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%-";
@@ -177,7 +178,8 @@ in
signal = 1;
tooltip = true;
tooltip-format = "Volume: {volume}%\nOutput: {desc}";
- on-click = "pgrep pavucontrol && pkill pavucontrol || pavucontrol --tab=3";
+ on-click = "ctl audio sink";
+ on-click-right = "pgrep -f 'waybar.*slider' && pkill -f 'waybar.*slider' || (waybar -c ${config.xdg.configHome}/waybar/slider.json &)";
on-click-middle = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
on-scroll-up = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ --limit 1.0";
on-scroll-down = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-";
@@ -289,6 +291,22 @@ in
#custom-power {
padding: 0 16px 0 10px;
}
+
+ #pulseaudio-slider {
+ padding: 0 10px;
+ }
+
+ #pulseaudio-slider trough {
+ min-width: 150px;
+ min-height: 4px;
+ }
+
+ #pulseaudio-slider slider {
+ min-width: 0;
+ min-height: 0;
+ background: transparent;
+ border: none;
+ }
'';
};
@@ -326,6 +344,20 @@ in
xdg.configFile."waybar/themes/midnight.css".text = mkWaybarTheme config.palettes.midnight;
xdg.configFile."waybar/themes/daylight.css".text = mkWaybarTheme config.palettes.daylight;
+ xdg.configFile."waybar/slider.json".text = builtins.toJSON {
+ position = "top";
+ layer = "top";
+ height = 38;
+ "margin-top" = 38;
+ exclusive = false;
+ "modules-right" = [ "pulseaudio/slider" ];
+ "pulseaudio/slider" = {
+ min = 0;
+ max = 100;
+ orientation = "horizontal";
+ };
+ };
+
xdg.configFile."fuzzel/fuzzel.ini".text = ''
include=${config.xdg.configHome}/fuzzel/themes/theme.ini
diff --git a/scripts/ctl b/scripts/ctl
index d907b72..cea9267 100755
--- a/scripts/ctl
+++ b/scripts/ctl
@@ -42,7 +42,19 @@ keyboard)
;;
pick)
require fuzzel
- choice=$(printf 'QWERTY\nDvorak\nColemak' | fuzzel --dmenu --prompt="keyboard: " --lines=3 --no-icons)
+ variant=$(hyprctl getoption input:kb_variant 2>/dev/null | awk '/^str:/{print $2}' | cut -d, -f2)
+ case "$variant" in
+ dvorak) current="Dvorak" ;;
+ colemak) current="Colemak" ;;
+ *) current="QWERTY" ;;
+ esac
+ choice=$(printf 'QWERTY\nDvorak\nColemak' | \
+ awk -v cur="$current" '{
+ prefix = ($0 == cur) ? " > " : " "
+ printf "%s%s\t%s\n", prefix, $0, $0
+ }' | \
+ fuzzel --dmenu --prompt="kbd: " --no-icons --lines=3 \
+ --with-nth=1 --accept-nth=2 --width=24)
[ -z "$choice" ] && exit 0
case "$choice" in
QWERTY) variant="" ;;
@@ -62,32 +74,52 @@ keyboard)
esac
;;
audio)
- require wpctl pw-dump jq
+ require wpctl pw-dump jq fuzzel
case "$2" in
- out)
- sinks="$(pw-dump | jq -r '.[] | select(.info.props."media.class" == "Audio/Sink") | "\(.id)\t\(.info.props."node.description" // .info.props."node.name" // "unknown")"')"
- [ -z "$sinks" ] && exit 0
- if [ "$XDG_SESSION_TYPE" = x11 ]; then
- choice="$(printf "%s\n" "$sinks" | awk -F'\t' '{print $1": "$2}' | dmenu -i -p "select sink:" | cut -d: -f1)"
+ sink|source)
+ if [ "$2" = sink ]; then
+ class="Audio/Sink"
+ prompt="sink: "
+ default_meta="default.audio.sink"
+ pad=7
else
- count=$(printf "%s\n" "$sinks" | wc -l)
- choice="$(printf "%s\n" "$sinks" | awk -F'\t' '{print $1": "$2}' | fuzzel --dmenu --prompt="sink: " --lines="$count" | cut -d: -f1)"
+ class="Audio/Source"
+ prompt="source: "
+ default_meta="default.audio.source"
+ pad=8
fi
- [ "$choice" ] && wpctl set-default "$choice"
- ;;
- in)
- sources="$(pw-dump | jq -r '.[] | select(.info.props."media.class" == "Audio/Source") | "\(.id)\t\(.info.props."node.description" // .info.props."node.name" // "unknown")"')"
- [ -z "$sources" ] && exit 0
- if [ "$XDG_SESSION_TYPE" = x11 ]; then
- choice="$(printf "%s\n" "$sources" | awk -F'\t' '{print $1": "$2}' | dmenu -i -p "select source:" | cut -d: -f1)"
- else
- count=$(printf "%s\n" "$sources" | wc -l)
- choice="$(printf "%s\n" "$sources" | awk -F'\t' '{print $1": "$2}' | fuzzel --dmenu --prompt="source: " --lines="$count" | cut -d: -f1)"
- fi
- [ "$choice" ] && wpctl set-default "$choice"
+ dump=$(pw-dump)
+ devices=$(printf '%s' "$dump" | jq -r --arg class "$class" \
+ '.[] | select(.info.props."media.class" == $class) | "\(.id)\t\(.info.props."node.description" // .info.props."node.name" // "unknown")\t\(.info.props."node.name" // "")"')
+ [ -z "$devices" ] && exit 0
+ default_name=$(printf '%s' "$dump" | jq -r --arg key "$default_meta" \
+ '.[] | select(.type == "PipeWire:Interface:Metadata" and .info.props."metadata.name" == "default") | .info.metadata[] | select(.key == $key) | .value | fromjson | .name')
+ rows=$(printf '%s\n' "$devices" | while IFS="$(printf '\t')" read -r id name node_name; do
+ active=$([ "$node_name" = "$default_name" ] && echo ">" || echo "")
+ printf '%s\t%s\t%s\n' "$id" "$name" "$active"
+ done)
+ [ -z "$rows" ] && exit 0
+ w1=$(printf '%s\n' "$rows" | awk -F'\t' 'BEGIN{m=11}{l=length($2);if(l>m)m=l}END{print m}')
+ fw=$((w1 + pad + 10))
+ sep=$(awk -v n="$w1" 'BEGIN{for(i=0;i%$((pad - 3))s" "")
+ header=$(printf "%s%s\n%s%s" "$indent" "Device name" "$indent" "$sep")
+ count=$(printf '%s\n' "$rows" | wc -l)
+ choice=$(printf '%s\n' "$rows" | \
+ awk -F'\t' -v w1="$w1" -v indent="$indent" -v active_prefix="$active_prefix" '{
+ prefix = ($3 == ">") ? active_prefix : indent
+ printf "%s%-*s\t%s\n", prefix, w1, $2, $1
+ }' | \
+ fuzzel --dmenu --prompt="$prompt" --no-icons --lines="$count" \
+ --with-nth=1 --accept-nth=2 \
+ --mesg="$header" --mesg-mode=expand \
+ --font="monospace:size=12" --width="$fw")
+ [ -z "$choice" ] && exit 0
+ wpctl set-default "$choice"
;;
*)
- echo "Usage: ctl audio {in|out}" >&2
+ echo "Usage: ctl audio {sink|source}" >&2
exit 1
;;
esac
@@ -143,8 +175,6 @@ wifi)
station=$(iwctl device list 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | awk '/station/{print $1}')
[ -z "$station" ] && { echo "ctl: no wifi device found" >&2; exit 1; }
while :; do
- iwctl station "$station" scan 2>/dev/null
- sleep 1
networks=$(iwctl station "$station" get-networks 2>/dev/null | \
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | \
awk 'NR>4 && /\S/ && !/^[[:space:]]*-/' | \
@@ -176,13 +206,13 @@ wifi)
w1=$(printf '%s\n' "$networks" | awk -F'\t' 'BEGIN{m=12}{l=length($1);if(l>m)m=l}END{print m}')
w2=$(printf '%s\n' "$networks" | awk -F'\t' 'BEGIN{m=8}{l=length($2);if(l>m)m=l}END{print m}')
w3=$(printf '%s\n' "$networks" | awk -F'\t' 'BEGIN{m=6}{l=length($3);if(l>m)m=l}END{print m}')
- fw=$((w1 + 4 + w2 + 4 + w3 + 14))
- sep=$(awk -v n="$fw" 'BEGIN{for(i=0;i") ? " > " : " "
+ prefix = ($4 == ">") ? " > " : " "
printf "%s%-*s %-*s %s\t%s\n", prefix, w1, $1, w2, $2, $3, $1
}' | \
fuzzel --dmenu --prompt="wifi: " --no-icons --lines="$count" \
diff --git a/scripts/mux b/scripts/mux
index 6ec0e95..36733e2 100755
--- a/scripts/mux
+++ b/scripts/mux
@@ -172,7 +172,7 @@ cmd)
sed 's/ / /' |
fzf --reverse --prompt ':' --print-query \
--delimiter '\t' --with-nth '1,2' --accept-nth '1' \
- --bind 'ctrl-y:transform-query(echo {1})+disable-search')
+ --bind 'ctrl-y:transform-query(echo {1})')
rc=$?
query=$(printf '%s' "$result" | head -1)
action=$(printf '%s' "$result" | sed -n '2p')