Fuzzy search, refile, and link insertion for orgmode with telescope.nvim or snacks.nvim picker.
Jump to any heading in your org_agenda_files. You can filter by typing — the search matches against filename, tags, TODO state, and title.
search-headlines.webm
Press <C-Space> to switch to file-level search. Files with a #+TITLE: show the title instead of the filename.
Move a headline under a different parent. Position your cursor on a headline, open the refile picker, and pick the destination.
refile.webm
Pick a tag, then browse the headlines that have it. <C-t> takes you back to the tag list.
tag-search.webm
Search for a headline or file and insert an org link at the cursor.
insert-link.webm
{
"nvim-orgmode/telescope-orgmode.nvim",
event = "VeryLazy",
dependencies = {
"nvim-orgmode/orgmode",
"folke/snacks.nvim",
},
config = function()
local tom = require("telescope-orgmode")
tom.setup({ adapter = "snacks" })
vim.keymap.set("n", "<leader>fh", tom.search_headings, { desc = "Org headlines" })
vim.keymap.set("n", "<leader>ft", tom.search_tags, { desc = "Org tags" })
vim.keymap.set("n", "<leader>r", tom.refile_heading, { desc = "Org refile" })
vim.keymap.set("n", "<leader>li", tom.insert_link, { desc = "Org insert link" })
end,
}{
"nvim-orgmode/telescope-orgmode.nvim",
event = "VeryLazy",
dependencies = {
"nvim-orgmode/orgmode",
"nvim-telescope/telescope.nvim",
},
config = function()
require("telescope").load_extension("orgmode")
local ext = require("telescope").extensions.orgmode
vim.keymap.set("n", "<leader>fh", ext.search_headings, { desc = "Org headlines" })
vim.keymap.set("n", "<leader>ft", ext.search_tags, { desc = "Org tags" })
vim.keymap.set("n", "<leader>r", ext.refile_heading, { desc = "Org refile" })
vim.keymap.set("n", "<leader>li", ext.insert_link, { desc = "Org insert link" })
end,
}-- Telescope
require("telescope").load_extension("orgmode")
-- Snacks
require("telescope-orgmode").setup({ adapter = "snacks" })| Key | Action | Context |
|---|---|---|
<C-Space> |
Toggle between headline and org file search | All pickers |
<C-f> |
Toggle current file filter | Headlines |
<C-t> |
Open tag picker / return to tag list | Headlines / Tags |
<C-s> |
Toggle tag sort (frequency ↔ alphabetical) | Tags |
<CR> |
Confirm selection | All |
Pass options to setup() (Snacks) or telescope.setup({ extensions = { orgmode = { ... } } }) (Telescope). You can also pass them per call.
| Option | Type | Default | Description |
|---|---|---|---|
adapter |
string | 'telescope' |
'telescope' or 'snacks' |
max_depth |
number|nil | nil | Max headline level (nil = all, 0 = files only) |
show_location |
boolean | true | Show filename/category column |
show_tags |
boolean | true | Show tags column |
show_todo_state |
boolean | true | Show TODO state column |
show_priority |
boolean | true | Show priority column |
location_max_width |
number | 15 | Max width for location column |
tags_max_width |
number | 15 | Max width for tags column |
-- Org files only
tom.search_headings({ mode = "orgfiles" })
-- Current file only
tom.search_headings({ only_current_file = true })
-- Limit depth
tom.refile_heading({ max_depth = 3 })
-- Sort tags alphabetically
tom.search_tags({ initial_sort = "alphabetical" })lua/telescope-orgmode/
├── adapters/ # Telescope & Snacks implementations
├── lib/ # Shared logic (actions, config, state, filters)
├── entry_maker/ # Headline/file → picker entry conversion
├── org.lua # Orgmode API wrapper
└── init.lua # Public API, adapter routing
make test # Run tests
make format # Format with StyLua
make lint # Check formatting
make demo-env # Interactive demo environment
make demo # Record demo videos (requires VHS)