This commit is contained in:
2025-06-18 14:38:36 +01:00
commit 71b7bd7373
32 changed files with 1494 additions and 0 deletions

26
lua/aucmd.lua Normal file
View File

@ -0,0 +1,26 @@
-- Highlight when yanking (copying) text
-- See `:help vim.highlight.on_yank()`
vim.api.nvim_create_autocmd('TextYankPost', {
desc = 'Highlight when yanking (copying) text',
group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }),
callback = function()
vim.highlight.on_yank()
end,
})
-- disable spell in terminals
vim.api.nvim_create_autocmd('TermOpen', {
desc = 'disable spell in terminal',
pattern = '*',
callback = function(_)
vim.wo[0].spell = false
end,
})
vim.api.nvim_create_autocmd('BufRead', {
desc = 'disable spell for certain filetypes',
pattern = { '*.out', '*.log' },
callback = function(_)
vim.wo[0].spell = false
end,
})

48
lua/keymaps.lua Normal file
View File

@ -0,0 +1,48 @@
-- Clear highlights on search when pressing <Esc> in normal mode
-- See `:help hlsearch`
vim.keymap.set('n', '<C-h>', '<cmd>nohlsearch<CR>')
-- Diagnostic keymaps
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
-- is not what someone will guess without a bit more experience.
--
-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
-- or just use <C-\><C-n> to exit terminal mode
vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })
-- disable help button
vim.keymap.set({ 'n', 'v', 't', 'i' }, '<F1>', '<Nop>')
-- disable space
vim.keymap.set({ 'n', 'v' }, '<space>', '<Nop>')
-- disable cmd mode (as best we can)
vim.keymap.set('n', 'q:', '<Nop>')
vim.keymap.set('n', 'Q', '<Nop>')
-- center the cursor on big jumps
vim.keymap.set('n', '<c-d>', '<c-d>zz')
vim.keymap.set('n', '<c-d>', '<c-d>zz')
vim.keymap.set('n', 'n', 'nzz')
vim.keymap.set('n', 'N', 'Nzz')
-- better handling of wrapped lines
vim.keymap.set('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
vim.keymap.set('n', '<leader>j', '<cmd>bprev<cr>', { desc = 'Previous buffer' })
vim.keymap.set('n', '<leader>k', '<cmd>bnext<cr>', { desc = 'Next buffer' })
vim.keymap.set('n', '<leader>x', '<cmd>bd<cr>', { desc = 'Delete buffer' })
vim.keymap.set('n', '<leader>b', '<cmd>b#<cr>', { desc = 'Last buffer' })
vim.keymap.set('n', '<c-w>b', '<cmd>w<bar>%db<bar>e#<bar>bd#<cr>', { desc = 'Delete all buffers apart from current' })
-- better visual mode pasting
vim.keymap.set('v', 'p', 'pgvy', { silent = true })
vim.keymap.set('v', 'P', 'Pgvy', { silent = true })
vim.keymap.set({ 'n', 'v' }, 'x', '"_x', { silent = true })
vim.keymap.set({ 'n', 'v' }, 'X', '"_X', { silent = true })
vim.keymap.set('n', '<c-w>v', '<cmd>vsplit<cr>', { desc = 'Create vertical split' })

View File

@ -0,0 +1,31 @@
local M = {
filetypes = { 'go', 'gomod' },
}
-- disable lsp if wrong version installed
function M.enable()
local enable = true
if
pcall(function()
vim
.system({ 'golangci-lint', '--version' }, { text = true }, function(out)
if out.code ~= 0 then
enable = false
return
end
if out.stdout:match ' 1%.%d+%.%d+' then
enable = false
return
end
end)
:wait()
end)
then
return enable
else
return false -- disable if golangci-lint isn't available
end
end
return M

53
lua/lsp/init.lua Normal file
View File

@ -0,0 +1,53 @@
local M = {}
function M.setup()
local servers = {
ts_ls = { filetypes = { 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' } },
gopls = { filetypes = { 'go', 'gomod' } },
rust_analyzer = {
filetypes = { 'rust' },
settings = {
['rust-analyzer'] = {
check = {
command = 'clippy',
extraArgs = {
'--',
'-Dclippy::correctness',
'-Wclippy::complexity',
'-Wclippy::pedantic',
'-Wclippy::perf',
},
},
},
},
},
golangci_lint_ls = require 'lsp.golangci_lint_ls',
erlangls = { cmd = { '/home/fergusmolloy/.local/bin/erlang_ls' }, filetypes = { 'erlang' } },
elixirls = { cmd = { 'elixir-ls' }, filetypes = { 'elixir' } },
lua_ls = require 'lsp.lua_ls',
}
local on_attach = require 'lsp.on_attach'
local lspconfig = require 'lspconfig'
for server, config in pairs(servers) do
if require('lsp.utils').check_ft(server, config) then
if config['enable'] then
if not config['enable']() then
vim.notify('Disabling language server ' .. server, vim.log.levels.WARN)
goto continue
end
end
else
goto continue
end
config.capabilities = require('blink.cmp').get_lsp_capabilities(config.capabilities)
config.on_attach = require 'lsp.on_attach'
vim.lsp.enable(server)
vim.lsp.config(server, config)
::continue::
end
end
return M

34
lua/lsp/lua_ls.lua Normal file
View File

@ -0,0 +1,34 @@
return {
on_init = function(client)
if client.workspace_folders then
local path = client.workspace_folders[1].name
if path ~= vim.fn.stdpath 'config' and (vim.uv.fs_stat(path .. '/.luarc.json') or vim.uv.fs_stat(path .. '/.luarc.jsonc')) then
return
end
end
client.config.settings.Lua = vim.tbl_deep_extend('force', client.config.settings.Lua, {
runtime = {
-- Tell the language server which version of Lua you're using
-- (most likely LuaJIT in the case of Neovim)
version = 'LuaJIT',
},
-- Make the server aware of Neovim runtime files
workspace = {
checkThirdParty = false,
library = {
vim.env.VIMRUNTIME,
-- Depending on the usage, you might want to add additional paths here.
-- "${3rd}/luv/library"
-- "${3rd}/busted/library",
},
-- or pull in all of 'runtimepath'. NOTE: this is a lot slower and will cause issues when working on your own configuration (see https://github.com/neovim/nvim-lspconfig/issues/3189)
-- library = vim.api.nvim_get_runtime_file("", true)
},
})
end,
settings = {
Lua = {},
},
filetypes = { 'lua' },
}

29
lua/lsp/on_attach.lua Normal file
View File

@ -0,0 +1,29 @@
return function(client, bufnr)
require('nvim-navbuddy').attach(client, bufnr)
local nmap = function(keys, func, desc)
if desc then
desc = 'LSP: ' .. desc
end
vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc })
end
nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition')
nmap('gi', vim.lsp.buf.implementation, '[G]oto [I]mplementation')
nmap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition')
nmap('<leader>rn', vim.lsp.buf.rename, '[R]e[N]ame')
nmap('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
nmap('K', vim.lsp.buf.hover, 'Hover docs')
-- Lesser used LSP functionality
nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
nmap('<leader>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder')
nmap('<leader>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder')
nmap('<leader>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, '[W]orkspace [L]ist Folders')
nmap('<leader>e', vim.diagnostic.open_float, 'Open floating diagnostics')
nmap('<leader>q', vim.diagnostic.setloclist, 'Open diagnostics list')
end

15
lua/lsp/utils.lua Normal file
View File

@ -0,0 +1,15 @@
local M = {}
function M.check_ft(server, config)
if config.filetypes == nil or next(config.filetypes) == nil then
return true -- if no filetypes specified then enable
else
config.server = server
for _, ft in ipairs(config.filetypes) do
if vim.bo[0].filetype == ft then
return true
end
end
end
return false
end
return M

67
lua/options.lua Normal file
View File

@ -0,0 +1,67 @@
-- Show which line your cursor is on
vim.o.cursorline = true
-- highligt vertical column
vim.o.colorcolumn = '100'
-- better diff
vim.o.diffopt = 'internal,filler,closeoff,iwhiteall'
-- Make line numbers default
vim.o.number = true
vim.o.relativenumber = true
-- Enable mouse mode, can be useful for resizing splits for example!
vim.o.mouse = 'a'
-- Don't show the mode, since it's already in the status line
vim.o.showmode = false
-- Enable break indent
vim.o.breakindent = true
-- Save undo history
vim.o.undofile = true
-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
vim.o.ignorecase = true
vim.o.smartcase = true
-- search and replace
vim.o.gdefault = true
vim.o.hlsearch = true
-- Keep signcolumn on by default
vim.opt.signcolumn = 'yes'
-- Decrease update time
vim.opt.updatetime = 250
-- Decrease mapped sequence wait time
vim.opt.timeoutlen = 300
-- Configure how new splits should be opened
vim.opt.splitright = true
vim.opt.splitbelow = true
-- Sets how neovim will display certain whitespace characters in the editor.
-- See `:help 'list'`
-- and `:help 'listchars'`
vim.opt.list = true
vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '' }
-- Minimal number of screen lines to keep around the cursor.
vim.opt.scrolloff = 8
vim.o.sidescrolloff = 8
vim.o.tabstop = 4
vim.o.shiftwidth = 4
-- better grepping
vim.o.grepprg = 'rg --vimgrep --smart-case'
vim.o.grepformat = '%f:%l:%c:%m'
vim.o.termguicolors = true
-- enable spell checking
vim.o.spell = true
vim.o.spelllang = 'en_gb'

58
lua/plugins/ai.lua Normal file
View File

@ -0,0 +1,58 @@
local file = vim.fn.glob '~/projects/cdy-nvim'
if file ~= '' then
return {
{
'projects/cdy-nvim',
dir = '~/projects/cdy-nvim',
cmd = { 'CodyChat', 'CodyAsk', 'CodySetModel', 'CodyToggleFileContext', 'CodyToggleRepoContext', 'CodyNew' },
dependencies = {
'MunifTanjim/nui.nvim',
'nvim-lua/plenary.nvim',
},
keys = {
{ '<leader>cc', '<cmd>CodyChat<cr>', desc = 'Open cody chat' },
{ '<leader>cn', '<cmd>CodyNew<cr>', desc = 'Start new cody chat' },
},
dev = true,
opts = {
include_file = true,
include_repo = true,
},
},
}
else
return {
{
'olimorris/codecompanion.nvim',
lazy = false,
opts = {
strategies = {
chat = {
adapter = 'anthropic',
},
inline = {
adapter = 'anthropic',
},
},
},
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-treesitter/nvim-treesitter',
},
},
-- {
-- 'pasky/claude.vim',
-- lazy = false,
-- config = function()
-- local api_key = os.getenv 'ANTHROPIC_API_KEY'
-- vim.g.claude_api_key = api_key
-- vim.cmd [[
-- let g:claude_map_implement = "<Leader>ci"
-- let g:claude_map_open_chat = "<Leader>cc"
-- let g:claude_map_send_chat_message = "<C-]>"
-- let g:claude_map_cancel_response = "<Leader>cx"
-- ]]
-- end,
-- },
}
end

55
lua/plugins/blink.lua Normal file
View File

@ -0,0 +1,55 @@
return {
{
'saghen/blink.cmp',
version = 'v0.13.1',
event = 'LspAttach',
dependencies = {
'Kaiser-Yang/blink-cmp-avante',
'hrsh7th/nvim-cmp',
'L3MON4D3/LuaSnip',
'saadparwaiz1/cmp_luasnip',
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-nvim-lua',
'hrsh7th/cmp-path',
'hrsh7th/cmp-buffer',
},
opts = {
keymap = {
preset = 'enter',
['<c-j>'] = { 'select_next', 'fallback' },
['<c-k>'] = { 'select_prev', 'fallback' },
['<c-l>'] = { 'hide', 'fallback' },
},
cmdline = { enabled = false },
term = { enabled = false },
completion = {
accept = {
auto_brackets = { enabled = true },
},
documentation = { auto_show = true },
},
appearance = {
use_nvim_cmp_as_default = true,
nerd_font_variant = 'mono',
},
sources = {
default = { 'avante', 'lsp', 'path', 'snippets', 'buffer' },
per_filetype = {
codecompanion = { 'codecompanion' },
},
providers = {
avante = {
module = 'blink-cmp-avante',
name = 'Avante',
opts = {},
},
},
},
snippets = { preset = 'luasnip' },
},
opts_extend = { 'sources.default' },
},
}

View File

@ -0,0 +1,56 @@
return {
{
'olimorris/codecompanion.nvim',
dependencies = {
{ 'nvim-treesitter/nvim-treesitter', build = ':TSUpdate' },
{ 'nvim-lua/plenary.nvim' },
-- Test with blink.cmp
{
'saghen/blink.cmp',
lazy = false,
version = '*',
opts = {
keymap = {
preset = 'enter',
['<S-Tab>'] = { 'select_prev', 'fallback' },
['<Tab>'] = { 'select_next', 'fallback' },
},
cmdline = { sources = { 'cmdline' } },
sources = {
default = { 'lsp', 'path', 'buffer', 'codecompanion' },
},
},
},
},
opts = {
adapters = {
ollama = function()
return require('codecompanion.adapters').extend('ollama', {
schema = {
model = {
default = 'hf.co/Qwen/Qwen2.5-Coder-7B-Instruct-GGUF:latest',
},
num_ctx = {
default = 4096,
},
},
})
end,
allow_insecure = true,
},
--Refer to: https://github.com/olimorris/codecompanion.nvim/blob/main/lua/codecompanion/config.lua
strategies = {
--NOTE: Change the adapter as required
chat = {
adapter = 'ollama',
completion_provider = 'blink', -- blink|cmp|coc|default
},
inline = { adapter = 'ollama' },
cmd = { adapter = 'ollama' },
},
opts = {
log_level = 'DEBUG',
},
},
},
}

60
lua/plugins/conform.lua Normal file
View File

@ -0,0 +1,60 @@
return {
{
'stevearc/conform.nvim',
event = 'LspAttach',
ft = { 'lua', 'elixir', 'go', 'erlang', 'typescriptreact', 'typescript', 'json', 'nix' },
cmd = 'Format',
keys = {
{
'<leader>fm',
function()
require('conform').format { async = true, lsp_format = 'fallback' }
end,
desc = 'Format buffer',
},
},
config = function()
require('conform').setup {
notify_on_error = true,
format_on_save = function(bufnr)
local cwd = vim.fn.getcwd()
if cwd:match '/cashout' or cwd:match '/cbe' then
vim.notify_once('Detected cashout repo, auto format disabled', vim.log.levels.WARN)
return
elseif vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then
return
end
return { timeout = 500, lsp_fallback = true }
end,
formatters_by_ft = {
lua = { 'stylua' },
go = { 'gofmt', 'goimports' },
typescript = { 'prettier' },
typescriptreact = { 'prettier' },
json = { 'prettier' },
nix = { 'nixfmt' },
},
}
vim.api.nvim_create_user_command('Format', function(args)
require('conform').format { async = true, lsp_format = 'fallback' }
end, { desc = 'Format buffer' })
vim.api.nvim_create_user_command('FormatDisable', function(args)
if args.bang then
-- FormatDisable! will disable formatting just for this buffer
vim.b.disable_autoformat = true
else
vim.g.disable_autoformat = true
end
end, {
desc = 'Disable autoformat-on-save',
bang = true,
})
vim.api.nvim_create_user_command('FormatEnable', function()
vim.b.disable_autoformat = false
vim.g.disable_autoformat = false
end, {
desc = 'Re-enable autoformat-on-save',
})
end,
},
}

51
lua/plugins/dap.lua Normal file
View File

@ -0,0 +1,51 @@
local view = require 'plugins.dap.dap-view'
return {
{
'mfussenegger/nvim-dap',
dependencies = {
'leoluz/nvim-dap-go',
view.get_config(),
},
ft = { 'go' },
event = 'LspAttach',
keys = {
{ '<F7>', '<cmd>DapStepInto<cr>' },
{ '<F8>', '<cmd>DapContinue<cr>' },
{ '<F9>', '<cmd>DapStepOver<cr>' },
{
'<leader>dt',
function()
require('dap-go').debug_test()
end,
desc = 'Debug closest go test',
},
},
config = function()
require('dap-go').setup {
dap_configurations = {
{
type = 'go',
name = 'Debug COSCT',
request = 'launch',
mode = 'test',
program = '${file}',
buildFlags = { '-tags=service_legacy' },
outputMode = 'remote',
},
},
}
end,
},
{
'weissle/persistent-breakpoints.nvim',
ft = { 'go' },
opts = {
load_breakpoints_event = { 'VimEnter' },
},
keys = {
{ '<leader>db', '<cmd>PBToggleBreakpoint<cr>', desc = 'Toggle breakpoint' },
{ '<leader>dB', '<cmd>PBSetConditionalBreakpoint<cr>', desc = 'Set conditional breakpoint' },
{ '<leader>dl', '<cmd>PBSetLogPoint<cr>', desc = 'Set log point' },
},
},
}

View File

@ -0,0 +1,53 @@
M = {}
M.get_config = function()
return {
'igorlfs/nvim-dap-view',
opts = {
winbar = {
controls = { enabled = true },
sections = { 'watches', 'scopes', 'console', 'breakpoints', 'threads', 'repl' },
},
windows = {
terminal = {
-- `go` is known to not use the terminal.
hide = { 'go' },
},
},
},
keys = {
{ '<leader>dvv', '<cmd>DapViewToggle<cr>' },
{ '<leader>dvb', '<cmd>DapViewShow breakpoints<cr>' },
{ '<leader>dvs', '<cmd>DapViewShow scopes<cr>' },
{ '<leader>dvw', '<cmd>DapViewShow watches<cr>' },
{ '<leader>dvW', '<cmd>DapViewWatch<cr>' },
{ '<leader>dvr', '<cmd>DapViewShow repl<cr>' },
{ '<leader>dvc', '<cmd>DapViewShow console<cr>' },
},
config = function(_, opts)
require('dap-view').setup(opts)
vim.api.nvim_create_autocmd('QuitPre', {
group = vim.api.nvim_create_augroup('dap-view-extra', {}),
pattern = '*',
callback = function(_)
local wins = vim.api.nvim_list_wins()
local splits = 0
for _, w in ipairs(wins) do
local buf = vim.api.nvim_win_get_buf(w)
local name = vim.api.nvim_buf_get_name(buf)
if not (name:match 'dap%-view' or name:match 'dap%-repl' or name == '') then
splits = splits + 1
end
end
if splits == 1 then
require('dap-view').close()
end
end,
})
end,
}
end
return M

75
lua/plugins/fzf.lua Normal file
View File

@ -0,0 +1,75 @@
return {
{
'ibhagwan/fzf-lua',
opts = {},
keys = {
{
'<leader>ff',
function()
require('fzf-lua').files()
end,
desc = 'Find files',
},
{
'<leader>fw',
function()
require('fzf-lua').live_grep_glob { rg_glob = true }
end,
desc = 'Find word',
},
{
'<leader>fb',
function()
require('fzf-lua').buffers()
end,
desc = 'Find buffer',
},
-- lsp
{
'<leader>gr',
function()
require('fzf-lua').lsp_references()
end,
desc = 'Find references',
},
{
'<leader>ds',
function()
require('fzf-lua').lsp_document_symbols()
end,
desc = 'Find document symbols',
},
{
'<leader>dd',
function()
require('fzf-lua').diagnostics_document()
end,
desc = 'Find document diagnostics',
},
{
'<leader>dw',
function()
require('fzf-lua').diagnostics_workspace()
end,
desc = 'Find workspace diagnostics',
},
-- dap
{
'<leader>dc',
function()
require('fzf-lua').dap_configurations()
end,
desc = 'Run DAP configuration',
},
{
'<leader>dq',
function()
require('fzf-lua').dap_commands()
end,
desc = 'Send DAP command',
},
},
},
}

19
lua/plugins/gitsigns.lua Normal file
View File

@ -0,0 +1,19 @@
return {
{ -- Adds git related signs to the gutter, as well as utilities for managing changes
'lewis6991/gitsigns.nvim',
lazy = false,
keys = {
{ '<leader>gb', '<cmd>Gitsigns blame<cr>', desc = 'Show blame for current buffer' },
{ '<leader>gp', '<cmd>Gitsigns preview_hunk<cr>', desc = 'Preview hunk' },
},
opts = {
signs = {
add = { text = '+' },
change = { text = '~' },
delete = { text = '_' },
topdelete = { text = '' },
changedelete = { text = '~' },
},
},
},
}

102
lua/plugins/harpoon.lua Normal file
View File

@ -0,0 +1,102 @@
return {
{
'ThePrimeagen/harpoon',
branch = 'harpoon2',
dependencies = {
'nvim-lua/plenary.nvim',
'ibhagwan/fzf-lua',
},
keys = {
{
'<leader>i',
function()
require('harpoon'):list():add()
end,
desc = 'add current buffer to harpoon',
},
{
'<leader>u',
function()
local harpoon = require 'harpoon'
local harpoon_files = harpoon:list()
local file_paths = {}
for _, item in ipairs(harpoon_files.items) do
if item.value ~= nil or item.value ~= '' then
table.insert(file_paths, item.value)
end
end
require('fzf-lua').fzf_exec(file_paths, {
fn_transform = function(x)
return require('fzf-lua').make_entry.file(x, { file_icons = true, color_icons = true })
end,
actions = {
['default'] = require('fzf-lua').actions.file_edit,
['ctrl-x'] = function(selected, _)
for i, item in ipairs(harpoon_files.items) do
if item.value == selected[1] then
harpoon:list():remove_at(i)
return
end
end
vim.notify('Could not find item ' .. selected[1] .. ' in harpoon list', vim.log.levels.WARN)
end,
},
})
end,
desc = 'Find in harpoon list',
},
{
'<leader>fy',
function()
local harpoon = require 'harpoon'
local harpoon_files = harpoon:list 'yeet'
local file_paths = {}
for _, item in ipairs(harpoon_files.items) do
if item.value ~= nil or item.value ~= '' then
table.insert(file_paths, item.value)
end
end
require('fzf-lua').fzf_exec(file_paths, {
actions = {
['default'] = function(selection)
require('yeet').execute(selection[1])
end,
['ctrl-x'] = function(selected, _)
for i, item in ipairs(harpoon_files.items) do
if item.value == selected[1] then
harpoon:list('yeet'):remove_at(i)
return
end
end
vim.notify('Could not find item ' .. selected[1] .. ' in harpoon list [yeet]', vim.log.levels.WARN)
end,
},
})
end,
desc = 'Find yeet',
},
{
'<leader><BS>',
function()
local harpoon = require 'harpoon'
harpoon.ui:toggle_quick_menu(harpoon:list 'yeet')
end,
desc = 'Open yeet cache',
},
},
config = function()
local harpoon = require 'harpoon'
harpoon:setup {
yeet = {
select = function(list_item, _, _)
require('yeet').execute(list_item.value)
end,
},
}
end,
},
}

103
lua/plugins/init.lua Normal file
View File

@ -0,0 +1,103 @@
return {
-- NOTE: [ THEMES ]
-- {
-- 'yorumicolors/yorumi.nvim',
-- },
-- {
-- 'savq/melange-nvim',
-- },
-- {
-- 'sainnhe/gruvbox-material',
-- lazy = false,
-- config = function()
-- vim.g.gruvbox_material_background = 'medium'
-- vim.g.gruvbox_material_enable_italic = true
-- vim.cmd 'colorscheme gruvbox-material'
-- end,
-- },
{
'rebelot/kanagawa.nvim',
lazy = false,
config = function()
vim.cmd 'colorscheme kanagawa'
end,
},
{ -- Git integrations
'tpope/vim-fugitive',
cmd = { 'G', 'Git' },
keys = {
{ '<leader>gg', '<cmd>Git<cr>', desc = 'Open git fugitive' },
},
},
{ -- traverse undotree
'mbbill/undotree',
keys = {
{ '<leader>fu', '<cmd>UndotreeToggle<cr>', desc = 'Toggle undotree' },
},
},
{ -- better f motions
'justinmk/vim-sneak',
keys = {
{ 's', '<Plug>Sneak_s', desc = 'Sneak forward' },
{ 'S', '<Plug>Sneak_S', desc = 'Sneak backwards' },
},
},
{ -- surround motions
'kylechui/nvim-surround',
opts = {},
event = 'VeryLazy',
},
{ -- put cursor where you left it
'farmergreg/vim-lastplace',
lazy = false,
},
{ -- Useful plugin to show you pending keybinds.
'folke/which-key.nvim',
event = 'VeryLazy',
opts = {},
},
{
-- `lazydev` configures Lua LSP for your Neovim config, runtime and plugins
-- used for completion, annotations and signatures of Neovim apis
'folke/lazydev.nvim',
ft = 'lua',
opts = {
library = {
-- Load luvit types when the `vim.uv` word is found
{ path = '${3rd}/luv/library', words = { 'vim%.uv' } },
},
},
},
{
'nmac427/guess-indent.nvim',
Event = 'BufEnter',
opts = {},
},
-- Highlight todo, notes, etc in comments
{
'folke/todo-comments.nvim',
event = 'VimEnter',
dependencies = { 'nvim-lua/plenary.nvim' },
opts = { signs = false },
},
{
'j-hui/fidget.nvim',
version = '*',
opts = {
notification = {
override_vim_notify = true,
},
},
lazy = false,
},
}

36
lua/plugins/lsp.lua Normal file
View File

@ -0,0 +1,36 @@
return {
{
'neovim/nvim-lspconfig',
dependencies = {
'hrsh7th/nvim-cmp',
'saghen/blink.cmp',
{
'SmiteshP/nvim-navbuddy',
dependencies = {
'SmiteshP/nvim-navic',
'MunifTanjim/nui.nvim',
},
opts = { lsp = { auto_attach = true } },
keys = {
{ '<leader>n', '<cmd>Navbuddy<cr>', desc = 'Open Navbuddy' },
},
},
},
ft = { 'lua', 'elixir', 'go', 'erlang', 'typescript', 'typescriptreact', 'rust' },
config = function()
require('lsp').setup()
end,
},
{
'windwp/nvim-ts-autotag',
ft = { 'javascriptreact', 'typescriptreact', 'html' },
opts = {
opts = {
-- Defaults
enable_close = true, -- Auto close tags
enable_rename = true, -- Auto rename pairs of tags
enable_close_on_slash = false, -- Auto close on trailing </
},
},
},
}

29
lua/plugins/lualine.lua Normal file
View File

@ -0,0 +1,29 @@
return {
{
'nvim-lualine/lualine.nvim',
opts = {
options = {
icons_enabled = true,
theme = 'auto',
component_separators = { left = '|', right = '|' },
section_separators = { left = '', right = '' },
},
tabline = { lualine_a = { 'buffers' } },
sections = {
lualine_a = { 'mode' },
lualine_b = { 'branch', 'diff', 'diagnostics' },
lualine_c = { 'filename' },
lualine_x = { 'encoding', 'filetype' },
lualine_y = { {
name = 'datetime',
extra_config = { style = 'Time %H:%M' },
} },
lualine_z = { 'searchcount' },
},
inactive_sections = {
lualine_a = { 'mode' },
lualine_c = { 'filename' },
},
},
},
}

15
lua/plugins/luasnip.lua Normal file
View File

@ -0,0 +1,15 @@
return {
{
'L3MON4D3/LuaSnip',
ft = { 'go', 'elixir' },
main = 'luasnip.configs',
opts = {
store_selection_keys = '<tab>',
},
config = function()
require('luasnip').add_snippets('go', require 'snippets.go')
require('luasnip').add_snippets('erlang', require 'snippets.erlang')
require('luasnip').add_snippets('elixir', require 'snippets.elixir')
end,
},
}

49
lua/plugins/noice.lua Normal file
View File

@ -0,0 +1,49 @@
return {}
-- {
-- 'folke/noice.nvim',
-- dependencies = {
-- 'MunifTanjim/nui.nvim',
-- },
-- Event = 'VeryLazy',
-- opts = {
-- lsp = {
-- -- override markdown rendering so that **cmp** and other plugins use **Treesitter**
-- override = {
-- ['vim.lsp.util.convert_input_to_markdown_lines'] = true,
-- ['vim.lsp.util.stylize_markdown'] = true,
-- ['cmp.entry.get_documentation'] = true, -- requires hrsh7th/nvim-cmp
-- },
-- },
-- -- you can enable a preset for easier configuration
-- presets = {
-- bottom_search = true, -- use a classic bottom cmdline for search
-- command_palette = true, -- position the cmdline and popupmenu together
-- long_message_to_split = true, -- long messages will be sent to a split
-- inc_rename = false, -- enables an input dialog for inc-rename.nvim
-- lsp_doc_border = false, -- add a border to hover docs and signature help
-- },
-- messages = {
-- enabled = true,
-- view_search = false,
-- },
-- popupmenu = {
-- enabled = true,
-- },
-- -- filter out annoying erlangls messages
-- routes = {
-- {
-- filter = {
-- event = 'lsp',
-- kind = 'progress',
-- find = 'Indexing',
-- cond = function(message)
-- local client = vim.tbl_get(message.opts, 'progress', 'client')
-- return client == 'erlangls'
-- end,
-- },
-- opts = { skip = true },
-- },
-- },
-- },
-- },
-- }

28
lua/plugins/notes.lua Normal file
View File

@ -0,0 +1,28 @@
return {
{
'epwalsh/obsidian.nvim',
version = '*',
ft = 'markdown',
dependencies = {
'nvim-lua/plenary.nvim',
},
config = function(_, opts)
require('obsidian').setup(opts)
vim.api.nvim_create_autocmd('FileType', {
group = vim.api.nvim_create_augroup('MarkdownConceal', {}),
pattern = 'markdown',
callback = function(ev)
vim.opt_local.conceallevel = 2
end,
})
end,
opts = {
workspaces = {
{
name = 'notes',
path = '~/notes',
},
},
},
},
}

11
lua/plugins/oil.lua Normal file
View File

@ -0,0 +1,11 @@
return {
{
'stevearc/oil.nvim',
opts = {
skip_confirm_for_simple_edits = true,
},
keys = {
{ '<leader>fo', '<cmd>Oil --float<cr>', desc = 'Open oil' },
},
},
}

View File

@ -0,0 +1,77 @@
return {
{ -- Highlight, edit, and navigate code
'nvim-treesitter/nvim-treesitter',
dependencies = {
'nvim-treesitter/nvim-treesitter-textobjects', -- maybe try mini.ai instead?
},
build = ':TSUpdate',
main = 'nvim-treesitter.configs', -- Sets main module to use for opts
opts = {
auto_install = false,
highlight = { enable = true },
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
node_incremental = 'v',
node_decremental = 'V',
scope_incremental = '<c-v>',
},
},
textobjects = {
swap = {
enable = true,
swap_next = {
['<leader>a'] = '@parameter.inner',
},
swap_previous = {
['<leader>A'] = '@parameter.inner',
},
},
select = {
enable = true,
-- Automatically jump forward to textobj, similar to targets.vim
lookahead = true,
keymaps = {
-- You can use the capture groups defined in textobjects.scm
['af'] = '@function.outer',
['if'] = '@function.inner',
['ac'] = '@class.outer',
-- You can optionally set descriptions to the mappings (used in the desc parameter of
-- nvim_buf_set_keymap) which plugins like which-key display
['ic'] = { query = '@class.inner', desc = 'Select inner part of a class region' },
-- You can also use captures from other query groups like `locals.scm`
['as'] = { query = '@local.scope', query_group = 'locals', desc = 'Select language scope' },
-- custom
['ip'] = { query = '@parameter.inner', desc = 'Select inner parameter' },
},
-- You can choose the select mode (default is charwise 'v')
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * method: eg 'v' or 'o'
-- and should return the mode ('v', 'V', or '<c-v>') or a table
-- mapping query_strings to modes.
selection_modes = {
['@parameter.outer'] = 'v', -- charwise
['@function.outer'] = 'V', -- linewise
['@class.outer'] = '<c-v>', -- blockwise
},
-- If you set this to `true` (default is `false`) then any textobject is
-- extended to include preceding or succeeding whitespace. Succeeding
-- whitespace has priority in order to act similarly to eg the built-in
-- `ap`.
--
-- Can also be a function which gets passed a table with the keys
-- * query_string: eg '@function.inner'
-- * selection_mode: eg 'v'
-- and should return true or false
include_surrounding_whitespace = true,
},
},
},
},
}

