The file needs to be saved as ~/.config/nvim/init.lua. Its from the Rad Lectures
vim.g.mapleader = " "
vim.g.maplocalleader = " "
vim.opt.number = true -- Line numbers
vim.opt.relativenumber = true -- Relative line numbers
vim.opt.cursorline = true -- Highlight current line
vim.opt.wrap = false -- Don't wrap lines
vim.opt.scrolloff = 10 -- Keep 10 lines above/below cursor
vim.opt.sidescrolloff = 8 -- Keep 8 columns left/right of cursor
-- Indentation
vim.opt.tabstop = 2 -- Tab width
vim.opt.shiftwidth = 2 -- Indent width
vim.opt.softtabstop = 2 -- Soft tab stop
vim.opt.expandtab = true -- Use spaces instead of tabs
vim.opt.smartindent = true -- Smart auto-indenting
vim.opt.autoindent = true -- Copy indent from current line
-- Search settings
vim.opt.ignorecase = true -- Case insensitive search
vim.opt.smartcase = true -- Case sensitive if uppercase in search
vim.opt.hlsearch = false -- Don't highlight search results
vim.opt.incsearch = true -- Show matches as you type
-- Visual settings
vim.opt.termguicolors = true -- Enable 24-bit colors
vim.opt.signcolumn = "yes" -- Always show sign column
vim.opt.colorcolumn = "100" -- Show column at 100 characters
vim.opt.showmatch = true -- Highlight matching brackets
vim.opt.matchtime = 2 -- How long to show matching bracket
vim.opt.cmdheight = 1 -- Command line height
vim.opt.completeopt = "menuone,noinsert,noselect" -- Completion options
vim.opt.showmode = false -- Don't show mode in command line
vim.opt.pumheight = 10 -- Popup menu height
vim.opt.pumblend = 10 -- Popup menu transparency
vim.opt.winblend = 0 -- Floating window transparency
vim.opt.conceallevel = 0 -- Don't hide markup
vim.opt.concealcursor = "" -- Don't hide cursor line markup
vim.opt.lazyredraw = true -- Don't redraw during macros
vim.opt.synmaxcol = 300 -- Syntax highlighting limit
-- File handling
vim.opt.backup = false -- Don't create backup files
vim.opt.writebackup = false -- Don't create backup before writing
vim.opt.swapfile = false -- Don't create swap files
vim.opt.undofile = true -- Persistent undo
vim.opt.undodir = vim.fn.expand("~/.tmp/nvim") -- Undo directory
-- Create undo directory if it doesn't exist
local undodir = vim.fn.expand("~/.vim/undodir")
if vim.fn.isdirectory(undodir) == 0 then
vim.fn.mkdir(undodir, "p")
end
vim.opt.updatetime = 300 -- Faster completion
vim.opt.timeoutlen = 500 -- Key timeout duration
vim.opt.ttimeoutlen = 0 -- Key code timeout
vim.opt.autoread = true -- Auto reload files changed outside vim
vim.opt.autowrite = false
-- Behavior settings
vim.opt.hidden = true -- Allow hidden buffers
vim.opt.errorbells = false -- No error bells
vim.opt.backspace = "indent,eol,start" -- Better backspace behavior
vim.opt.autochdir = false -- Don't auto change directory
vim.opt.iskeyword:append("-") -- Treat dash as part of word
vim.opt.path:append("**") -- include subdirectories in search
vim.opt.selection = "exclusive" -- Selection behavior
vim.opt.mouse = "a" -- Enable mouse support
vim.opt.clipboard:append("unnamedplus") -- Use system clipboard
vim.opt.modifiable = true -- Allow buffer modifications
vim.opt.encoding = "UTF-8" -- Set encoding
-- Cursor settings
-- vim.opt.guicursor = "n-v-c:block,i-ci-ve:block,r-cr:hor20,o:hor50,a:blinkwait700-blinkoff400-blinkon250-Cursor/lCursor,sm:block-blinkwait175-blinkoff150-blinkon175"
-- Folding settings
vim.opt.foldmethod = "expr" -- Use expression for folding
vim.opt.foldexpr = "nvim_treesitter#foldexpr()" -- Use treesitter for folding
vim.opt.foldlevel = 99 -- Start with all folds open
-- Split behavior
vim.opt.splitbelow = true -- Horizontal splits go below
vim.opt.splitright = true -- Vertical splits go right
-- Key mappings
vim.g.mapleader = " " -- Set leader key to space
vim.g.maplocalleader = " " -- Set local leader key (NEW)
-- ; to :
vim.keymap.set("n", ";", ":")
-- Normal mode mappings
vim.keymap.set("n", "<leader>c", ":nohlsearch<CR>", { desc = "Clear search highlights" })
-- Y to EOL
vim.keymap.set("n", "Y", "y$", { desc = "Yank to end of line" })
-- Center screen when jumping
vim.keymap.set("n", "n", "nzzzv", { desc = "Next search result (centered)" })
vim.keymap.set("n", "N", "Nzzzv", { desc = "Previous search result (centered)" })
vim.keymap.set("n", "<C-d>", "<C-d>zz", { desc = "Half page down (centered)" })
vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = "Half page up (centered)" })
-- Better paste behavior
vim.keymap.set("x", "<leader>p", '"_dP', { desc = "Paste without yanking" })
-- Delete without yanking
vim.keymap.set({ "n", "v" }, "<leader>d", '"_d', { desc = "Delete without yanking" })
-- Buffer navigation
vim.keymap.set("n", "<leader>bn", ":bnext<CR>", { desc = "Next buffer" })
vim.keymap.set("n", "<leader>bp", ":bprevious<CR>", { desc = "Previous buffer" })
-- Better window navigation
vim.keymap.set("n", "<C-h>", "<C-w>h", { desc = "Move to left window" })
vim.keymap.set("n", "<C-j>", "<C-w>j", { desc = "Move to bottom window" })
vim.keymap.set("n", "<C-k>", "<C-w>k", { desc = "Move to top window" })
vim.keymap.set("n", "<C-l>", "<C-w>l", { desc = "Move to right window" })
-- Splitting & Resizing
vim.keymap.set("n", "<leader>sv", ":vsplit<CR>", { desc = "Split window vertically" })
vim.keymap.set("n", "<leader>sh", ":split<CR>", { desc = "Split window horizontally" })
vim.keymap.set("n", "<C-Up>", ":resize +2<CR>", { desc = "Increase window height" })
vim.keymap.set("n", "<C-Down>", ":resize -2<CR>", { desc = "Decrease window height" })
vim.keymap.set("n", "<C-Left>", ":vertical resize -2<CR>", { desc = "Decrease window width" })
vim.keymap.set("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "Increase window width" })
-- Move lines up/down
vim.keymap.set("n", "<A-j>", ":m .+1<CR>==", { desc = "Move line down" })
vim.keymap.set("n", "<A-k>", ":m .-2<CR>==", { desc = "Move line up" })
vim.keymap.set("v", "<A-j>", ":m '>+1<CR>gv=gv", { desc = "Move selection down" })
vim.keymap.set("v", "<A-k>", ":m '<-2<CR>gv=gv", { desc = "Move selection up" })
-- Better indenting in visual mode
vim.keymap.set("v", "<", "<gv", { desc = "Indent left and reselect" })
vim.keymap.set("v", ">", ">gv", { desc = "Indent right and reselect" })
-- Quick file navigation
vim.keymap.set("n", "<leader>e", ":Explore<CR>", { desc = "Open file explorer" })
vim.keymap.set("n", "<leader>ff", ":find ", { desc = "Find file" })
-- Better J behavior
vim.keymap.set("n", "J", "mzJ`z", { desc = "Join lines and keep cursor position" })
-- Quick config editing
vim.keymap.set("n", "<leader>rc", ":e ~/.config/nvim/init.lua<CR>", { desc = "Edit config" })
-- theme & transparency
-- vim.cmd.colorscheme("default")
vim.cmd.colorscheme("lunaperche")
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalNC", { bg = "none" })
vim.api.nvim_set_hl(0, "EndOfBuffer", { bg = "none" })
vim.api.nvim_set_hl(0, "StatusLine", { bg = "grey20" })
vim.api.nvim_set_hl(0, "CursorLine", { bg = "grey30" })
vim.api.nvim_set_hl(0, "Comment", { fg = "grey40" })
-- ============================================================================
-- TABS
-- ============================================================================
-- Tab display settings
vim.opt.showtabline = 1 -- Always show tabline (0=never, 1=when multiple tabs, 2=always)
vim.opt.tabline = '' -- Use default tabline (empty string uses built-in)
-- Transparent tabline appearance
vim.cmd([[
hi TabLineFill guibg=NONE ctermfg=242 ctermbg=NONE
]])
-- Alternative navigation (more intuitive)
vim.keymap.set('n', '<leader>tn', ':tabnew<CR>', { desc = 'New tab' })
vim.keymap.set('n', '<leader>tx', ':tabclose<CR>', { desc = 'Close tab' })
-- Tab moving
vim.keymap.set('n', '<leader>tm', ':tabmove<CR>', { desc = 'Move tab' })
vim.keymap.set('n', '<leader>t>', ':tabmove +1<CR>', { desc = 'Move tab right' })
vim.keymap.set('n', '<leader>t<', ':tabmove -1<CR>', { desc = 'Move tab left' })
-- Function to open file in new tab
local function open_file_in_tab()
vim.ui.input({ prompt = 'File to open in new tab: ', completion = 'file' }, function(input)
if input and input ~= '' then
vim.cmd('tabnew ' .. input)
end
end)
end
-- Function to duplicate current tab
local function duplicate_tab()
local current_file = vim.fn.expand('%:p')
if current_file ~= '' then
vim.cmd('tabnew ' .. current_file)
else
vim.cmd('tabnew')
end
end
-- Function to close tabs to the right
local function close_tabs_right()
local current_tab = vim.fn.tabpagenr()
local last_tab = vim.fn.tabpagenr('$')
for i = last_tab, current_tab + 1, -1 do
vim.cmd(i .. 'tabclose')
end
end
-- Function to close tabs to the left
local function close_tabs_left()
local current_tab = vim.fn.tabpagenr()
for i = current_tab - 1, 1, -1 do
vim.cmd('1tabclose')
end
end
-- Enhanced keybindings
vim.keymap.set('n', '<leader>tO', open_file_in_tab, { desc = 'Open file in new tab' })
vim.keymap.set('n', '<leader>td', duplicate_tab, { desc = 'Duplicate current tab' })
vim.keymap.set('n', '<leader>tr', close_tabs_right, { desc = 'Close tabs to the right' })
vim.keymap.set('n', '<leader>tL', close_tabs_left, { desc = 'Close tabs to the left' })
-- Function to close buffer but keep tab if it's the only buffer in tab
local function smart_close_buffer()
local buffers_in_tab = #vim.fn.tabpagebuflist()
if buffers_in_tab > 1 then
vim.cmd('bdelete')
else
-- If it's the only buffer in tab, close the tab
vim.cmd('tabclose')
end
end
vim.keymap.set('n', '<leader>bd', smart_close_buffer, { desc = 'Smart close buffer/tab' })
-- ============================================================================
-- STATUSLINE
-- ============================================================================
-- Git branch function
local function git_branch()
local branch = vim.fn.system("git branch --show-current 2>/dev/null | tr -d '\n'")
if branch ~= "" then
return " " .. branch .. " "
end
return ""
end
-- File type with icon
local function file_type()
local ft = vim.bo.filetype
local icons = {
lua = "[LUA]",
python = "[PY]",
javascript = "[JS]",
html = "[HTML]",
css = "[CSS]",
json = "[JSON]",
markdown = "[MD]",
vim = "[VIM]",
sh = "[SH]",
}
if ft == "" then
return " "
end
return (icons[ft] or ft)
end
-- Word count for text files
local function word_count()
local ft = vim.bo.filetype
if ft == "markdown" or ft == "text" or ft == "tex" then
local words = vim.fn.wordcount().words
return " " .. words .. " words "
end
return ""
end
-- File size
local function file_size()
local size = vim.fn.getfsize(vim.fn.expand('%'))
if size < 0 then return "" end
if size < 1024 then
return size .. "B "
elseif size < 1024 * 1024 then
return string.format("%.1fK", size / 1024)
else
return string.format("%.1fM", size / 1024 / 1024)
end
end
-- Mode indicators with icons
local function mode_icon()
local mode = vim.fn.mode()
local modes = {
n = "NORMAL",
i = "INSERT",
v = "VISUAL",
V = "V-LINE",
["\22"] = "V-BLOCK", -- Ctrl-V
c = "COMMAND",
s = "SELECT",
S = "S-LINE",
["\19"] = "S-BLOCK", -- Ctrl-S
R = "REPLACE",
r = "REPLACE",
["!"] = "SHELL",
t = "TERMINAL"
}
return modes[mode] or " " .. mode:upper()
end
_G.mode_icon = mode_icon
_G.git_branch = git_branch
_G.file_type = file_type
_G.file_size = file_size
vim.cmd([[
highlight StatusLineBold gui=bold cterm=bold
]])
-- Function to change statusline based on window focus
local function setup_dynamic_statusline()
vim.api.nvim_create_autocmd({"WinEnter", "BufEnter"}, {
callback = function()
vim.opt_local.statusline = table.concat {
" ",
"%#StatusLineBold#",
"%{v:lua.mode_icon()}",
"%#StatusLine#",
" │ %f %h%m%r",
"%{v:lua.git_branch()}",
" │ ",
"%{v:lua.file_type()}",
" | ",
"%{v:lua.file_size()}",
"%=", -- Right-align everything after this
"%l:%c %P ", -- Line:Column and Percentage
}
end
})
vim.api.nvim_set_hl(0, "StatusLineBold", { bold = true })
vim.api.nvim_create_autocmd({"WinLeave", "BufLeave"}, {
callback = function()
vim.opt_local.statusline = " %f %h%m%r │ %{v:lua.file_type()} | %= %l:%c %P "
end
})
end
setup_dynamic_statusline()
Make sure to create a few folders first.
$ mkdir -p ~/.vim/files/{backup,swap,undo,info}
This needs to be saved as ~/.vimrc.
set nocompatible " vim tries to emulate old vi, this tells it not to
filetype plugin indent on " Load plugins according to detected filetype.
syntax on " Enable syntax highlighting.
set laststatus =2 " Always show statusline.
set display =lastline " Show as much as possible of the last line.
" dont litter the current folder with backup files
set backup
set backupdir =$HOME/.vim/files/backup/
set backupext =-vimbackup
set backupskip =
set directory =$HOME/.vim/files/swap//
set updatecount =100
set undofile
set undodir =$HOME/.vim/files/undo/
set viminfo ='100,n$HOME/.vim/files/info/viminfo
"Interact with vim using ; instead of :"
:nmap ; :
" clear search highlight
nnoremap \\ :noh<cr>
"Highlight trailing white space"
highlight ExtraWhitespace ctermbg=red guibg=red
au ColorScheme * highlight ExtraWhitespace guibg=red
au BufEnter * match ExtraWhitespace /\s\+$/
au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
au InsertLeave * match ExtraWhiteSpace /\s\+$/
" Change status line background color based on mode.
highlight StatusLine ctermfg=black ctermbg=white
autocmd InsertLeave * highlight StatusLine ctermfg=black ctermbg=white
autocmd InsertEnter * highlight StatusLine ctermfg=darkgreen ctermbg=black
"Strip trailing white space on save"
function! TrimWhiteSpace()
let l = line(".")
let c = col(".")
%s/\s\+$//e
call cursor(l, c)
endfunction
autocmd BufWritePre *.* :call TrimWhiteSpace()
" restore cursor position when reopening a file, except if it's a git commit
autocmd BufReadPost * if @% !~# '\.git[\/\\]COMMIT_EDITMSG$' && line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif