Leader Everywhere: Keymap Philosophy and Core Bindings
Part 2 of the Neovim Config Series — Part 1: One Config Two Oses the Anatomy of my Neovim Setup
Leader Everywhere: Keymap Philosophy and Core Bindings

Every key has a meaning. Space has all of them.
Part 2 of the Neovim Config Series — Part 1: One Config Two Oses the Anatomy of my Neovim Setup
If the first article was about the skeleton of this config, this one is about the nervous system. Keymaps are where a Neovim setup either pays off or falls apart. After enough time in this editor, you stop thinking about individual keybindings and start thinking about systems — groups of related actions that share a prefix, follow a pattern, and feel predictable the moment you use them for the first time.
My keymaps.lua is the longest file in the config. It handles everything from window splits to terminal pane navigation to the Snacks picker that replaced Telescope. But before diving into individual bindings, there is something more important to understand: the keymap language itself.
Every prefix in this config is a word. Every suffix is a letter that completes that word. Press <Space> and pause — which-key shows you the first level. Press m and pause — everything markdown-related appears. Press mf and pause — every fold operation is right there. You never need to memorize the full chord. You read it one letter at a time until you find what you want.
That is the system. Everything else follows from it.
🗺️ Which-Key as a Documentation Layer
I use which-key.nvim not just as a popup hint system but as a naming convention enforcer. Before any keymap is set, every group is registered through wk.add():
local wk = require("which-key")
wk.add({
mode = { "n", "v" },
{ "<leader>m", group = "[m]arkdown" },
{ "<leader>mf", group = "[f]old Markdown" },
{ "<leader>mp", group = "[p]rint" },
-- ...
})
The group entries do not bind any keys. They register a label so that when you press <Space>m and pause, which-key shows you [m]arkdown instead of a raw character. The square bracket convention [x] is deliberate — the bracketed letter is always the key you just pressed. It is self-documenting: you see what you typed and what it means in a single label.
This forces thinking about keymap trees before individual bindings. The tree is the design. The bindings are just leaves.
🌳 The Full Leader Tree — Reading the Language
Here is every namespace in the config and what it means. Read this once and you will be able to navigate the entire keymap space without a reference sheet.
<leader>t — Trouble


