🌲 Otree.nvim
Otree.nvim is a lightweight and customizable file tree explorer for Neovim, built for speed, simplicity, and seamless user experience. It optionally integrates with oil.nvim to provide an elegant and efficient file operations workflow.
✨ Features
- Fast and responsive file tree using
fd(optional) - Optional integration with
oil.nvimfor enhanced file operations - Supports icons from mini.icons, nvim-web-devicons, or a default fallback
- Optional Git and LSP signs to show file changes and diagnostics
- Highly customizable keybindings and appearance
- Optional Netrw hijack for a cleaner startup experience
- Toggle visibility for hidden and ignored files
- Floating window support with adjustable dimensions
⚙️ Requirements
Optional Dependencies
fd- For faster directory traversaloil.nvim- For file operations (create, delete, move, rename files/directories)
📦 Installation
Using lazy.nvim:
return {
"Eutrius/Otree.nvim",
lazy = false,
dependencies = {
-- Optional: Enhanced file operations
"stevearc/oil.nvim",
-- Optional: Icon support
-- { "echasnovski/mini.icons", opts = {} },
-- "nvim-tree/nvim-web-devicons",
},
config = function()
require("Otree").setup()
end
}
⚙️ Configuration
Here is the default configuration, which can be customized to suit your preferences:
require("Otree").setup({
win_size = 30,
open_on_startup = false,
use_default_keymaps = true,
hijack_netrw = true,
show_hidden = false,
show_ignore = false,
cursorline = true,
focus_on_enter = false,
open_on_left = true,
git_signs = false,
lsp_signs = false,
oil = "float",
ignore_patterns = {},
keymaps = {
["<CR>"] = "actions.select",
["l"] = "actions.select",
["h"] = "actions.close_dir",
["<Esc>"] = "actions.close_win",
["<C-h>"] = "actions.goto_parent",
["<C-l>"] = "actions.goto_dir",
["<M-h>"] = "actions.goto_home_dir",
["cd"] = "actions.change_home_dir",
["L"] = "actions.open_dirs",
["H"] = "actions.close_dirs",
["o"] = "actions.oil_dir",
["O"] = "actions.oil_into_dir",
["t"] = "actions.open_tab",
["v"] = "actions.open_vsplit",
["s"] = "actions.open_split",
["."] = "actions.toggle_hidden",
["i"] = "actions.toggle_ignore",
["r"] = "actions.refresh",
["f"] = "actions.focus_file",
["?"] = "actions.open_help",
},
tree = {
space_after_icon = " ",
space_after_connector = " ",
connector_space = " ",
connector_last = "└",
connector_middle = "├",
vertical_line = "│",
},
icons = {
title = " ",
default_file = "",
default_directory = "",
empty_dir = "",
trash = " ",
keymap = "⌨ ",
oil = " ",
},
highlights = {
directory = "Directory",
file = "Normal",
tree = "Comment",
title = "Title",
float_normal = "NormalFloat",
float_border = "FloatBorder",
link_path = "Comment",
git_ignored = "NonText",
git_untracked = "DiagnosticInfo",
git_modified = "DiagnosticWarn",
git_added = "DiagnosticHint",
git_deleted = "DiagnosticError",
git_conflict = "DiagnosticError",
git_renamed = "DiagnosticHint",
git_copied = "DiagnosticHint",
lsp_warn = "DiagnosticWarn",
lsp_info = "DiagnosticInfo",
lsp_hint = "DiagnosticHint",
lsp_error = "DiagnosticError",
},
float = {
center = true,
width_ratio = 0.4,
height_ratio = 0.7,
padding = 2,
cursorline = true,
border = "rounded",
},
})
🗝️ Keybindings
| Keybinding | Action |
|---|---|
<CR>, l |
Select file or open folder |
h |
Close selected directory |
<Esc> |
Close file tree window |
<C-h> |
Navigate to parent directory |
<C-l> |
Enter selected directory |
<M-h> |
Go to home directory |
cd |
Change home directory |
L |
Open all directories at the same level |
H |
Close all directories at the same level |
o |
Open parent directory in Oil* |
O |
Open selected directory in Oil* |
t |
Open file in new tab |
v |
Open file in vertical split |
s |
Open file in horizontal split |
. |
Toggle hidden files visibility |
i |
Toggle ignored files visibility |
r |
Refresh tree view |
f |
Focus the previous buffer |
? |
Show help with keybinding reference |
*Requires oil.nvim for file operations
🧪 User Commands
| Command | Description |
|---|---|
:Otree |
Toggle the file tree window |
:OtreeFocus |
Focus the file tree window |
🎨 Highlight Groups
Otree defines the following highlight groups that you can customize to match your colorscheme:
| Highlight Group | Default Link | Description |
|---|---|---|
OtreeDirectory |
Directory |
Directory names in the tree |
OtreeFile |
Normal |
File names in the tree |
OtreeTree |
Comment |
Tree connectors and lines |
OtreeTitle |
Title |
Window title |
OtreeFloatNormal |
NormalFloat |
Floating window background |
OtreeFloatBorder |
FloatBorder |
Floating window border |
OtreeLinkPath |
Comment |
Symlink path display |
OtreeGitUntracked |
DiagnosticInfo |
Git untracked files |
OtreeGitIgnored |
NonText |
Git ignored files |
OtreeGitModified |
DiagnosticWarn |
Git modified files |
OtreeGitAdded |
DiagnosticHint |
Git added files |
OtreeGitDeleted |
DiagnosticError |
Git deleted files |
OtreeGitConflict |
DiagnosticError |
Git merge conflicts |
OtreeGitRenamed |
DiagnosticHint |
Git renamed files |
OtreeGitCopied |
DiagnosticHint |
Git copied files |
OtreeLspInfo |
DiagnosticInfo |
LSP informational messages |
OtreeLspHint |
DiagnosticHint |
LSP hints and suggestions |
OtreeLspWarn |
DiagnosticWarn |
LSP warnings |
OtreeLspError |
DiagnosticError |
LSP errors |
🔧 Git Signs
Otree uses a set of icons and highlight groups to visually indicate Git status within the tree view.
| Git Status | Symbol | Icon | Highlight Group |
|---|---|---|---|
| Ignored | ! |
! |
OtreeGitIgnored |
| Untracked | ? |
? |
OtreeGitUntracked |
| Modified | M |
~ |
OtreeGitModified |
| Added | A |
+ |
OtreeGitAdded |
| Deleted | D |
- |
OtreeGitDeleted |
| Renamed | R |
> |
OtreeGitRenamed |
| Copied | C |
= |
OtreeGitCopied |
| Conflict | U |
! |
OtreeGitConflict |
🔧 Lsp Signs
Otree uses a fix icon "•" and a set of highlight groups to visually indicate Lsp diagnostics within the tree view.
| Lsp Diagnostic | Highlight Group |
|---|---|
| Info | OtreeLspInfo |
| Hint | OtreeLspHint |
| Warn | OtreeLspWarn |
| Error | OtreeLspError |
⚙️ Oil.nvim Integration
Otree can optionally integrate with oil.nvim for enhanced file management capabilities.
⚠️ Note: Without oil.nvim, there are no file operations available (create, delete, move, rename). Oil integration is required for any file management beyond basic navigation and opening.
Automatic Configuration
If oil.nvim is installed but not already configured, Otree will automatically set it up with these optimized defaults:
require("oil").setup({
default_file_explorer = false,
skip_confirm_for_simple_edits = true,
delete_to_trash = true,
cleanup_delay_ms = false,
})
If Oil is already configured, Otree respects your existing setup and will not override any settings.
Opening Modes
You can configure how Oil opens using the oil option in your Otree setup:
require("Otree").setup({
oil = "float" -- Opens Oil in a floating window (default)
-- Any other value opens Oil directly inside the tree window
})
Hidden Files Synchronization
Toggling hidden files in Otree automatically syncs with Oil's view_options.show_hidden setting, ensuring consistent visibility across both interfaces.
Dynamic Titles
Oil views display dynamically generated titles with icons and relative paths for better context and navigation.
⚠️ Important Note
Do not use oil_preview when Oil is open in floating mode. This may cause rendering or focus issues. Close floating Oil windows before using preview functionality.
🔧 Fallback Behavior
When optional dependencies are not available:
- Without
fd: Falls back to basic directory listing (slower performance) - Without
oil.nvim: No file operations available - only navigation and opening files is supported - Without icon plugins: Uses simple default icons for files and directories