skip to content
Andrea Boscolo Camiletto

My personal configuration files. Click on each section to expand and view the full configuration.

Neovim Configuration

~/.config/nvim/

init.lua

-- Leader early
vim.g.mapleader = " "
-- lazy.nvim bootstrap
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)
-- Core config
require("config.options")
require("config.keymaps")
require("config.autocmds")
-- Plugins
require("lazy").setup("plugins", { ui = { border = "rounded" } })

lua/config/options.lua

vim.cmd("let g:netrw_liststyle = 3")
vim.g.deprecation_warnings = false
vim.g.bigfile_size = 1024 * 1024 * 1.5
vim.opt.relativenumber = true
vim.opt.number = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.wrap = false
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.cursorline = true
vim.opt.termguicolors = true
vim.opt.background = "dark"
vim.opt.signcolumn = "yes"
vim.opt.backspace = "indent,eol,start"
vim.g.loaded_netrwPlugin = 1
vim.g.loaded_netrw = 1
vim.opt.splitright = true
vim.opt.splitbelow = true
vim.opt.laststatus = 3
vim.opt.splitkeep = "screen"
vim.opt.clipboard = "unnamedplus"
-- diagnostics
vim.diagnostic.config({
signs = {
text = {
[vim.diagnostic.severity.ERROR] = "",
[vim.diagnostic.severity.WARN] = "",
[vim.diagnostic.severity.HINT] = "",
[vim.diagnostic.severity.INFO] = "»",
},
},
})

lua/config/keymaps.lua

-- basics
vim.keymap.set("n", "<leader>qq", "<cmd>qall<CR>", { desc = "Quit all" })
vim.keymap.set("i", "jk", "<ESC>", { desc = "Exit insert mode with jk" })
vim.keymap.set("n", "<leader>cc", ":nohl<CR>", { desc = "Clear search highlights" })
-- remove s/S
vim.api.nvim_set_keymap("n", "s", "<Nop>", { noremap = true, silent = true })
vim.api.nvim_set_keymap("v", "s", "<Nop>", { noremap = true, silent = true })
-- buffer navigation
local function GoToNthBuffer(n)
local buffers = vim.tbl_filter(function(b)
return vim.fn.buflisted(b) == 1
end, vim.api.nvim_list_bufs())
if buffers[n] then
vim.api.nvim_set_current_buf(buffers[n])
end
end
vim.keymap.set("n", "<leader>bn", "<cmd>bn<CR>", { desc = "Next buffer" })
vim.keymap.set("n", "<leader>bv", "<cmd>bp<CR>", { desc = "Previous buffer" })
vim.keymap.set("n", "<leader>bd", "<cmd>bd<CR>", { desc = "Close buffer" })
for i = 1, 9 do
vim.keymap.set("n", "<leader>b" .. i, function() GoToNthBuffer(i) end, { desc = "Go to buffer " .. i })
end
-- Select all
vim.keymap.set("n", "<leader>sa", "ggVG", { desc = "Select all" })
-- Keep visual selection after indent/outdent
vim.keymap.set("v", ">", ">gv", { desc = "Indent and reselect" })
vim.keymap.set("v", "<", "<gv", { desc = "Outdent and reselect" })
-- yazi
vim.keymap.set("n", "<leader>yy", "<cmd>Yazi<CR>", { desc = "Open yazi" })
-- codecompanion (optional)
vim.keymap.set("n", "<leader>ax", "<cmd>CodeCompanionChat Toggle<CR>", { desc = "CodeCompanion Toggle Chat" })
vim.keymap.set("v", "<leader>ax", "<cmd>CodeCompanionChat Add<CR>", { desc = "CodeCompanion Add Chat" })

lua/config/autocmds.lua

-- Track the start and end of macro recording for statusline
vim.api.nvim_create_autocmd("RecordingEnter", {
pattern = "*",
callback = function()
vim.g.macro_recording = "Recording @" .. vim.fn.reg_recording()
vim.cmd("redrawstatus")
end,
})
vim.api.nvim_create_autocmd("RecordingLeave", {
pattern = "*",
callback = function()
vim.g.macro_recording = ""
vim.cmd("redrawstatus")
end,
})

lua/plugins/colorscheme.lua

return {
{
"rose-pine/neovim",
name = "rose-pine",
lazy = false,
priority = 1000,
config = function()
vim.cmd("colorscheme rose-pine-main")
end,
},
}

lua/plugins/formatting.lua

return {
{
"stevearc/conform.nvim",
event = { "BufReadPre", "BufNewFile" },
config = function()
local conform = require("conform")
conform.setup({
formatters_by_ft = {
javascript = { "prettier" },
typescript = { "prettier" },
javascriptreact = { "prettier" },
typescriptreact = { "prettier" },
css = { "prettier" },
html = { "prettier" },
json = { "prettier" },
yaml = { "prettier" },
markdown = { "prettier" },
lua = { "stylua" },
python = { "ruff_organize_imports", "ruff_fix", "ruff_format" },
},
format_on_save = function(bufnr)
if vim.g.disable_autoformat or vim.b[bufnr].disable_autoformat then return end
return { timeout_ms = 500, lsp_fallback = true }
end,
formatters = { taplo = { args = { "format", "--option", "column_width=180", "-" } } },
})
local function show_notification(message, level)
vim.notify(message, level, { title = "conform.nvim" })
end
vim.api.nvim_create_user_command("FormatToggle", function(args)
local is_global = not args.bang
if is_global then
vim.g.disable_autoformat = not vim.g.disable_autoformat
if vim.g.disable_autoformat then
show_notification("Autoformat-on-save disabled globally", "info")
else
show_notification("Autoformat-on-save enabled globally", "info")
end
else
vim.b.disable_autoformat = not vim.b.disable_autoformat
if vim.b.disable_autoformat then
show_notification("Autoformat-on-save disabled for this buffer", "info")
else
show_notification("Autoformat-on-save enabled for this buffer", "info")
end
end
end, { desc = "Toggle autoformat-on-save", bang = true })
end,
},
}

lua/plugins/git.lua

return {
{
"kdheepak/lazygit.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
cmd = { "LazyGit", "LazyGitConfig", "LazyGitCurrentFile", "LazyGitFilter", "LazyGitFilterCurrentFile" },
keys = {
{ "<leader>gg", "<cmd>LazyGit<CR>", desc = "LazyGit" },
},
},
{ "lewis6991/gitsigns.nvim", config = function() require("gitsigns").setup() end },
}

lua/plugins/mini.lua

return {
{
"nvim-mini/mini.nvim",
lazy = false,
keys = {
{ "<leader>ee", function() MiniFiles.open(vim.uv.cwd(), true) end, desc = "Open mini-files" },
{ "<leader>ef", function() MiniFiles.open(vim.api.nvim_buf_get_name(0), true) end, desc = "Open mini-files at current file" },
{ "<leader>mmm", function() MiniMap.open() end, desc = "MiniMap open" },
{ "<leader>mmc", function() MiniMap.close() end, desc = "MiniMap close" },
-- Pickers
{ "<leader>ff", "<cmd>Pick files<CR>", desc = "Find files" },
{ "<leader>fg", function() MiniPick.builtin.grep_live() end, desc = "Find grep" },
{ "<leader>fv", "<cmd>Pick visit_paths<CR>", desc = "Find visit_paths" },
{ "<leader>fd", function() MiniExtra.pickers.diagnostic() end, desc = "Find diagnostic" },
{ "<leader>fl", function() MiniExtra.pickers.lsp() end, desc = "Find location" },
{ "<leader>fh", "<cmd>Pick help<CR>", desc = "Find help" },
{ "<leader>fk", "<cmd>Pick keymaps<CR>", desc = "Find keymaps" },
{ "<leader>fb", "<cmd>Pick buffers<CR>", desc = "Find buffers" },
-- Sessions
{ "<leader>ws", function() MiniSessions.select() end, desc = "Select session" },
{ "<leader>wr", function() MiniSessions.get_latest() end, desc = "Load session" },
},
config = function()
-- basics
require("mini.basics").setup({
options = { basic = true },
mappings = { basic = true, move_with_alt = true },
autocommands = { basic = true },
})
-- icons
require("mini.icons").setup()
-- navigation/UI
require("mini.files").setup({ mappings = { synchronize = "<C-s>" }, options = { use_as_default_explorer = false } })
require("mini.tabline").setup()
require("mini.bracketed").setup()
require("mini.fuzzy").setup()
require("mini.pick").setup()
-- editor
require("mini.extra").setup()
local gen_ai_spec = require("mini.extra").gen_ai_spec
local ai = require("mini.ai")
require("mini.ai").setup({
n_lines = 500,
custom_textobjects = {
B = gen_ai_spec.buffer(),
D = gen_ai_spec.diagnostic(),
I = gen_ai_spec.indent(),
L = gen_ai_spec.line(),
N = gen_ai_spec.number(),
o = ai.gen_spec.treesitter({
a = { "@block.outer", "@conditional.outer", "@loop.outer" },
i = { "@block.inner", "@conditional.inner", "@loop.inner" },
}),
f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }),
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }),
},
})
require("mini.indentscope").setup()
require("mini.surround").setup({
mappings = {
add = "gsa",
delete = "gsd",
find = "gsf",
find_left = "gsF",
highlight = "gsh",
replace = "gsr",
update_n_lines = "gsn",
},
})
require("mini.statusline").setup({
use_icons = vim.g.have_nerd_font,
content = {
active = function()
local mode, mode_hl = MiniStatusline.section_mode({ trunc_width = 120 })
local git = MiniStatusline.section_git({ trunc_width = 40 })
local diff = MiniStatusline.section_diff({ trunc_width = 75 })
local diagnostics = MiniStatusline.section_diagnostics({ trunc_width = 75 })
local lsp = MiniStatusline.section_lsp({ trunc_width = 75 })
local filename = MiniStatusline.section_filename({ trunc_width = 140 })
local fileinfo = MiniStatusline.section_fileinfo({ trunc_width = 120 })
local location = MiniStatusline.section_location({ trunc_width = 200 })
local search = MiniStatusline.section_searchcount({ trunc_width = 75 })
local macro = vim.g.macro_recording
return MiniStatusline.combine_groups({
{ hl = mode_hl, strings = { mode } },
{ hl = "MiniStatuslineDevinfo", strings = { git, diff, diagnostics } },
"%<",
{ hl = "MiniStatuslineFilename", strings = { filename } },
"%=",
{ hl = "MiniStatuslineFilename", strings = { macro } },
{ hl = "MiniStatuslineFileinfo", strings = { fileinfo } },
{ hl = mode_hl, strings = { search, location } },
})
end,
},
})
require("mini.comment").setup()
require("mini.pairs").setup({
mappings = {
["("] = { action = "open", pair = "()", neigh_pattern = ".[^%w]" },
["["] = { action = "open", pair = "[]", neigh_pattern = ".[^%w]" },
["{"] = { action = "open", pair = "{}", neigh_pattern = ".[^%w]" },
[")"] = { action = "close", pair = "()", neigh_pattern = "[^\\]." },
["]"] = { action = "close", pair = "[]", neigh_pattern = "[^\\]." },
["}"] = { action = "close", pair = "{}", neigh_pattern = "[^\\]." },
['"'] = { action = "closeopen", pair = '""', neigh_pattern = ".[^%w]", register = { cr = false } },
["'"] = { action = "closeopen", pair = "''", neigh_pattern = ".[^%w]", register = { cr = false } },
["`"] = { action = "closeopen", pair = "``", neigh_pattern = ".[^%w]", register = { cr = false } },
},
})
local notify = require("mini.notify")
notify.setup()
vim.notify = notify.make_notify({
ERROR = { duration = 5000 },
WARN = { duration = 4000 },
INFO = { duration = 3000 },
})
require("mini.cursorword").setup()
require("mini.starter").setup()
require("mini.git").setup()
require("mini.sessions").setup({ file = ".session.vim" })
require("mini.visits").setup()
require("mini.map").setup()
-- animate (with mouse scroll guard)
local mouse_scrolled = false
for _, scroll in ipairs({ "Up", "Down" }) do
local key = "<ScrollWheel" .. scroll .. ">"
vim.keymap.set({ "", "i" }, key, function()
mouse_scrolled = true
return key
end, { expr = true })
end
local animate = require("mini.animate")
animate.setup({
cursor = { enable = false, timing = animate.gen_timing.linear({ duration = 50, unit = "total" }) },
scroll = {
timing = animate.gen_timing.linear({ duration = 50, unit = "total" }),
subscroll = animate.gen_subscroll.equal({
predicate = function(total_scroll)
if mouse_scrolled then
mouse_scrolled = false
return false
end
return total_scroll > 1
end,
}),
},
})
-- miniclue
local miniclue = require("mini.clue")
miniclue.setup({
triggers = {
{ mode = "n", keys = "<Leader>" },
{ mode = "x", keys = "<Leader>" },
{ mode = "i", keys = "<C-x>" },
{ mode = "n", keys = "g" },
{ mode = "x", keys = "g" },
{ mode = "n", keys = "'" },
{ mode = "n", keys = "`" },
{ mode = "x", keys = "'" },
{ mode = "x", keys = "`" },
{ mode = "n", keys = '"' },
{ mode = "x", keys = '"' },
{ mode = "i", keys = "<C-r>" },
{ mode = "c", keys = "<C-r>" },
{ mode = "n", keys = "<C-w>" },
{ mode = "n", keys = "z" },
{ mode = "x", keys = "z" },
},
clues = {
miniclue.gen_clues.builtin_completion(),
miniclue.gen_clues.g(),
miniclue.gen_clues.marks(),
miniclue.gen_clues.registers(),
miniclue.gen_clues.windows(),
miniclue.gen_clues.z(),
},
})
end,
},
}

