From 5650e2f96a619cbbb9b45bc3a8b5e091d22037bb Mon Sep 17 00:00:00 2001 From: pablu Date: Fri, 3 Jul 2026 11:09:56 +0200 Subject: [PATCH] make hypr-nvim smart-nav better, now use ipc for quicker communication than synth binds --- .chezmoiignore | 1 + dot_config/hypr/config/autostart.lua | 2 - dot_config/hypr/config/binds.lua | 40 ++++++++-------- dot_config/hypr/config/constants.lua | 4 +- dot_config/hypr/config/general.lua | 17 +++++-- dot_config/hypr/config/rules.lua | 20 ++++++-- dot_config/nvim/init.lua.tmpl | 35 ++++++-------- dot_config/nvim/lua/hypr-nav.lua | 56 +++++++++++++++++++++++ dot_config/nvim/lua/plugins/autoclose.lua | 6 ++- 9 files changed, 126 insertions(+), 55 deletions(-) create mode 100644 dot_config/nvim/lua/hypr-nav.lua diff --git a/.chezmoiignore b/.chezmoiignore index b29f061..7fda614 100644 --- a/.chezmoiignore +++ b/.chezmoiignore @@ -1,5 +1,6 @@ README.md {{- if ne .chezmoi.hostname "gentoo" }} +.config/nvim/lua/hypr-nav.lua .wallpaper .config/dunst .config/fuzzel diff --git a/dot_config/hypr/config/autostart.lua b/dot_config/hypr/config/autostart.lua index 7ef5a5e..a85447d 100644 --- a/dot_config/hypr/config/autostart.lua +++ b/dot_config/hypr/config/autostart.lua @@ -1,8 +1,6 @@ hl.on("hyprland.start", function() hl.exec_cmd("awww-daemon") hl.exec_cmd("awww restore") - -- hl.exec_cmd("awww img ~/.wallpaper/cat.gif -o " .. SECONDARY_DISPLAY) - -- hl.exec_cmd("awww img ~/.wallpaper/train_station.gif -o " .. MAIN_DISPLAY) hl.exec_cmd("gentoo-pipewire-launcher") hl.exec_cmd("/usr/libexec/hyprpolkitagent") hl.exec_cmd("dunst") diff --git a/dot_config/hypr/config/binds.lua b/dot_config/hypr/config/binds.lua index d0f8ba0..06b64f7 100644 --- a/dot_config/hypr/config/binds.lua +++ b/dot_config/hypr/config/binds.lua @@ -14,34 +14,35 @@ hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("grim -o" .. MAIN_DISPLAY .. " \"${HOME}/screenshots/screenshot-$(date +%F-%T).png\"")) hl.bind(mainMod .. " + SHIFT + S", hl.dsp.exec_cmd("grim -g \"$(slurp)\" - | wl-copy")) -local synth = { - left = false, - right = false, - up = false, - down = false, -} - local function smart_nav(direction) return function() - if synth[direction] then - return - end - local win = hl.get_active_window() - if not win or win.class ~= "com.mitchellh.ghostty" or win.title ~= "vim" then + if not win + or win.class ~= "com.mitchellh.ghostty" + or not ( + (win.title or ""):lower():find("^nvim") + or (win.title or ""):lower():find(" - nvim") + or (win.title or ""):lower():find("^vim") + or (win.title or ""):lower():find(" - vim")) + then hl.dispatch(hl.dsp.focus({ direction = direction })) return end - hl.dispatch(hl.dsp.pass({ window = "activewindow" })) - synth[direction] = true - end -end + local runtime_dir = os.getenv("XDG_RUNTIME_DIR") or "/tmp" + local socket_path = string.format("%s/nvim-hypr-nav-%x.sock", runtime_dir, tostring(win.stable_id)) -local function smart_nav_release(direction) - return function() - synth[direction] = false + local handle = io.popen( + string.format("echo nav:%s | socat - UNIX-CONNECT:%s", + direction, socket_path)) + + local response = handle:read("*a") + handle:close() + + if response:find("failed") then + hl.dispatch(hl.dsp.focus({ direction = direction })) + end end end @@ -54,7 +55,6 @@ local movement_keys = { for key, dir in pairs(movement_keys) do hl.bind(mainMod .. " + " .. key, smart_nav(dir)) - hl.bind(mainMod .. " + " .. key, smart_nav_release(dir), { release = true }) end hl.bind(mainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" })) diff --git a/dot_config/hypr/config/constants.lua b/dot_config/hypr/config/constants.lua index c20177a..c00ff00 100644 --- a/dot_config/hypr/config/constants.lua +++ b/dot_config/hypr/config/constants.lua @@ -4,5 +4,5 @@ BROWSER = "firefox" HYPRLOCK = "hyprlock" STEAM = "steam" -MAIN_DISPLAY = "DP-7" -SECONDARY_DISPLAY = "DP-6" +MAIN_DISPLAY = "desc:HP Inc. OMEN 27qs CNC3081YHT" +SECONDARY_DISPLAY = "desc:Dell Inc. DELL U2415 7MT016A72F5" diff --git a/dot_config/hypr/config/general.lua b/dot_config/hypr/config/general.lua index 4543663..6145d32 100644 --- a/dot_config/hypr/config/general.lua +++ b/dot_config/hypr/config/general.lua @@ -3,7 +3,8 @@ hl.monitor({ output = MAIN_DISPLAY, mode = "2560x1440@240", position = "auto", - scale = "auto" + scale = "auto", + vrr = 2, }) hl.monitor({ @@ -11,7 +12,7 @@ hl.monitor({ mode = "preferred", position = "auto-left", scale = "auto", - transform = 1 + transform = 1, }) -- backup monitor @@ -60,9 +61,15 @@ hl.config({ }, cursor = { - no_hardware_cursors = 1, - no_warps = true, - hide_on_key_press = true + no_hardware_cursors = true, + -- no_warps = true, + hide_on_key_press = true, + inactive_timeout = 20, + default_monitor = MAIN_DISPLAY + }, + + render = { + direct_scanout = 2 } }) diff --git a/dot_config/hypr/config/rules.lua b/dot_config/hypr/config/rules.lua index 971ba32..0e17e4a 100644 --- a/dot_config/hypr/config/rules.lua +++ b/dot_config/hypr/config/rules.lua @@ -16,11 +16,11 @@ hl.window_rule({ -- Workspaces to monitors -for i = 1, 6 do - hl.workspace_rule({ workspace = tostring(i), monitor = MAIN_DISPLAY, persistent = true }) +for i = 1, 5 do + hl.workspace_rule({ workspace = tostring(i), monitor = MAIN_DISPLAY, persistent = true, default = i == 1 }) end for i = 6, 10 do - hl.workspace_rule({ workspace = tostring(i), monitor = SECONDARY_DISPLAY, persistent = true }) + hl.workspace_rule({ workspace = tostring(i), monitor = SECONDARY_DISPLAY, persistent = true, default = i == 6 }) end @@ -59,3 +59,17 @@ hl.window_rule({ focus_on_activate = false, suppress_event = "active activatefocus" }) + +hl.window_rule({ + match = { + class = "gamescope" + }, + immediate = true, + monitor = MAIN_DISPLAY, + content = "game", + decorate = false, + keep_aspect_ratio = false, + no_anim = true, + no_blur = true, + no_shadow = true, +}) diff --git a/dot_config/nvim/init.lua.tmpl b/dot_config/nvim/init.lua.tmpl index b04e420..0912ed5 100644 --- a/dot_config/nvim/init.lua.tmpl +++ b/dot_config/nvim/init.lua.tmpl @@ -40,29 +40,8 @@ end, { desc = "Pane split down" }) -- Movement {{ if eq .chezmoi.hostname "gentoo" }} -local function smart_move(direction, vim_cmd) - return function() - local before = vim.api.nvim_get_current_win() - vim.cmd("wincmd " .. vim_cmd) - - if before == vim.api.nvim_get_current_win() then - vim.system({ - "hyprctl", - "dispatch", - string.format( - "hl.dsp.focus({direction = '%s' })", - direction - ) - }) - end - end -end - -vim.keymap.set({ 'n', 'i', 'v' }, '', smart_move("left", "h"), { noremap = true, silent = false, desc = "Move to left windows" }); -vim.keymap.set({ 'n', 'i', 'v' }, '', smart_move("right", "l"), { noremap = true, silent = false, desc = "Move to right windows" }); -vim.keymap.set({ 'n', 'i', 'v' }, '', smart_move("down", "j"), { noremap = true, silent = false, desc = "Move to down window" }); -vim.keymap.set({ 'n', 'i', 'v' }, '', smart_move("up", "k"), { noremap = true, silent = false, desc = "Move to up window" }); +require("hypr-nav") {{ end }} @@ -285,3 +264,15 @@ for _, key in ipairs({ }) do vim.keymap.set("n", key, "") end + +for _, key in ipairs({ + "", + "", + "", + "", + "", + "", + "" +}) do + vim.keymap.set("i", key, "") +end diff --git a/dot_config/nvim/lua/hypr-nav.lua b/dot_config/nvim/lua/hypr-nav.lua new file mode 100644 index 0000000..fc05495 --- /dev/null +++ b/dot_config/nvim/lua/hypr-nav.lua @@ -0,0 +1,56 @@ +local direction_map = { + left = "h", + right = "l", + up = "k", + down = "j" +} + +local runtime_dir = os.getenv("XDG_RUNTIME_DIR") or "/tmp" +local function get_stable_id() + local handle = io.popen("hyprctl activewindow -j 2>/dev/null") + local data = handle:read("*a") + handle:close() + local ok, json = pcall(vim.json.decode, data) + if ok and json and json.stableId then + return tostring(json.stableId) + end + return "unknown" +end + +local stable_id = get_stable_id() + +local socket_path = string.format("%s/nvim-hypr-nav-%s.sock", runtime_dir, stable_id) + +local server = vim.uv.new_pipe(false) +server:bind(socket_path) +server:listen(128, function(err) + if err then vim.notify("hypr-nav: " .. err, vim.log.levels.ERROR) end + + local conn = vim.uv.new_pipe(false) + server:accept(conn) + + conn:read_start(function(err, data) + if not data then + pcall(function() conn:close() end) + return + end + local direction = data:match("nav:(%a+)") + if not direction then + pcall(function() conn:write("invalid\n") end) + + pcall(function() conn:close() end) + return + end + + vim.schedule(function() + local before = vim.api.nvim_get_current_win() + local wincmd_dir = direction_map[direction] or direction:sub(1, 1) + vim.cmd("wincmd " .. wincmd_dir) + local after = vim.api.nvim_get_current_win() + local response = (before == after) and "failed\n" or "success\n" + + pcall(function() conn:write(response) end) + pcall(function() conn:close() end) + end) + end) +end) diff --git a/dot_config/nvim/lua/plugins/autoclose.lua b/dot_config/nvim/lua/plugins/autoclose.lua index cd9e6ce..16ca5f1 100644 --- a/dot_config/nvim/lua/plugins/autoclose.lua +++ b/dot_config/nvim/lua/plugins/autoclose.lua @@ -1,6 +1,10 @@ return { 'm4xshen/autoclose.nvim', config = function() - require('autoclose').setup() + require('autoclose').setup({ + keys = { + ["'"] = { escape = true, close = false, pair = "''" }, + } + }) end }