Two-panel floating UI for managing favorite directories and files in Neovim
Features • Installation • Quick Start • Configuration • Keymaps • API
|
|
|
Neovim 0.8+ (0.11+ recommended) |
nvim-float (UI framework) |
Optional Dependencies
| Dependency | Purpose |
|---|---|
| nvim-web-devicons | Enhanced file type icons |
| mini.icons | Alternative icon provider |
| Nerd Font | Proper icon display in terminal |
{
"mikevskater/nvim-favdir",
dependencies = {
"mikevskater/nvim-float",
"nvim-tree/nvim-web-devicons", -- optional
},
cmd = { "FavdirOpen", "FavdirToggle", "FavdirAddDir", "FavdirAddFile" },
keys = {
{ "<leader>ofd", "<cmd>FavdirOpen<cr>", desc = "Open favorite directories" },
},
opts = {
-- Overrideable controls
keymaps = {
open = "<leader>ofd",
confirm = "<CR>",
expand_or_browse = "o",
go_up = "<BS>",
next_panel = "<Tab>",
prev_panel = "<S-Tab>",
add = "a",
delete = "d",
rename = "r",
move = "m",
move_group = "M",
sort = "s",
sort_order = "S",
reorder_up = "<C-k>",
reorder_down = "<C-j>",
open_split = "<C-s>",
open_vsplit = "|",
open_tab = "<C-t>",
yank_path = "y",
refresh = "R",
collapse_all = "zM",
toggle_hidden = ".",
close = "q",
close_alt = "<Esc>",
}
},
}Other Package Managers
packer.nvim
use {
"mikevskater/nvim-favdir",
requires = { "mikevskater/nvim-float" },
config = function()
require("nvim-favdir").setup()
end
}vim-plug
Plug 'mikevskater/nvim-float'
Plug 'mikevskater/nvim-favdir'
" After plug#end():
lua require('nvim-favdir').setup()mini.deps
add({ source = "mikevskater/nvim-float" })
add({ source = "mikevskater/nvim-favdir" })|
Open the UI require("nvim-favdir").setup()
-- Then use:
-- :FavdirOpen
-- or <leader>ofd |
Add Favorites -- Add current directory
:FavdirAddDir
-- Add current file
:FavdirAddFile
-- Or press 'a' in the UI |
Navigate |
Default Configuration
require('nvim-favdir').setup({
-- File paths
data_file = vim.fn.stdpath('data') .. '/favdirs.json',
ui_state_file = vim.fn.stdpath('data') .. '/favdirs_ui_state.json',
-- Window sizing (0.0 to 1.0)
window_height_ratio = 0.7, -- 70% of editor height
window_width_ratio = 0.8, -- 80% of editor width
left_panel_width_ratio = 0.35, -- 35% for groups panel
-- Groups
default_groups = {}, -- Groups created on first run
protected_groups = {}, -- Groups that cannot be deleted
-- Display
use_nerd_font = true, -- Auto-detected if available
-- Debug
debug_mode = false,
log_to_file = false,
})| Option | Type | Default | Description |
|---|---|---|---|
data_file |
string | ~/.local/share/nvim/favdirs.json |
Path to data file |
ui_state_file |
string | ~/.local/share/nvim/favdirs_ui_state.json |
Path to UI state |
window_height_ratio |
number | 0.7 |
Window height ratio |
window_width_ratio |
number | 0.8 |
Window width ratio |
left_panel_width_ratio |
number | 0.35 |
Left panel width ratio |
default_groups |
string[] | {} |
Groups created on first run |
protected_groups |
string[] | {} |
Groups that cannot be deleted |
use_nerd_font |
boolean | true |
Use Nerd Font icons |
cd_command |
string | "lcd" |
Directory change command ("cd", "lcd", "tcd") |
debug_mode |
boolean | false |
Enable debug logging |
Example: Custom Groups
require('nvim-favdir').setup({
default_groups = {
"Work",
"Work.Active",
"Work.Archive",
"Projects",
"Config",
},
protected_groups = { "Work", "Config" },
})Example: Custom Window Size
require('nvim-favdir').setup({
window_height_ratio = 0.9,
window_width_ratio = 0.95,
left_panel_width_ratio = 0.4,
})| Command | Description |
|---|---|
:FavdirOpen |
Open the favorite directories UI |
:FavdirToggle |
Toggle the UI (open/close) |
:FavdirAddDir |
Add current working directory to favorites |
:FavdirAddFile |
Add current buffer's file to favorites |
All keymaps are customizable via the keymaps option in setup.
Navigation
| Key | Left Panel | Right Panel |
|---|---|---|
<CR> |
Select group | Open file / cd to dir |
<Tab> |
Switch to right panel | Switch to left panel |
<S-Tab> |
Switch to right panel | Switch to left panel |
o |
Expand/collapse group | Browse folder contents |
<BS> |
— | Go up folder level |
Actions
| Key | Left Panel | Right Panel |
|---|---|---|
a |
Add group or dir link | Add item to group |
d |
Delete group/dir link | Remove item |
r |
Rename / set nickname | Set item display name |
m |
— | Move item to group |
M |
Move group to parent | — |
y |
Copy group path | Copy item path |
Sorting
| Key | Action |
|---|---|
s |
Cycle sort mode |
S |
Toggle ascending/descending |
<C-k> |
Reorder item up |
<C-j> |
Reorder item down |
Sort modes:
- Groups:
custom→alpha - Items:
custom→name→created→modified→size→type
View
| Key | Action |
|---|---|
R |
Refresh all panels (reload data, clear caches) |
zM |
Collapse all expanded groups |
. |
Toggle hidden files (dotfiles) in directory views |
Opening (Right Panel)
| Key | Action |
|---|---|
<C-s> |
Open in horizontal split |
| |
Open in vertical split |
<C-t> |
Open in new tab |
Window
| Key | Action |
|---|---|
q |
Close UI |
<Esc> |
Close UI |
Custom Keymaps
require('nvim-favdir').setup({
keymaps = {
open = "<leader>fd", -- Change global keymap
delete = "x", -- Use 'x' instead of 'd'
add = "n", -- Use 'n' instead of 'a'
close = "q",
-- Set to false to disable
close_alt = false,
}
})local favdir = require('nvim-favdir')| Function | Description |
|---|---|
favdir.setup(opts) |
Initialize with configuration |
favdir.show() |
Open the UI |
favdir.toggle() |
Toggle UI visibility |
favdir.add_cwd(group?) |
Add cwd to group (prompts if nil) |
favdir.add_file(group?) |
Add current file to group |
favdir.get_data() |
Get all data (groups, items) |
favdir.get_groups() |
Get list of group paths |
Usage Examples
-- Custom keymap
vim.keymap.set('n', '<leader>fd', require('nvim-favdir').toggle)
-- Add current directory to a specific group
vim.keymap.set('n', '<leader>fa', function()
require('nvim-favdir').add_cwd("Work")
end)
-- List all groups
local groups = require('nvim-favdir').get_groups()
-- { "Work", "Work.Active", "Projects", ... }
-- Get all data for external use
local data = require('nvim-favdir').get_data()
for _, group in ipairs(data.groups) do
print(group.name, #group.items .. " items")
endNote: See
:help favdirfor complete API documentation.
|
Main Data ( {
"groups": [
{
"name": "Work",
"order": 1,
"items": [
{ "path": "/path/to/dir", "type": "dir", "order": 1 }
],
"children": [],
"dir_links": []
}
]
} |
UI State ( {
"expanded_groups": ["Work"],
"last_selected_group": "Work",
"focused_panel": "left",
"left_cursor": { "row": 1, "col": 0 },
"right_cursor": { "row": 1, "col": 0 },
"left_sort_mode": "custom",
"right_sort_mode": "name"
} |
Run :echo stdpath('data') to see your data directory path.
Icons not displaying correctly?
Install a Nerd Font and set it in your terminal.
Popular choices: FiraCode, JetBrainsMono, Hack
How do I reset all data?
rm ~/.local/share/nvim/favdirs.json
rm ~/.local/share/nvim/favdirs_ui_state.jsonThen restart Neovim.
How do I enable debug logging?
require('nvim-favdir').setup({
debug_mode = true,
log_to_file = true, -- writes to ~/.local/share/nvim/favdir.log
})How do nested groups work?
Use dot notation: "Work.Projects.Active" creates:
Work/
└── Projects/
└── Active/
What are directory links?
Directory links let you browse a filesystem directory in the right panel without adding its contents as individual items. Useful for frequently accessed folders.
Press a in the left panel and choose "Directory Link" to create one.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Found a bug or have a feature request? Please open an issue on GitHub Issues.
|
When opening an issue, please include:
|


