Skip to content

Instantly share code, notes, and snippets.

@VadimBrodsky
Last active March 25, 2025 02:35
Show Gist options
  • Save VadimBrodsky/6bd99ac1aae34e5f289ab73099ad4d5f to your computer and use it in GitHub Desktop.
Save VadimBrodsky/6bd99ac1aae34e5f289ab73099ad4d5f to your computer and use it in GitHub Desktop.
AI init.lua for Neovim
-----------------------------------------------------------
-- init.lua - Neovim configuration for Terminal & VSCode --
-----------------------------------------------------------
-- This configuration uses lazy.nvim as the plugin manager,
-- sets up Treesitter, LSP, and several useful plugins.
-- It is designed to be simple, maintainable, and easy to extend.
-----------------------------------------------------------
-- 1. Bootstrap lazy.nvim if not already installed
-----------------------------------------------------------
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-----------------------------------------------------------
-- 2. Basic Settings
-----------------------------------------------------------
vim.o.number = true -- Enable line numbers
vim.o.relativenumber = true -- Show relative line numbers
vim.o.expandtab = true -- Use spaces instead of tabs
vim.o.shiftwidth = 4 -- Size of an indent
vim.o.tabstop = 4 -- Number of spaces per tab
vim.o.smartindent = true -- Insert indents automatically
vim.o.termguicolors = true -- Enable 24-bit RGB colors
vim.cmd("colorscheme desert") -- Set colorscheme (change as desired)
-----------------------------------------------------------
-- 3. Plugin Setup via lazy.nvim
-----------------------------------------------------------
require("lazy").setup({
-- Treesitter: Advanced syntax highlighting and code understanding
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate", -- Automatically update parsers on install
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = { "lua", "python", "javascript", "html", "css" },
highlight = { enable = true },
indent = { enable = true },
})
end,
},
-- LSP Configurations: Built-in LSP support
"neovim/nvim-lspconfig", -- Common configurations for Neovim LSP
-- Mason: Manage external editor tooling (LSP servers, linters, etc.)
{
"williamboman/mason.nvim",
build = ":MasonUpdate",
config = function()
require("mason").setup()
end,
},
-- Bridges Mason with nvim-lspconfig
"williamboman/mason-lspconfig.nvim",
-- Completion Framework: nvim-cmp and its LSP source
"hrsh7th/nvim-cmp",
"hrsh7th/cmp-nvim-lsp",
-- Telescope: Fuzzy finder for files, buffers, etc.
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
require("telescope").setup({
defaults = {
layout_strategy = "vertical",
},
})
end,
},
-- Git Integration: Inline git signs in the gutter
{
"lewis6991/gitsigns.nvim",
config = function()
require("gitsigns").setup()
end,
},
-- Status Line: A lean and powerful statusline
{
"nvim-lualine/lualine.nvim",
config = function()
require("lualine").setup({
options = { theme = "auto" },
})
end,
},
-- Indent Guides: Visual indent lines for code
{
"lukas-reineke/indent-blankline.nvim",
config = function()
-- Customize the indent guide color
vim.cmd([[highlight IndentBlanklineIndent1 guifg=#E06C75 gui=nocombine]])
require("indent_blankline").setup({
char = "│",
show_trailing_blankline_indent = false,
})
end,
},
})
-----------------------------------------------------------
-- 4. LSP Setup and Configuration
-----------------------------------------------------------
-- on_attach function to map keys after the LSP server attaches to the current buffer.
local on_attach = function(client, bufnr)
local opts = { noremap = true, silent = true }
local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
-- Basic LSP key mappings
buf_set_keymap("n", "gd", "<cmd>lua vim.lsp.buf.definition()<CR>", opts) -- Go to definition
buf_set_keymap("n", "K", "<cmd>lua vim.lsp.buf.hover()<CR>", opts) -- Hover docs
buf_set_keymap("n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>", opts) -- Go to implementation
buf_set_keymap("n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>", opts) -- Show references
buf_set_keymap("n", "<leader>rn", "<cmd>lua vim.lsp.buf.rename()<CR>", opts) -- Rename symbol
-- Additional key mappings can be defined here
end
-- Use mason-lspconfig to ensure specific LSP servers are installed.
local lspconfig = require("lspconfig")
local mason_lspconfig = require("mason-lspconfig")
mason_lspconfig.setup({
ensure_installed = { "lua_ls", "pyright", "tsserver", "html", "cssls" },
})
-- Setup handlers for all installed servers.
mason_lspconfig.setup_handlers({
function(server_name)
lspconfig[server_name].setup({
on_attach = on_attach,
capabilities = require("cmp_nvim_lsp").default_capabilities(),
})
end,
})
-----------------------------------------------------------
-- 5. Additional Configurations & Autocommands
-----------------------------------------------------------
-- Automatically reload Neovim whenever you save this init.lua file.
vim.cmd([[
augroup reload_init
autocmd!
autocmd BufWritePost init.lua source <afile> | echo "Reloaded init.lua"
augroup END
]])
-----------------------------------------------------------
-- End of init.lua configuration
-----------------------------------------------------------
-- Comprehensive Neovim Configuration
-- Designed to work seamlessly in terminal and VSCode Neovim extension
-- Bootstrap lazy.nvim plugin manager
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Global leader key (use space as leader)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- Core Neovim Settings
-- These settings provide a solid, cross-platform foundation
local core_settings = {
-- User Interface Improvements
number = true, -- Show line numbers
relativenumber = true, -- Show relative line numbers
cursorline = true, -- Highlight current line
wrap = false, -- Disable line wrapping
scrolloff = 8, -- Keep 8 lines visible when scrolling
signcolumn = "yes", -- Always show sign column
-- Editing Improvements
smartindent = true, -- Smart autoindenting
expandtab = true, -- Use spaces instead of tabs
tabstop = 2, -- 2 spaces per tab
shiftwidth = 2, -- 2 spaces for indent width
-- Search Improvements
hlsearch = false, -- Don't highlight all search matches
incsearch = true, -- Incremental search
ignorecase = true, -- Ignore case in search
smartcase = true, -- Unless search contains uppercase
-- Performance and Backup
swapfile = false, -- No swap files
backup = false, -- No backup files
undodir = os.getenv("HOME") .. "/.vim/undodir", -- Centralized undo history
undofile = true, -- Persistent undo
-- Clipboard and Mouse
clipboard = "unnamedplus", -- Use system clipboard
mouse = "a", -- Enable mouse in all modes
}
-- Apply core settings
for key, value in pairs(core_settings) do
vim.opt[key] = value
end
-- Plugin Specifications
local plugins = {
-- Treesitter: Advanced syntax highlighting and parsing
{
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
config = function()
require('nvim-treesitter.configs').setup {
-- A list of parser names, or "all"
ensure_installed = {
"lua", "python", "javascript", "typescript",
"rust", "go", "markdown", "vim", "bash"
},
-- Install parsers synchronously (only applied to `ensure_installed`)
sync_install = false,
-- Automatically install missing parsers when entering buffer
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = false,
},
}
end
},
-- LSP Configuration
{
'neovim/nvim-lspconfig',
dependencies = {
-- Useful status updates for LSP
'j-hui/fidget.nvim',
-- Additional lua configuration, makes nvim stuff amazing
'folke/neodev.nvim',
},
config = function()
local lspconfig = require('lspconfig')
-- Setup language servers
local servers = {
'lua_ls', -- Lua Language Server
'pyright', -- Python
'tsserver', -- TypeScript
'rust_analyzer', -- Rust
'gopls' -- Go
}
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup {
-- Add custom configuration for each LSP if needed
}
end
-- Global mappings for LSP features
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
-- Enable completion triggered by <c-x><c-o>
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
-- Buffer local mappings
local opts = { buffer = ev.buf }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
vim.keymap.set({ 'n', 'v' }, '<space>ca', vim.lsp.buf.code_action, opts)
end,
})
end
},
-- Fuzzy Finder
{
'nvim-telescope/telescope.nvim',
tag = '0.1.5',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
local builtin = require('telescope.builtin')
-- Fuzzy find mappings
vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
vim.keymap.set('n', '<leader>fg', builtin.live_grep, {})
vim.keymap.set('n', '<leader>fb', builtin.buffers, {})
vim.keymap.set('n', '<leader>fh', builtin.help_tags, {})
end
},
-- Git Integration
{
'lewis6991/gitsigns.nvim',
config = function()
require('gitsigns').setup {
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '‾' },
changedelete = { text = '~' },
},
-- Enable git signs in VSCode as well
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local function map(mode, l, r, opts)
opts = opts or {}
opts.buffer = bufnr
vim.keymap.set(mode, l, r, opts)
end
-- Navigation
map('n', ']c', function()
if vim.wo.diff then return ']c' end
vim.schedule(function() gs.next_hunk() end)
return '<Ignore>'
end, {expr=true})
map('n', '[c', function()
if vim.wo.diff then return '[c' end
vim.schedule(function() gs.prev_hunk() end)
return '<Ignore>'
end, {expr=true})
-- Actions
map('n', '<leader>hs', gs.stage_hunk)
map('n', '<leader>hr', gs.reset_hunk)
map('v', '<leader>hs', function() gs.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end)
map('v', '<leader>hr', function() gs.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end)
end
}
end
},
-- File Tree
{
'nvim-tree/nvim-tree.lua',
dependencies = {
'nvim-tree/nvim-web-devicons', -- optional, for file icons
},
config = function()
require("nvim-tree").setup({
view = {
width = 30,
},
renderer = {
group_empty = true,
},
filters = {
dotfiles = false,
},
})
-- Key mapping to toggle file tree
vim.keymap.set('n', '<leader>t', ':NvimTreeToggle<CR>', { noremap = true, silent = true })
end
},
-- Colorscheme
{
'folke/tokyonight.nvim',
lazy = false, -- Ensure it loads during startup
priority = 1000, -- Load before other plugins
config = function()
vim.cmd([[colorscheme tokyonight-moon]])
end
},
-- Status Line
{
'nvim-lualine/lualine.nvim',
dependencies = { 'nvim-tree/nvim-web-devicons' },
config = function()
require('lualine').setup {
options = {
theme = 'tokyonight',
section_separators = { left = '', right = '' },
component_separators = { left = '', right = '' }
}
}
end
}
}
-- Setup Lazy Plugin Manager
require("lazy").setup(plugins, {
-- Lazy configuration
ui = {
-- Custom border for plugin management UI
border = "rounded"
},
-- Performance optimizations
performance = {
rtp = {
-- Disable some default plugins
disabled_plugins = {
"gzip",
"matchit",
"matchparen",
"netrwPlugin",
"tarPlugin",
"tohtml",
"tutor",
"zipPlugin"
}
}
}
})
-- Custom Keymappings
-- Make moving between splits easier
vim.keymap.set('n', '<leader>h', '<C-w>h', { noremap = true, silent = true })
vim.keymap.set('n', '<leader>j', '<C-w>j', { noremap = true, silent = true })
vim.keymap.set('n', '<leader>k', '<C-w>k', { noremap = true, silent = true })
vim.keymap.set('n', '<leader>l', '<C-w>l', { noremap = true, silent = true })
-- Quick escape from insert mode
vim.keymap.set('i', 'jk', '<ESC>', { noremap = true, silent = true })
-- VSCode Detection and Special Handling
-- Check if running in VSCode Neovim extension
if vim.g.vscode then
-- VSCode-specific keybindings or modifications can be added here
print("Running in VSCode Neovim extension")
else
print("Running in terminal Neovim")
end
-- Final Note: This configuration aims to provide a robust,
-- cross-platform Neovim setup that is easy to understand and extend.
--[[
Basic Neovim settings
- Applies to both terminal and VSCode environments
--]]
vim.g.mapleader = ' ' -- Set leader key to space
vim.opt.number = true -- Show line numbers
vim.opt.relativenumber = true
vim.opt.tabstop = 2 -- 2 spaces per tab
vim.opt.shiftwidth = 2
vim.opt.expandtab = true -- Use spaces instead of tabs
vim.opt.termguicolors = true-- Enable true color support
vim.opt.mouse = 'a' -- Enable mouse in all modes
vim.opt.splitright = true -- Vertical splits open to the right
vim.opt.splitbelow = true -- Horizontal splits open below
--[[
Key mappings
- Leader-based mappings for common actions
--]]
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
-- Navigation between windows
keymap('n', '<C-h>', '<C-w>h', opts)
keymap('n', '<C-j>', '<C-w>j', opts)
keymap('n', '<C-k>', '<C-w>k', opts)
keymap('n', '<C-l>', '<C-w>l', opts)
-- Buffer management
keymap('n', '<leader>q', ':bd<CR>', opts) -- Close buffer
keymap('n', '<leader>w', ':w<CR>', opts) -- Save buffer
keymap('n', '<leader>e', ':Explore<CR>', opts) -- File explorer
--[[
Plugin management with Lazy.nvim
- Auto-install lazy.nvim if not present
--]]
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable', -- latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
--[[
Plugin specifications
- Core functionality grouped together
- Conditionally load VSCode-specific plugins
--]]
require('lazy').setup({
-- Plugin manager can manage itself
'folke/lazy.nvim',
-- Colorscheme (only load outside VSCode)
not vim.g.vscode and {
'folke/tokyonight.nvim',
config = function()
vim.cmd.colorscheme('tokyonight-night')
end
} or nil,
-- Syntax parsing
{
'nvim-treesitter/nvim-treesitter',
build = ':TSUpdate',
config = function()
require('nvim-treesitter.configs').setup({
ensure_installed = { 'lua', 'python', 'javascript', 'typescript', 'bash' },
highlight = { enable = true },
indent = { enable = true },
})
end
},
-- LSP Configuration
{
'neovim/nvim-lspconfig',
dependencies = {
'williamboman/mason.nvim',
'williamboman/mason-lspconfig.nvim',
},
config = function()
require('mason').setup()
require('mason-lspconfig').setup({
ensure_installed = { 'lua_ls', 'pyright', 'tsserver' }
})
local lsp = require('lspconfig')
local on_attach = function(client, bufnr)
local bufopts = { noremap=true, silent=true, buffer=bufnr }
keymap('n', 'gD', vim.lsp.buf.declaration, bufopts)
keymap('n', 'gd', vim.lsp.buf.definition, bufopts)
keymap('n', 'K', vim.lsp.buf.hover, bufopts)
keymap('n', 'gi', vim.lsp.buf.implementation, bufopts)
keymap('n', '<leader>rn', vim.lsp.buf.rename, bufopts)
keymap('n', '<leader>ca', vim.lsp.buf.code_action, bufopts)
keymap('n', '<leader>f', vim.lsp.buf.format, bufopts)
end
-- Setup LSP servers
require('mason-lspconfig').setup_handlers({
function(server_name)
lsp[server_name].setup({ on_attach = on_attach })
end,
})
end
},
-- Useful plugins
{ 'nvim-lua/plenary.nvim' }, -- Dependency for many plugins
{ 'nvim-telescope/telescope.nvim', branch = '0.1.x' }, -- Fuzzy finder
{ 'folke/which-key.nvim', config = true }, -- Keybinding help
{ 'numToStr/Comment.nvim', config = true }, -- Smart comments
{ 'windwp/nvim-autopairs', config = true }, -- Auto-pair brackets
{ 'folke/trouble.nvim', dependencies = 'nvim-tree/nvim-web-devicons' }, -- Diagnostics
})
--[[
Post-plugin configuration
--]]
-- Telescope keymaps
keymap('n', '<leader>ff', ':Telescope find_files<CR>', opts)
keymap('n', '<leader>fg', ':Telescope live_grep<CR>', opts)
keymap('n', '<leader>fb', ':Telescope buffers<CR>', opts)
-- Trouble.nvim keymaps
keymap('n', '<leader>xx', ':TroubleToggle<CR>', opts)
keymap('n', '<leader>xw', ':TroubleToggle workspace_diagnostics<CR>', opts)
-- Enable which-key for leader key
require('which-key').register({}, { prefix = '<leader>' })
--[[
VSCode-specific adjustments
--]]
if vim.g.vscode then
-- Disable some features that VSCode handles
vim.opt.relativenumber = false
vim.opt.number = false
-- Add any VSCode-specific mappings here
end
-- init.lua for Neovim (works in terminal and vscode-neovim)
-- Bootstrap lazy.nvim if not already installed
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazypath,
})
end
vim.opt.runtimepath:prepend(lazypath)
-- Lazy.nvim plugin configuration
require("lazy").setup({
{ "nvim-treesitter/nvim-treesitter", build = ":TSUpdate" }, -- Treesitter
{ "nvim-lspconfig" }, -- LSP configuration
{ "hrsh7th/nvim-cmp" }, -- Autocompletion
{ "hrsh7th/cmp-nvim-lsp" }, -- LSP source for cmp
{ "hrsh7th/cmp-buffer" }, -- Buffer source for cmp
{ "hrsh7th/cmp-path" }, -- Path source for cmp
{ "hrsh7th/cmp-cmdline" }, -- Command line source for cmp
{ "L3MON4D3/LuaSnip" }, -- Snippets engine
{ "saadparwaiz1/cmp_luasnip" }, -- Snippets source for cmp
{ "nvim-tree/nvim-tree.lua" }, -- File explorer
{ "nvim-tree/nvim-web-devicons" }, -- Icons for nvim-tree
{ "nvim-telescope/telescope.nvim", tag = '0.1.*', dependencies = { 'nvim-lua/plenary.nvim' } }, -- Fuzzy finder
{ "nvim-telescope/telescope-file-browser.nvim" }, -- file browser extension for telescope
{ "nvim-telescope/telescope-symbols.nvim" }, -- Symbols extension
{ "nvim-telescope/telescope-live_grep.nvim" }, -- live grep extension
{ "nvim-telescope/telescope-fzf-native.nvim", build = 'make' }, -- FZF native sorter for telescope
{ "nvim-lualine/lualine.nvim" }, -- Statusline
{ "nvim-lua/plenary.nvim" }, -- Required by telescope
{ "windwp/nvim-autopairs" }, -- Auto pairs
{ "lewis6991/gitsigns.nvim" }, -- Git signs
{ "folke/tokyonight.nvim", opts = {} }, -- colorscheme
{ "folke/trouble.nvim", dependencies = { "nvim-tree/nvim-web-devicons" } }, -- trouble
}, {})
-- Treesitter configuration
require("nvim-treesitter.configs").setup({
ensure_installed = { "lua", "python", "javascript", "typescript", "html", "css", "json", "c","cpp" }, -- Install parsers for these languages
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<c-space>",
node_incremental = "<c-space>",
scope_incremental = "<c-s>",
node_decremental = "<c-backspace>",
},
},
})
-- LSP configuration
local lspconfig = require("lspconfig")
-- Common capabilities for LSP
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- Setup servers
lspconfig.lua_ls.setup { capabilities = capabilities }
lspconfig.pyright.setup { capabilities = capabilities }
lspconfig.tsserver.setup { capabilities = capabilities }
lspconfig.clangd.setup { capabilities = capabilities } -- for c/cpp
-- Completion configuration (nvim-cmp)
local cmp = require("cmp")
local luasnip = require("luasnip")
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
{ name = "cmdline" },
}),
})
-- nvim-tree configuration
require("nvim-tree").setup({
sort_by = "case_sensitive",
view = {
adaptive_size = true,
},
renderer = {
group_empty = true,
},
})
-- Telescope configuration
require("telescope").setup {
defaults = {
mappings = {
i = {
["<C-u>"] = false,
["<C-d>"] = false,
},
},
},
extensions = {
["file_browser"] = {
theme = "dropdown",
-- disables netrw and enables telescope-file-browser in its place
hijack_netrw = true,
},
},
}
require("telescope").load_extension("file_browser")
require("telescope").load_extension("symbols")
require("telescope").load_extension("live_grep")
require("telescope").load_extension("fzf")
-- Lualine configuration
require("lualine").setup()
-- Autopairs configuration
require("nvim-autopairs").setup {}
-- Gitsigns configuration
require('gitsigns').setup {}
-- Colorscheme
vim.cmd [[colorscheme tokyonight-night]]
-- Keymaps
vim.keymap.set("n", "<leader>e", ":NvimTreeToggle<CR>")
vim.keymap.set("n", "<leader>ff", "<cmd>Telescope find_files<cr>")
vim.keymap.set("n", "<leader>fg", "<cmd>Telescope live_grep<cr>")
vim.keymap.set("n", "<leader>fb", "<cmd>Telescope buffers<cr>")
vim.keymap.set("n", "<leader>fs", "<cmd>Telescope symbols<cr>")
vim.keymap.set("n", "<leader>ft", "<cmd>Telescope file_browser<cr>")
vim.keymap.set("n", "<leader>tt", "<cmd>TroubleToggle<cr>")
vim.keymap.set("n", "<leader>xw", "<cmd>Trouble workspace_diagnostics<cr>")
vim.keymap.set("n", "<leader>xd", "<cmd>Trouble document_diagnostics<cr>")
-- init.lua: Neovim configuration
-- Designed to work in both terminal Neovim and VSCode Neovim extension
-- Uses Lazy.nvim as plugin manager with Treesitter, LSP, and essential plugins
-- Set leader key early (used by many plugins and mappings)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- Basic Neovim settings for a smooth experience
vim.opt.number = true -- Show line numbers
vim.opt.relativenumber = true -- Relative line numbers for easier navigation
vim.opt.tabstop = 2 -- 2 spaces for tabs
vim.opt.shiftwidth = 2 -- 2 spaces for indentation
vim.opt.expandtab = true -- Use spaces instead of tabs
vim.opt.smartindent = true -- Smart auto-indentation
vim.opt.termguicolors = true -- Enable 24-bit RGB colors
vim.opt.clipboard = "unnamedplus" -- Sync clipboard with system
-- Bootstrap Lazy.nvim (plugin manager) if not installed
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Plugin setup with Lazy.nvim
require("lazy").setup({
-- Colorscheme: Simple and clean, works well in terminal and VSCode
{
"folke/tokyonight.nvim",
lazy = false, -- Load immediately
priority = 1000, -- Load before other plugins
config = function()
vim.cmd([[colorscheme tokyonight]])
end,
},
-- Treesitter: Syntax highlighting and code parsing
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = { "lua", "javascript", "python", "html", "css" }, -- Add languages as needed
highlight = { enable = true }, -- Enable syntax highlighting
indent = { enable = true }, -- Enable auto-indentation
})
end,
},
-- LSP: Language server protocol support
{
"neovim/nvim-lspconfig",
dependencies = {
-- LSP installer helper (optional but simplifies setup)
{ "williamboman/mason.nvim", config = true },
{ "williamboman/mason-lspconfig.nvim" },
},
config = function()
-- Setup LSP servers (add more as needed)
local lspconfig = require("lspconfig")
lspconfig.lua_ls.setup({}) -- Lua language server
lspconfig.pyright.setup({}) -- Python language server
-- Keymaps for LSP (only active when LSP is attached)
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local buf = args.buf
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { buffer = buf, desc = "Go to definition" })
vim.keymap.set("n", "K", vim.lsp.buf.hover, { buffer = buf, desc = "Hover documentation" })
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, { buffer = buf, desc = "Rename symbol" })
end,
})
end,
},
-- Autocompletion (works with LSP)
{
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP source for cmp
"hrsh7th/cmp-buffer", -- Buffer source
"hrsh7th/cmp-path", -- Filepath source
"L3MON4D3/LuaSnip", -- Snippet engine
"saadparwaiz1/cmp_luasnip", -- Snippet source
},
config = function()
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
}),
})
end,
},
-- File explorer
{
"nvim-tree/nvim-tree.lua",
dependencies = { "nvim-tree/nvim-web-devicons" }, -- Icons for file types
config = function()
require("nvim-tree").setup({
view = { width = 30 },
})
vim.keymap.set("n", "<leader>e", ":NvimTreeToggle<CR>", { desc = "Toggle file explorer" })
end,
},
-- Statusline (lightweight and simple)
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
require("lualine").setup({
options = { theme = "tokyonight" },
})
end,
},
-- Fuzzy finder (Telescope)
{
"nvim-telescope/telescope.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
local telescope = require("telescope")
telescope.setup({})
vim.keymap.set("n", "<leader>ff", telescope.builtin.find_files, { desc = "Find files" })
vim.keymap.set("n", "<leader>fg", telescope.builtin.live_grep, { desc = "Grep files" })
end,
},
}, {
-- Lazy.nvim options
install = { colorscheme = { "tokyonight" } }, -- Fallback colorscheme during plugin install
performans = {
rtp = {
-- Disable some default plugins for faster startup (optional)
disabled_plugins = { "gzip", "tarPlugin", "zipPlugin" },
},
},
})
-- General keymaps (not plugin-specific)
vim.keymap.set("n", "<leader>w", ":w<CR>", { desc = "Save file" })
vim.keymap.set("n", "<leader>q", ":q<CR>", { desc = "Quit" })
-- VSCode-specific adjustments (only apply if running in VSCode)
if vim.g.vscode then
-- Disable features that conflict with VSCode (e.g., file explorer)
vim.keymap.set("n", "<leader>e", "<Cmd>call VSCodeNotify('workbench.action.toggleSidebarVisibility')<CR>", { desc = "Toggle VSCode sidebar" })
end
-- End of configuration
--------------------------------------------------------------------------------
-- Comprehensive Neovim Configuration (init.lua)
-- Works in both terminal Neovim and VSCode Neovim extension
--------------------------------------------------------------------------------
-- Check if running inside VSCode Neovim extension
local is_vscode = vim.g.vscode ~= nil
--------------------------------------------------------------------------------
-- BASIC SETTINGS
--------------------------------------------------------------------------------
-- Leader key (set before lazy.nvim)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- General settings
vim.opt.number = true -- Line numbers
vim.opt.relativenumber = true -- Relative line numbers
vim.opt.clipboard = "unnamedplus" -- Use system clipboard
vim.opt.mouse = "a" -- Enable mouse in all modes
vim.opt.undofile = true -- Persistent undo
vim.opt.ignorecase = true -- Ignore case in search
vim.opt.smartcase = true -- Override ignorecase when search has uppercase
vim.opt.updatetime = 250 -- Faster CursorHold events
vim.opt.timeoutlen = 300 -- Time to wait for mapped sequence
vim.opt.splitright = true -- Split windows right
vim.opt.splitbelow = true -- Split windows below
vim.opt.termguicolors = true -- True color support
-- Indentation
vim.opt.expandtab = true -- Use spaces instead of tabs
vim.opt.shiftwidth = 2 -- Number of spaces for indentation
vim.opt.tabstop = 2 -- Number of spaces tab counts for
vim.opt.softtabstop = 2 -- Number of spaces for <Tab> while editing
vim.opt.smartindent = true -- Smart autoindenting
-- UI settings
vim.opt.cursorline = true -- Highlight current line
vim.opt.signcolumn = "yes" -- Always show sign column
vim.opt.scrolloff = 8 -- Lines of context around cursor
vim.opt.sidescrolloff = 8 -- Columns of context around cursor
vim.opt.colorcolumn = "80" -- Show column at 80 characters
vim.opt.showmode = false -- Don't show mode (shown in statusline)
vim.opt.wrap = false -- Don't wrap lines
vim.opt.hlsearch = false -- Don't highlight search
-- Disable certain settings in VSCode
if is_vscode then
vim.opt.number = false
vim.opt.relativenumber = false
vim.opt.signcolumn = "no"
vim.opt.cursorline = false
end
--------------------------------------------------------------------------------
-- KEY MAPPINGS
--------------------------------------------------------------------------------
-- Helper function for easier key mapping
local function map(mode, lhs, rhs, opts)
opts = opts or { noremap = true, silent = true }
vim.keymap.set(mode, lhs, rhs, opts)
end
-- Better window navigation
map("n", "<C-h>", "<C-w>h")
map("n", "<C-j>", "<C-w>j")
map("n", "<C-k>", "<C-w>k")
map("n", "<C-l>", "<C-w>l")
-- Resize windows with arrows
map("n", "<C-Up>", ":resize -2<CR>")
map("n", "<C-Down>", ":resize +2<CR>")
map("n", "<C-Left>", ":vertical resize -2<CR>")
map("n", "<C-Right>", ":vertical resize +2<CR>")
-- Stay in indent mode when indenting in visual mode
map("v", "<", "<gv")
map("v", ">", ">gv")
-- Move text up and down
map("v", "J", ":m '>+1<CR>gv=gv")
map("v", "K", ":m '<-2<CR>gv=gv")
-- Clear search highlight with <leader>/
map("n", "<leader>/", ":nohlsearch<CR>")
-- Leader key mappings (only for terminal Neovim)
if not is_vscode then
-- File explorer
map("n", "<leader>e", ":Explore<CR>")
-- Save and quit shortcuts
map("n", "<leader>w", ":w<CR>")
map("n", "<leader>q", ":q<CR>")
map("n", "<leader>Q", ":qa!<CR>")
-- Buffer navigation
map("n", "<S-l>", ":bnext<CR>")
map("n", "<S-h>", ":bprevious<CR>")
map("n", "<leader>c", ":bd<CR>")
end
--------------------------------------------------------------------------------
-- LAZY.NVIM SETUP
--------------------------------------------------------------------------------
-- Bootstrap lazy.nvim if not installed
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- Latest stable release
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
-- Define plugins with lazy.nvim
require("lazy").setup({
-- Only load these plugins when not in VSCode
-- Core plugins for terminal Neovim experience
{
"catppuccin/nvim",
name = "catppuccin",
priority = 1000, -- Load first to prevent flash
enabled = not is_vscode,
config = function()
require("catppuccin").setup({
flavour = "mocha", -- Options: latte, frappe, macchiato, mocha
transparent_background = false,
})
vim.cmd.colorscheme("catppuccin")
end,
},
{
"nvim-lualine/lualine.nvim",
enabled = not is_vscode,
opts = {
options = {
icons_enabled = true,
theme = "catppuccin",
component_separators = { left = '|', right = '|' },
section_separators = { left = '', right = '' },
},
},
},
-- Treesitter for better syntax highlighting
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
enabled = not is_vscode, -- Only load in terminal Neovim
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = {
"c", "lua", "vim", "vimdoc", "javascript", "typescript",
"html", "css", "json", "python", "rust", "markdown",
},
sync_install = false,
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = false,
},
indent = { enable = true },
})
end,
},
-- LSP configuration
{
"neovim/nvim-lspconfig",
enabled = not is_vscode,
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP source for nvim-cmp
},
},
-- Autocompletion
{
"hrsh7th/nvim-cmp",
enabled = not is_vscode,
dependencies = {
"hrsh7th/cmp-buffer", -- Buffer completions
"hrsh7th/cmp-path", -- Path completions
"hrsh7th/cmp-cmdline", -- Command line completions
"saadparwaiz1/cmp_luasnip", -- Snippet completions
"L3MON4D3/LuaSnip", -- Snippet engine
"rafamadriz/friendly-snippets", -- Snippet collection
"onsails/lspkind.nvim", -- VS Code-like pictograms
},
config = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
local lspkind = require("lspkind")
-- Load friendly snippets
require("luasnip.loaders.from_vscode").lazy_load()
cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-k>"] = cmp.mapping.select_prev_item(),
["<C-j>"] = cmp.mapping.select_next_item(),
["<C-b>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<C-Space>"] = cmp.mapping.complete(),
["<C-e>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({ select = false }),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expandable() then
luasnip.expand()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
}),
formatting = {
format = lspkind.cmp_format({
mode = "symbol_text",
maxwidth = 50,
ellipsis_char = "...",
}),
},
})
end,
},
-- Mason for easy LSP installation
{
"williamboman/mason.nvim",
enabled = not is_vscode,
config = true,
},
{
"williamboman/mason-lspconfig.nvim",
enabled = not is_vscode,
config = function()
require("mason-lspconfig").setup({
ensure_installed = {
"lua_ls",
"tsserver",
"pyright",
"html",
"cssls",
"jsonls"
},
automatic_installation = true,
})
end,
},
-- Telescope for fuzzy finding
{
"nvim-telescope/telescope.nvim",
enabled = not is_vscode,
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
local telescope = require("telescope")
telescope.setup()
-- Telescope keymaps
map("n", "<leader>ff", ":Telescope find_files<CR>")
map("n", "<leader>fg", ":Telescope live_grep<CR>")
map("n", "<leader>fb", ":Telescope buffers<CR>")
map("n", "<leader>fh", ":Telescope help_tags<CR>")
end,
},
-- Git integration
{
"lewis6991/gitsigns.nvim",
enabled = not is_vscode,
config = true,
},
-- Which-key for keybinding help
{
"folke/which-key.nvim",
enabled = not is_vscode,
config = function()
require("which-key").setup()
end,
},
-- Comment.nvim for easy commenting
{
"numToStr/Comment.nvim",
config = true,
},
-- Auto-pairs for bracket completion
{
"windwp/nvim-autopairs",
event = "InsertEnter",
config = true,
},
})
--------------------------------------------------------------------------------
-- LSP CONFIGURATION
--------------------------------------------------------------------------------
if not is_vscode then
local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- Configure lua_ls for Neovim Lua development
lspconfig.lua_ls.setup({
capabilities = capabilities,
settings = {
Lua = {
diagnostics = {
globals = { "vim" }, -- Recognize vim global
},
workspace = {
library = vim.api.nvim_get_runtime_file("", true),
checkThirdParty = false,
},
telemetry = {
enable = false,
},
},
},
})
-- Set up other LSP servers
local servers = { "tsserver", "pyright", "html", "cssls", "jsonls" }
for _, lsp in ipairs(servers) do
lspconfig[lsp].setup({
capabilities = capabilities,
})
end
-- LSP keybindings
-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("UserLspConfig", {}),
callback = function(ev)
-- Buffer local mappings
local opts = { buffer = ev.buf }
map("n", "gD", vim.lsp.buf.declaration, opts)
map("n", "gd", vim.lsp.buf.definition, opts)
map("n", "K", vim.lsp.buf.hover, opts)
map("n", "gi", vim.lsp.buf.implementation, opts)
map("n", "<C-k>", vim.lsp.buf.signature_help, opts)
map("n", "<leader>rn", vim.lsp.buf.rename, opts)
map("n", "<leader>ca", vim.lsp.buf.code_action, opts)
map("n", "gr", vim.lsp.buf.references, opts)
map("n", "<leader>f", function() vim.lsp.buf.format { async = true } end, opts)
end,
})
end
--------------------------------------------------------------------------------
-- ADDITIONAL CONFIGURATIONS
--------------------------------------------------------------------------------
-- Create autocommand group for user config
local augroup = vim.api.nvim_create_augroup("UserConfig", { clear = true })
-- Highlight on yank
vim.api.nvim_create_autocmd("TextYankPost", {
group = augroup,
callback = function()
vim.highlight.on_yank({ higroup = "IncSearch", timeout = 150 })
end,
})
-- Remove trailing whitespace on save
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup,
pattern = "*",
command = "%s/\\s\\+$//e",
})
-- Return to last edit position when opening files
vim.api.nvim_create_autocmd("BufReadPost", {
group = augroup,
callback = function()
local mark = vim.api.nvim_buf_get_mark(0, "\"")
if mark[1] > 0 and mark[1] <= vim.api.nvim_buf_line_count(0) then
vim.api.nvim_win_set_cursor(0, mark)
end
end,
})
-- Print a message when configuration is loaded
print("Neovim configuration loaded successfully!")
can you help me with an init.lua neovim setup that would work well within the terminal context as well as in the vscode neovim extension context, it needs to be very easy to follow so comments can be good thing and it should be maintainable and extensible using the features of lua but not overly complex. The whole configuration needs to be in a single file, it should include lazy as the plugin manager and it should setup treesitter LSP and a handful of useful plugins.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment