This commit is contained in:
2026-02-26 11:15:22 +01:00
commit d36d07d224
19 changed files with 2020 additions and 0 deletions

14
lua/custom/keymaps.lua Normal file
View File

@@ -0,0 +1,14 @@
-- Set custom maps
local map = vim.keymap.set
-- Horizontal split for terminal
map('n', '<C-t>', ':split | terminal<CR>', { desc = '[T]erminal (Horizontal Split)' })
-- Open neo-filetree
map('n', '<C-e>', ':Neotree toggle<CR>', { desc = '[E]xplorer (toggle neotree)' })
-- Open lazygit in overlay
map('n', '<C-g>', '<cmd>LazyGit<CR>', { desc = 'LazyGit' })
-- Telescope grep all files in working dir
map('n', '<C-f>', '<cmd>builtin.grep_string<CR>', { desc = '[F]ind (Telescope ripgrep all files in work_dir)' })

View File

@@ -0,0 +1,8 @@
-- Add custom comments package
-- https://github.com/numToStr/Comment.nvim
return {
'numToStr/Comment.nvim',
opts = {
-- add any options here
}
}

View File

@@ -0,0 +1,31 @@
-- Open fff.nvim
-- https://github.com/dmtrKovalenko/fff.nvim
return {
'dmtrKovalenko/fff.nvim',
build = function()
-- this will download prebuild binary or try to use existing rustup toolchain to build from source
-- (if you are using lazy you can use gb for rebuilding a plugin if needed)
require('fff.download').download_or_build_binary()
end,
-- if you are using nixos
-- build = "nix run .#release",
opts = { -- (optional)
debug = {
enabled = false, -- we expect your collaboration at least during the beta
show_scores = true, -- to help us optimize the scoring system, feel free to share your scores!
},
},
-- No need to lazy-load with lazy.nvim.
-- This plugin initializes itself lazily.
lazy = false,
keys = {
{
'ff', -- try it if you didn't it is a banger keybinding for a picker
function()
require('fff').find_files()
end,
desc = 'FFFind files',
},
},
}

View File

@@ -0,0 +1,18 @@
-- You can add your own plugins here or in other files in this directory!
-- I promise not to create any merge conflicts in this directory :)
--
-- See the kickstart.nvim README for more information
return {
-- {
-- 'navarasu/onedark.nvim',
-- priority = 1000, -- make sure to load this before all the other start plugins
-- config = function()
-- require('onedark').setup {
-- style = 'warmer',
-- }
-- require('onedark').load()
-- end,
-- },
-- { 'catppuccin/nvim', name = 'catppuccin', priority = 1000 },
--
}

View File

@@ -0,0 +1,23 @@
-- Open lazygit
-- https://github.com/kdheepak/lazygit.nvim
return {
'kdheepak/lazygit.nvim',
lazy = true,
cmd = {
'LazyGit',
'LazyGitConfig',
'LazyGitCurrentFile',
'LazyGitFilter',
'LazyGitFilterCurrentFile',
},
-- optional for floating window border decoration
dependencies = {
'nvim-lua/plenary.nvim',
},
-- setting the keybinding for LazyGit with 'keys' is recommended in
-- order to load the plugin when the command is run for the first time
keys = {
{ '<leader>lg', '<cmd>LazyGit<cr>', desc = 'LazyGit' },
},
}

View File

