_ __ _______ __
/ | / /__ ____ / ____(_)___ ____/ /__ _____
/ |/ / _ \/ __ \/ /_ / / __ \/ __ / _ \/ ___/
/ /| / __/ /_/ / __/ / / / / / /_/ / __/ /
/_/ |_/\___/\____/_/ /_/_/ /_/\__,_/\___/_/
File browser, command runner and editor toolkit for Vim/Neovim.
Installation
Plug 'mefardales/neofinder'
curl -fsSL https://raw.githubusercontent.com/mefardales/neofinder/main/install.sh | bash
git clone https://github.com/mefardales/neofinder.git ~/.vim/pack/plugins/start/neofinder
git clone https://github.com/mefardales/neofinder.git ~/.local/share/nvim/site/pack/plugins/start/neofinder
Palette
Open with :Neo or <Leader>fp. Everything starts here:
Browse :ff file browser
Favorites :fv bookmarked directories
Buffers :fb open buffers
Tags :fg tagged file groups
Terminal :fR open terminal
Run :fr execute commands
Commands :fe edit/create commands
Config :fc config.toml
Keybindings
Palette & Navigation
| <Leader>fp | Palette |
| <Leader>ff | File browser |
| <Leader>fv | Favorites |
| <Leader>fb | Buffers |
| <Leader>fg | Tag groups |
| <Leader>ft | Tag file |
| <Leader>fu | Untag file |
| <Leader>fr | Run commands |
| <Leader>fe | Edit commands |
| <Leader>fc | Config |
Inside the Finder
| Enter | Open / enter dir |
| Backspace | Go up / back |
| Ctrl-V | Vertical split |
| Ctrl-X | Horizontal split |
| Ctrl-T | Tag file |
| Ctrl-D | Untag / delete |
| Ctrl-B | Buffer list |
| Ctrl-R | Refresh cache |
| Tab | Finder ↔ editor |
| Ctrl-W +/- | Resize panel |
| Esc | Close |
Search Modes
The mode is detected automatically by what you type:
| Query | Mode |
|---|---|
| main | Fuzzy match |
| *.py | Glob filter |
| test_* | Glob filter |
| Query | Mode |
|---|---|
| ~/ | Navigate to home |
| /etc/ | Navigate to /etc |
| ../ | Go up one level |
File Browser
Open with <Leader>ff. Lists current directory. Type to search.
Fuzzy & Glob
Type letters for fuzzy match. Use *.py or test_* for glob patterns.
Path Navigation
Type ~/, /etc/, or ../ to jump to any directory.
Cached & Indexed
Listings are cached. Python indexes the full tree on first search (lazy, non-blocking).
Auto-cd
Set autochdir = true in config. cwd follows the active file.
Tags & Favorites
Tags
Bookmark files into named groups.
| <Leader>ft | Tag current file |
| <Leader>fu | Untag current file |
| <Leader>fg | Browse groups |
| Ctrl-T | Tag in finder |
| Ctrl-D | Untag in finder |
Stored in ~/.neofinder/tags:
servers:/etc/nginx/nginx.conf
dotfiles:/home/user/.bashrc
Favorites
Bookmark directories for quick access.
| <Leader>fv | Open favorites |
| Enter on [+] | Add current dir |
| Enter | Open browser there |
| Ctrl-D | Remove favorite |
Stored in ~/.neofinder/favorites, one dir per line.
Windows & Buffers
Windows
| <Leader>sv | Vertical split |
| <Leader>sh | Horizontal split |
| <Leader>sc | Close window |
| Shift+Tab | Cycle windows |
| Shift+Arrow | Resize |
Buffers & Terminal
| <Leader>bn | Next buffer |
| <Leader>bp | Previous buffer |
| <Leader>fb | Buffer list |
| Shift+Tab | Terminal → editor |
| PageUp/Down | Scroll terminal |
Command System
Every command is a .toml handler + .py logic. The TOML declares the contract (inputs, validation, output), the .py focuses on logic. Shell-only commands need no .py at all.
name = "NetScan"
desc = "Ping sweep or port check"
deps = ["input", "output", "shell"]
out = "[Scan ${host}]"
filetype = "log"
[in]
host = "Host/IP: "
[validate]
commands = ["ping"]
[header]
show = true
separator = "="
width = 50
info = ["host"]
[error]
empty = "Host unreachable"
# host is auto-injected from [in]
# header is auto-printed from [header]
stdout, stderr, rc = nf.sh(
"ping -c 3 %s" % host
)
STDOUT.write(stdout.splitlines())
if rc != 0:
STDERR.print("Host unreachable")
name = "DiskUsage"
desc = "Disk usage summary"
deps = ["output", "shell"]
out = "[Disk Usage]"
[shell]
cmd = "df -h"
Handler fields
| Field | Type | Description |
|---|---|---|
| name | string | Command name (PascalCase) |
| desc | string | Description in palette |
| deps | array | input, output, shell, buffer, tags |
| out | string | Output buffer title. Supports ${var} |
| filetype | string | Syntax highlight for output buffer (log, git, etc.) |
| timeout | int | Kill after N seconds |
| platform | string | Restrict to OS: "linux,darwin" |
| silent | bool | If true, don't open output buffer |
| pipe | string | "buffer" loads current buffer into STDIN |
Input [in]
| Format | Example | Description |
|---|---|---|
| Simple | host = "Host: " | String prompt |
| Default | port = { prompt = "Port: ", default = "80" } | Pre-filled value |
| Options | mode = { prompt = "Mode: ", options = ["fast", "full"] } | Select from list |
| Confirm | ok = { prompt = "Continue?", type = "confirm" } | Yes/no dialog |
| File | path = { prompt = "File: ", type = "file" } | Path with tab completion |
Sections
[validate]
commands = ["git"] require binaries
filetype = ["python"] restrict filetypes
min_lines = 1 buffer must have content
[env]
Auto-injected variables (no prompt):
timestamp = "datetime.now()..."
cwd = "nf.dir"
[header]
show = true auto-print header
separator = "=" width = 50
info = ["host"] show input vars
[shell]
Run shell cmd without .py:
cmd = "df -h"
Supports ${var} interpolation
[error]
empty = "No results" when STDOUT empty
fail = "Failed" on non-zero exit
[in] + [env] + [shell]
Combine them for powerful shell-only commands that ask input, validate, and run without any Python.
Pipeline
Chain steps like Airflow DAGs: a >> b >> c >> d. Each step's STDOUT flows as STDIN to the next.
[pipeline]
chain = "scan >> filter >> sort"
on_fail = "stop"
[pipeline.steps]
scan = { type = "shell", cmd = "lsof -i -nP" }
filter = { type = "shell", cmd = "grep LISTEN" }
sort = { type = "shell", cmd = "sort -k2" }
# Step types:
# shell = run shell command
# command = run NeoFinder command
# python = eval python code
# on_fail per step or global:
# stop = abort pipeline
# continue = keep going
# skip = skip, pass prev output
Standard I/O
STDIN
.text .lines .varname
Input from handler [in] or pipe
STDOUT / STDERR
.print() .write()
STDOUT → output buffer. STDERR → error messages.
Python API
Available as nf.* inside every command.
Context
nf.file # full path
nf.filename # name only
nf.dir # cwd
nf.line # current line
nf.filetype
nf.theme
Shell
out, err, rc = nf.sh("cmd")
nf.sh_output("cmd")
nf.sh_lines("cmd")
Input
nf.input("prompt")
nf.confirm("sure?")
nf.select(["a", "b"])
Buffer
nf.buf.lines / .text / .name
nf.buf.line / .line_number
nf.buf.selection
nf.buf.write(x)
nf.buf.append(x)
nf.buf.clear()
nf.buf[0] = "x"
Files & Tags
nf.open(p) / .vsplit(p)
nf.split(p) / .scratch(lines)
nf.buffers()
nf.tags.groups()
nf.tags.files("group")
nf.tags.add(path, "group")
Messages
nf.echo("msg")
nf.warn("msg")
nf.error("msg")
Built-in Commands
| Command | Description |
|---|---|
| HelloWorld | System check |
| HelloDemo | API reference |
| RunHere | Run shell command |
| GitLog | Git commits |
| GrepHere | Grep in cwd |
| Command | Description |
|---|---|
| SortBuffer | Sort buffer lines |
| TaggedFiles | Tags by group |
| NetInfo | Network info |
| NetScan | Port scan |
| NetConns | Connections |
Configuration
All settings in ~/.neofinder/config.toml. Open with <Leader>fc. Save to apply instantly.
[theme]
name = "matrix"
brightness = 0 # -40 to 40
background = "" # "" or "#1a1a2e"
bold_keywords = true
italic_comments = true
transparent_bg = false
guifont = "" # "JetBrains Mono:h12"
[finder]
height = 15
preview = true
max_files = 50000
show_hidden = true
sort_by = "name" # "name", "modified", "size"
[statusline]
enabled = true
show_clock = true
show_branch = true
[editor]
line_numbers = false
tabstop = 4
expandtab = true
autochdir = true
hidden = true
swapfile = false
undofile = true
splitright = true
mouse = "a"
[search]
ignorecase = true
smartcase = true
hlsearch = true
[on_save]
trim_whitespace = true
final_newline = true
[keybindings]
enabled = true
[keybindings.map]
Ctrl+s = ":w<CR>"
F5 = ":!python3 %<CR>"
# Single letter = <Leader>nf + letter
[keybindings.commands]
a = "NetInfo"
b = "NetScan"
Themes
matrix
Green on black (default)
Custom themes: ~/.neofinder/themes/<name>.vim. Set name = "matrix" under [theme] in config.
Project Structure
neofinder/
├── plugin/neofinder.vim Commands, mappings, startup
├── autoload/neofinder.vim Palette, browse, backend
├── autoload/neofinder/
│ ├── core.vim Finder UI, fuzzy/glob filter
│ ├── config.vim TOML config loader
│ ├── python.vim Command system (.py + .toml)
│ ├── tags.vim Tags, favorites
│ ├── actions.vim Open, split, tag, execute
│ ├── sources.vim Data gathering
│ ├── theme.vim Matrix theme + customizations
│ ├── statusline.vim Powerline statusline
│ ├── preview.vim File preview
│ ├── buffers.vim Buffer manager, terminal
│ ├── indexer.vim + .py Fast file indexer
│ ├── runtime.py Python runtime (nf.*)
│ ├── toml_parser.py TOML parser
│ └── commands/ Built-in .toml + .py pairs
├── docs/index.html This page
├── install.sh
└── README.md
Help
*neofinder.txt* File browser, command runner and editor toolkit
Author: mefardales
License: MIT
Repo: https://github.com/mefardales/neofinder
CONTENTS *neofinder-contents*
1. Overview .............. |neofinder-overview|
2. Quick start ........... |neofinder-quickstart|
3. Mappings .............. |neofinder-mappings|
4. Commands .............. |neofinder-commands|
5. Configuration ......... |neofinder-config|
1. OVERVIEW *neofinder-overview*
NeoFinder is a file browser with fuzzy/glob search, a tag
system, a command runner with Python scripting, and split/buffer
management. Everything is accessed through a single palette.
2. QUICK START *neofinder-quickstart*
Install with your plugin manager and run:
>
:Neo
<
This opens the palette. From there:
:ff file browser :fv favorites
:fb buffers :fg tag groups
:fr run command :fe edit commands
:fc config :fR terminal
3. MAPPINGS *neofinder-mappings*
<Leader>fp Open palette
<Leader>ff File browser
<Leader>fv Favorites
<Leader>fb Buffers
<Leader>fg Tag groups
<Leader>ft Tag current file
<Leader>fu Untag current file
Inside finder:
<CR> Open file / enter directory
<BS> Go up / back
<C-v> Open in vertical split
<C-x> Open in horizontal split
<C-t> Tag file
<C-d> Untag / delete
<Tab> Toggle finder / editor
<Esc> Close finder
4. COMMANDS *neofinder-commands*
Commands are .toml + .py pairs in ~/.neofinder/commands/.
:NeoRun {name} Run a command by name
:NeoEdit {name} Edit a command
:NeoNew Create new command
The Python runtime exposes nf.* for shell, buffers, I/O:
>
out, err, rc = nf.sh("ls -la")
nf.buf.append(out.splitlines())
nf.echo("Done")
<
5. CONFIGURATION *neofinder-config*
All settings live in ~/.neofinder/config.toml.
Open with <Leader>fc and save to apply.
>
[theme]
name = "matrix" " only theme: matrix
[finder]
height = 15
preview = true
[editor]
tabstop = 4
expandtab = true
<
vim:tw=78:ts=8:ft=help:norl: