aboutsummaryrefslogtreecommitdiff
path: root/dot_config/hypr/config/binds.lua
blob: a5a9e6b9699c2a64e85609cbcf72c994d351ed9f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
local mainMod = "SUPER"

-- Quit Keys
hl.bind(mainMod .. " + Q", hl.dsp.window.close())
hl.bind(mainMod .. " + CTRL + Q", hl.dsp.exit())

-- Program keys
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(TERMINAL))
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd(MENU))
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(BROWSER))
hl.bind(mainMod .. " + O", hl.dsp.exec_cmd(HYPRLOCK))
hl.bind(mainMod .. " + G", hl.dsp.exec_cmd(STEAM))
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 function focus_hyprland(direction)
  hl.dispatch(hl.dsp.focus({ direction = direction }))
end

local function is_direct_nvim(title)
  title = (title or ""):lower()

  return title:find("^nvim")
      or title:find(" - nvim", 1, true)
      or title:find("^vim")
      or title:find(" - vim", 1, true)
end

local function ask_direct_nvim(win, direction)
  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 handle = io.popen(string.format(
    "printf 'nav:%s\\n' | socat -T 0.25 -,ignoreeof UNIX-CONNECT:%s 2>/dev/null",
    direction,
    socket_path
  ))

  if not handle then
    return false
  end

  local response = handle:read("*a")
  handle:close()

  return response:find("success", 1, true) ~= nil
end

local function smart_nav(direction)
  return function()
    local win = hl.get_active_window()

    if not win then
      return
    end

    if win.class ~= "com.mitchellh.ghostty" then
      focus_hyprland(direction)
      return
    end

    local title = (win.title or ""):lower()

    if title == "herdr" then
      local helper = (os.getenv("HOME") or "")
          .. "/.config/hypr/scripts/herdr-smart-nav"

      local handle = io.popen(helper .. " " .. direction)

      if not handle then
        focus_hyprland(direction)
        return
      end

      local result = handle:read("*a")
      handle:close()

      if result:find("hyprland", 1, true) then
        focus_hyprland(direction)
      end

      return
    end

    if is_direct_nvim(title) and ask_direct_nvim(win, direction) then
      return
    end

    focus_hyprland(direction)
  end
end

local movement_keys = {
  H = "left",
  L = "right",
  J = "down",
  K = "up"
}

for key, dir in pairs(movement_keys) do
  hl.bind(mainMod .. " + " .. key, smart_nav(dir))
end

hl.bind(mainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" }))
hl.bind(mainMod .. " + SHIFT + L", hl.dsp.window.move({ direction = "right" }))
hl.bind(mainMod .. " + SHIFT + J", hl.dsp.window.move({ direction = "down" }))
hl.bind(mainMod .. " + SHIFT + K", hl.dsp.window.move({ direction = "up" }))

hl.bind(mainMod .. " + CTRL + H", hl.dsp.window.resize({ x = -10, y = 0, relative = true }), { repeating = true })
hl.bind(mainMod .. " + CTRL + L", hl.dsp.window.resize({ x = 10, y = 0, relative = true }), { repeating = true })
hl.bind(mainMod .. " + CTRL + J", hl.dsp.window.resize({ x = 0, y = -10, relative = true }), { repeating = true })
hl.bind(mainMod .. " + CTRL + K", hl.dsp.window.resize({ x = 0, y = 10, relative = true }), { repeating = true })

for i = 1, 10 do
  local key = i % 10
  hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }))
  hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
end

-- Resize Keys
hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen({ action = "toggle" }))
hl.bind(mainMod .. " + v", hl.dsp.window.float())
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })

-- Multimedia Keys
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"),
  { locked = true, repeating = true })
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),
  { locked = true, repeating = true })
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"))
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })

-- hl.bind("code:51", hl.dsp.pass({ window = "class:^([Dd]iscord)$" }), { non_consuming = true })