@@ -0,0 +1,114 @@
-- Simple PDF viewer using pdftoppm + image.nvim
-- Requires: poppler (brew install poppler)
return {
'3rd/image.nvim',
config = function()
local image = require('image')
image.setup({})
local pdf_state = {}
vim.api.nvim_create_autocmd('BufReadPost', {
pattern = '*.pdf',
callback = function()
local pdf_path = vim.fn.expand('%:p')
local temp_dir = vim.fn.tempname()
vim.fn.mkdir(temp_dir, 'p')
local bufnr = vim.api.nvim_get_current_buf()
-- Convert all pages upfront
vim.notify('Converting PDF...', vim.log.levels.INFO)
vim.fn.jobstart({
'pdftoppm', '-png',
pdf_path, temp_dir .. '/page'
}, {
on_exit = function(_, code)
vim.schedule(function()
if code ~= 0 then
vim.notify('Failed to convert PDF', vim.log.levels.ERROR)
return
end
-- Count generated files
local handle = vim.loop.fs_scandir(temp_dir)
local page_count = 0
if handle then
while true do
local name = vim.loop.fs_scandir_next(handle)
if not name then break end
if name:match('^page%-%d+%.png$') then
page_count = page_count + 1
end
end
end
pdf_state[bufnr] = {
temp_dir = temp_dir,
current_page = 1,
total_pages = page_count,
}
local function show_page(page_num)
local state = pdf_state[bufnr]
if not state then return end
image.clear()
vim.bo[bufnr].modifiable = true
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {''})
vim.bo[bufnr].modifiable = false
local page_file = string.format('%s/page-%02d.png', state.temp_dir, page_num)
local img = image.from_file(page_file, { buffer = bufnr })
if img then
img:render()
vim.notify(string.format('Page %d / %d', page_num, state.total_pages), vim.log.levels.INFO)
else
vim.notify('Failed to load page ' .. page_num, vim.log.levels.ERROR)
end
end
local function change_page(delta)
local state = pdf_state[bufnr]
if not state then return end
local new_page = state.current_page + delta
if new_page < 1 or new_page > state.total_pages then
return
end
state.current_page = new_page
show_page(new_page)
end
-- Keymaps
vim.keymap.set('n', 'j', function() change_page(1) end, { buffer = bufnr, desc = 'Next page' })
vim.keymap.set('n', 'k', function() change_page(-1) end, { buffer = bufnr, desc = 'Previous page' })
vim.keymap.set('n', '<Right>', function() change_page(1) end, { buffer = bufnr, desc = 'Next page' })
vim.keymap.set('n', '<Left>', function() change_page(-1) end, { buffer = bufnr, desc = 'Previous page' })
vim.keymap.set('n', 'q', '<cmd>bd!<cr>', { buffer = bufnr, silent = true })
-- Show first page
show_page(1)
end)
end
})
end,
})
-- Cleanup
vim.api.nvim_create_autocmd('BufDelete', {
pattern = '*.pdf',
callback = function(args)
if pdf_state[args.buf] then
image.clear()
vim.fn.delete(pdf_state[args.buf].temp_dir, 'rf')
pdf_state[args.buf] = nil
end
end,
})
end,
}

52
lua/kickstart/health.lua Normal file
View File

@@ -0,0 +1,52 @@
--[[
--
-- This file is not required for your own configuration,
-- but helps people determine if their system is setup correctly.
--
--]]
local check_version = function()
local verstr = tostring(vim.version())
if not vim.version.ge then
vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr))
return
end
if vim.version.ge(vim.version(), '0.10-dev') then
vim.health.ok(string.format("Neovim version is: '%s'", verstr))
else
vim.health.error(string.format("Neovim out of date: '%s'. Upgrade to latest stable or nightly", verstr))
end
end
local check_external_reqs = function()
-- Basic utils: `git`, `make`, `unzip`
for _, exe in ipairs { 'git', 'make', 'unzip', 'rg' } do
local is_executable = vim.fn.executable(exe) == 1
if is_executable then
vim.health.ok(string.format("Found executable: '%s'", exe))
else
vim.health.warn(string.format("Could not find executable: '%s'", exe))
end
end
return true
end
return {
check = function()
vim.health.start 'kickstart.nvim'
vim.health.info [[NOTE: Not every warning is a 'must-fix' in `:checkhealth`
Fix only warnings for plugins and languages you intend to use.
Mason will give warnings for languages that are not installed.
You do not need to install, unless you want to use those languages!]]
local uv = vim.uv or vim.loop
vim.health.info('System Information: ' .. vim.inspect(uv.os_uname()))
check_version()
check_external_reqs()
end,
}