lua/plugins/misc.lua

return {
{
"gbprod/yanky.nvim",
opts = { system_clipboard = { sync_with_ring = false } },
keys = {
{ "y", "<Plug>(YankyYank)", mode = { "n", "x" }, desc = "Yank", remap = true },
{ "p", "<Plug>(YankyPutAfter)", mode = { "n", "x" }, desc = "Put after", remap = true },
{ "P", "<Plug>(YankyPutBefore)", mode = { "n", "x" }, desc = "Put before", remap = true },
{ "gp", "<Plug>(YankyGPutAfter)", mode = { "n", "x" }, desc = "GPut after", remap = true },
{ "gP", "<Plug>(YankyGPutBefore)", mode = { "n", "x" }, desc = "GPut before", remap = true },
{ "<c-p>", "<Plug>(YankyPreviousEntry)", mode = "n", desc = "Yanky previous", remap = true },
{ "<c-n>", "<Plug>(YankyNextEntry)", mode = "n", desc = "Yanky next", remap = true },
},
},
{
"nmac427/guess-indent.nvim",
config = function()
require("guess-indent").setup({})
end,
},
}

lua/plugins/navigation.lua

return {
-- Flash
{
"folke/flash.nvim",
keys = {
{ "s", function() require("flash").jump() end, mode = { "n", "x", "o" }, desc = "Flash" },
{ "S", function() require("flash").treesitter() end, mode = { "n", "x", "o" }, desc = "Flash TS" },
{ "r", function() require("flash").remote() end, mode = "o", desc = "Remote Flash" },
{ "R", function() require("flash").treesitter_search() end, mode = { "o", "x" }, desc = "TS Search" },
{ "<c-s>", function() require("flash").toggle() end, mode = "c", desc = "Toggle Flash Search" },
},
config = function()
require("flash").setup()
end,
},
-- Multicursor
{
"jake-stewart/multicursor.nvim",
keys = {
{ "<leader><up>", function() require("multicursor-nvim").lineAddCursor(-1) end, mode = {"n","v"}, desc = "MC add up" },
{ "<leader><down>", function() require("multicursor-nvim").lineAddCursor(1) end, mode = {"n","v"}, desc = "MC add down" },
{ "<localleader><up>", function() require("multicursor-nvim").lineSkipCursor(-1) end, mode = {"n","v"}, desc = "MC skip up" },
{ "<localleader><down>", function() require("multicursor-nvim").lineSkipCursor(1) end, mode = {"n","v"}, desc = "MC skip down" },
{ "<leader>n", function() require("multicursor-nvim").matchAddCursor(1) end, mode = {"n","v"}, desc = "MC add next" },
{ "<leader>v", function() require("multicursor-nvim").matchSkipCursor(1) end, mode = {"n","v"}, desc = "MC skip next" },
{ "<leader>N", function() require("multicursor-nvim").matchAddCursor(-1) end, mode = {"n","v"}, desc = "MC add prev" },
{ "<leader>V", function() require("multicursor-nvim").matchSkipCursor(-1) end, mode = {"n","v"}, desc = "MC skip prev" },
{ "<leader>A", function() require("multicursor-nvim").matchAllAddCursors() end, mode = {"n","v"}, desc = "MC add all" },
{ "<leader><left>", function() require("multicursor-nvim").nextCursor() end, mode = {"n","v"}, desc = "MC next" },
{ "<leader>x", function() require("multicursor-nvim").deleteCursor() end, mode = {"n","v"}, desc = "MC delete" },
{ "<c-leftmouse>", function() require("multicursor-nvim").handleMouse() end, mode = "n", desc = "MC mouse" },
{ "<c-q>", function() require("multicursor-nvim").toggleCursor() end, mode = {"n","v"}, desc = "MC toggle" },
{ "<leader><c-q>", function() require("multicursor-nvim").duplicateCursors() end, mode = {"n","v"}, desc = "MC duplicate" },
{ "<esc>", function()
local mc = require("multicursor-nvim")
if not mc.cursorsEnabled() then mc.enableCursors()
elseif mc.hasCursors() then mc.clearCursors() end
end, mode = "n", desc = "MC clear/enable" },
{ "<leader>rc", function() require("multicursor-nvim").restoreCursors() end, mode = "n", desc = "MC restore" },
{ "I", function() require("multicursor-nvim").insertVisual() end, mode = "v", desc = "MC insert visual" },
{ "A", function() require("multicursor-nvim").appendVisual() end, mode = "v", desc = "MC append visual" },
{ "<c-i>", function() require("multicursor-nvim").jumpForward() end, mode = {"n","v"}, desc = "MC jump fwd" },
{ "<c-o>", function() require("multicursor-nvim").jumpBackward() end, mode = {"n","v"}, desc = "MC jump back" },
},
config = function()
require("multicursor-nvim").setup()
end,
},
-- precognition
{ "tris203/precognition.nvim", keys = { {"<leader>ll", function() require("precognition").toggle() end, desc = "Precognition" } } },
-- tmux navigator
{
"christoomey/vim-tmux-navigator",
cmd = { "TmuxNavigateLeft", "TmuxNavigateDown", "TmuxNavigateUp", "TmuxNavigateRight", "TmuxNavigatePrevious" },
keys = {
{ "<c-h>", "<cmd><C-U>TmuxNavigateLeft<cr>", desc = "Navigate left" },
{ "<c-j>", "<cmd><C-U>TmuxNavigateDown<cr>", desc = "Navigate down" },
{ "<c-k>", "<cmd><C-U>TmuxNavigateUp<cr>", desc = "Navigate up" },
{ "<c-l>", "<cmd><C-U>TmuxNavigateRight<cr>", desc = "Navigate right" },
{ "<c-\\>", "<cmd><C-U>TmuxNavigatePrevious<cr>", desc = "Navigate previous" },
},
},
}