80
lua/plugins/yeet.lua Normal file
View File

@ -0,0 +1,80 @@
return {
{
'samharju/yeet.nvim',
opts = {
clear_before_yeet = false,
interrupt_before_yeet = true,
yeet_and_run = true,
custom_eval = function(cmd_string)
if cmd_string:match '#test' then
-- get current win's filetype
local bufnr = vim.api.nvim_win_get_buf(0)
local ft = vim.bo[bufnr].filetype
if ft == 'go' then
local dap_go = require 'dap-go-ts'
local test = dap_go.closest_test()
cmd_string = cmd_string:gsub('#test', test.name)
end
end
if cmd_string:match '#cwd' then
local cwd = vim.fn.getcwd()
cmd_string = cmd_string:gsub('#cwd', cwd)
end
if cmd_string:match '#file' then
local file = vim.api.nvim_buf_get_name(0)
cmd_string = cmd_string:gsub('#file', file)
end
return cmd_string
end,
},
keys = {
{
-- Open target selection
'<leader>yt',
function()
require('yeet').select_target()
end,
desc = 'Open yeet target select',
},
{
-- Douple tap \ to yeet at something
'\\\\',
function()
require('yeet').execute()
end,
desc = 'Yeet',
},
{
-- Toggle autocommand for yeeting after write
'<leader>yo',
function()
require('yeet').toggle_post_write()
if vim.g.yeetaucmd then
vim.g.yeetaucmd = false
vim.notify 'disabled yeet aucmd'
else
vim.g.yeetaucmd = true
vim.notify 'enabled yeet aucmd'
end
end,
desc = 'Toggle post write yeet aucmd',
},
{
-- Yeet visual selection. Useful sending core to a repl or running multiple commands.
'<leader>yv',
function()
require('yeet').execute_selection { clear_before_yeet = false }
end,
mode = { 'n', 'v' },
desc = 'Yeet selected text',
},
},
},
}

