"I've been using Vim for about 2 years now, mostly because I can't figure out how to exit it." (I Am Developer)
This Lua plugin for Neovim brings together hundreds of helpful tips, tricks, and shortcuts, all available through a custom picker. It's easy to expand with your own entries, so the collection grows with you and your workflow.






I started to work on this little plugin because I love neovim and I still remember how difficult it was to learn the basic commands.
The plugin should help you to learn some basic (:wq, write and quit) and some not so basic commands (ddp, move line down) related to neovim.
I have provided a solid initial batch of tips and if you have your favorite one that is not listed, I will be happy to include it in the next release with proper credits. Send your commands, tips and tricks to me, create an issue or submit a pull request. You can also add your own tips and tricks that will be stored on your local computer, you don't have to share anything with me.
nui.nvim - no heavyweight pickers (fzf-lua, telescope, snacks, mini...)markview.nvim, render-markdown.nvim, or raw markdown display (auto-detected){
"saxon1964/neovim-tips",
version = "*", -- Only update on tagged releases
dependencies = {
"MunifTanjim/nui.nvim",
-- OPTIONAL: Choose your preferred markdown renderer (or omit for raw markdown)
"MeanderingProgrammer/render-markdown.nvim", -- Clean rendering
-- OR: "OXY2DEV/markview.nvim", -- Rich rendering with advanced features
},
opts = {
-- OPTIONAL: Location of user defined tips (default value shown below)
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
-- OPTIONAL: Prefix for user tips to avoid conflicts (default: "[User] ")
user_tip_prefix = "[User] ",
-- OPTIONAL: Show warnings when user tips conflict with builtin (default: true)
warn_on_conflicts = true,
-- OPTIONAL: Daily tip mode (default: 1)
-- 0 = off, 1 = once per day, 2 = every startup
daily_tip = 1,
-- OPTIONAL: Bookmark symbol (default: "🌟 ")
bookmark_symbol = "🌟 ",
},
init = function()
-- OPTIONAL: Change to your liking or drop completely
-- The plugin does not provide default key mappings, only commands
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
end
}
use {
"saxon1964/neovim-tips",
tag = "*", -- Only update on tagged releases
requires = {
"MunifTanjim/nui.nvim",
-- OPTIONAL: Choose your preferred renderer
"MeanderingProgrammer/render-markdown.nvim", -- OR "OXY2DEV/markview.nvim"
},
config = function()
require("neovim_tips").setup {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
user_tip_prefix = "[User] ", -- Prefix for user tips
warn_on_conflicts = true, -- Warn about title conflicts
daily_tip = 1, -- Daily tip: 0=off, 1=once per day, 2=every startup
}
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
end
}
Plug 'MunifTanjim/nui.nvim'
Plug 'MeanderingProgrammer/render-markdown.nvim'
Plug 'saxon1964/neovim-tips', { 'tag': '*' } " Only update on tagged releases
lua << EOF
require("neovim_tips").setup {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
daily_tip = 1, -- Daily tip: 0=off, 1=once per day, 2=every startup
}
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
EOF
call minpac#init()
call minpac#add('MunifTanjim/nui.nvim')
call minpac#add('MeanderingProgrammer/render-markdown.nvim')
call minpac#add('saxon1964/neovim-tips', {'tag': '*'}) " Only update on tagged releases
lua << EOF
require("neovim_tips").setup {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
daily_tip = 1, -- Daily tip: 0=off, 1=once per day, 2=every startup
}
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
EOF
require "paq" {
"MunifTanjim/nui.nvim";
"MeanderingProgrammer/render-markdown.nvim";
{ "saxon1964/neovim-tips", tag = "*" }; -- Only update on tagged releases
}
require("neovim_tips").setup {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
daily_tip = 1, -- Daily tip: 0=off, 1=once per day, 2=every startup
}
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
call dein#begin('~/.cache/dein')
call dein#add('MunifTanjim/nui.nvim')
call dein#add('MeanderingProgrammer/render-markdown.nvim')
call dein#add('saxon1964/neovim-tips')
call dein#end()
lua << EOF
require("neovim_tips").setup {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
daily_tip = 1, -- Daily tip: 0=off, 1=once per day, 2=every startup
}
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
EOF
WARNING: vim.pack, Neovim's built-in plugin manager, is still being developed! Early testing of existing features is appreciated, but expect breaking changes without notice. More information can be found in the official documentation.
vim.pack.add({
"https://github.com/MunifTanjim/nui.nvim",
"https://github.com/saxon1964/neovim-tips",
})
require("neovim_tips").setup({
-- Path to user tips file
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
-- Prefix added to user tip titles to prevent conflicts
user_tip_prefix = "[User] ",
-- Show warnings when user tips have conflicting titles with builtin tips
warn_on_conflicts = true,
-- Daily tip mode: 0=off, 1=once per day, 2=every startup
daily_tip = 1,
})
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
require("lazy").setup({
{
"saxon1964/neovim-tips",
dependencies = {
"MunifTanjim/nui.nvim",
"MeanderingProgrammer/render-markdown.nvim"
},
opts = {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
},
init = function()
local map = vim.keymap.set
map("n", "<leader>nto", ":NeovimTips<CR>", { desc = "Neovim tips", noremap = true, silent = true })
map("n", "<leader>nte", ":NeovimTipsEdit<CR>", { desc = "Edit your Neovim tips", noremap = true, silent = true })
map("n", "<leader>nta", ":NeovimTipsAdd<CR>", { desc = "Add your Neovim tip", noremap = true, silent = true })
map("n", "<leader>nth", ":help neovim-tips<CR>", { desc = "Neovim tips help", noremap = true, silent = true })
map("n", "<leader>ntr", ":NeovimTipsRandom<CR>", { desc = "Show random tip", noremap = true, silent = true })
map("n", "<leader>ntp", ":NeovimTipsPdf<CR>", { desc = "Open Neovim tips PDF", noremap = true, silent = true })
end,
},
})
File lua/user/plugins/neovim_tips.lua:
return {
{
"saxon1964/neovim-tips",
dependencies = {
"MunifTanjim/nui.nvim",
"MeanderingProgrammer/render-markdown.nvim"
},
opts = {
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
},
},
}
File lua/user/mappings.lua
return {
n = {
["<leader>nto"] = { "<cmd>NeovimTips<cr>", desc = "Neovim tips" },
["<leader>nte"] = { "<cmd>NeovimTipsEdit<cr>", desc = "Edit your Neovim tips" },
["<leader>nta"] = { "<cmd>NeovimTipsAdd<cr>", desc = "Add your Neovim tip" },
["<leader>nth"] = { "<cmd>help neovim-tips<cr>", desc = "Neovim tips help" },
["<leader>ntr"] = { "<cmd>NeovimTipsRandom<cr>", desc = "Random Neovim tip" },
["<leader>ntp"] = { "<cmd>NeovimTipsPdf<cr>", desc = "Open Neovim tips PDF" },
},
}
The plugin can show you a random tip in a beautiful popup when you start Neovim. This helps you discover new tips and improve your workflow naturally.
daily_tip = 0: Disabled (no popup)daily_tip = 1: Once per day (default)daily_tip = 2: Every Neovim startup~/.local/share/nvim/neovim_tips/persistent.jsonq or <Esc>
All tips have been compiled into a beautifully formatted PDF book with almost 400 pages that you can read offline or print for reference.
Use the :NeovimTipsPdf command to open the PDF book in your system's default PDF viewer:
:NeovimTipsPdf
The command automatically detects your operating system and uses the appropriate command:
openxdg-open (with fallbacks to gnome-open or kde-open)startThe PDF is located at pdf/book/NeovimTips.pdf within the plugin directory and includes all 945+ tips organized by category with a professional layout.
:NeovimTips — Open searchable list of tips with beautiful three-pane interface:NeovimTipsEdit — Edit your personal tips file:NeovimTipsAdd — Insert a new tip template into your personal file and start editing:NeovimTipsRandom — Displays random tip upon user requestThe plugin automatically detects and uses available markdown renderers for enhanced tip display:
markview.nvim (Priority 1)
"OXY2DEV/markview.nvim" to dependenciesrender-markdown.nvim (Priority 2)
"MeanderingProgrammer/render-markdown.nvim" to dependenciesRaw Markdown (Fallback)
nui.nvimThe plugin automatically:
The plugin provides comprehensive built-in documentation accessible via Neovim's help system. All features, commands, and configuration options are documented with examples and cross-references.
:help neovim-tips — Complete plugin documentation:help neovim-tips-commands — All available commands:help neovim-tips-search — Advanced search syntax and examples:help neovim-tips-configuration — Configuration options with examples:help neovim-tips-user-tips — Creating and managing custom tips:help neovim-tips-daily — Daily tip feature configuration:help :NeovimTips — Main picker command:help :NeovimTipsEdit — Edit personal tips file:help :NeovimTipsAdd — Add new tip template:help :NeovimTipsRandom — Random tip displayThe help system includes:
t:tag, c:category, etc.)Pro tip: Start with :help neovim-tips for a complete overview, then use :help neovim-tips-<topic> for specific areas of interest.
The tips picker features powerful search capabilities that let you find tips by title, category, or tags with intelligent filtering.
Simply start typing to search tip titles:
vim motion → finds tips with both "vim" and "motion" in title
insert character → finds tips about inserting characters
delete word → finds tips about deleting words
Use t: prefix to search by tags:
t:motion → finds all tips tagged with "motion"
t:delete → finds all tips tagged with "delete"
t:operator → finds all tips tagged with "operator"
Use c: prefix to search by categories:
c:editing → finds all tips in "Editing" category
c:search → finds all tips in "Search" category
c:"Key Mappings" → finds tips in "Key Mappings" category (quoted for spaces)
Use b: prefix to search your bookmarked tips:
b: → shows all your bookmarked tips
b:delete → shows bookmarked tips with "delete" in title
b:motion → shows bookmarked tips with "motion" in title
Bookmarking Tips:
Ctrl+b in the picker or daily tip to bookmark/unbookmarkMix different search types with spaces (all must match):
motion c:editing t:operator → tips with "motion" in title, "Editing" category, and "operator" tag
insert file t:save → tips with "insert file" in title and "save" tag
b: c:editing t:motion → bookmarked tips in "Editing" category with "motion" tag
b:delete c:text → bookmarked tips with "delete" in title from "Text" category
Don't know what tags or categories are available? Use the help feature:
t:? — Shows popup with all available tags (1000+ tags)c:? — Shows popup with all available categories (70+ categories)MOTION, motion, and Motion all work the samet:"write file"Try these searches to see the power of the system:
t:motion → 5 tips about motion commands
c:editing t:delete → editing tips that involve deletion
motion c:editing t:operator → 1 specific tip about motion + editing + operators
insert file → tips about inserting files
c:"Key Mappings" leader → leader key mapping tips
The plugin currently includes tips organized into 69+ categories. Here's the complete list for easy reference when using category search (c:category):
c:editing → All editing tips
c:"Key Mappings" → All key mapping tips (quoted for spaces)
c:search t:pattern → Search tips tagged with "pattern"
motion c:editing → Motion tips in editing category
Each tip should follow this format:
# Title: My tip title
# Category: My category name
# Tags: tag1, tag2, tag3
---
This is a description of what the tip does.
```vim
some-command
```
Some additional text here.
***
Alternatively, use can use === (3 equal signs) instead of *** (3 asterisks) to finish the tip. This format is used for all tips, built-in or created by you and stored separately.
Each tip has to start with the # Title: line, followed by # Category: and a list of # Tags.
Description of the tip starts with --- and ends with *** or ===. There is NO predefined format for description. Anything between the starting and ending marker will be interpreted as a text in markdown (.md) format. Fzf-lua will render the markdown description in the right FZF panel.
# Title: Delete word under the cursor
# Category: Edit
# Tags: delete, word, cursor
---
In normal mode use `diw` to delete the word under the cursor.
```vim
diw
```
***
The author of this plugin has done his best to provide a significant number of built-in Neovim commands, tips and tricks. But Neovim is an endless source of inspiration to many and, I believe, to you as well.
It is possible to mix your own tips with the built-in collection. Use :NeovimTipsAdd to add your own tip to the collection or :NeovimTipsEdit to edit the file with your custom tips. If the file for your custom tips does not exist, it will be created automatically. The location of the file can be adjusted (see "Configuration Options").
User tips follow the same format as builtin tips described above.
To prevent conflicts with builtin tips, user tips are automatically prefixed with [User] by default. Do NOT add the prefix yourself. This means if you create a tip with the title Join lines, it will appear as [User] Join lines in the interface and will not interfere with the built-in tip with the title Join lines.
All configuration options are optional with sensible defaults. For detailed explanations and examples, see :help neovim-tips-configuration.
require("neovim_tips").setup({
-- Path to user tips file
user_file = vim.fn.stdpath("config") .. "/neovim_tips/user_tips.md",
-- Prefix added to user tip titles to prevent conflicts
user_tip_prefix = "[User] ",
-- Show warnings when user tips have conflicting titles with builtin tips
warn_on_conflicts = true,
-- Daily tip mode: 0=off, 1=once per day, 2=every startup
daily_tip = 1,
-- Bookmark symbol (default: 🌟)
bookmark_symbol = "🌟 ",
})
-- Default: [User] prefix
user_tip_prefix = "[User] " -- "Join lines" becomes "[User] Join lines"
-- Custom emoji prefix
user_tip_prefix = "🔧 " -- "Join lines" becomes "🔧 Join lines"
-- No prefix (not recommended, may cause conflicts)
user_tip_prefix = "" -- "Join lines" stays "Join lines"
-- Default star emoji
bookmark_symbol = "🌟 " -- bright gold star
-- Alternative star options
bookmark_symbol = "⭐ " -- classic star
bookmark_symbol = "✨ " -- sparkles
bookmark_symbol = "💫 " -- dizzy star
-- Other colorful options
bookmark_symbol = "🔥 " -- fire
bookmark_symbol = "💎 " -- gem
bookmark_symbol = "🏆 " -- trophy
bookmark_symbol = "⚡ " -- lightning
bookmark_symbol = "🎯 " -- target
bookmark_symbol = "📌 " -- pin
-- Simple text options
bookmark_symbol = "★ " -- unicode star
bookmark_symbol = "[★] " -- bracketed star
bookmark_symbol = "• " -- bullet point
If you're using completion engines like blink.cmp or nvim-cmp and want to disable autocompletion suggestions in the picker's search bar, you can use the custom filetype neovim-tips-search. For more troubleshooting help, see :help neovim-tips-troubleshooting:
require('blink.cmp').setup({
enabled = function()
return vim.bo.filetype ~= "neovim-tips-search"
end,
-- ... rest of your config
})
require('cmp').setup({
enabled = function()
return vim.bo.filetype ~= "neovim-tips-search"
end,
-- ... rest of your config
})
<plugin_directory>/data/~/.config/nvim/neovim_tips/user_tips.mdt:tag and c:category syntaxt:? and c:?For comprehensive documentation with examples, troubleshooting, and detailed configuration options, use Neovim's built-in help system:
:help neovim-tips
All plugin features are fully documented with cross-references and copy-friendly examples!