lua/plugins/treesitter.lua

return {
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
dependencies = { "windwp/nvim-ts-autotag", "nvim-treesitter/nvim-treesitter-textobjects" },
config = function()
local treesitter = require("nvim-treesitter.configs")
treesitter.setup({
highlight = { enable = true },
indent = { enable = true, disable = { "yaml", "python" } },
autotag = { enable = true },
ensure_installed = {
"bash", "c", "diff", "html", "javascript", "jsdoc", "json", "jsonc", "lua", "luadoc",
"luap", "markdown", "markdown_inline", "printf", "python", "query", "regex", "toml", "tsx",
"typescript", "vim", "vimdoc", "xml", "yaml", "ninja", "rst",
},
incremental_selection = {
enable = true,
keymaps = { init_selection = "<C-space>", node_incremental = "<C-space>", scope_incremental = false, node_decremental = "<bs>" },
},
})
end,
},
}

lua/plugins/ui.lua

return {
{
"folke/noice.nvim",
dependencies = { "MunifTanjim/nui.nvim" },
config = function()
require("noice").setup({
lsp = { override = { ["vim.lsp.util.convert_input_to_markdown_lines"] = true, ["vim.lsp.util.stylize_markdown"] = true } },
presets = { command_palette = true, long_message_to_split = true, inc_rename = false, lsp_doc_border = false },
})
end,
},
{ "folke/trouble.nvim", config = function() require("trouble").setup() end },
{ "OXY2DEV/helpview.nvim" },
{ "sphamba/smear-cursor.nvim", config = function() require("smear_cursor").setup({ stiffness = 0.8, trailing_stiffness = 0.5, distance_stop_animating = 0.5, hide_target_hack = true }) end },
}