1
lua/snippets/elixir.lua Normal file
View File

@ -0,0 +1 @@
return {}

116
lua/snippets/erlang.lua Normal file
View File

@ -0,0 +1,116 @@
local ls = require 'luasnip'
local s = ls.snippet
local sn = ls.snippet_node
local isn = ls.indent_snippet_node
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local r = ls.restore_node
local events = require 'luasnip.util.events'
local ai = require 'luasnip.nodes.absolute_indexer'
local extras = require 'luasnip.extras'
local l = extras.lambda
local rep = extras.rep
local p = extras.partial
local m = extras.match
local n = extras.nonempty
local dl = extras.dynamic_lambda
local fmt = require('luasnip.extras.fmt').fmt
local fmta = require('luasnip.extras.fmt').fmta
local conds = require 'luasnip.extras.expand_conditions'
local postfix = require('luasnip.extras.postfix').postfix
local types = require 'luasnip.util.types'
local parse = require('luasnip.util.parser').parse_snippet
local ms = ls.multi_snippet
local k = require('luasnip.nodes.key_indexer').new_key
return {
s({ trig = 'mod', name = 'Module', description = 'insert module with filename populated' }, {
t '-module(',
f(function(args, snip)
local filename = snip.env.TM_FILENAME
local rev = string.reverse(filename)
local dot = string.find(rev, '.', 1, true)
if dot == nil then
return filename
else
return filename:sub(1, -(dot + 1))
end
end, {}),
t ').',
}),
s({ trig = 'fn', name = 'function', description = 'new function' }, {
i(1, 'function_name'),
t '(',
i(2),
t { ') ->', '' },
i(0),
t '.',
}),
s({ trig = 'case', name = 'case statement', description = 'new case statement' }, {
t 'case ',
i(1),
t { ' of', '' },
i(2),
t 'end',
}),
s({ trig = 'HT', name = 'list pattern', description = 'list pattern' }, {
t '[ ',
i(1, 'Head'),
t ' | ',
i(2, 'Tail'),
t ' ]',
}),
s({ trig = 'tup', name = 'tuple pattern', description = 'tuple pattern' }, {
t '{ ',
i(1, 'Value'),
t ' }',
}),
s({ trig = 'DOWN', name = 'Down message', description = 'down message for matching' }, {
t "{'DOWN', Ref, process, Pid, Reason}",
}),
s({ trig = 'mexp', name = 'merge exports', description = 'merge multiple lines of exports into one' }, {
t '-export([',
f(function(_, snip)
local all_exports = ''
local is_first = true
for _, line in ipairs(snip.env.LS_SELECT_RAW) do
local exports = line:gsub('-export%(%[(.*)%]%).', '%1')
if is_first then
all_exports = all_exports .. exports
is_first = false
else
all_exports = all_exports .. ',' .. exports
end
end
return all_exports
end, {}),
t ']).',
}),
s({ trig = 'server', name = 'gen server template', description = 'create gen server outline' }, {
t {
'-behavoir(gen_server).',
'-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).',
'',
'init(State) ->',
'\t{ok, State}.',
'',
'handle_call(_Event, _From, State) ->',
'\t{noreply, State}.',
'',
'handle_cast(_Event, State) ->',
'\t{noreply, State}.',
'',
'handle_info(_Event, State) ->',
'\t{noreply, State}.',
'',
'terminate(_Reason, _State) ->',
'\tok.',
'',
'code_change(_OldSvn, State, _Extra) ->',
'\t{ok, State}.',
},
}),
}

