Skip to content

mikevskater/nvim-favdir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nvim-favdir

Two-panel floating UI for managing favorite directories and files in Neovim

Neovim Lua License

FeaturesInstallationQuick StartConfigurationKeymapsAPI


Demo

nvim-favdir demo


Features

Core

  • Hierarchical groups with nested subgroups
  • Add favorite directories and files
  • Directory links for filesystem browsing
  • Persistent storage (JSON)
  • Protected groups (prevent deletion)

Two-Panel UI

  • Left panel: Groups and directory links
  • Right panel: Items or directory contents
  • Tab/Shift-Tab panel navigation
  • Cursor position persistence
  • Configurable window dimensions

Sorting

  • Groups: Custom order, Alphabetical
  • Items: Custom, Name, Created, Modified, Size, Type
  • Toggle ascending/descending
  • Manual reordering with Ctrl+K/J

File Operations

  • Open files in current window
  • Open in horizontal split (<C-s>)
  • Open in vertical split (|)
  • Open in new tab (<C-t>)
  • cd into directories

UI Polish

  • Nerd Font icons with ASCII fallback
  • nvim-web-devicons integration
  • Expand/collapse group hierarchy
  • State persistence across sessions

Management

  • Add, rename, delete groups
  • Move items between groups
  • Move groups to different parents
  • Bulk operations via directory links

Requirements

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

Installation

lazy.nvim (Recommended)

{
  "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" })

Quick Start

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

<Tab>     Switch panels
<CR>      Open/select
o         Expand/browse
<BS>      Go up folder
q         Close

Configuration

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,
})

Options Reference

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,
})

Commands

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

Keymaps

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

Group management demo

Sorting
Key Action
s Cycle sort mode
S Toggle ascending/descending
<C-k> Reorder item up
<C-j> Reorder item down

Sort modes:

  • Groups: customalpha
  • Items: customnamecreatedmodifiedsizetype

Sorting demo

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,
  }
})

API

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")
end

Note: See :help favdir for complete API documentation.


Data Files

Main Data (favdirs.json)

{
  "groups": [
    {
      "name": "Work",
      "order": 1,
      "items": [
        { "path": "/path/to/dir", "type": "dir", "order": 1 }
      ],
      "children": [],
      "dir_links": []
    }
  ]
}

UI State (favdirs_ui_state.json)

{
  "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.


FAQ

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.json

Then 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.


Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Commit your changes (git commit -m 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Issues

Found a bug or have a feature request? Please open an issue on GitHub Issues.

When opening an issue, please include:

  • Bug or Feature — Label your issue type
  • Description — Clear description of the issue or feature
  • Steps to Reproduce — Minimal steps to reproduce (for bugs)
  • Expected Behavior — What you expected to happen

License

MIT License — see LICENSE for details.


Made with Lua for Neovim

About

Two-panel floating UI for managing favorite directories and files in Neovim

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages