Tip: I highly recommend checking out my first video, Vim for Absolute Beginners, before diving into the setup!
At this point you have already setup lazy.nvim. You can check windows setup or for Linux.
And Your folder structure will look like this
yeasin@Workstation ~/.config/nvim
.
├── init.lua
├── lua
│ └── config
│ ├── lazy.lua -- setup early video
│ ├── plugins -- we gonna put plugins here
|
Neo-tree File Explorer Setup
Set up Neo-tree to browse your project files visually right inside Neovim. (Requirements: You must have a Nerd Font active for the icons to display properly).
If you are on windows, you can check fix-terminal-fonts-windows-with-nerd-fonts .
Configure code
.config/nvim/lua/config/plugins/neo_tree.lua
return {
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
"nvim-tree/nvim-web-devicons",
},
cmd = "Neotree",
keys = {
{ "<leader>e", ":Neotree toggle<CR>", desc = "Toggle File Explorer" },
},
config = function()
require("neo-tree").setup({
sources = { "filesystem", "buffers", "git_status", "diagnostics" },
filesystem = {
follow_current_file = true,
use_libuv_file_watcher = true,
},
window = { width = 35 },
diagnostics = {
enable = true,
show_on_dirs = true,
},
})
-- auto-refresh diagnostics in Neo-tree
vim.api.nvim_create_autocmd({ "DiagnosticChanged" }, {
callback = function()
pcall(function()
require("neo-tree.sources.diagnostics").refresh()
end)
end,
})
end,
},
{
"antosha417/nvim-lsp-file-operations",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-neo-tree/neo-tree.nvim", -- loads after Neo-tree
},
config = function()
require("lsp-file-operations").setup()
end,
},
{
"s1n7ax/nvim-window-picker",
version = "2.*",
config = function()
require("window-picker").setup({
autoselect_one = true,
filter_rules = {
include_current_win = false,
bo = {
filetype = { "neo-tree", "neo-tree-popup", "notify" },
buftype = { "terminal", "quickfix" },
},
},
})
end,
},
}
Neovim Status Line & Theme Setup (Tokyo Night)
Give your editor a clean, modern look with the Tokyo Night theme and a custom status line.
statusline code
.config/nvim/lua/config/plugins/status_line.lua
return {
"echasnovski/mini.statusline",
version = "*",
opts = {},
}
themes code
.config/nvim/lua/config/plugins/themes.lua
local M = {}
-- 🔹 Theme selector: 1 = Tokyo Night, 2 = One Dark
local theme_index = 1
M[1] = {
"folke/tokyonight.nvim",
enabled = theme_index == 1,
lazy = false,
priority = 1000,
opts = {
style = "storm", -- Theme variant: "storm", "night", "moon", "day"
transparent = false,
styles = { sidebars = "transparent", floats = "transparent" },
},
config = function()
vim.cmd("colorscheme tokyonight")
end,
}
M[2] = {
"joshdick/onedark.vim",
enabled = theme_index == 2,
config = function()
vim.cmd("colorscheme onedark")
vim.g.onedark_style = "dark"
vim.g.onedark_terminal_italics = 1
end,
}
return M
Toggleterm (Floating terminal)
Configure code
.config/nvim/lua/config/plugins/terminal.lua
return {
{
"akinsho/toggleterm.nvim",
version = "*",
opts = {
open_mapping = [[<c-\>]],
direction = "float",
shade_terminals = true,
shading_factor = 50,
float_opts = {
border = "rounded",
width = function()
return math.floor(vim.o.columns * 0.8)
end,
height = function()
return math.floor(vim.o.lines * 0.8)
end,
},
},
},
}
buffer
Nvim Buffers Made Easy: Tabs, Open Files & Fast Switching
config buffer.nvim
.config/nvim/lua/config/plugins/buffer.lua
return {
"akinsho/bufferline.nvim",
opts = {
options = {
numbers = "ordinal", -- Show buffer numbers (1, 2, 3, …)
},
},
}
.config/nvim/lua/config/keymap.lua
--- switch to buffer
function _G.goto_buffer(n)
local buffers = {}
for _, buf in ipairs(vim.fn.getbufinfo({ buflisted = 1 })) do
if vim.api.nvim_buf_is_loaded(buf.bufnr) then
table.insert(buffers, buf.bufnr)
end
end
if n <= #buffers then
vim.api.nvim_set_current_buf(buffers[n])
end
end
-- mappings
for i = 1, 9 do
vim.api.nvim_set_keymap(
"n",
"<M-" .. i .. ">",
string.format([[<cmd>lua _G.goto_buffer(%d)<CR>]], i),
{ noremap = true, silent = true }
)
end
Also make sure to add on
init.lua
vim.g.maplocalleader = " "
vim.g.mapleader = " "
require("config.lazy")
require("config.keymap") --this
vim.opt.clipboard:append("unnamedplus")
vim.opt.numberwidth = 2
vim.opt.signcolumn = "auto"
vim.o.number = true
vim.o.mouse = "a"
vim.opt.wrap = true
vim.opt.spell = true
vim.opt.spelllang = { "en_us" }
local o = vim.o
o.expandtab = true -- expand tab input with spaces characters
o.smartindent = true -- syntax aware indentations for newline inserts
o.tabstop = 2 -- num of space characters per tab
o.shiftwidth = 2 -- spaces per indentation level
fzf.nvim
Fast fuzzy finder: Don’t waste time.
config
.config/nvim/lua/plugins/fzf.lua
return {
"ibhagwan/fzf-lua",
dependencies = { "echasnovski/mini.icons" }, -- or use your preferred icon plugin
opts = {
files = {
ignore = {
".*/%.flutter%-plugins$",
".*/%.flutter%-plugins%-dependencies$",
".*/%.dart_tool/.*",
".*/build/.*",
".*/%.pub/.*",
".*/%.packages$",
"*./example/*",
},
},
},
config = function(_, opts)
local fzf = require("fzf-lua")
fzf.setup(opts)
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
fzf.register_ui_select({ silent = true })
end,
})
end,
keys = {
{
"<leader>ff",
function()
require("fzf-lua").files()
end,
desc = "Find Files in project directory",
},
{
"<leader>fg",
function()
require("fzf-lua").live_grep()
end,
desc = "Find by grepping in project directory",
},
{
"<leader>fc",
function()
require("fzf-lua").files({ cwd = vim.fn.stdpath("config") })
end,
desc = "Find in neovim configuration",
},
{
"<leader>fh",
function()
require("fzf-lua").helptags()
end,
desc = "[F]ind [H]elp",
},
{
"<leader>fk",
function()
require("fzf-lua").keymaps()
end,
desc = "[F]ind [K]eymaps",
},
{
"<leader>fb",
function()
require("fzf-lua").builtin()
end,
desc = "[F]ind [B]uiltin FZF",
},
{
"<leader>fw",
function()
local mode = vim.fn.mode()
if mode == "v" or mode == "V" then
require("fzf-lua").grep_visual()
else
require("fzf-lua").grep_cword()
end
end,
desc = "[F]ind current word or visual selection",
},
{
"<leader>fW",
function()
require("fzf-lua").grep_cWORD()
end,
desc = "[F]ind current [W]ORD",
},
{
"<leader>fd",
function()
require("fzf-lua").diagnostics_document()
end,
desc = "[F]ind [D]iagnostics",
},
{
"<leader>fr",
function()
require("fzf-lua").resume()
end,
desc = "[F]ind [R]esume",
},
{
"<leader>fo",
function()
require("fzf-lua").oldfiles()
end,
desc = "[F]ind [O]ld Files",
},
{
"<leader><leader>",
function()
require("fzf-lua").buffers()
end,
desc = "[,] Find existing buffers",
},
{
"<leader>/",
function()
require("fzf-lua").lgrep_curbuf()
end,
desc = "[/] Live grep the current buffer",
},
},
}