73
lua/snippets/go.lua Normal file
View File

@ -0,0 +1,73 @@
local ls = require 'luasnip'
local s = ls.snippet
local sn = ls.snippet_node
local isn = ls.indent_snippet_node
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local r = ls.restore_node
local events = require 'luasnip.util.events'
local ai = require 'luasnip.nodes.absolute_indexer'
local extras = require 'luasnip.extras'
local l = extras.lambda
local rep = extras.rep
local p = extras.partial
local m = extras.match
local n = extras.nonempty
local dl = extras.dynamic_lambda
local fmt = require('luasnip.extras.fmt').fmt
local fmta = require('luasnip.extras.fmt').fmta
local conds = require 'luasnip.extras.expand_conditions'
local postfix = require('luasnip.extras.postfix').postfix
local types = require 'luasnip.util.types'
local parse = require('luasnip.util.parser').parse_snippet
local ms = ls.multi_snippet
local k = require('luasnip.nodes.key_indexer').new_key
return {
s({ trig = 'struct', name = 'struct', description = 'Create a new struct' }, {
t 'type ',
i(1, 'StructName'),
t { ' struct {', '\t' },
i(0),
t { '', '}' },
}),
s({ trig = 'enil', name = 'err is nil', description = 'check if err is nil' }, {
t 'if ',
i(1, 'err'),
t { ' != nil {', '\t' },
i(2),
t { '', '}' },
}),
s({ trig = 'snil', name = 'err is nil (surround)', description = 'check if err is nil (surround)' }, {
t 'if ',
i(1, 'err'),
t { ' != nil {', '' },
f(function(_, snip)
local res, env = {}, snip.env
for _, ele in ipairs(env.LS_SELECT_RAW) do
table.insert(res, ele)
end
return res
end, {}),
t { '', '}' },
}),
s({ trig = 'erris', name = 'errors.Is', description = 'repalce err == with errors.Is' }, {
t 'error.Is(',
f(function(_, snip)
local line = snip.env.LS_SELECT_RAW[1]
return line:gsub(' ?== ?', ', ')
end, {}),
t ')',
}),
s({ trig = 'errnis', name = 'not errors.Is', description = 'repalce err != with !errors.Is' }, {
t '!error.Is(',
f(function(_, snip)
local line = snip.env.LS_SELECT_RAW[1]
return line:gsub(' ?!= ?', ', ')
end, {}),
t ')',
}),
}