Tmux Configuration

~/.config/tmux/tmux.conf

Terminal window
# Set proper colors
set-option -sa terminal-overrides ",xterm*:Tc"
set -g mouse on
set -g default-terminal "screen-256color"
set-option -g status-position top
# Set prefix
unbind C-b
set -g prefix C-Space
bind C-Space send-prefix
# Shift Alt vim keys to switch windows
bind -n M-H previous-window
bind -n M-L next-window
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'christoomey/vim-tmux-navigator'
set -g @plugin 'catppuccin/tmux'
set -g @plugin 'tmux-plugins/tmux-yank'
run '~/.tmux/plugins/tpm/tpm'
# set vi-mode
set-window-option -g mode-keys vi
# keybindings
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle
bind-key -T copy-mode-vi y send-keys -X copy-selection-closing
bind -r k select-pane -U
bind -r j select-pane -D
bind -r h select-pane -L
bind -r l select-pane -R
bind '"' split-window -v -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
# Start windows and panes at 1, not 0
set -g base-index 1
set -g pane-base-index 1
set-window-option -g pane-base-index 1
set-option -g renumber-windows on
set -g @catppuccin_window_left_separator ""
set -g @catppuccin_window_right_separator " "
set -g @catppuccin_window_middle_separator ""
set -g @catppuccin_window_number_position "right"
set -g @catppuccin_window_default_fill "number"
set -g @catppuccin_window_default_text "#W"
set -g @catppuccin_window_current_fill "number"
set -g @catppuccin_window_current_text "#W#{?window_zoomed_flag,(),}"
set -g @catppuccin_status_modules_right "directory meetings date_time"
set -g @catppuccin_status_modules_left "session"
set -g @catppuccin_status_left_separator " "
set -g @catppuccin_status_right_separator " "
set -g @catppuccin_status_right_separator_inverse "no"
set -g @catppuccin_status_fill "icon"
set -g @catppuccin_status_connect_separator "no"
set -g @catppuccin_directory_text "#{b:pane_current_path}"
set -g @catppuccin_date_time_text "%H:%M"