t stands for Trouble — the diagnostic and todo list plugin. The subtree follows a logical branching:
t → [t]rouble (the namespace)
tt → [t]odos (todo-related commands)
ttt → [t]elescope (find todos via Telescope)
ttQ → [Q]uickfix todo (open todos in quickfix list)
ttL → [L]ist todo (list all todos in project)
ttA → [A]ll todo (all todos via Trouble's filtering)
tr → [r]un (run Trouble panels)
trd → [d]iagnostics (open diagnostics panel)
trb → [b]uffer (buffer-scoped diagnostics)
trs → [s]ymbols (symbol tree)
trD → [D]efinitions (LSP definitions and references)
trl → [l]ocation list (location list)
trq → [q]uickfix list (quickfix list)
The split between tt and tr is intentional. tr — "trouble run" — opens Trouble panels. tt — "trouble todos" — is specifically for todo comments: fixme, todo, hack, note tags scattered through the codebase, surfaced and filterable. ttt adds a third t to open those todos through Telescope for fuzzy searching. Three ts in a row sounds absurd until it clicks: trouble → todos → telescope.
keymap.set("n", "<leader>trd", ":Trouble diagnostics <cr>", { desc = "[TROUBLE] Diagnostics" })
keymap.set("n", "<leader>trb", ":Trouble diagnostics toggle filter.bug=0<cr>", { desc = "[TROUBLE] Buffer Diagnostics" })
keymap.set("n", "<leader>trs", ":Trouble symbols toggle focus=false<cr>", { desc = "[TROUBLE] Symbols" })
keymap.set("n", "<leader>trD", ":Trouble lsp toggle focus=false win.position=right <cr>",{ desc = "[TROUBLE] LSP Definitions" })
keymap.set("n", "<leader>trl", ":Trouble loclist toggle <cr>", { desc = "[TROUBLE] Location List" })
keymap.set("n", "<leader>trq", ":Trouble qflist toggle <cr>", { desc = "[TROUBLE] QuickFix List" })
keymap.set("n", "<leader>tttf", ":TodoTelescope <cr>", { desc = "[TODO] Find with Telescope" })
keymap.set("n", "<leader>ttQ", ":TodoQuickFix <cr>", { desc = "[TODO] QuickFix" })
keymap.set("n", "<leader>ttL", ":TodoLocList <cr>", { desc = "[TODO] Loc List" })
keymap.set("n", "<leader>ttA", ":Trouble todo <cr>", { desc = "[TODO] All with Trouble" })
<leader>f — Find (Snacks Picker)

f stands for find. Not "Snacks" — the letter is chosen for what you do, not which plugin does it. That distinction matters because the picker has changed twice already (Telescope → fzf-lua → Snacks) and the keymaps have not had to change once:
f → [f]ind (the namespace — powered by Snacks)
ff → find [f]iles (file picker)
fg → find with [g]rep (live grep)
fb → find [b]uffers (open buffers)
fh → find [h]elp tags (Neovim help)
fi → find, resu[i]me (resume last picker session)
fj → find diagnostics [j] (workspace diagnostics)
fk → find trees[k]itter (treesitter symbols)
fI → find LSP [I]mpl. (LSP definitions)
fd → find type [d]ef. (LSP type definitions)
fl → find [l]ocal (hidden) (files in current buffer's directory)
fL → find [L]arge (root) (files from project root, hidden included)
ff and fg are the two you use ninety percent of the time. ff opens the file picker. fg opens live grep — type a string and Snacks searches the entire project in real time. For a Next.js and Sitecore monorepo with thousands of files, grep speed is what drove the picker migration in the first place.
fl and fL are the context-sensitive variants. fl opens files relative to the current buffer's directory — essential when you are deep inside a component folder and want to see sibling files without navigating back to root:
keymap.set("n", "<leader>fl", function()
Snacks.picker.files({ cwd = vim.fn.expand("%:p:h"), hidden = true, follow = true })
end, { desc = "[Snacks] files in current directory" })
keymap.set("n", "<leader>fL", function()
Snacks.picker.files({ root = true, hidden = true, follow = true })
end, { desc = "[Snacks] files in root directory" })
hidden = true and follow = true on both mean .env.local files and symlinked vendor paths are always included — the kind of thing that bites you once and then you add it everywhere.
<leader>g — Git

g is git. One level deep, one command for now:
g → [g]it
gl → [l]azy
glg → [g]it lazygit (open LazyGit floating window)
keymap.set("n", "<leader>glg", function()
require("snacks.lazygit").open()
end, { desc = "[LAZYGIT] Open lazygit" })
gl reads as "git lazy," glg reads as "git lazy-git." Opening LazyGit through Snacks means it inherits the same floating window behavior as the rest of the Snacks UI — consistent, no jarring context switch.
<leader>m — Markdown



m is the largest non-Obsidian namespace. Everything markdown-related branches from here:
m → [m]arkdown
mf → [f]old
mf1 → fold H[1] and below
mf2 → fold H[2] and below
mf3 → fold H[3] and below
mf4 → fold H[4] and below
mfu → [u]nfold all
mff → [f]old current heading
mft → [t]oggle fold
mfs → [s]how heading context
mp → [p]rint (copy to clipboard)
mpd → print [d]irectory (full path)
mpr → print [r]elative path
mpf → print [f]ilename
mpD → print [D]ate
mt → [t]ext operations
mts → [s]trikethrough toggle
mtc → [c]heckbox regex
mthd → [h]eading [d]ashes
mr → [r]ender
mrt → [t]oggle browser preview
mP → [P]rompt template
mPiwt → insert [w]ork [t]emplate
moto → [o]bsidian [t]able [o]f contents
motoc → TOC with [c]wiki links (Obsidian-compatible)
motoC → TOC [C]ompatible with browser
The mp group — "markdown print" — deserves a pause. "Print" here means copy to clipboard, not paper. mpd copies the full absolute path of the current file (with ~ substituted for the home directory) formatted as a comment // ~/path/to/file, ready to paste inline into code or a PR comment. mpr copies the project-relative path. mpf copies just the filename. mpD copies today's date in MM-DD-YYYY format for note titles and commit messages. One group, four clipboard utilities — "print" because that is what they do.
mt is "markdown text" — operations on the content of the current line. mts wraps the line in ~ delimiters to toggle strikethrough (or removes them if already present, preserving indentation). mtc copies a Vim regex that matches all empty checkboxes in the file — paste it into the command line, append the replacement, run. mthd converts spaces in the current heading to dashes, turning # My New Note into # My-New-Note for use as a URL anchor or Obsidian note ID.
mrt — "markdown render toggle" — opens the current file in a browser via MarkdownPreview. The r for "render" distinguishes it from mp "print" even though both send content somewhere outside Neovim.
moto — "markdown obsidian table of contents" — generates a TOC for the current file. motoc produces wikilink-style headings for Obsidian's internal navigation. motoC (uppercase C) produces standard Markdown anchor links for browser-rendered output. Same operation, two output formats, one letter apart.
The folding subsystem under mf is deep enough to warrant its own article — which is exactly where this series goes next.
🎩 The z_ Shortcuts: A Hat Tip to Linkarzu
The <leader>mf1 through <leader>mfu bindings are the discoverable, which-key-visible version of the fold system. But the bindings I actually reach for every day are different — six shortcuts that live entirely outside the leader namespace, on the z key.
These were directly inspired by Linkarzu — a content creator whose dotfiles and YouTube series on Neovim and Markdown workflows are worth following if any of this resonates. His approach to fold keymaps stuck with me, and I adapted it into my own config. Credit where it is due.
The full implementation:
-- Credit: inspired by Linkarzu
-- https://linkarzu.com/
-- https://github.com/linkarzu/dotfiles-latest
keymap.set("n", "zj", function()
vim.cmd("silent update") -- save if modified
vim.cmd("edit!") -- reload to refresh fold expressions
vim.cmd("normal! zR") -- open all folds first to avoid toggle issues
md_utils.fold_markdown_headings({ 6, 5, 4, 3, 2, 1 })
vim.cmd("normal! zz") -- center cursor on screen
end, { desc = "[P]Fold all headings level 1 or above" })
keymap.set("n", "zk", function()
vim.cmd("silent update")
vim.cmd("edit!")
vim.cmd("normal! zR")
md_utils.fold_markdown_headings({ 6, 5, 4, 3, 2 })
vim.cmd("normal! zz")
end, { desc = "[P]Fold all headings level 2 or above" })
keymap.set("n", "zl", function()
vim.cmd("silent update")
vim.cmd("edit!")
vim.cmd("normal! zR")
md_utils.fold_markdown_headings({ 6, 5, 4, 3 })
vim.cmd("normal! zz")
end, { desc = "[P]Fold all headings level 3 or above" })
keymap.set("n", "z;", function()
vim.cmd("silent update")
vim.cmd("edit!")
vim.cmd("normal! zR")
md_utils.fold_markdown_headings({ 6, 5, 4 })
vim.cmd("normal! zz")
end, { desc = "[P]Fold all headings level 4 or above" })
keymap.set("n", "zu", function()
vim.cmd("silent update")
vim.cmd("edit!")
vim.cmd("normal! zR") -- unfold everything
vim.cmd("normal! zz")
end, { desc = "[P]Unfold all headings" })
-- zi normally toggles folding entirely — overridden here
-- jumps to the heading above the cursor and folds it
keymap.set("n", "zi", function()
vim.cmd("silent update")
vim.cmd("normal gk") -- move to heading above (respects mappings)
vim.cmd("normal! za") -- toggle fold (raw, no mappings)
vim.cmd("normal! zz")
end, { desc = "[P]Fold the heading cursor currently on" })
Every one of these follows the same three-step pattern: save the file, reload it so the fold expressions are fresh, then run the fold operation. The save-then-reload is not optional — foldexpr is evaluated at load time, so unsaved changes are invisible to the fold system. Without it, you get stale folds that do not reflect what is actually on screen.
The progression zj → zk → zl → z; maps to H1 → H2 → H3 → H4. It is positional — the keys move rightward along the home row as the heading level gets deeper. Once it lands, it never leaves. zu unfolds everything. zi overrides Neovim's built-in zi (toggle folding entirely, a command that rarely comes up in practice) and replaces it with something far more useful: jump to the nearest heading above the cursor and fold it.
The original comment in the source file still says “I know, it reads like ‘madafaka’ but k for me means 2” — which is exactly the kind of honest, practical documentation that makes a config worth reading.
<leader>o — Obsidian


o is Obsidian — and notes are everywhere in this dotfiles. I am a dedicated note-taker, and Obsidian is where ideas land, work gets tracked, and knowledge accumulates. Because I move between macOS and Windows, the entire integration had to work identically on both — vault operations are backed by parallel ZSH and PowerShell scripts, paths resolve correctly on either OS, and nothing breaks switching machines mid-week. The full cross-platform breakdown — vault structure, shell scripts, the whole setup — gets its own article later in this series. So it is no surprise that o is the most expansive namespace in the config, covering note creation, daily notes, template insertion, title formatting, backlinks, file operations, and vault management:
o → [o]bsidian
on → [n]ew
onn → new [n]ote
od → [d]aily notes
odf → [f]ormat daily
odft → format [t]itle
of → [f]ormat
oft → format [t]itle (strip date, capitalize words)
ofT → format [T]odo title (strip date, preserve TODO: prefix)
oi → [i]nsert template
oin → insert [n]otes template
oit → insert [t]odo template
oiw → insert [w]ork-tracker template
oB → [B]acklinks
oBl → backlinks [l]ist
ok → [k]atalogize (move to zettelkasten folder)
oD → [D]elete note and close buffer
oW → [W]indows (legacy platform-specific commands)
oWk → [k] zettelkasten move (Windows)
oWD → [D]elete note (Windows)
oi — "obsidian insert" — injects a pre-built template into the current buffer. Three templates are registered: notes for general notes, todo for actionable items, and work-tracker for daily work logging. Pressing <leader>oin drops the entire notes template — frontmatter, headings, sections — into whatever buffer is open. No copy-pasting, no manual frontmatter construction.
keymap.set("n", "<leader>oin", ":Obsidian template notes<CR>", { desc = "Insert notes template" })
keymap.set("n", "<leader>oit", ":Obsidian template todo<CR>", { desc = "Insert todo template" })
keymap.set("n", "<leader>oiw", ":Obsidian template work-tracker<CR>", { desc = "Insert work-tracker template" })
of — "obsidian format" — manipulates note titles in place. oft strips Obsidian's default date-prefixed filename format from the H1 heading, replaces dashes with spaces, and capitalizes each word — turning # 2024-01-15_my-new-note into # My New Note in a single keypress. ofT does the same but preserves a TODO: prefix, so # TODO: 2024-01-15_my-note becomes # TODO: My Note.
ok — "obsidian katalogize" (the k is phonetic) — moves the current file into the zettelkasten folder of the vault. It attempts os.rename() first for a fast in-place move, then falls back to a read-write-delete pattern for cross-filesystem moves (Google Drive on macOS, different drive letters on Windows). Platform-aware, zero manual file management.
oD — "obsidian Delete" — deletes the current file from disk and closes the buffer. Uppercase D is intentional: destructive operations get uppercase letters throughout this config.
Obsidian gets a full dedicated article later in this series, covering the vault structure, the PowerShell and ZSH scripts that power the workflow, and the cross-platform file operations in depth. A special mention goes to @ZazenCodes — his dotfiles were a significant source of inspiration for how I approached the Obsidian side of this config. If you are building your own Obsidian workflow inside Neovim, his repository is worth a careful read.
<leader>a — AI

a is AI — specifically OpenCode, which replaced Copilot:
a → [ai]
at → [t]oggle OpenCode session (keep session alive)
aa → [a]sk a question
The terminal mode keymaps that make OpenCode usable in a split pane are covered below.
<leader>A — Annotations/Notes


Uppercase A is annotations — two plugins, two modes: AS for sticky notes pinned to specific lines, and AN for a persistent sidebar notes file. The which-key group labels are registered in keymaps.lua, but the actual bindings live in sticky.lua alongside the plugins themselves. This namespace gets a full dedicated section in Part 3, including the <Nop> override pattern that prevents fusen's default keymaps from polluting the m markdown namespace.
A → [A]nnotations
AS → [S]ticky annotations
ASa → [a]dd or edit note
ASc → [c]lear note
ASC → [C]lear all notes in buffer
ASD → [D]elete all notes everywhere
ASn → [n]ext note
ASp → [p]revious note
ASl → [l]ist all notes
AN → sidebar [N]otes
ANt → [t]oggle right sidebar
ANf → [f]loating window toggle
ANs → [s]how notes
ANh → [h]ide notes
ANe → [e]dit notes file
<leader>r — Refactoring
r is refactoring — Treesitter-powered code transformations courtesy of refactoring.nvim by ThePrimeagen. The namespace covers extraction, inlining, and a picker that surfaces every available operation for the current context:
r → [r]efactoring
re → [e]xtract function
rE → [E]xtract function to file
rv → [v]ariable extract
ri → [i]nline variable
rI → [I]nline function
rs → [s]elect refactor (picker)
Like Annotations, the actual keymaps live in treesitter.lua alongside the plugin — not in keymaps.lua. The full breakdown including mode details (x vs n) and why { expr = true } is required for all of these gets its own section in Part 3.
<leader>U — Utilities

U uppercase for utilities — small developer tools that do not belong to any specific plugin:
U → [U]tils
Uc → [c]onsole
Ucl → [l]og variable (word under cursor)
UcL → [L]og full token (WORD under cursor)
Ucl — "utils console log" — reads the word under the cursor (<cword>) and copies a ready-to-paste console.log('myVar: ', myVar); to the system clipboard. UcL does the same but uses <cWORD>, which captures everything up to the next whitespace including dots, dollar signs, and optional chaining operators. <cword> stops at event in event.target.value. <cWORD> captures the whole thing. Having both adjacent means you pick the right one without switching modes.
keymap.set("n", "<leader>Ucl", function()
local var = vim.fn.expand("<cword>")
local log = string.format("console.log('%s: ', %s);", var, var)
vim.fn.setreg("+", log)
print("copied: " .. log)
end, { desc = "[LOG] Copy console.log variable under cursor" })
keymap.set("n", "<leader>UcL", function()
local var = vim.fn.expand("<cWORD>")
local log = string.format("console.log('%s: ', %s);", var, var)
vim.fn.setreg("+", log)
print("copied: " .. log)
end, { desc = "[LOG] Full Token Copy console.log variable under cursor" })
🧠 Discipline: Enforced Good Habits
The first thing that runs after the module imports is this:
local discipline = require("utilities.discipline")
discipline.strict()
discipline.lua is a small module inspired by craftzdog's dotfiles. It counts consecutive presses of h, j, k, l, +, and -. If you press any of them more than 90 times within a 2-second window without a count prefix, a warning notification fires with the 🤬 title. The count resets on a 2-second idle timer, so normal navigation is never interrupted.
The point is not to block movement — the key still works. The point is to make you notice when you are doing something a motion command would handle better. Using a count prefix (15j, 3h) resets the counter immediately. The module rewards deliberate navigation and flags lazy repetition. It is annoying for exactly as long as it takes to internalize the lesson.
🪟 Window Management
Window management lives intentionally outside the <leader> space. Splitting and moving between splits are too frequent to route through a prefix:
-- Split
keymap.set("n", "ss", ":split<Return>", opts) -- horizontal split
keymap.set("n", "sv", ":vsplit<Return>", opts) -- vertical split
-- Move between splits
keymap.set("n", "sh", "<C-w>h")
keymap.set("n", "sk", "<C-w>k")
keymap.set("n", "sj", "<C-w>j")
keymap.set("n", "sl", "<C-w>l")
-- Resize (arrow key = literal direction)
keymap.set("n", "<C-w><left>", "<C-w><")
keymap.set("n", "<C-w><right>", "<C-w>>")
keymap.set("n", "<C-w><up>", "<C-w>+")
keymap.set("n", "<C-w><down>", "<C-w>-")
The s prefix overrides Vim's built-in s (substitute character) — I never use it directly, cl is semantically clearer for that. Reclaiming s gives a clean two-key namespace: ss horizontal, sv vertical, then sh/sj/sk/sl to move in each direction. The hjkl suffix makes the direction obvious with no mental translation required.
Tabs follow the same clarity-first logic:
keymap.set("n", "te", ":tabedit", opts) -- new tab
keymap.set("n", "<tab>", ":tabnext<Return>", opts) -- next tab
keymap.set("n", "<s-tab>", ":tabprev<Return>", opts) -- previous tab
🔍 The Picker Migration: Telescope → fzf-lua → Snacks
The keymaps.lua file contains two large blocks of commented-out code. They are the history of the picker evolution, kept deliberately as a record rather than deleted.
Telescope was the first stop, with the frecency extension ranking files by how often and how recently you open them. Effective, but the startup overhead and extension maintenance burden grew over time.
fzf-lua came next and was noticeably faster — especially for live grep across the monorepo. The grep speed difference on thousands of files across multiple sites and tenants was real and measurable.
Snacks.nvim is where it landed. Folke ships the picker as part of the same plugin that handles the dashboard, notifications, and LazyGit integration. One well-maintained dependency covering a wide surface area beats three separate plugins to juggle. And critically: vim.g.lazyvim_picker = "snacks" in options.lua routes all of LazyVim's default picker calls through Snacks automatically. One line. Zero keymap changes.
The commented-out Telescope and fzf-lua blocks stay in the file as a migration record and occasional reference — the history of decisions made and why.
🖥️ Terminal Mode
Terminal mode is where Neovim keybindings break badly if you do not handle it explicitly. The default escape — <C-\><C-n> — is a two-chord sequence that is awkward to remember under pressure:
keymap.set("t", "<Esc>", [[<C-\><C-n>]], { desc = "Exit Terminal Input Mode" })
keymap.set("t", "<C-h>", [[<C-\><C-n><C-w>h]], { desc = "Move to left pane" })
keymap.set("t", "<C-j>", [[<C-\><C-n><C-w>j]], { desc = "Move to bottom pane" })
keymap.set("t", "<C-k>", [[<C-\><C-n><C-w>k]], { desc = "Move to top pane" })
keymap.set("t", "<C-l>", [[<C-\><C-n><C-w>l]], { desc = "Move to right pane" })
The "t" mode means these only apply inside terminal buffers. <Esc> exits to normal mode. The four <C-hjkl> bindings exit terminal mode and immediately move to the adjacent split. Terminal panes feel like first-class windows, not a special-cased exception.
This matters most with OpenCode running in a vertical split on the right. Jumping between the file being edited and the AI session with <C-h> and <C-l> — without thinking about whether the terminal is in insert mode — is what keeps the flow unbroken. The autocmd from the first article adds a second layer: when the cursor leaves a terminal window, Neovim sends <C-\><C-n> automatically. Together these two mechanisms mean being trapped in terminal insert mode simply does not happen.
🔧 Supporting Keymaps
A few bindings that do not fit a namespace but come up constantly in practice.
<C-j> — Diagnostics jump. Jumps to the next error in the current buffer, skipping warnings and hints. In a TypeScript codebase with a busy diagnostic panel, targeting errors only is significantly faster for triaging what actually matters.
+ / - — Increment and decrement. Replaces <C-a> and <C-x>. The originals conflict with tmux prefix sequences. +/- on the number row feel natural for "more" and "less." Note that discipline.lua tracks - presses — a gentle reminder not to spam decrement either.
<leader>O — Open in browser. Calls vim.ui.open() on the current file and hands it to the OS default application. HTML to the browser, images to Preview, PDFs to the viewer. No filetype conditions. One binding for everything.
<leader>rn — Rename with preview. Opens IncRename, which shows a live preview of the LSP rename as you type across the entire project. The trailing space in :IncRenamepositions the cursor ready for immediate input.
<C-p> — Link paste. Available in normal, visual, and insert mode. Assumes a URL is in the clipboard and inserts it as a plain Markdown link skeleton [](), then pastes the URL into the () portion automatically. Works for any URL, not just GitHub.
What Comes Next 🔭
This article covered the keymap language — the namespace tree, the which-key labeling convention, and every top-level prefix from t (Trouble) through U (Utilities) and what each letter means. It also covered the foundation: discipline, window management, the three-generation picker migration, and terminal mode.
Part 3 goes deep on two areas that deserve their own space: the custom Markdown folding system — a full Treesitter-powered fold expression, a heading inspection utility, and the zj/zk/zl/z; ergonomic progression — and the plugin-specific keymaps that live alongside their plugins: Blink completions, Conform formatting, Multicursor, DAP debugging, Sticky notes, and the Refactoring suite.
If you want to be notified when the next part drops, follow me here on Medium.
The full config lives in my dotfiles repository — fork it, steal what is useful, make it yours.
메타데이터
- post_id
- e839998f3e41
- slug
- leader-everywhere-keymap-philosophy-and-core-bindings-e839998f3e41
- url
- https://medium.com/@my.mvplace/leader-everywhere-keymap-philosophy-and-core-bindings-e839998f3e41
- canonical_url
- https://medium.com/@my.mvplace/leader-everywhere-keymap-philosophy-and-core-bindings-e839998f3e41
- author_url
- https://medium.com/@my.mvplace
- status
- ok
- fetched_at
- 2026-06-14 11:28:49