View File

@@ -0,0 +1,8 @@
-- autopairs
-- https://github.com/windwp/nvim-autopairs
return {
'windwp/nvim-autopairs',
event = 'InsertEnter',
opts = {},
}

View File

@@ -0,0 +1,218 @@
-- debug.lua
--
-- Shows how to use the DAP plugin to debug your code.
--
-- Primarily focused on configuring the debugger for Go, but can
-- be extended to other languages as well. That's why it's called
-- kickstart.nvim and not kitchen-sink.nvim ;)
return {
-- NOTE: Yes, you can install new plugins here!
'mfussenegger/nvim-dap',
-- NOTE: And you can specify dependencies as well
dependencies = {
-- Creates a beautiful debugger UI
'rcarriga/nvim-dap-ui',
-- Required dependency for nvim-dap-ui
'nvim-neotest/nvim-nio',
-- Installs the debug adapters for you
'mason-org/mason.nvim',
'jay-babu/mason-nvim-dap.nvim',
-- Add your own debuggers here
'leoluz/nvim-dap-go',
-- Fuzzy find variables with Telescope
'nvim-telescope/telescope-dap.nvim',
},
keys = {
-- Basic debugging keymaps, feel free to change to your liking!
{
'<F5>',
function()
require('dap').continue()
end,
desc = 'Debug: Start/Continue',
},
{
'<F1>',
function()
require('dap').step_into()
end,
desc = 'Debug: Step Into',
},
{
'<F2>',
function()
require('dap').step_over()
end,
desc = 'Debug: Step Over',
},
{
'<F3>',
function()
require('dap').step_out()
end,
desc = 'Debug: Step Out',
},
{
'<leader>b',
function()
require('dap').toggle_breakpoint()
end,
desc = 'Debug: Toggle Breakpoint',
},
{
'<leader>B',
function()
require('dap').set_breakpoint(vim.fn.input 'Breakpoint condition: ')
end,
desc = 'Debug: Set Breakpoint',
},
-- Toggle to see last session result. Without this, you can't see session output in case of unhandled exception.
{
'<F7>',
function()
require('dapui').toggle()
end,
desc = 'Debug: See last session result.',
},
-- Telescope DAP integration for fuzzy finding
{
'<leader>dv',
function()
require('telescope').extensions.dap.variables()
end,
desc = 'Debug: Find [V]ariables',
},
{
'<leader>df',
function()
require('telescope').extensions.dap.frames()
end,
desc = 'Debug: Find [F]rames',
},
{
'<leader>dc',
function()
require('telescope').extensions.dap.commands()
end,
desc = 'Debug: Find [C]ommands',
},
{
'<leader>db',
function()
require('telescope').extensions.dap.list_breakpoints()
end,
desc = 'Debug: List [B]reakpoints',
},
},
config = function()
local dap = require 'dap'
local dapui = require 'dapui'
require('mason-nvim-dap').setup {
-- Makes a best effort to setup the various debuggers with
-- reasonable debug configurations
automatic_installation = true,
-- You can provide additional configuration to the handlers,
-- see mason-nvim-dap README for more information
handlers = {},
-- You'll need to check that you have the required things installed
-- online, please don't ask me how to install them :)
ensure_installed = {
-- Update this to ensure that you have the debuggers for the langs you want
'delve',
'php-debug-adapter',
},
}
-- Dap UI setup
-- For more information, see |:help nvim-dap-ui|
dapui.setup {
-- Set icons to characters that are more likely to work in every terminal.
-- Feel free to remove or use ones that you like more! :)
-- Don't feel like these are good choices.
icons = { expanded = '', collapsed = '', current_frame = '*' },
controls = {
icons = {
pause = '',
play = '',
step_into = '',
step_over = '',
step_out = '',
step_back = 'b',
run_last = '▶▶',
terminate = '',
disconnect = '',
},
},
}
-- Change breakpoint icons
-- vim.api.nvim_set_hl(0, 'DapBreak', { fg = '#e51400' })
-- vim.api.nvim_set_hl(0, 'DapStop', { fg = '#ffcc00' })
-- local breakpoint_icons = vim.g.have_nerd_font
-- and { Breakpoint = '', BreakpointCondition = '', BreakpointRejected = '', LogPoint = '', Stopped = '' }
-- or { Breakpoint = '●', BreakpointCondition = '⊜', BreakpointRejected = '⊘', LogPoint = '◆', Stopped = '⭔' }
-- for type, icon in pairs(breakpoint_icons) do
-- local tp = 'Dap' .. type
-- local hl = (type == 'Stopped') and 'DapStop' or 'DapBreak'
-- vim.fn.sign_define(tp, { text = icon, texthl = hl, numhl = hl })
-- end
dap.listeners.after.event_initialized['dapui_config'] = dapui.open
dap.listeners.before.event_terminated['dapui_config'] = dapui.close
dap.listeners.before.event_exited['dapui_config'] = dapui.close
-- Install golang specific config
require('dap-go').setup {
delve = {
-- On Windows delve must be run attached or it crashes.
-- See https://github.com/leoluz/nvim-dap-go/blob/main/README.md#configuring
detached = vim.fn.has 'win32' == 0,
},
}
-- PHP/Xdebug configuration
dap.adapters.php = {
type = 'executable',
command = 'node',
args = { vim.fn.stdpath('data') .. '/mason/packages/php-debug-adapter/extension/out/phpDebug.js' },
}
dap.configurations.php = {
{
type = 'php',
request = 'launch',
name = 'Listen for Xdebug',
port = 9003,
},
{
type = 'php',
request = 'launch',
name = 'Listen for Xdebug (DDEV)',
port = 9003,
pathMappings = {
['/var/www/html'] = '${workspaceFolder}',
},
},
{
type = 'php',
request = 'launch',
name = 'Run current script',
port = 9003,
cwd = '${fileDirname}',
program = '${file}',
runtimeExecutable = 'php',
},
}
-- Load telescope-dap extension
require('telescope').load_extension('dap')
end,
}

View File

@@ -0,0 +1,61 @@
-- Adds git related signs to the gutter, as well as utilities for managing changes
-- NOTE: gitsigns is already included in init.lua but contains only the base
-- config. This will add also the recommended keymaps.
return {
{
'lewis6991/gitsigns.nvim',
opts = {
on_attach = function(bufnr)
local gitsigns = require '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
vim.cmd.normal { ']c', bang = true }
else
gitsigns.nav_hunk 'next'
end
end, { desc = 'Jump to next git [c]hange' })
map('n', '[c', function()
if vim.wo.diff then
vim.cmd.normal { '[c', bang = true }
else
gitsigns.nav_hunk 'prev'
end
end, { desc = 'Jump to previous git [c]hange' })
-- Actions
-- visual mode
map('v', '<leader>hs', function()
gitsigns.stage_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'git [s]tage hunk' })
map('v', '<leader>hr', function()
gitsigns.reset_hunk { vim.fn.line '.', vim.fn.line 'v' }
end, { desc = 'git [r]eset hunk' })
-- normal mode
map('n', '<leader>hs', gitsigns.stage_hunk, { desc = 'git [s]tage hunk' })
map('n', '<leader>hr', gitsigns.reset_hunk, { desc = 'git [r]eset hunk' })
map('n', '<leader>hS', gitsigns.stage_buffer, { desc = 'git [S]tage buffer' })
map('n', '<leader>hu', gitsigns.stage_hunk, { desc = 'git [u]ndo stage hunk' })
map('n', '<leader>hR', gitsigns.reset_buffer, { desc = 'git [R]eset buffer' })
map('n', '<leader>hp', gitsigns.preview_hunk, { desc = 'git [p]review hunk' })
map('n', '<leader>hb', gitsigns.blame_line, { desc = 'git [b]lame line' })
map('n', '<leader>hd', gitsigns.diffthis, { desc = 'git [d]iff against index' })
map('n', '<leader>hD', function()
gitsigns.diffthis '@'
end, { desc = 'git [D]iff against last commit' })
-- Toggles
map('n', '<leader>tb', gitsigns.toggle_current_line_blame, { desc = '[T]oggle git show [b]lame line' })
map('n', '<leader>tD', gitsigns.preview_hunk_inline, { desc = '[T]oggle git show [D]eleted' })
end,
},
},
}

View File

@@ -0,0 +1,9 @@
return {
{ -- Add indentation guides even on blank lines
'lukas-reineke/indent-blankline.nvim',
-- Enable `lukas-reineke/indent-blankline.nvim`
-- See `:help ibl`
main = 'ibl',
opts = {},
},
}

View File

@@ -0,0 +1,60 @@
return {
{ -- Linting
'mfussenegger/nvim-lint',
event = { 'BufReadPre', 'BufNewFile' },
config = function()
local lint = require 'lint'
lint.linters_by_ft = {
markdown = { 'markdownlint' },
}
-- To allow other plugins to add linters to require('lint').linters_by_ft,
-- instead set linters_by_ft like this:
-- lint.linters_by_ft = lint.linters_by_ft or {}
-- lint.linters_by_ft['markdown'] = { 'markdownlint' }
--
-- However, note that this will enable a set of default linters,
-- which will cause errors unless these tools are available:
-- {
-- clojure = { "clj-kondo" },
-- dockerfile = { "hadolint" },
-- inko = { "inko" },
-- janet = { "janet" },
-- json = { "jsonlint" },
-- markdown = { "vale" },
-- rst = { "vale" },
-- ruby = { "ruby" },
-- terraform = { "tflint" },
-- text = { "vale" }
-- }
--
-- You can disable the default linters by setting their filetypes to nil:
-- lint.linters_by_ft['clojure'] = nil
-- lint.linters_by_ft['dockerfile'] = nil
-- lint.linters_by_ft['inko'] = nil
-- lint.linters_by_ft['janet'] = nil
-- lint.linters_by_ft['json'] = nil
-- lint.linters_by_ft['markdown'] = nil
-- lint.linters_by_ft['rst'] = nil
-- lint.linters_by_ft['ruby'] = nil
-- lint.linters_by_ft['terraform'] = nil
-- lint.linters_by_ft['text'] = nil
-- Create autocommand which carries out the actual linting
-- on the specified events.
local lint_augroup = vim.api.nvim_create_augroup('lint', { clear = true })
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
group = lint_augroup,
callback = function()
-- Only run the linter in buffers that you can modify in order to
-- avoid superfluous noise, notably within the handy LSP pop-ups that
-- describe the hovered symbol using Markdown.
if vim.bo.modifiable then
lint.try_lint()
end
end,
})
end,
},
}

View File

@@ -0,0 +1,28 @@
-- Neo-tree is a Neovim plugin to browse the file system
-- https://github.com/nvim-neo-tree/neo-tree.nvim
return {
'nvim-neo-tree/neo-tree.nvim',
version = '*',
dependencies = {
'nvim-lua/plenary.nvim',
'nvim-tree/nvim-web-devicons', -- not strictly required, but recommended
'MunifTanjim/nui.nvim',
},
lazy = false,
keys = {
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
},
opts = {
filesystem = {
filtered_items = {
visible = true, -- Also show '.' files.
},
window = {
mappings = {
['\\'] = 'close_window',
},
},
},
},
}