Skip to content

Instantly share code, notes, and snippets.

@limxingzhi
Last active May 12, 2026 17:30
Show Gist options
  • Select an option

  • Save limxingzhi/fa3be5045caded9d4e09f2423dbfcec7 to your computer and use it in GitHub Desktop.

Select an option

Save limxingzhi/fa3be5045caded9d4e09f2423dbfcec7 to your computer and use it in GitHub Desktop.
My nvim config with lazy, treesitter, telescope, undotree, lspconfig and coc
-- init.lua
-- lines to scroll per page
local page_length = 10
local page_short_length = 3
-- configure better defaults
(function()
-- Enable line numbers
vim.o.number = true
-- Set the number of spaces in a tab when editing
vim.o.softtabstop = 2
-- Set the number of spaces to use for autoindent
vim.o.shiftwidth = 2
-- Convert tabs to spaces
vim.o.expandtab = true
-- Enable autoindentation
vim.o.autoindent = true
-- Use the system clipboard
vim.o.clipboard = "unnamed"
-- Enable mouse support in all modes
vim.o.mouse = "a"
-- Minimal number of screen lines to keep above and below the cursor.
vim.opt.scrolloff = 3
-- Set a long timeout for key sequences
vim.opt.timeoutlen = 999999
-- Ignore case in search patterns
vim.o.ignorecase = true
-- Relative line numbers
vim.wo.relativenumber = true
-- Setting leader key and ex
vim.g.mapleader = " "
-- Set vsplit to open file on right globally
vim.o.splitright = true
-- Set the trailing characters
vim.opt.list = true
vim.opt.listchars = { tab = '>-', trail = '.', lead = '.', }
-- always show gutter
vim.opt.signcolumn = "yes"
-- set update time to 300ms
vim.opt.updatetime = 300
-- removing octal so increment 07 wouldnt go to 10
vim.opt.nrformats:remove("octal")
end)();
-- map cursor movements
(function()
-- Function to map cursor to move x times in y direction
local map_move_cursor = function(length, direction, key)
vim.keymap.set({ 'n', 'v' }, key, function()
vim.cmd('normal! ' .. length .. direction)
end, { noremap = true, silent = true })
end
-- opening EX with leader key
vim.keymap.set("n", "<leader>ex", vim.cmd.Ex)
-- moving cursor a few positions over
map_move_cursor(page_length, 'h', 'H')
map_move_cursor(page_length, 'l', 'L')
map_move_cursor(page_length, 'j', 'J')
map_move_cursor(page_length, 'k', 'K')
map_move_cursor(page_short_length, 'h', '<M-h>')
map_move_cursor(page_short_length, 'l', '<M-l>')
map_move_cursor(page_short_length, 'j', '<M-j>')
map_move_cursor(page_short_length, 'k', '<M-k>')
end)();
-- map window movement keys
(function()
-- Function to remap <c-w><key> to <leader>w<key>
local remap_ldr_move = function(key, other_commands)
vim.keymap.set({ 'n', 'v' }, '<leader>w' .. key, '<cmd>wincmd ' .. key .. '<CR>' .. other_commands,
{ noremap = true, silent = true })
end
remap_ldr_move('h', '')
remap_ldr_move('j', '')
remap_ldr_move('k', '')
remap_ldr_move('l', '')
remap_ldr_move('w', '') -- move to the next window
remap_ldr_move('=', '') -- Readjust panels evenly
remap_ldr_move('r', '') -- Rotate opened windows with <leader>wr
-- Split window vertically with <leader>wv
vim.keymap.set('n', '<leader>wv', '<cmd>split<CR>', { noremap = true, silent = true })
-- Split window horizontally with <leader>ws
vim.keymap.set('n', '<leader>ws', '<cmd>vsplit<CR>', { noremap = true, silent = true })
-- Close current window with <leader>wc
vim.keymap.set('n', '<leader>wc', '<cmd>close<CR>', { noremap = true, silent = true })
end)();
-- custom scroll bindings
(function()
-- Set scroll to only x lines
vim.api.nvim_set_keymap('n', '<C-d>', page_length .. 'j' .. page_length .. '<C-e>',
{ noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<C-u>', page_length .. 'k' .. page_length .. '<C-y>',
{ noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<M-d>', page_short_length .. 'j' .. page_short_length .. '<C-e>',
{ noremap = true, silent = true })
vim.api.nvim_set_keymap('n', '<M-u>', page_short_length .. 'k' .. page_short_length .. '<C-y>',
{ noremap = true, silent = true })
-- Replace text without yanking (black hole register)
vim.keymap.set('v', '<leader>p', [["_dP]], { noremap = true, silent = true });
-- set no highlight
vim.keymap.set('n', '<leader>nn', '<cmd>noh<CR>', { noremap = true, silent = true });
end)();
-- Set <leader>nt to open new tab functions
vim.keymap.set({ 'n', 'v' }, '<leader>nt', '<cmd>tab split<CR>', { noremap = true, silent = true })
-- Set formatoptions globally in Neovim
vim.api.nvim_create_autocmd({ "BufEnter", "BufRead", "BufNewFile" }, {
pattern = "*",
callback = function()
-- Remove 'r' and 'o' from formatoptions for all file types
vim.opt.formatoptions:remove("r")
vim.opt.formatoptions:remove("o")
end,
})
-- Adds an event listener that highlights the just yanked text
vim.api.nvim_create_autocmd('TextYankPost', {
desc = 'Highlight when yanking text',
group = vim.api.nvim_create_augroup('xz-highlight-yank', { clear = true }),
callback = function()
vim.highlight.on_yank()
end,
})
---- # Plugins ----
-- Configure lazy
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)
require("lazy").setup({
-- Install gruvbox theme
{
"ellisonleao/gruvbox.nvim",
priority = 1000,
config = function()
require("gruvbox").setup({
dim_inactive = false,
bold = false,
transparent_mode = false,
contrast = "", -- hard or soft or empty string
})
vim.o.background = "dark" -- or "light" for light mode
vim.cmd([[colorscheme gruvbox]])
-- for ghostty transparency
vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
vim.api.nvim_set_hl(0, "NormalNC", { bg = "none" })
end
},
-- endof : Install gruvbox theme
-- Install catppuccino theme
{
"catppuccin/nvim",
name = "catppuccin",
priority = 1000,
config = function()
-- -- catppuccin-latte, catppuccin-frappe, catppuccin-macchiato, catppuccin-mocha
-- vim.o.background = "dark" -- or "light" for light mode
-- vim.cmd.colorscheme "catppuccin-mocha"
-- -- for ghostty transparency
-- vim.api.nvim_set_hl(0, "Normal", { bg = "none" })
-- vim.api.nvim_set_hl(0, "NormalNC", { bg = "none" })
end
},
-- endof : Install catppuccino theme
-- Install Telescope
{
'nvim-telescope/telescope-ui-select.nvim',
},
{
'nvim-telescope/telescope.nvim',
tag = 'v0.2.0',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
local builtin = require('telescope.builtin')
-- local actions = require('telescope.actions')
-- load extension into telescope
require('telescope').load_extension("ui-select")
require('telescope').setup({
defaults = {
layout_strategy = "horizontal",
},
pickers = {
find_files = {
find_command = { 'rg', '--files', '--hidden', '-g', '!.git' },
},
},
extensions = {
["ui-select"] = {
require("telescope.themes").get_dropdown {}
}
}
})
-- find files in project
vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
-- find files in buffers
vim.keymap.set('n', '<leader><space>', builtin.buffers, {})
-- find help
vim.keymap.set('n', '<leader>fh', builtin.help_tags, {})
-- find register
vim.keymap.set('n', '<leader>fr', builtin.registers, {})
-- find marks
vim.keymap.set('n', '<leader>fm', builtin.marks, {})
-- live grep : note, install ripgrep in the system first
vim.keymap.set('n', '<leader>fg', builtin.live_grep, {
vimgrep_arguments = table.insert(
require('telescope.config').values.vimgrep_arguments,
'--fixed-strings'
),
})
-- fuzzy find in current buffer
vim.keymap.set('n', '<leader>fz', builtin.current_buffer_fuzzy_find, {})
end
},
-- endof : Install Telescope
-- Install Telescope fuzzy finder
{
'nvim-telescope/telescope-fzf-native.nvim',
build = 'make',
config = function()
-- load extension into telescope
require('telescope').load_extension('fzf')
end
},
-- endof : Install Telescope fuzzy finder
-- Install Undotree
{
'mbbill/undotree',
config = function()
vim.keymap.set('n', '<leader>u', vim.cmd.UndotreeToggle)
end
},
-- endof : Install Undotree
-- Install LSP
{
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end
},
{
"williamboman/mason-lspconfig.nvim",
config = function()
require("mason-lspconfig").setup({
ensure_installed = {
"lua_ls",
"ts_ls",
"cssls",
-- "prettier",
"eslint@4.8.0",
"denols",
},
automatic_installation = true
})
end
},
{
"neovim/nvim-lspconfig",
config = function()
-- Define LSP server configurations using the new API
vim.lsp.config['lua_ls'] = {
cmd = { 'lua-language-server' },
filetypes = { 'lua' },
root_markers = { '.luarc.json', '.git' },
settings = { Lua = { diagnostics = { globals = { "vim" } } } }
}
vim.lsp.config["ts_ls"] = {
cmd = { "typescript-language-server", "--stdio" },
filetypes = { "javascript", "javascriptreact", "typescript", "typescriptreact" },
root_dir = vim.fs.root(0, { "package.json" }),
single_file_support = false,
}
vim.lsp.config["denols"] = {
cmd = { "deno", "lsp" },
filetypes = { "javascript", "javascriptreact", "typescript", "typescriptreact" },
root_dir = vim.fs.root(0, { "deno.json", "deno.jsonc" }),
}
vim.lsp.config["cssls"] = {
cmd = { "vscode-css-language-server", "--stdio" },
filetypes = { "css", "scss", "less" },
root_dir = vim.fs.root(0, { "package.json", ".git" }),
}
vim.lsp.config["gopls"] = {
cmd = { "gopls" },
filetypes = { "go", "gomod", "gowork", "gotmpl" },
root_dir = vim.fs.root(0, { "go.work", "go.mod", ".git" }),
}
vim.lsp.config["pylsp"] = {
cmd = { "pylsp" },
filetypes = { "python" },
root_dir = vim.fs.root(0, { "pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", ".git" }),
}
vim.lsp.config["terraformls"] = {
cmd = { "terraform-ls", "serve" },
filetypes = { "terraform", "tf", "terraform-vars" },
root_dir = vim.fs.root(0, { ".terraform", ".git" }),
}
-- Start each LSP automatically for matching filetypes
for name, config in pairs(vim.lsp.config) do
if config.filetypes then
vim.api.nvim_create_autocmd("FileType", {
pattern = config.filetypes,
callback = function(ev)
vim.lsp.enable(name)
end,
})
end
end
-- Global diagnostics keymaps
vim.keymap.set('n', '<leader>ee', vim.diagnostic.open_float)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next)
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist)
-- Buffer-local LSP mappings (on attach)
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('UserLspConfig', {}),
callback = function(ev)
vim.bo[ev.buf].omnifunc = 'v:lua.vim.lsp.omnifunc'
local opts = { buffer = ev.buf, silent = true }
vim.keymap.set('n', 'gk', vim.lsp.buf.hover, opts)
vim.keymap.set('n', 'gd', require('telescope.builtin').lsp_definitions, opts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
vim.keymap.set('n', '<leader>wa', vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set('n', '<leader>D', require('telescope.builtin').lsp_type_definitions, opts)
vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename, opts)
vim.keymap.set({ 'n', 'v' }, '<leader>ca', vim.lsp.buf.code_action, opts)
vim.keymap.set('n', '<leader>gr', require('telescope.builtin').lsp_references, opts)
vim.keymap.set('n', '<leader>wg', ':belowright split<CR>:lua vim.lsp.buf.definition()<CR>', opts)
vim.keymap.set('n', 'gi', require('telescope.builtin').lsp_references, opts)
end,
})
end
}
},
-- endof : Install LSP
-- Install lint
{
"mfussenegger/nvim-lint",
config = function()
require("lint").linters_by_ft = {
typescript = { "eslint" },
typescriptreact = { "eslint" },
}
vim.keymap.set({ "n", "v" }, "<leader>ll", function()
require("lint").try_lint()
end)
vim.api.nvim_create_autocmd({ "BufWritePost", "InsertEnter", "InsertLeave" }, {
callback = function()
require("lint").try_lint()
end,
})
end,
},
-- endof : Install lint
-- Install formatting
{
"stevearc/conform.nvim",
config = function()
local conform = require("conform")
conform.setup({
formatters_by_ft = {
lua = { "Stylua" },
javascript = { "prettier" },
typescript = { "prettier" },
javascriptreact = { "prettier" },
typescriptreact = { "prettier" },
}
})
vim.keymap.set({ "n", "v" }, "=", function()
conform.format({
lsp_fallback = true,
async = false,
timeout_ms = 2500
})
end)
end,
},
-- endof : Install formatting
-- Install completion
{
'nvim-mini/mini.completion',
version = '*',
config = function()
require('mini.completion').setup()
end
},
-- endof : Install completion
-- Install line indentation
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
config = function()
require("ibl").setup()
end
},
-- endof : Install line indentation
-- Install gitsigns
{
'lewis6991/gitsigns.nvim',
config = function()
require("gitsigns").setup({
current_line_blame_opts = {
virt_text_pos = 'overlay',
delay = 200,
},
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '?' },
changedelete = { text = '~' },
},
})
vim.keymap.set({ "v", "n" }, "<leader>gb", function()
vim.cmd("Gitsigns toggle_current_line_blame")
end)
end,
},
-- endof : Install gitsigns
-- Install : neo tree
{
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
},
config = function()
local opts = { silent = true, noremap = true }
-- open and focus into tree
vim.keymap.set({ "n", "v" }, "<leader>to", function()
vim.cmd("Neotree source=filesystem action=focus position=float reveal=true")
end, opts)
-- close the tree
vim.keymap.set({ "n", "v" }, "<leader>tc", function()
vim.cmd("Neotree action=close")
end, opts)
-- open tree on the right and do not focus
vim.keymap.set({ "n", "v" }, "<leader>tp", function()
vim.cmd("Neotree source=filesystem action=show position=right reveal=true")
end, opts)
-- show git status in tree layout
vim.keymap.set({ "n", "v" }, "<leader>tg", function()
vim.cmd("Neotree source=git_status action=focus position=float reveal=true")
end, opts)
-- show buffers in tree layout
vim.keymap.set({ "n", "v" }, "<leader>tb", function()
vim.cmd("Neotree source=buffers action=focus position=float reveal=true")
end, opts)
-- setting up defaults
require("neo-tree").setup({
sort_case_insensitive = true,
filesystem = {
filtered_items = {
visible = false, -- when true, they will just be displayed differently than normal items
hide_dotfiles = false,
hide_gitignored = true,
},
},
})
end
},
-- endof : Install : neo tree
-- Install toychest session helper
{
"limxingzhi/toychest.nvim",
config = function() require("toychest").setup() end
},
-- endof : Install toychest session helper
-- Install text object helper
{
'nvim-mini/mini.ai',
version = '*',
config = function()
require('mini.ai').setup({})
end
},
-- endof : Install text object helper
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment