diff --git a/.gitignore b/.gitignore
index 964ab1b..c7b2ce6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ result
 README.html
 *.qcow2
 *.log
+.luarc.json
diff --git a/dotfiles/neovim/.luarc.json b/dotfiles/neovim/.luarc.json
deleted file mode 100644
index 23b9ee2..0000000
--- a/dotfiles/neovim/.luarc.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "workspace.checkThirdParty": false
-}
\ No newline at end of file
diff --git a/dotfiles/neovim/ftplugin/lua.lua b/dotfiles/neovim/ftplugin/lua.lua
index b8b77cb..463918b 100644
--- a/dotfiles/neovim/ftplugin/lua.lua
+++ b/dotfiles/neovim/ftplugin/lua.lua
@@ -2,24 +2,38 @@ local opts = function(desc)
   return { desc = desc, buffer = true }
 end
 
-vim.keymap.set("n", "<leader>lf", ":source %<cr>", opts("Run [l]ua [f]ile "))
-vim.keymap.set("n", "<leader>ls", function()
-  local path = vim.api.nvim_buf_get_name(0)
-  local status, M = pcall(dofile, path)
+local function runLocal(functionName)
+  return function()
+    local path = vim.api.nvim_buf_get_name(0)
+    local status, M = pcall(dofile, path)
 
-  if status then
-    if M ~= nil then
-      if type(M.setup) == "function" then
-        M.setup()
-        print("M.setup() executed succesfully!")
+    if status then
+      if M ~= nil then
+        if type(M[functionName]) == "function" then
+          M[functionName]()
+          print("M." .. functionName .. "() executed succesfully!")
+        else
+          print("Module does not return a " .. functionName .. " function")
+        end
       else
-        print("Module does not return a setup function")
+        print("Module returned nil")
       end
     else
-      print("Module returned nil")
+      print("Cannot import current file :(")
     end
-  else
-    print("Cannot import current file :(")
   end
-end, opts("Run .setup() in current file"))
+end
 
+vim.keymap.set("n", "<leader>lf", ":source %<cr>", opts("Run [l]ua [f]ile "))
+vim.keymap.set(
+  "n",
+  "<leader>ls",
+  runLocal("setup"),
+  opts("Run .[s]etup() in current file")
+)
+vim.keymap.set(
+  "n",
+  "<leader>lc",
+  runLocal("config"),
+  opts("Run .[c]onfig() in current file")
+)
diff --git a/dotfiles/neovim/lazy-lock.json b/dotfiles/neovim/lazy-lock.json
index f48df31..18b0f2a 100644
--- a/dotfiles/neovim/lazy-lock.json
+++ b/dotfiles/neovim/lazy-lock.json
@@ -14,6 +14,7 @@
   "dressing.nvim": { "branch": "master", "commit": "6bde51adabba06f7fd4a469885a85f36d78a5f52" },
   "fidget.nvim": { "branch": "main", "commit": "0ba1e16d07627532b6cae915cc992ecac249fb97" },
   "flash.nvim": { "branch": "main", "commit": "967117690bd677cb7b6a87f0bc0077d2c0be3a27" },
+  "formatter.nvim": { "branch": "master", "commit": "44c89f09dcc220dc2a9b056e93c3a87c86e79804" },
   "github-actions-yaml.vim": { "branch": "master", "commit": "f2f16243447cea174daa6b4a9ffd3ff9213814ef" },
   "gitlinker.nvim": { "branch": "master", "commit": "cc59f732f3d043b626c8702cb725c82e54d35c25" },
   "harpoon": { "branch": "master", "commit": "21f4c47c6803d64ddb934a5b314dcb1b8e7365dc" },
@@ -27,6 +28,7 @@
   "kotlin-vim": { "branch": "master", "commit": "53fe045906df8eeb07cb77b078fc93acda6c90b8" },
   "lazy.nvim": { "branch": "main", "commit": "dac844ed617dda4f9ec85eb88e9629ad2add5e05" },
   "lean.nvim": { "branch": "main", "commit": "67580fab5bed73920fa3fdd712fc8e805c389c3d" },
+  "live-command.nvim": { "branch": "main", "commit": "d460067d47948725a6f25b20f31ea8bbfdfe4622" },
   "lspkind.nvim": { "branch": "master", "commit": "57610d5ab560c073c465d6faf0c19f200cb67e6e" },
   "lualine.nvim": { "branch": "master", "commit": "45e27ca739c7be6c49e5496d14fcf45a303c3a63" },
   "magma-nvim": { "branch": "main", "commit": "ff3deba8a879806a51c005e50782130246143d06" },
diff --git a/dotfiles/neovim/lua/.luarc.json b/dotfiles/neovim/lua/.luarc.json
deleted file mode 100644
index e1b9d70..0000000
--- a/dotfiles/neovim/lua/.luarc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json",
-    "Lua.workspace.checkThirdParty": false
-}
\ No newline at end of file
diff --git a/dotfiles/neovim/lua/my/abbreviations/fp.lua b/dotfiles/neovim/lua/my/abbreviations/fp.lua
index e70b18f..782cfaf 100644
--- a/dotfiles/neovim/lua/my/abbreviations/fp.lua
+++ b/dotfiles/neovim/lua/my/abbreviations/fp.lua
@@ -23,9 +23,17 @@ M.functions = {
 }
 
 function M.setup()
-  A.manyGlobalAbbr(scrap.expand_many(M.types, A.no_capitalization))
-  A.manyGlobalAbbr(scrap.expand_many(M.symols, A.no_capitalization))
-  A.manyGlobalAbbr(scrap.expand_many(M.functions, A.no_capitalization))
+  scrap.many_local_abbreviations(
+    scrap.expand_many(M.types, A.no_capitalization)
+  )
+
+  scrap.many_local_abbreviations(
+    scrap.expand_many(M.symols, A.no_capitalization)
+  )
+
+  scrap.many_local_abbreviations(
+    scrap.expand_many(M.functions, A.no_capitalization)
+  )
 end
 
 return M
diff --git a/dotfiles/neovim/lua/my/abbreviations/init.lua b/dotfiles/neovim/lua/my/abbreviations/init.lua
index 6a9e4ec..9950881 100644
--- a/dotfiles/neovim/lua/my/abbreviations/init.lua
+++ b/dotfiles/neovim/lua/my/abbreviations/init.lua
@@ -24,7 +24,6 @@ function M.manyGlobalAbbr(abbreviations)
   end
 end
 
-
 function M.setup()
   require("my.abbreviations.global").setup()
 end
diff --git a/dotfiles/neovim/lua/my/init.lua b/dotfiles/neovim/lua/my/init.lua
index 5acb6be..9100155 100644
--- a/dotfiles/neovim/lua/my/init.lua
+++ b/dotfiles/neovim/lua/my/init.lua
@@ -3,9 +3,8 @@ local M = {}
 function M.setup()
   -- Import my other files
   require("my.options").setup()
-  require('my.keymaps').setup()
-  require('my.lazy').setup()
-  require('my.abbreviations').setup()
+  require("my.keymaps").setup()
+  require("my.lazy").setup()
 end
 
 return M
diff --git a/dotfiles/neovim/lua/my/lazy.lua b/dotfiles/neovim/lua/my/lazy.lua
index a42eba0..cf801b9 100644
--- a/dotfiles/neovim/lua/my/lazy.lua
+++ b/dotfiles/neovim/lua/my/lazy.lua
@@ -13,6 +13,15 @@ function M.setup()
       enabled = false,
       notify = false,
     },
+    dev = {
+      -- Fallback to git when local plugin doesn't exist
+      fallback = true,
+
+      -- Directory where I store my local plugin projects
+      path = "~/Projects",
+
+      patterns = { "Mateiadrielrafael" },
+    },
     performance = {
       rtp = {
         paths = {
diff --git a/dotfiles/neovim/lua/my/plugins/format-nvim.lua b/dotfiles/neovim/lua/my/plugins/format-nvim.lua
new file mode 100644
index 0000000..4d16493
--- /dev/null
+++ b/dotfiles/neovim/lua/my/plugins/format-nvim.lua
@@ -0,0 +1,42 @@
+local env = require("my.helpers.env")
+local K = require("my.keymaps")
+
+local M = {
+  "mhartington/formatter.nvim",
+  event = "BufReadPre",
+  cond = env.vscode.not_active(),
+}
+
+function M.config()
+  local any = require("formatter.filetypes.any")
+  local formatters = {
+    markdown = {
+      require("formatter.filetypes.markdown").prettierd,
+    },
+    lua = {
+      require("formatter.filetypes.lua").stylua,
+    },
+    ["*"] = {
+      any.remove_trailing_whitespace,
+    },
+  }
+
+  require("formatter").setup({ filetype = formatters })
+
+  local format = function()
+    if formatters[vim.bo.filetype] ~= nil then
+      vim.cmd([[Format]])
+    elseif next(vim.lsp.get_active_clients({ bufnr = 0 })) == nil then
+      vim.lsp.buf.format()
+    end
+  end
+
+  K.nmap("<leader>F", format, "[F]ormat file")
+
+  vim.api.nvim_create_autocmd("BufWritePre", {
+    group = vim.api.nvim_create_augroup("Formatting", { clear = false }),
+    callback = format,
+  })
+end
+
+return M
diff --git a/dotfiles/neovim/lua/my/plugins/hydra.lua b/dotfiles/neovim/lua/my/plugins/hydra.lua
index 8ec0d85..61e849b 100644
--- a/dotfiles/neovim/lua/my/plugins/hydra.lua
+++ b/dotfiles/neovim/lua/my/plugins/hydra.lua
@@ -2,58 +2,361 @@ local M = {
   -- keybinds where you only hit the head once
   "anuvyklack/hydra.nvim",
   dependencies = {
-    "jbyuki/venn.nvim", -- draw ascii diagrams
     "mrjones2014/smart-splits.nvim", -- the name says it all
   },
-  keys = { "<C-S-w>", "<leader>V" },
+  keys = { "<C-S-w>" },
 }
 
-local venn_hint = [[
- Arrow^^^^^^   Select region with <C-v>
- ^ ^ _K_ ^ ^   _f_: surround it with box
- _H_ ^ ^ _L_
- ^ ^ _J_ ^ ^                      _<Esc>_
-]]
+-- {{{ Helpers
+local function identity(x)
+  return x
+end
 
-local window_hint = [[
- ^^^^^^^^^^^^     Move      ^^    Size   ^^   ^^     Split
- ^^^^^^^^^^^^-------------  ^^-----------^^   ^^---------------
+local function len(x)
+  return #x
+end
+
+local function box(value, w, h)
+  return { value = value, width = w, height = h }
+end
+
+local function min(l, r)
+  if l < r then
+    return l
+  else
+    return r
+  end
+end
+
+local function max(l, r)
+  return -min(-l, -r)
+end
+
+local function zip_with(l, r, f, default)
+  local output = {}
+  for i = 1, max(#l, #r), 1 do
+    output[i] = f(l[i] or default, r[i] or default)
+  end
+
+  return output
+end
+
+local function flatten_list(list)
+  local output = {}
+
+  for i = 1, #list, 1 do
+    for j = 1, #list[i], 1 do
+      table.insert(output, list[i][j])
+    end
+  end
+
+  return output
+end
+
+local function map_list(list, f)
+  local output = {}
+  for i = 1, #list, 1 do
+    output[i] = f(list[i])
+  end
+  return output
+end
+
+local function l_repeat(v, times)
+  if times == 0 then
+    return {}
+  end
+
+  local o = {}
+
+  for i = 1, times, 1 do
+    o[i] = v
+  end
+
+  return o
+end
+
+local function s_repeat(text, times)
+  local o = ""
+
+  for _ = 1, times, 1 do
+    o = o .. text
+  end
+
+  return o
+end
+local function string_split(text, sep)
+  ---@diagnostic disable-next-line: redefined-local
+  local sep, fields = sep or ":", {}
+  local pattern = string.format("([^%s]+)", sep)
+  text:gsub(pattern, function(c)
+    fields[#fields + 1] = c
+  end)
+  return fields
+end
+
+local function table_max(list, f, default)
+  if #list == 0 then
+    return default
+  end
+  ---@diagnostic disable-next-line: redefined-local
+  local f = f or identity
+  local c_max = list[1]
+  for i = 1, #list, 1 do
+    if f(list[i]) >= f(c_max) then
+      c_max = list[i]
+    end
+  end
+
+  return c_max
+end
+
+local function string_value(t)
+  if type(t) == "string" then
+    return t
+  end
+
+  return t.value
+end
+
+local function lines(text)
+  return string_split(string_value(text), "\n")
+end
+
+local function unlines(text)
+  return table.concat(text, "\n")
+end
+
+local function map_lines(text, f)
+  return unlines(map_list(lines(text), f))
+end
+
+local function string_width(t)
+  if type(t) == "string" then
+    return #table_max(lines(t), len, "")
+  end
+
+  return t.width
+end
+
+local function string_height(t)
+  if type(t) == "string" then
+    return #lines(t)
+  end
+
+  return t.height
+end
+
+local function half_down(num)
+  return math.floor(num / 2)
+end
+
+local function half_up(num)
+  return math.ceil(num / 2)
+end
+-- }}}
+-- {{{ Hint helpers
+local H = {}
+
+function H.highlight(t)
+  return box("_" .. t .. "_", string_width(t), 1)
+end
+
+function H.spacing(amount)
+  return s_repeat(" ", amount)
+end
+
+function H.spacing_for(text)
+  return H.spacing(string_width(text))
+end
+
+function H.spacing_largest(values)
+  return H.spacing_for(table_max(values))
+end
+
+H.nojustify = { justify = "nojustify" }
+
+function H.pad_left(text, length)
+  local spaces = length - string_width(text)
+
+  return box(
+    map_lines(text, function(line)
+      return H.spacing(spaces) .. line
+    end),
+    length,
+    string_height(text)
+  )
+end
+
+function H.pad_right(text, length)
+  local spaces = length - string_width(text)
+  return box(
+    map_lines(text, function(line)
+      return line .. H.spacing(spaces)
+    end),
+    length,
+    string_height(text)
+  )
+end
+
+function H.pad_around(text, length)
+  local spaces = length - string_width(text)
+  return box(
+    map_lines(text, function(line)
+      return H.spacing(half_up(spaces)) .. line .. H.spacing(half_down(spaces))
+    end),
+    length,
+    string_height(text)
+  )
+end
+
+function H.pad(text, length, justify)
+  if justify == "nojustify" then
+    return text
+  elseif justify == "center" then
+    return H.pad_around(text, length)
+  elseif justify == "right" then
+    return H.pad_left(text, length)
+  else
+    return H.pad_right(text, length)
+  end
+end
+
+function H.directional(h, j, k, l, spacing_amount)
+  ---@diagnostic disable-next-line: redefined-local
+  local spacing_amount = spacing_amount or 1
+
+  return H.concat_many_w({
+    H.highlight(k),
+    H.concat_many_h({
+      H.highlight(h),
+      H.spacing(spacing_amount),
+      H.highlight(l),
+    }),
+    H.highlight(j),
+  })
+end
+
+function H.add_title(title, body)
+  local width = max(string_width(title), string_width(body))
+
+  return H.concat_many_w({
+    title,
+    s_repeat("-", width),
+    body,
+  })
+end
+
+function H.concat_h(left, right, spacing_amount)
+  ---@diagnostic disable-next-line: redefined-local
+  local spacing_amount = spacing_amount or 0
+
+  return box(
+    unlines(zip_with(lines(left), lines(right), function(l, r)
+      return l .. H.spacing(spacing_amount) .. r
+    end, "")),
+    string_width(left) + string_width(right) + spacing_amount,
+    max(string_height(left), string_height(right))
+  )
+end
+
+function H.concat_w(above, below, opts)
+  ---@diagnostic disable-next-line: redefined-local
+  local opts = opts or {}
+  local spacing_amount = opts.spacing_amount or 0
+  local justify = opts.justify or "center"
+  local width = max(string_width(above), string_width(below))
+
+  return box(
+    unlines(flatten_list({
+      { H.pad(above, width, justify).value },
+      l_repeat(H.spacing(width), spacing_amount),
+      { H.pad(below, width, justify).value },
+    })),
+    width,
+    spacing_amount + string_height(above) + string_height(below)
+  )
+end
+
+function H.concat_many_h(list, spacing_amount)
+  local result = list[1]
+
+  for i = 2, #list, 1 do
+    result = H.concat_h(result, list[i], spacing_amount)
+  end
+
+  return result
+end
+
+function H.concat_many_w(list, opts)
+  local result = list[1]
+
+  for i = 2, #list, 1 do
+    result = H.concat_w(result, list[i], opts)
+  end
+
+  return result
+end
+
+function H.pad_lengths_right(list)
+  local max_length = table_max(list, string_width)
+  return map_list(list, function(t)
+    return H.concat_h(t, H.spacing(max_length - string_width(t)))
+  end)
+end
+
+M.hint = H
+-- }}}
+
+local window_hint_old = [[
+ ^^^^^^     Move    ^^^^^^  ^^    Size   ^^   ^^     Split
+ ^^^^^^-------------^^^^^^  ^^-----------^^   ^^---------------
  ^ ^ _k_ ^ ^  ^ ^ _K_ ^ ^   ^   _<C-k>_   ^   _s_: horizontally
  _h_ ^ ^ _l_  _H_ ^ ^ _L_   _<C-h>_ _<C-l>_   _v_: vertically
  ^ ^ _j_ ^ ^  ^ ^ _J_ ^ ^   ^   _<C-j>_   ^   _q_: close
- focus^^^^^^  window^^^^^^  ^_=_: equalize^   _o_: close remaining
+ ^^^focus^^^  ^^^window^^^  ^_=_: equalize^   _o_: close remaining
 ]]
 
+local window_hint = H.concat_many_h({
+  H.add_title(
+    "Move",
+    H.concat_h(
+      H.concat_w(H.directional("h", "j", "k", "l", 3), "focus"),
+      H.concat_w(
+        H.directional("H", "J", "K", "L", 3),
+        "window",
+        { justify = "left" }
+      ),
+      2
+    )
+  ),
+  H.add_title(
+    "Size",
+    H.concat_w(
+      H.directional("<C-h>", "<C-j>", "<C-k>", "<C-l>"),
+      H.concat_many_h({
+        H.highlight("="),
+        ": equalize",
+      })
+    )
+  ),
+  H.add_title(
+    "Split",
+    H.concat_many_w({
+      H.concat_h(H.highlight("s"), ": horizontally"),
+      H.concat_h(H.highlight("v"), ": vertical"),
+      H.concat_h(H.highlight("q"), ": close"),
+      H.concat_h(H.highlight("o"), ": close remaining"),
+    }, { justify = "left" })
+  ),
+}, 3).value
+
+print(window_hint)
+
 function M.config()
   local Hydra = require("hydra")
   local pcmd = require("hydra.keymap-util").pcmd
   local splits = require("smart-splits")
 
-  -- {{{ Diagrams
-  Hydra({
-    name = "Draw Diagram",
-    hint = venn_hint,
-    config = {
-      invoke_on_body = true,
-      hint = {
-        border = "rounded",
-      },
-      on_enter = function()
-        vim.o.virtualedit = "all"
-      end,
-    },
-    mode = "n",
-    body = "<leader>V",
-    heads = {
-      { "H", "<C-v>h:VBox<CR>" },
-      { "J", "<C-v>j:VBox<CR>" },
-      { "K", "<C-v>k:VBox<CR>" },
-      { "L", "<C-v>l:VBox<CR>" },
-      { "f", ":VBox<CR>", { mode = "v" } },
-      { "<Esc>", nil, { exit = true } },
-    },
-  })
-  -- }}}
   -- {{{ Windows
   local resize = function(direction)
     return function()
diff --git a/dotfiles/neovim/lua/my/plugins/init.lua b/dotfiles/neovim/lua/my/plugins/init.lua
index 86a0aba..e1be4ed 100644
--- a/dotfiles/neovim/lua/my/plugins/init.lua
+++ b/dotfiles/neovim/lua/my/plugins/init.lua
@@ -96,10 +96,20 @@ return {
   },
 
   -- Helper libs
-  "nvim-lua/plenary.nvim",
+  {
+    "nvim-lua/plenary.nvim",
+    -- Autoload when running tests
+    cmd = { "PlenaryBustedDirectory", "PlenaryBustedFile" },
+  },
   "MunifTanjim/nui.nvim",
   "nvim-tree/nvim-web-devicons", -- nice looking icons
-  "mateiadrielrafael/scrap.nvim", -- vim-abolish rewrite
+  {
+    "mateiadrielrafael/scrap.nvim",
+    event = "InsertEnter",
+    config = function()
+      require("my.abbreviations").setup()
+    end,
+  }, -- vim-abolish rewrite
 
   {
     "terrortylor/nvim-comment",
diff --git a/dotfiles/neovim/lua/my/plugins/null-ls.lua b/dotfiles/neovim/lua/my/plugins/null-ls.lua
index 74a6010..0f417fe 100644
--- a/dotfiles/neovim/lua/my/plugins/null-ls.lua
+++ b/dotfiles/neovim/lua/my/plugins/null-ls.lua
@@ -5,6 +5,7 @@ local M = {
   event = "BufReadPre",
   dependencies = "neovim/nvim-lspconfig",
   cond = env.vscode.not_active(),
+  enable = false,
 }
 
 function M.config()
diff --git a/dotfiles/neovim/lua/my/plugins/obsidian.lua b/dotfiles/neovim/lua/my/plugins/obsidian.lua
new file mode 100644
index 0000000..f72d987
--- /dev/null
+++ b/dotfiles/neovim/lua/my/plugins/obsidian.lua
@@ -0,0 +1,31 @@
+local env = require("my.helpers.env")
+local vault = "/home/adrielus/Projects/stellar-sanctum"
+
+return {
+  "epwalsh/obsidian.nvim",
+  event = "VeryLazy",
+  dependencies = {
+    "nvim-lua/plenary.nvim",
+  },
+  opts = {
+    dir = vault,
+    notes_subdir = "chaos",
+    daily_notes = {
+      folder = "daily",
+      date_format = "%Y-%m-%d",
+    },
+    completion = {
+      nvim_cmp = true,
+      min_chars = 2,
+      new_notes_location = "current_dir",
+      prepend_note_id = true,
+    },
+    mappings = {},
+  },
+  keys = {
+    { "<C-O>", "<cmd>ObsidianQuickSwitch<cr>" },
+  },
+  cond = env.vscode.not_active()
+    and env.firenvim.not_active()
+    and vim.loop.cwd() == vault,
+}
diff --git a/dotfiles/neovim/lua/my/plugins/treesitter.lua b/dotfiles/neovim/lua/my/plugins/treesitter.lua
index f02d480..75c06d0 100644
--- a/dotfiles/neovim/lua/my/plugins/treesitter.lua
+++ b/dotfiles/neovim/lua/my/plugins/treesitter.lua
@@ -13,8 +13,6 @@ local M = {
         --{{{Languages
         ensure_installed = {
           "bash",
-          "javascript",
-          "typescript",
           "c",
           "cpp",
           "css",
@@ -22,18 +20,22 @@ local M = {
           "elixir",
           "fish",
           "html",
+          "javascript",
           "json",
           "jsonc",
           "latex",
+          "lua",
+          "markdown",
+          "markdown_inline",
+          "nix",
           "python",
           "rust",
           "scss",
           "toml",
           "tsx",
+          "typescript",
           "vim",
           "yaml",
-          "nix",
-          "lua",
         },
         sync_install = false,
         --}}}
diff --git a/dotfiles/neovim/lua/my/plugins/venn.lua b/dotfiles/neovim/lua/my/plugins/venn.lua
new file mode 100644
index 0000000..9db9b9e
--- /dev/null
+++ b/dotfiles/neovim/lua/my/plugins/venn.lua
@@ -0,0 +1,52 @@
+local M = {
+  "jbyuki/venn.nvim", -- draw ascii diagrams
+  dependencies = {
+    "anuvyklack/hydra.nvim",
+  },
+  keys = { "<leader>V" },
+}
+
+local venn_hint = [[
+ ^^^Arrow^^^   Select region with <C-v>
+ ^ ^ _K_ ^ ^   _f_: surround it with box
+ _H_ ^ ^ _L_
+ ^ ^ _J_ ^ ^                      _<Esc>_
+]]
+
+function M.config()
+  local Hydra = require("hydra")
+
+  Hydra({
+    name = "Draw Diagram",
+    hint = venn_hint,
+    config = {
+      color = "pink",
+      invoke_on_body = true,
+      hint = {
+        border = "single",
+      },
+      on_enter = function()
+        vim.o.virtualedit = "all"
+      end,
+    },
+    mode = "n",
+    desc = "[V]enn mode",
+    body = "<leader>V",
+    heads = {
+      { "H", "<C-v>h:VBox<CR>" },
+      { "J", "<C-v>j:VBox<CR>" },
+      { "K", "<C-v>k:VBox<CR>" },
+      { "L", "<C-v>l:VBox<CR>" },
+      { "f", ":VBox<CR>", { mode = "v" } },
+      { "<Esc>", nil, { exit = true } },
+    },
+  })
+end
+
+function M.init()
+  require("which-key").register({
+    ["<leader>V"] = { name = "[V]enn mode" },
+  })
+end
+
+return M
diff --git a/dotfiles/neovim/lua/my/plugins/whichkey.lua b/dotfiles/neovim/lua/my/plugins/whichkey.lua
index 5100e57..d70b17c 100644
--- a/dotfiles/neovim/lua/my/plugins/whichkey.lua
+++ b/dotfiles/neovim/lua/my/plugins/whichkey.lua
@@ -1,4 +1,3 @@
-local env = require("my.helpers.env")
 local M = {
   "folke/which-key.nvim",
   event = "VeryLazy",
@@ -7,15 +6,11 @@ local M = {
 function M.config()
   local wk = require("which-key")
 
-  local winblend = 0
-
-  if env.neovide.active() then
-    winblend = 30
-  end
-
   wk.setup({
     window = {
-      winblend = winblend,
+      winblend = 0,
+      pumblend = 0,
+      border = "single",
     },
     layout = { align = "center" },
   })
@@ -28,7 +23,6 @@ function M.config()
       l = { name = "[L]ocal" },
       w = { name = "[W]orkspace" },
       y = { name = "[Y]ank" },
-      v = "which_key_ignore",
     },
   })
 end