Skip to content

Instantly share code, notes, and snippets.

@sjahl
Last active November 11, 2023 04:04
Show Gist options
  • Save sjahl/956b082713ed00e7e254f4f61bc605e7 to your computer and use it in GitHub Desktop.
Save sjahl/956b082713ed00e7e254f4f61bc605e7 to your computer and use it in GitHub Desktop.
WIP lazyvim-lite clone with native nixpkgs
programs.neovim = {
enable = true;
viAlias = true;
vimAlias = true;
defaultEditor = true;
configure = {
packages.myVimPackage = with pkgs.vimPlugins; {
start = [
telescope-nvim
tokyonight-nvim
plenary-nvim
lualine-nvim
gitsigns-nvim
nvim-treesitter.withAllGrammars
nvim-treesitter-context
nvim-lspconfig
vim-terraform
nvim-cmp
cmp-nvim-lsp
cmp-buffer
cmp-cmdline
luasnip
cmp_luasnip
vim-illuminate
mini-nvim
nvim-web-devicons
kanagawa-nvim
];
};
customRC = ''
luafile ${./neovim.lua}
'';
};
};
-- general keymaps
vim.g.mapleader = ' '
local opt = vim.opt
opt.autowrite = true -- Enable auto write
opt.clipboard = "unnamedplus" -- Sync with system clipboard
opt.completeopt = "menu,menuone,noselect"
opt.conceallevel = 3 -- Hide * markup for bold and italic
opt.confirm = true -- Confirm to save changes before exiting modified buffer
opt.expandtab = true -- Use spaces instead of tabs
opt.formatoptions = "jcroqlnt" -- tcqj
opt.grepformat = "%f:%l:%c:%m"
opt.grepprg = "rg --vimgrep"
opt.ignorecase = true -- Ignore case
opt.inccommand = "nosplit" -- preview incremental substitute
opt.laststatus = 3 -- global statusline
opt.list = true -- Show some invisible characters (tabs...
opt.mouse = "a" -- Enable mouse mode
opt.number = true -- Print line number
opt.pumblend = 10 -- Popup blend
opt.pumheight = 10 -- Maximum number of entries in a popup
opt.relativenumber = true -- Relative line numbers
opt.scrolloff = 4 -- Lines of context
opt.sessionoptions = { "buffers", "curdir", "tabpages", "winsize", "help", "globals", "skiprtp", "folds" }
opt.shiftround = true -- Round indent
opt.shiftwidth = 2 -- Size of an indent
opt.shortmess:append({ W = true, I = true, c = true, C = true })
opt.showmode = false -- Dont show mode since we have a statusline
opt.sidescrolloff = 8 -- Columns of context
opt.signcolumn = "yes:1" -- Always show the signcolumn, otherwise it would shift the text each time
opt.smartcase = true -- Don't ignore case with capitals
opt.smartindent = true -- Insert indents automatically
opt.spelllang = { "en" }
opt.splitbelow = true -- Put new windows below current
opt.splitkeep = "screen"
opt.splitright = true -- Put new windows right of current
opt.tabstop = 2 -- Number of spaces tabs count for
opt.termguicolors = true -- True color support
opt.undofile = true
opt.undolevels = 10000
opt.updatetime = 200 -- Save swap file and trigger CursorHold
opt.virtualedit = "block" -- Allow cursor to move where there is no text in visual block mode
opt.wildmode = "longest:full,full" -- Command-line completion mode
opt.winminwidth = 5 -- Minimum window width
opt.wrap = false -- Disable line wrap
-- Appearance
require("tokyonight").setup({
styles = {
functions = { italic = false },
keywords = { italic = false },
},
})
require("kanagawa").setup({
keywordStyle = { italic = false },
statementStyle = { bold = false },
colors = {
theme = {
all = {
ui = {
bg_gutter = "none"
}
}
}
},
overrides = function(colors)
local theme = colors.theme
return {
IlluminatedWordRead = { bg = theme.ui.bg_p2 },
IlluminatedWordWrite = { bg = theme.ui.bg_p2 },
IlluminatedWordText = { bg = theme.ui.bg_p2 },
Boolean = { bold = false },
}
end,
})
vim.cmd 'colorscheme kanagawa'
-- change the color of the line number for LSP diagnostics
vim.cmd 'sign define DiagnosticSignError text= linehl= texthl=DiagnosticSignError numhl=DiagnosticSignError'
vim.cmd 'sign define DiagnosticSignHint text= linehl= texthl=DiagnosticSignHint numhl=DiagnosticSignHint'
vim.cmd 'sign define DiagnosticSignInfo text= linehl= texthl=DiagnosticSignInfo numhl=DiagnosticSignInfo'
vim.cmd 'sign define DiagnosticSignWarn text= linehl= texthl=DiagnosticSignWarn numhl=DiagnosticSignWarn'
-- status line
local function diff_source()
local gitsigns = vim.b.gitsigns_status_dict
if gitsigns then
return {
added = gitsigns.added,
modified = gitsigns.changed,
removed = gitsigns.removed
}
end
end
require('lualine').setup({
options = {
section_separators = '',
component_separators = ''
},
sections = {
lualine_a = {'mode'},
lualine_b = {'branch', 'diagnostics'},
lualine_c = {'filename'},
lualine_x = {{'diff', source = diff_source}, {'filetype', icon_only = true, icon = { align = 'right'}, }},
lualine_y = {'progress'},
lualine_z = {'location'}
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_c = {'filename'},
lualine_x = {'location'},
lualine_y = {},
lualine_z = {}
},
})
require('gitsigns').setup({
update_debounce = 1000,
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)
map('n', '<leader>hS', gs.stage_buffer)
map('n', '<leader>hu', gs.undo_stage_hunk)
map('n', '<leader>hR', gs.reset_buffer)
map('n', '<leader>hp', gs.preview_hunk)
map('n', '<leader>hb', function() gs.blame_line{full=true} end)
map('n', '<leader>tb', gs.toggle_current_line_blame)
map('n', '<leader>hd', gs.diffthis)
map('n', '<leader>hD', function() gs.diffthis('~') end)
map('n', '<leader>td', gs.toggle_deleted)
-- Text object
map({'o', 'x'}, 'ih', ':<C-U>Gitsigns select_hunk<CR>')
end
})
-- Navigation and searching
local builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>ff', builtin.find_files, {})
vim.keymap.set('n', '<leader>fp', builtin.git_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, {})
-- completion
-- Set up nvim-cmp.
local cmp = require'cmp'
cmp.setup({
snippet = {
-- REQUIRED - you must specify a snippet engine
expand = function(args)
require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
end,
},
window = {
-- completion = cmp.config.window.bordered(),
-- documentation = cmp.config.window.bordered(),
},
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 }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'luasnip' },
}, {
{ name = 'buffer' },
})
})
-- Set configuration for specific filetype.
-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline({ '/', '?' }, {
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'buffer' }
}
})
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
})
-- treesitter and lsp
local nvim_lsp = require('lspconfig')
-- Mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true }
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts)
-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
if vim.bo[bufnr].buftype ~= "" or vim.bo[bufnr].filetype == "helm" then
vim.diagnostic.disable(bufnr)
vim.defer_fn(function()
vim.diagnostic.reset(nil, bufnr)
end, 1000)
end
-- Enable completion triggered by <c-x><c-o>
vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
-- Mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
local bufopts = { noremap=true, silent=true, buffer=bufnr }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, bufopts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts)
vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<space>F',function() vim.lsp.buf.format { async = true } end, bufopts)
end
-- Set up lspconfig.
local capabilities = require('cmp_nvim_lsp').default_capabilities()
require('lspconfig')['gopls'].setup{
on_attach = on_attach,
capabilities = capabilities,
}
require('lspconfig')['terraformls'].setup{
on_attach = on_attach,
capabilities = capabilities,
}
require('lspconfig')['pyright'].setup{
on_attach = on_attach,
capabilities = capabilities,
}
require'nvim-treesitter.configs'.setup {
highlight = {
-- `false` will disable the whole extension
enable = true,
-- NOTE: these are the names of the parsers and not the filetype. (for example if you want to
-- disable highlighting for the `tex` filetype, you need to include `latex` in this list as this is
-- the name of the parser)
-- list of language that will be disabled
-- disable = { "c", "rust" },
-- Or use a function for more flexibility, e.g. to disable slow treesitter highlight for large files
disable = function(lang, buf)
local max_filesize = 100 * 1024 -- 100 KB
local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf))
if ok and stats and stats.size > max_filesize then
return true
end
end,
-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
-- Using this option may slow down your editor, and you may see some duplicate highlights.
-- Instead of true it can also be a list of languages
-- additional_vim_regex_highlighting = false,
},
}
require'treesitter-context'.setup{}
require('illuminate').configure({
delay = 200,
large_file_cutoff = 2000,
large_file_overrides = {
providers = { "lsp" },
},
})
-- mini helper modules
require('mini.comment').setup({})
require('mini.surround').setup({})
require('mini.ai').setup({})
require('mini.pairs').setup({})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment