init wrapper-module config

This commit is contained in:
Daniel Winkler 2026-01-30 14:22:39 +11:00
commit 91755583fd
46 changed files with 4277 additions and 0 deletions

183
plugin/00_options.lua Normal file
View file

@ -0,0 +1,183 @@
--stylua: ignore start
local later = MiniDeps.later
local now = MiniDeps.now
local nix = require('config.nix')
if not Config.isNixCats then
now(function()
MiniDeps.add({ name = "mini.nvim" })
end)
end
-- Leader key =================================================================
vim.g.mapleader = ' '
vim.g.maplocalleader = ','
-- General ====================================================================
vim.o.backup = true -- Don't store backup
vim.opt.backupdir = vim.fn.stdpath('data') .. '/backups'
vim.o.mouse = 'a' -- Enable mouse
vim.o.mousescroll = 'ver:25,hor:6' -- Customize mouse scroll
vim.o.scrolloff = 8 -- Lines above and below cursor
vim.o.switchbuf = 'usetab' -- Use already opened buffers when switching
vim.o.writebackup = true -- Don't store backup (better performance)
vim.o.undofile = true -- Enable persistent undo
vim.o.wildmenu = true -- Enable wildmenu
vim.o.wildmode = 'full' -- Show all matches in command line completion
vim.o.shada = "'100,<50,s10,:1000,/100,@100,h" -- Limit what is stored in ShaDa file
vim.cmd('filetype plugin indent on') -- Enable all filetype plugins
-- UI =========================================================================
vim.o.breakindent = true -- Indent wrapped lines to match line start
vim.o.colorcolumn = '+1' -- Draw colored column one step to the right of desired maximum width
vim.o.cursorline = false -- Enable highlighting of the current line
vim.o.foldenable = false -- Enable folding
vim.o.linebreak = true -- Wrap long lines at 'breakat' (if 'wrap' is set)
vim.o.list = true -- Show helpful character indicators
vim.o.number = true -- Show line numbers
vim.o.pumheight = 10 -- Make popup menu smaller
vim.o.relativenumber = true -- Show relative line numbers
vim.o.ruler = false -- Don't show cursor position
vim.o.shortmess = 'FOSWaco' -- Disable certain messages from |ins-completion-menu|
vim.o.showmode = false -- Don't show mode in command line
vim.o.signcolumn = 'yes' -- Always show signcolumn or it would frequently shift
vim.o.splitbelow = true -- Horizontal splits will be below
vim.o.splitright = true -- Vertical splits will be to the right
vim.o.wrap = true -- Display long lines as just one line
vim.o.background = nix.get_setting('dark', "background") --'light' -- Set background
vim.o.listchars = table.concat({ 'extends:…', 'nbsp:␣', 'precedes:…', 'tab:> ', 'trail:·' }, ',') -- Special text symbols
vim.o.cursorlineopt = 'screenline,number' -- Show cursor line only screen line when wrapped
vim.o.breakindentopt = 'list:-1' -- Add padding for lists when 'wrap' is on
if vim.fn.has('nvim-0.9') == 1 then
vim.o.shortmess = 'CFOSWaco' -- Don't show "Scanning..." messages
vim.o.splitkeep = 'screen' -- Reduce scroll during window split
end
if vim.fn.has('nvim-0.10') == 0 then
vim.o.termguicolors = true -- Enable gui colors (Neovim>=0.10 does this automatically)
end
if vim.fn.has('nvim-0.11') == 1 then
-- vim.o.completeopt = 'menuone,fuzzy' -- Use fuzzy matching for built-in completion noselect,
vim.o.winborder = 'rounded' -- Use double-line as default border
end
if vim.fn.has('nvim-0.12') == 1 then
vim.o.pummaxwidth = 100 -- Limit maximum width of popup menu
vim.o.completefuzzycollect = 'keyword,files,whole_line' -- Use fuzzy matching when collecting candidates
end
vim.o.complete = '.,w,b,kspell' -- Use spell check and don't use tags for completion
-- Colors =====================================================================
-- Enable syntax highlighing if it wasn't already (as it is time consuming)
-- Don't use defer it because it affects start screen appearance
if vim.fn.exists('syntax_on') ~= 1 then vim.cmd('syntax enable') end
-- Editing ====================================================================
vim.o.autoindent = true -- Use auto indent
vim.o.expandtab = true -- Convert tabs to spaces
vim.o.formatoptions = 'qnl1j' -- Improve comment editing
vim.o.ignorecase = true -- Ignore case when searching (use `\C` to force not doing that)
vim.o.incsearch = true -- Show search results while typing
vim.o.infercase = true -- Infer letter cases for a richer built-in keyword completion
vim.o.shiftwidth = 2 -- Use this number of spaces for indentation
vim.o.smartcase = true -- Don't ignore case when searching if pattern has upper case
vim.o.smartindent = true -- Make indenting smart
vim.o.tabstop = 2 -- Insert 2 spaces for a tab
vim.o.virtualedit = 'block' -- Allow going past the end of line in visual block mode
vim.o.iskeyword = '@,48-57,_,192-255,-' -- Treat dash separated words as a word text object
-- Define pattern for a start of 'numbered' list. This is responsible for
-- correct formatting of lists when using `gw`. This basically reads as 'at
-- least one special character (digit, -, +, *) possibly followed some
-- punctuation (. or `)`) followed by at least one space is a start of list
-- item'
vim.o.formatlistpat = [[^\s*[0-9\-\+\*]\+[\.\)]*\s\+]]
-- Spelling ===================================================================
vim.o.spelllang = 'en_us,de' -- Define spelling dictionaries
vim.o.spelloptions = 'camel' -- Treat parts of camelCase words as seprate words
-- vim.o.dictionary = vim.fn.stdpath('config') .. '/misc/dict/english.txt' -- Use specific dictionaries
-- Folds ======================================================================
vim.o.foldmethod = 'indent' -- Set 'indent' folding method
vim.o.foldlevel = 1 -- Display all folds except top ones
vim.o.foldnestmax = 10 -- Create folds only for some number of nested levels
vim.g.markdown_folding = 1 -- Use folding by heading in markdown files
if vim.fn.has('nvim-0.10') == 1 then
vim.o.foldtext = '' -- Use underlying text with its highlighting
end
-- Diagnostics ================================================================
local diagnostic_opts = {
-- Define how diagnostic entries should be shown
signs = { priority = 9999, severity = { min = 'HINT', max = 'ERROR' } },
virtual_lines = false,
virtual_text = { current_line = false, severity = { min = 'WARN', max = 'ERROR' } },
jump = { float = false },
underline = false,
-- Don't update diagnostics when typing
update_in_insert = false,
}
later(function() vim.diagnostic.config(diagnostic_opts) end)
-- Custom autocommands ========================================================
local augroup = vim.api.nvim_create_augroup('CustomSettings', {})
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'markdown' },
group = augroup,
callback = function()
vim.diagnostic.config({
signs = {
severity = { min = 'WARN', max = 'ERROR' }
},
virtual_text = {
current_line = false,
severity = { min = 'HINT', max = 'ERROR' }
}
})
end
})
vim.api.nvim_create_autocmd("FileType", {
desc = "remove formatoptions",
callback = function()
vim.opt.formatoptions:remove({ "r", "o" }) -- Don't continue comments on enter or o
vim.b.minitrailspace_disable = true -- Don't highlight trailing space by default
end,
})
vim.api.nvim_create_autocmd('FileType', {
group = augroup,
callback = function()
-- Don't auto-wrap comments and don't insert comment leader after hitting 'o'
-- If don't do this on `FileType`, this keeps reappearing due to being set in
-- filetype plugins.
vim.cmd('setlocal formatoptions-=r formatoptions-=o')
end,
desc = [[Ensure proper 'formatoptions']],
})
-- Neovide ==============================================
if vim.g.neovide then
vim.g.neovide_cursor_vfx_mode = "pixiedust"
vim.g.neovide_cursor_smooth_blink = true
vim.g.neovide_cursor_animation_length = 0.02
vim.g.neovide_cursor_short_animation_length = 0
vim.g.neovide_font_hinting = 'none'
vim.g.neovide_font_edging = 'subpixelantialias'
vim.o.guifont = 'Iosevka Nerd Font,Symbols Nerd Font:h14:#e-subpixelantialias:#h-none'
vim.g.neovide_floating_corner_radius = 0.35
vim.keymap.set("n", "<leader>nf", "<cmd>NeovideFullscreen<CR>", { desc = "Toggle Neovide Fullscreen" })
end
--stylua: ignore end

119
plugin/01_lib.lua Normal file
View file

@ -0,0 +1,119 @@
-- Global Functions
Config.new_scratch_buffer = function() vim.api.nvim_win_set_buf(0, vim.api.nvim_create_buf(true, true)) end
-- Toggle quickfix window
Config.toggle_quickfix = function()
local cur_tabnr = vim.fn.tabpagenr()
for _, wininfo in ipairs(vim.fn.getwininfo()) do
if wininfo.quickfix == 1 and wininfo.tabnr == cur_tabnr then return vim.cmd('cclose') end
end
vim.cmd('copen')
end
Config.log = {}
Config.log_buf_id = Config.log_buf_id or nil
Config.start_hrtime = Config.start_hrtime or vim.loop.hrtime()
Config.log_print = function()
if Config.log_buf_id == nil or not vim.api.nvim_buf_is_valid(Config.log_buf_id) then
Config.log_buf_id = vim.api.nvim_create_buf(true, true)
end
vim.api.nvim_win_set_buf(0, Config.log_buf_id)
vim.api.nvim_buf_set_lines(Config.log_buf_id, 0, -1, false, vim.split(vim.inspect(Config.log), '\n'))
end
Config.log_clear = function()
Config.log = {}
Config.start_hrtime = vim.loop.hrtime()
vim.cmd('echo "Cleared log"')
end
-- Execute current line with `lua`
Config.execute_lua_line = function()
local line = 'lua ' .. vim.api.nvim_get_current_line()
vim.api.nvim_command(line)
print(line)
vim.api.nvim_input('<Down>')
end
-- Try opening current file's dir with fallback to cwd
Config.try_opendir = function()
local buff = vim.api.nvim_buf_get_name(0)
local ok, err = pcall(MiniFiles.open, buff)
if ok then return end
vim.notify(err)
MiniFiles.open()
end
-- For mini.start
--- Edit a file in the specified window, with smart buffer reuse
--- @param path string: File path to edit
--- @param win_id number|nil: Window ID (defaults to current window)
--- @return number|nil: Buffer ID on success, nil on failure
Config.edit = function(path, win_id)
-- Validate inputs
if type(path) ~= 'string' or path == '' then
return nil
end
win_id = win_id or 0
if not vim.api.nvim_win_is_valid(win_id == 0 and vim.api.nvim_get_current_win() or win_id) then
return nil
end
local current_buf = vim.api.nvim_win_get_buf(win_id)
-- Check if current buffer can be reused (empty, unmodified, single window)
local is_empty_buffer = vim.fn.bufname(current_buf) == ''
local is_regular_buffer = vim.bo[current_buf].buftype ~= 'quickfix'
local is_unmodified = not vim.bo[current_buf].modified
local is_single_window = #vim.fn.win_findbuf(current_buf) == 1
local has_only_empty_line = vim.deep_equal(vim.fn.getbufline(current_buf, 1, '$'), { '' })
local can_reuse_buffer = is_empty_buffer and is_regular_buffer and is_unmodified
and is_single_window and has_only_empty_line
-- Create or get buffer for the file
local normalized_path = vim.fn.fnamemodify(path, ':.')
local target_buf = vim.fn.bufadd(normalized_path)
-- Set buffer in window (use pcall to handle swap file messages gracefully)
local success = pcall(vim.api.nvim_win_set_buf, win_id, target_buf)
if not success then
return nil
end
-- Ensure buffer is listed
vim.bo[target_buf].buflisted = true
-- Clean up old buffer if it was reused
if can_reuse_buffer then
pcall(vim.api.nvim_buf_delete, current_buf, { unload = false })
end
return target_buf
end
-- Load library
local packdir = nixCats.vimPackDir or MiniDeps.config.path.package
-- See https://github.com/echasnovski/mini.deps/blob/2953b2089591a49a70e0a88194dbb47fb0e4635c/lua/mini/deps.lua#L518C5-L518C39
Config.source_path = function(path)
pcall(function() vim.cmd('source ' .. vim.fn.fnameescape(path)) end)
end
Config.add = (function(pkg)
vim.cmd.packadd(pkg)
local should_load_after_dir = vim.v.vim_did_enter == 1 and vim.o.loadplugins
if not should_load_after_dir then return end
local after_paths = vim.fn.glob(
packdir .. '/pack/myNeovimPackages/opt/' .. pkg .. '/after/plugin/**/*.{vim,lua}',
false,
true
)
vim.iter(after_paths):map(function(p)
Config.source_path(p)
end)
end)
Config.now_if_args = vim.fn.argc(-1) > 0 and MiniDeps.now or MiniDeps.later

130
plugin/02_startup.lua Normal file
View file

@ -0,0 +1,130 @@
local M = {}
-- Helper function to normalize input to a list
local function normalize_filetypes_input(input)
if type(input) == "string" then
return { input }
elseif type(input) == "table" then
return input
else
vim.notify("get_recent_files_by_ft_or_ext: Invalid input type for filetypes", vim.log.levels.ERROR)
return nil
end
end
-- Helper function to check if a file matches any target filetype
local function matches_target_filetype(file_path, file_ext, detected_ft, target_ft_map)
for target_ft in pairs(target_ft_map) do
if file_ext:lower() == target_ft:lower() or
(detected_ft and detected_ft == target_ft) then
return target_ft
end
end
return nil
end
-- Helper function to safely detect filetype
local function detect_filetype(file_path)
local success, ft_match_fn = pcall(function() return vim.filetype.match end)
if not (success and type(ft_match_fn) == "function") then
return nil
end
local ok, result = pcall(ft_match_fn, { filename = file_path })
return ok and type(result) == "string" and result ~= "" and result or nil
end
-- Helper function to capitalize first letter
local function capitalize_first(str)
return str:sub(1, 1):upper() .. str:sub(2)
end
function M.get_recent_files_by_ft_or_ext(target_filetypes_input)
local target_filetypes_list = normalize_filetypes_input(target_filetypes_input)
if not target_filetypes_list or #target_filetypes_list == 0 then
return {}
end
-- Create lookup map for O(1) filetype checking
local target_ft_map = {}
for _, ft in ipairs(target_filetypes_list) do
target_ft_map[ft] = true
end
local oldfiles = vim.v.oldfiles
if not oldfiles or #oldfiles == 0 then
return {}
end
local cwd = vim.fn.getcwd()
local fnamemodify = vim.fn.fnamemodify
local filereadable = vim.fn.filereadable
local getftime = vim.fn.getftime
-- Track most recent file for each target filetype
local most_recent_files = {}
for _, ft in ipairs(target_filetypes_list) do
most_recent_files[ft] = { file = nil, time = 0 }
end
local processed_paths = {}
for _, file_path in ipairs(oldfiles) do
local full_path = fnamemodify(file_path, ':p')
-- Skip if already processed or invalid
if processed_paths[full_path] or
filereadable(full_path) ~= 1 or
not full_path:find(cwd, 1, true) then
goto continue
end
processed_paths[full_path] = true
local file_ext = fnamemodify(full_path, ':e')
local detected_ft = detect_filetype(full_path)
local matched_ft = matches_target_filetype(full_path, file_ext, detected_ft, target_ft_map)
if matched_ft then
local mod_time = getftime(full_path)
if mod_time > most_recent_files[matched_ft].time then
most_recent_files[matched_ft] = { file = full_path, time = mod_time }
end
end
::continue::
end
-- Build result items
local result_items = {}
for ft, data in pairs(most_recent_files) do
if data.file then
local filename = fnamemodify(data.file, ':t')
local relative_path = fnamemodify(data.file, ':~:.')
table.insert(result_items, {
action = function() Config.edit(data.file) end,
name = string.format('%s (%s)', filename, relative_path),
section = 'Recent ' .. capitalize_first(ft),
})
end
end
return result_items
end
M.footer_text = (function()
return [[
$$$$$$$\ $$\ $$\ $$\ $$\ $$\ $$$$$$$\ $$\ $$\ $$\ $$\
$$ __$$\ \__| $$ |$ | $$ |$$ |$$ __$$\ $$ | $$ | $$ |\__|
$$ | $$ | $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$ |\_/$$$$$$$\ $$ /$$ / $$ | $$ | $$$$$$\ $$$$$$\ $$$$$$\ $$ | $$ |$$\ $$$$$$\$$$$\
$$ | $$ | \____$$\ $$ __$$\ $$ |$$ __$$\ $$ | $$ _____| $$ /$$ / $$ | $$ | \____$$\\_$$ _| \____$$\\$$\ $$ |$$ |$$ _$$ _$$\
$$ | $$ | $$$$$$$ |$$ | $$ |$$ |$$$$$$$$ |$$ | \$$$$$$\ $$ /$$ / $$ | $$ | $$$$$$$ | $$ | $$$$$$$ |\$$\$$ / $$ |$$ / $$ / $$ |
$$ | $$ |$$ __$$ |$$ | $$ |$$ |$$ ____|$$ | \____$$\ $$ /$$ / $$ | $$ |$$ __$$ | $$ |$$\ $$ __$$ | \$$$ / $$ |$$ | $$ | $$ |
$$$$$$$ |\$$$$$$$ |$$ | $$ |$$ |\$$$$$$$\ $$ | $$$$$$$ |$$ /$$ / $$$$$$$ |\$$$$$$$ | \$$$$ |\$$$$$$$ | \$ / $$ |$$ | $$ | $$ |
\_______/ \_______|\__| \__|\__| \_______|\__| \_______/ \__/ \__/ \_______/ \_______| \____/ \_______| \_/ \__|\__| \__| \__|
]]
end
)
Config.startup = M

78
plugin/03_terminal.lua Normal file
View file

@ -0,0 +1,78 @@
local M = {}
-- Configuration
Config.opt_bracket = true
M.opt_term = nil
-- Default terminal commands
-- Users can override this via Config.terminal_commands in their setup
local defaults = {
clickhouse_client = "clickhouse client -m",
clickhouse_local = "clickhouse local -m",
duckdb = "duckdb",
julia = "julia",
python = "ipython",
shell = "echo 'Hello " .. vim.env.USER .. "!'",
}
-- Registry of terminal commands
M.commands = vim.tbl_deep_extend("force", defaults, Config.terminal_commands or {})
-- Bracket paste control
function M.toggle_bracket()
Config.opt_bracket = not Config.opt_bracket
vim.g.slime_bracketed_paste = Config.opt_bracket
return Config.opt_bracket
end
-- Terminal management
function M.split_and_open_terminal()
vim.cmd("below terminal")
vim.cmd("resize " .. math.floor(vim.fn.winheight(0) * 0.9))
local term_buf = vim.api.nvim_win_get_buf(vim.api.nvim_get_current_win())
M.opt_term = term_buf
-- Set buffer-local variables for vim-slime
local job_id = vim.b[term_buf].terminal_job_id
vim.b[term_buf].slime_config = { jobid = job_id }
return M.opt_term
end
-- Public functions
function M.open_in_terminal(cmd)
local command = cmd or ""
local current_window = vim.api.nvim_get_current_win()
local code_buf = vim.api.nvim_get_current_buf()
-- Open terminal and get buffer
local term_buf = M.split_and_open_terminal()
-- Send command if provided
if command ~= "" then
-- We can use standard slime sending if needed, or direct chan_send for initialization
local job_id = vim.b[term_buf].terminal_job_id
if job_id then
vim.api.nvim_chan_send(job_id, command .. "\r")
end
end
-- Configure slime for the ORIGINAL code buffer to point to this new terminal
-- This makes "Send to Terminal" work immediately
local slime_config = { jobid = vim.b[term_buf].terminal_job_id }
-- Fix: Set the variable on the captured code buffer, not the current (terminal) buffer
vim.api.nvim_buf_set_var(code_buf, "slime_config", slime_config)
-- Switch back to code buffer
vim.api.nvim_set_current_win(current_window)
end
-- Predefined terminal commands
for name, command in pairs(M.commands) do
M["open_" .. name] = function()
M.open_in_terminal(command)
end
end
Config.terminal = M

147
plugin/04_treesitter.lua Normal file
View file

@ -0,0 +1,147 @@
local M = {}
-- Default parsers list moved from startup config
M.default_parsers = {
"bash", "bibtex", "c", "caddy", "cmake", "comment", "commonlisp", "cpp", "css", "csv",
"cuda", "desktop", "diff", "dockerfile", "doxygen", "editorconfig", "fortran", "git_config", "git_rebase",
"gitattributes", "gitcommit", "gitignore", "gnuplot", "go", "gpg", "html", "javascript", "jq", "json", "json5",
"julia", "just", "latex", "ledger", "lua", "luadoc", "luap", "luau", "make", "markdown", "markdown_inline",
"matlab", "meson", "muttrc", "nix", "nu", "passwd", "powershell", "prql", "python", "r", "query", "readline", "regex",
"requirements", "rnoweb", "rust", "sql", "ssh_config", "swift", "tmux", "toml", "tsv", "tsx", "typescript", "typst",
"vala", "vim", "vimdoc", "yaml", "zig",
}
-- Cache treesitter utils to avoid repeated requires
local smart_send = require('nix_smart_send')
-- Helper function to check if value exists in list (optimized with early return)
local function is_in_list(list, value)
if not list or not value then
return false
end
for _, v in ipairs(list) do
if v == value then
return true
end
end
return false
end
function M.add_global_node(nodes)
if not nodes then
return nil
end
local node_type = M.get_type()
if not node_type then
return nodes
end
-- Create a copy to avoid modifying the original
local global_nodes = vim.deepcopy(nodes)
-- Check if node type already exists to avoid duplicates
if not is_in_list(global_nodes, node_type) then
table.insert(global_nodes, node_type)
end
return global_nodes
end
function M.remove_global_node(nodes)
if not nodes then
return nil
end
local node_type = M.get_type()
if not node_type then
return nodes
end
local global_nodes = vim.deepcopy(nodes)
-- Remove all occurrences (iterate backwards to avoid index issues)
for i = #global_nodes, 1, -1 do
if global_nodes[i] == node_type then
table.remove(global_nodes, i)
end
end
return global_nodes
end
function M.set_global_nodes()
local input = vim.fn.input("Enter root nodes: ")
if input == "" then
return {}
end
local nodes_in = {}
-- Trim whitespace from each node name
for node in string.gmatch(input, '([^,]+)') do
local trimmed = vim.trim(node)
if trimmed ~= "" then
table.insert(nodes_in, trimmed)
end
end
return nodes_in
end
function M.get_type()
local cur_node = smart_send.get_current_node()
if not cur_node then
print("Not a node")
return nil
end
local node_type = cur_node:type()
print("Node type: " .. node_type)
return node_type
end
function M.setup_keybindings(global_nodes)
local current_global_nodes = global_nodes
vim.keymap.set({ 'n' }, '<localleader>r', function()
current_global_nodes = M.set_global_nodes()
end,
{ noremap = true, silent = true, desc = "set global_nodes", buffer = true })
vim.keymap.set({ 'n', 'v' }, '<localleader>v', function()
smart_send.move_to_next_non_empty_line(); smart_send.select_until_global(current_global_nodes)
end,
{ noremap = true, silent = true, desc = "Visual select next node after WS", buffer = true })
vim.keymap.set('n', '<localleader>a', function() smart_send.send_repl(current_global_nodes) end,
{ noremap = true, silent = true, desc = "Send node to REPL", buffer = true })
vim.keymap.set({ 'n', 'i' }, '<S-CR>', function() smart_send.send_repl(current_global_nodes) end,
{ noremap = true, silent = true, desc = "Send node to REPL", buffer = true })
vim.keymap.set('n', '<CR>', function() smart_send.send_repl(current_global_nodes) end,
{ noremap = true, silent = true, desc = "Send node to REPL", buffer = true })
vim.keymap.set('n', '<localleader>n',
function() current_global_nodes = M.add_global_node(current_global_nodes) end,
{ noremap = true, silent = true, desc = "Add node under cursor to globals", buffer = true })
vim.keymap.set('n', '<localleader>x',
function() current_global_nodes = M.remove_global_node(current_global_nodes) end,
{ noremap = true, silent = true, desc = "Remove node under cursor from globals", buffer = true })
vim.keymap.set('n', '<localleader>o', function()
pout = table.concat(global_nodes, ', ') .. ""
print(pout)
end, { noremap = true, silent = true, desc = "Print globals", buffer = true })
vim.keymap.set('n', '<localleader>p', function() M.get_type() end,
{ noremap = true, silent = true, desc = "Print node type", buffer = true })
end
Config.treesitter_helpers = M
return M

318
plugin/10_keymap.lua Normal file
View file

@ -0,0 +1,318 @@
-- Basic mappings =============================================================
-- NOTE: Most basic mappings come from 'mini.basics'
-- Shorter version of the most frequent way of going outside of terminal window
vim.keymap.set('t', '<C-h>', [[<C-\><C-N><C-w>h]])
-- Select all
-- vim.keymap.set({ "n", "v", "x" }, "<C-a>", "gg3vG$", { noremap = true, silent = true, desc = "Select all" })
-- Escape deletes highlights
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- Paste before/after linewise
local cmd = vim.fn.has('nvim-0.12') == 1 and 'iput' or 'put'
vim.keymap.set({ 'n', 'x' }, '[p', '<Cmd>exe "' .. cmd .. '! " . v:register<CR>', { desc = 'Paste Above' })
vim.keymap.set({ 'n', 'x' }, ']p', '<Cmd>exe "' .. cmd .. ' " . v:register<CR>', { desc = 'Paste Below' })
vim.keymap.set({ "n", "v", "x" }, "<leader>p", '"+p', { noremap = true, silent = true, desc = "Paste from clipboard" })
vim.keymap.set({ "n", "v", "x" }, "<leader>y", '"+y', { noremap = true, silent = true, desc = "Copy toclipboard" })
-- Leader mappings ============================================================
-- stylua: ignore start
-- Create global tables with information about clue groups in certain modes
-- Structure of tables is taken to be compatible with 'mini.clue'.
_G.Config.leader_group_clues = {
{ mode = 'n', keys = '<Leader>a', desc = '+AI' },
{ mode = 'n', keys = '<Leader>b', desc = '+Buffer' },
{ mode = 'n', keys = '<Leader>e', desc = '+Explore' },
{ mode = 'n', keys = '<Leader>f', desc = '+Find' },
{ mode = 'n', keys = '<Leader>fl', desc = '+LSP' },
{ mode = 'n', keys = '<Leader>fa', desc = '+Git' },
{ mode = 'n', keys = '<Leader>g', desc = '+Git' },
{ mode = 'n', keys = '<Leader>l', desc = '+LSP' },
{ mode = 'n', keys = '<Leader>L', desc = '+Lua/Log' },
{ mode = 'n', keys = '<Leader>o', desc = '+Other' },
{ mode = 'n', keys = '<Leader>r', desc = '+R' },
{ mode = 'n', keys = '<Leader>t', desc = '+Terminal' },
{ mode = 'n', keys = '<Leader>u', desc = '+UI' },
{ mode = 'n', keys = '<Leader>v', desc = '+Visits' },
{ mode = 'n', keys = '<Leader>w', desc = '+Windows' },
{ mode = 'x', keys = '<Leader>l', desc = '+LSP' },
{ mode = 'x', keys = '<Leader>r', desc = '+R' },
{ mode = 'n', keys = '<Leader>z', desc = '+ZK' },
{ mode = 'n', keys = '<Leader>zr', desc = '+Reviews' },
{ mode = 'x', keys = '<leader>a', desc = '+AI' },
}
-- Create `<Leader>` mappings
local nmap_leader = function(suffix, rhs, desc, opts)
opts = opts or {}
opts.desc = desc
vim.keymap.set('n', '<Leader>' .. suffix, rhs, opts)
end
local xmap_leader = function(suffix, rhs, desc, opts)
opts = opts or {}
opts.desc = desc
vim.keymap.set('x', '<Leader>' .. suffix, rhs, opts)
end
-- Other mappings
local nmap_lsp = function(keys, func, desc)
if desc then
desc = desc .. "(LSP)"
end
vim.keymap.set("n", keys, func, { desc = desc })
end
-- Switch buffers
nmap_leader('<Tab>', '<Cmd>bnext<CR>', 'Next buffer')
nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer')
-- a is for 'AI'
nmap_leader("ac", "<cmd>CodeCompanionChat Toggle<CR>", "Chat Toggle")
nmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
nmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
nmap_leader("ag", "<cmd>CodeCompanion /commit<CR>", "Generate commit message")
nmap_leader("ai", "<cmd>CodeCompanionActions<CR>", "Chat Action")
nmap_leader("al", "<cmd>CodeCompanion /lsp<CR>", "Explain LSP Diagnostics")
nmap_leader("an", "<cmd>CodeCompanionChat Add<CR>", "Chat New")
nmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
xmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
xmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
xmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
-- b is for 'buffer'
nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate')
nmap_leader('bd', '<Cmd>lua MiniBufremove.delete()<CR>', 'Delete')
nmap_leader('bD', '<Cmd>lua MiniBufremove.delete(0, true)<CR>', 'Delete!')
nmap_leader('bs', '<Cmd>lua Config.new_scratch_buffer()<CR>', 'Scratch')
nmap_leader('bw', '<Cmd>lua MiniBufremove.wipeout()<CR>', 'Wipeout')
nmap_leader('bW', '<Cmd>lua MiniBufremove.wipeout(0, true)<CR>', 'Wipeout!')
nmap_leader('bq', '<Cmd>qall<CR>', 'Quit all')
-- e is for 'explore' and 'edit'
nmap_leader('ed', '<Cmd>lua MiniFiles.open()<CR>', 'Directory')
nmap_leader('ef', '<Cmd>lua Config.try_opendir()<CR>', 'File directory')
nmap_leader('es', '<Cmd>lua MiniSessions.select()<CR>', 'Sessions')
nmap_leader('eq', '<Cmd>lua Config.toggle_quickfix()<CR>', 'Quickfix')
nmap_leader('ez', '<Cmd>lua MiniFiles.open(os.getenv("ZK_NOTEBOOK_DIR"))<CR>', 'Notes directory')
-- f is for 'fuzzy find'
nmap_leader('f/', '<Cmd>Pick history scope="/"<CR>', '"/" history')
nmap_leader('f:', '<Cmd>Pick history scope=":"<CR>', '":" history')
nmap_leader('f,', '<Cmd>Pick visit_labels<CR>', 'Visit labels')
nmap_leader('faa', '<Cmd>Pick git_hunks scope="staged"<CR>', 'Added hunks (all)')
nmap_leader('faA', '<Cmd>Pick git_hunks path="%" scope="staged"<CR>', 'Added hunks (current)')
nmap_leader('fb', '<Cmd>Pick buffers<CR>', 'Buffers')
nmap_leader(',', '<Cmd>Pick buffers<CR>', 'Buffers')
nmap_leader('fac', '<Cmd>Pick git_commits<CR>', 'Commits (all)')
nmap_leader('faC', '<Cmd>Pick git_commits path="%"<CR>', 'Commits (current)')
nmap_leader('fd', '<Cmd>Pick diagnostic scope="all"<CR>', 'Diagnostic workspace')
nmap_leader('fD', '<Cmd>Pick diagnostic scope="current"<CR>', 'Diagnostic buffer')
nmap_leader('ff', '<Cmd>Pick files<CR>', 'Files')
nmap_leader('fg', '<Cmd>Pick grep_live<CR>', 'Grep live')
nmap_leader('fG', '<Cmd>Pick grep pattern="<cword>"<CR>', 'Grep current word')
nmap_leader('fh', '<Cmd>Pick help<CR>', 'Help tags')
nmap_leader('fH', '<Cmd>Pick hl_groups<CR>', 'Highlight groups')
nmap_leader('fj', '<Cmd>Pick buf_lines scope="all"<CR>', 'Lines (all)')
nmap_leader('fJ', '<Cmd>Pick buf_lines scope="current"<CR>', 'Lines (current)')
nmap_leader('fam', '<Cmd>Pick git_hunks<CR>', 'Modified hunks (all)')
nmap_leader('faM', '<Cmd>Pick git_hunks path="%"<CR>', 'Modified hunks (current)')
nmap_leader('fm', '<Cmd>Pick marks<CR>', 'Marks')
nmap_leader('fn', '<cmd>ZkNotes<CR>', "Notes")
nmap_leader('fk', '<Cmd>Pick keymaps<CR>', 'Keymaps')
nmap_leader('fR', '<Cmd>Pick resume<CR>', 'Resume')
nmap_leader('fp', '<Cmd>Pick projects<CR>', 'Projects')
nmap_leader('fq', '<Cmd>Pick list scope="quickfix"<CR>', 'Quickfix')
nmap_leader('fr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
nmap_leader('flr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
nmap_leader('fS', '<Cmd>Pick lsp scope="workspace_symbol"<CR>', 'Symbols workspace (LSP)')
nmap_leader('flS', '<Cmd>Pick lsp scope="workspace_symbol"<CR>', 'Symbols workspace (LSP)')
nmap_leader('fs', '<Cmd>Pick lsp scope="document_symbol"<CR>', 'Symbols buffer (LSP)')
nmap_leader('fls', '<Cmd>Pick lsp scope="document_symbol"<CR>', 'Symbols buffer (LSP)')
nmap_leader('fld', '<Cmd>Pick lsp scope="definition"<CR>', 'Definition (LSP)')
nmap_leader('flD', '<Cmd>Pick lsp scope="declaration"<CR>', 'Declaration (LSP)')
nmap_leader('flt', '<Cmd>Pick lsp scope="type_definition"<CR>', 'Type Definition (LSP)')
nmap_leader('fv', '<Cmd>Pick visit_paths cwd=""<CR>', 'Visit paths (all)')
nmap_leader('fV', '<Cmd>Pick visit_paths<CR>', 'Visit paths (cwd)')
-- g is for git
local git_log_cmd = [[Git log --pretty=format:\%h\ \%as\ │\ \%s --topo-order]]
nmap_leader('gc', '<Cmd>Git commit<CR>', 'Commit')
nmap_leader('gC', '<Cmd>Git commit --amend<CR>', 'Commit amend')
nmap_leader('gd', '<Cmd>Git diff<CR>', 'Diff')
nmap_leader('gD', '<Cmd>Git diff -- %<CR>', 'Diff buffer')
nmap_leader('gg', '<Cmd>lua require("neogit").open()<CR>', 'Git tab')
nmap_leader('gl', '<Cmd>' .. git_log_cmd .. '<CR>', 'Log')
nmap_leader('gL', '<Cmd>' .. git_log_cmd .. ' --follow -- %<CR>', 'Log buffer')
nmap_leader('go', '<Cmd>lua MiniDiff.toggle_overlay()<CR>', 'Toggle overlay')
nmap_leader('gp', '<Cmd>Git pull<CR>', 'Pull')
nmap_leader('gP', '<Cmd>Git push<CR>', 'Push')
nmap_leader('gs', '<Cmd>lua MiniGit.show_at_cursor()<CR>', 'Show at cursor')
xmap_leader('gs', '<Cmd>lua MiniGit.show_at_cursor()<CR>', 'Show at selection')
-- j/k navigate quickfix
nmap_leader("j", '<cmd>cnext<CR>zz', "Quickfix next")
nmap_leader("k", '<cmd>cprev<CR>zz', "Quickfix prev")
-- l is for 'LSP' (Language Server Protocol)
vim.keymap.set({ 'n' }, 'grd', '<Cmd>lua vim.lsp.buf.definition()<CR>', { desc = 'Definition' })
vim.keymap.set({ 'n' }, 'grk', '<Cmd>lua vim.lsp.buf.hover()<CR>', { desc = 'Documentation' })
vim.keymap.set({ 'n' }, 'gre', '<Cmd>lua vim.diagnostic.open_float()<CR>', { desc = 'Diagnostics' })
nmap_lsp("K", '<Cmd>lua vim.lsp.buf.hover()<CR>', "Documentation")
local formatting_cmd = '<Cmd>lua require("conform").format({ lsp_fallback = true })<CR>'
nmap_leader('la', '<Cmd>lua vim.lsp.buf.code_action()<CR>', 'Actions')
nmap_leader('le', '<Cmd>lua vim.diagnostic.open_float()<CR>', 'Diagnostics popup')
nmap_leader('lf', formatting_cmd, 'Format')
nmap_leader('lk', '<Cmd>lua vim.lsp.buf.hover()<CR>', 'Documentation')
nmap_leader('li', '<Cmd>lua vim.lsp.buf.implementation()<CR>', 'Information')
-- use ]d and [d
--nmap_leader('lj', '<Cmd>lua vim.diagnostic.goto_next()<CR>', 'Next diagnostic')
--nmap_leader('lk', '<Cmd>lua vim.diagnostic.goto_prev()<CR>', 'Prev diagnostic')
nmap_leader('lR', '<Cmd>lua vim.lsp.buf.references()<CR>', 'References')
nmap_leader('lr', '<Cmd>lua vim.lsp.buf.rename()<CR>', 'Rename')
nmap_leader('ls', '<Cmd>lua vim.lsp.buf.definition()<CR>', 'Source definition')
xmap_leader('lf', formatting_cmd, 'Format selection')
-- L is for 'Lua'
nmap_leader('Lc', '<Cmd>lua Config.log_clear()<CR>', 'Clear log')
nmap_leader('LL', '<Cmd>luafile %<CR><Cmd>echo "Sourced lua"<CR>', 'Source buffer')
nmap_leader('Ls', '<Cmd>lua Config.log_print()<CR>', 'Show log')
nmap_leader('Lx', '<Cmd>lua Config.execute_lua_line()<CR>', 'Execute `lua` line')
-- m is free
-- o is for 'other'
local trailspace_toggle_command = '<Cmd>lua vim.b.minitrailspace_disable = not vim.b.minitrailspace_disable<CR>'
nmap_leader('od', '<Cmd>Neogen<CR>', 'Document')
nmap_leader('oh', '<Cmd>normal gxiagxila<CR>', 'Move arg left')
nmap_leader('ol', '<Cmd>normal gxiagxina<CR>', 'Move arg right')
nmap_leader('or', '<Cmd>lua MiniMisc.resize_window()<CR>', 'Resize to default width')
nmap_leader('oS', '<Cmd>lua Config.insert_section()<CR>', 'Section insert')
nmap_leader('ot', '<Cmd>lua MiniTrailspace.trim()<CR>', 'Trim trailspace')
nmap_leader('oT', trailspace_toggle_command, 'Trailspace hl toggle')
nmap_leader('oz', '<Cmd>lua MiniMisc.zoom()<CR>', 'Zoom toggle')
nmap_leader('ow',
"<Cmd>lua MiniSessions.write(vim.fn.input('Session name: ', string.match(vim.fn.getcwd(), \"[^/]+$\") .. '-session.vim'))<CR>",
'Write session')
-- r is for 'R'
nmap_leader('rc', '<Cmd>RSend devtools::check()<CR>', 'Check')
nmap_leader('rC', '<Cmd>RSend devtools::test_coverage()<CR>', 'Coverage')
nmap_leader('rd', '<Cmd>RSend devtools::document()<CR>', 'Document')
nmap_leader('ri', '<Cmd>RSend devtools::install(keep_source=TRUE)<CR>', 'Install')
nmap_leader('rk', '<Cmd>RSend quarto::quarto_preview("%")<CR>', 'Knit file')
nmap_leader('rl', '<Cmd>RSend devtools::load_all()<CR>', 'Load all')
nmap_leader('rL', '<Cmd>RSend devtools::load_all(recompile=TRUE)<CR>', 'Load all recompile')
nmap_leader('rm', '<Cmd>RSend Rcpp::compileAttributes()<CR>', 'Run examples')
nmap_leader('rT', '<Cmd>RSend testthat::test_file("%")<CR>', 'Test file')
nmap_leader('rt', '<Cmd>RSend devtools::test()<CR>', 'Test')
-- - Copy to clipboard and make reprex (which itself is loaded to clipboard)
xmap_leader('rx', '"+y :RSend reprex::reprex()<CR>', 'Reprex selection')
-- s is for 'send' (Send text to neoterm buffer)
nmap_leader('s', '<Cmd>SlimeSendCurrentLine<CR>j', 'Send to terminal')
-- - In simple visual mode send text and move to the last character in
-- selection and move to the right. Otherwise (like in line or block visual
-- mode) send text and move one line down from bottom of selection.
xmap_leader('s', '<Plug>SlimeRegionSend<CR>', 'Send to terminal')
-- t is for 'terminal'
vim.keymap.set("t", "<Esc>", [[<C-\><C-n>]], { desc = "Exit terminal mode" })
vim.keymap.set("n", "<leader>tc", '<Cmd>lua Config.terminal.open_clickhouse_client()<CR>',
{ desc = "Open Clickhouse client" })
vim.keymap.set("n", "<leader>tl", '<Cmd>lua Config.terminal.open_clickhouse_local()<CR>',
{ desc = "Open Clickhouse local" })
vim.keymap.set("n", "<leader>tp", '<Cmd>lua Config.terminal.open_python()<CR>', { desc = "Open Python" })
vim.keymap.set("n", "<leader>tj", '<Cmd>lua Config.terminal.open_julia()<CR>', { desc = "Open Julia" })
vim.keymap.set("n", "<leader>td", '<Cmd>lua Config.terminal.open_duckdb();Config.terminal.toggle_bracket()<CR>',
{ desc = "Open DuckDB" })
vim.keymap.set("n", "<leader>tx", '<Cmd>lua Config.terminal.open_in_terminal()<CR>', { desc = "Terminal Command" })
vim.keymap.set("n", "<leader>tt", '<Cmd>lua Config.terminal.open_shell()<CR>', { desc = "Terminal" })
nmap_leader("tb", '<Cmd>lua Config.terminal.toggle_bracket()<CR>', "Toggle bracketed paste")
nmap_leader("up", '<Cmd>lua Config.terminal.toggle_bracket()<CR>', "Toggle bracketed paste")
-- u is for UI
nmap_leader('ut', '<Cmd>TSContext toggle<CR>', 'Toggle TScontext')
nmap_leader('ua', '<Cmd>Copilot toggle<CR>', 'Toggle AI completion')
-- v is for 'visits'
nmap_leader('vv', '<Cmd>lua MiniVisits.add_label("core")<CR>', 'Add "core" label')
nmap_leader('vV', '<Cmd>lua MiniVisits.remove_label("core")<CR>', 'Remove "core" label')
nmap_leader('vl', '<Cmd>lua MiniVisits.add_label()<CR>', 'Add label')
nmap_leader('vL', '<Cmd>lua MiniVisits.remove_label()<CR>', 'Remove label')
local map_pick_core = function(keys, cwd, desc)
local rhs = function()
local sort_latest = MiniVisits.gen_sort.default({ recency_weight = 1 })
MiniExtra.pickers.visit_paths({
cwd = cwd,
filter = 'core',
sort = sort_latest
}, { source = { name = desc } })
end
nmap_leader(keys, rhs, desc)
end
map_pick_core('vc', '', 'Core visits (all)')
map_pick_core('vC', nil, 'Core visits (cwd)')
-- w is for 'windows'
nmap_leader("wh", "<C-w>h", "Go to Left Window", { remap = true })
nmap_leader("wj", "<C-w>j", "Go to Lower Window", { remap = true })
nmap_leader("wk", "<C-w>k", "Go to Upper Window", { remap = true })
nmap_leader("wl", "<C-w>l", "Go to Right Window", { remap = true })
nmap_leader("_", "<C-W>s", "Split Window Below", { remap = true })
nmap_leader("|", "<C-W>v", "Split Window Right", { remap = true })
nmap_leader("wd", "<C-W>c", "Delete Window", { remap = true })
nmap_leader("wo", "<C-W>o", "Delete Other Windows", { remap = true })
-- z is for 'ZettelKasten'
nmap_leader("zo", '<Cmd>ZkNotes<CR>', "Notes")
nmap_leader("zt", '<Cmd>ZkTags<cr>', "Tags")
nmap_leader(
"zrd",
'<Cmd>ZkNew { group = "dreviews" }<CR>',
"Daily Review"
)
nmap_leader(
"zrw",
'<Cmd>ZkNew { group = "wreviews" }<CR>',
"Weekly Review"
)
nmap_leader(
"zn",
'<Cmd>ZkNew { group = "inbox", title = vim.fn.input("Title: ") }<CR>',
"New"
)
nmap_leader(
"zp",
"<Cmd>ZkNew { group = 'permanent', title = vim.fn.input('Title: ') }<CR>",
"Permanent"
)
nmap_leader(
"zl",
"<Cmd>ZkNew { group = 'literature', title = vim.fn.input('Title: '), extra.author = vim.fn.input('Author: '), extra.year = vim.fn.input('Year: ') }<CR>",
"Literature"
)
nmap_leader(
"zd",
"<Cmd>ZkNew { group = 'dashboard', title = vim.fn.input('Title: ') }<CR>",
"Dashboard"
)
nmap_leader(
"zP",
"<Cmd>ZkNew { group = 'project', title = vim.fn.input('Title: ')}<CR>",
"Project"
)
-- stylua: ignore end

314
plugin/20_startup.lua Normal file
View file

@ -0,0 +1,314 @@
local now = MiniDeps.now
local later = MiniDeps.later
local now_if_args = Config.now_if_args
local nix = require('config.nix')
if not Config.isNixCats then
local add = MiniDeps.add
now_if_args(function()
add({
source = "nvim-treesitter/nvim-treesitter",
checkout = "master",
monitor = "main",
hooks = {
post_checkout = function()
vim.cmd("TSUpdate")
end,
},
})
add({
source = "nvim-treesitter/nvim-treesitter-textobjects",
checkout = "main",
})
add({ source = "zk-org/zk-nvim" })
end)
end
-- Mini.nvim
now(function()
local colorschemeName = nix.get_setting("onedark_dark", "colorscheme")
if colorschemeName == 'light' then
local palette = require('mini.hues').make_palette({
background = '#fefcf5',
foreground = '#657b83',
accent = 'bg',
saturation = 'high',
n_hues = 8
})
palette.fg_mid2 = "#586e75"
palette.fg_mid = "#073642"
palette.bg_edge = "#fdf6e3"
palette.accent_bg = "#eee8d5"
require('mini.hues').apply_palette(palette)
else
if colorschemeName == "cyberdream" and vim.o.background == 'light' then
colorschemeName = colorschemeName .. '-light'
end
vim.cmd.colorscheme(colorschemeName)
end
end)
now(function()
require("mini.basics").setup({
options = {
basic = true,
extra_ui = true
},
mappings = {
-- jk linewise, gy/gp system clipboard, gV select last change/yank
basic = true,
-- <C-hjkl> move between windows, <C-arrow> resize
windows = true,
move_with_alt = true,
option_toggle_prefix = "<leader>u"
},
autocommands = {
basic = true,
relnum_in_visual_mode = true
},
})
end)
now(function()
require("mini.icons").setup({
use_file_extension = function(ext, _)
local suf3, suf4 = ext:sub(-3), ext:sub(-4)
return suf3 ~= "scm" and suf3 ~= "txt" and suf3 ~= "yml" and suf4 ~= "json" and suf4 ~= "yaml"
end,
})
later(MiniIcons.mock_nvim_web_devicons)
later(MiniIcons.tweak_lsp_kind)
end)
now(function()
local predicate = function(notif)
if not (notif.data.source == "lsp_progress" and notif.data.client_name == "lua_ls") then
return true
end
-- Filter out some LSP progress notifications from 'lua_ls'
return notif.msg:find("Diagnosing") == nil and notif.msg:find("semantic tokens") == nil
end
local custom_sort = function(notif_arr)
return MiniNotify.default_sort(vim.tbl_filter(predicate, notif_arr))
end
require("mini.notify").setup({ content = { sort = custom_sort } })
vim.notify = MiniNotify.make_notify()
end)
now(function()
require("mini.sessions").setup()
end)
now(function()
local starter = require("mini.starter")
starter.setup({
evaluate_single = true,
items = {
starter.sections.recent_files(5, true),
function()
local section = Config.startup.get_recent_files_by_ft_or_ext({
"r",
"sql",
"julia",
"python",
"lua",
})
return section
end,
starter.sections.pick(),
starter.sections.sessions(5, true),
starter.sections.builtin_actions(),
starter.sections.recent_files(3, false),
},
footer = Config.startup.footer_text,
content_hooks = {
starter.gen_hook.adding_bullet(),
starter.gen_hook.indexing(
"all",
{ "Builtin actions", "Recent files (current directory)", "Recent files", }
),
starter.gen_hook.aligning("center", "center"),
starter.gen_hook.padding(3, 2),
},
})
end)
now(function()
require("mini.statusline").setup()
end)
now(function()
require("mini.tabline").setup()
end)
now(function()
local miniclue = require("mini.clue")
--stylua: ignore
miniclue.setup({
window = {
config = {
width = 'auto'
},
delay = 100,
},
clues = {
Config.leader_group_clues,
miniclue.gen_clues.builtin_completion(),
miniclue.gen_clues.g(),
miniclue.gen_clues.marks(),
miniclue.gen_clues.registers(),
miniclue.gen_clues.windows({ submode_resize = true, submode_move = true }),
miniclue.gen_clues.z(),
},
triggers = {
{ mode = 'n', keys = '<Leader>' }, -- Leader triggers
{ mode = 'n', keys = '<LocalLeader>' }, -- LocalLeader triggers
{ mode = 'x', keys = '<Leader>' },
{ mode = 'x', keys = '<LocalLeader>' },
{ mode = 'n', keys = [[\]] }, -- mini.basics
{ mode = 'n', keys = '[' }, -- mini.bracketed
{ mode = 'n', keys = ']' },
{ mode = 'x', keys = '[' },
{ mode = 'x', keys = ']' },
{ mode = 'i', keys = '<C-x>' }, -- Built-in completion
{ mode = 'n', keys = 'g' }, -- `g` key
{ mode = 'x', keys = 'g' },
{ mode = 'n', keys = '`' },
{ mode = 'x', keys = '`' },
{ mode = 'n', keys = '"' }, -- Registers
{ mode = 'x', keys = '"' },
{ mode = 'i', keys = '<C-r>' },
{ mode = 'c', keys = '<C-r>' },
{ mode = 'n', keys = '<C-w>' }, -- Window commands
{ mode = 'n', keys = 'z' }, -- `z` key
{ mode = 'x', keys = 'z' },
},
})
end)
-- Treesitter
now_if_args(function()
vim.treesitter.language.register("markdown", { "markdown", "codecompanion" })
-- Base configuration
local opts = {
highlight = { enable = true },
indent = { enable = false },
textobjects = {
move = {
enable = true,
set_jumps = true, -- whether to set jumps in the jumplist
goto_next_start = {
["]a"] = "@paramter.inner",
["]f"] = "@function.outer",
["]o"] = "@loop.*",
["]s"] = { query = "@local.scope", desc = "Next scope" },
["]z"] = { query = "@fold", desc = "Next fold" },
},
goto_next_end = {
["]M"] = "@function.outer",
["]["] = "@class.outer",
},
goto_previous_start = {
["[a"] = "@parameter.inner",
["[f"] = "@function.outer",
["[o"] = "@loop.*",
["[s"] = { query = "@local.scope", query_group = "locals", desc = "Prev. scope" },
["[z"] = { query = "@fold", query_group = "folds", desc = "Prev. fold" },
},
goto_previous_end = {
["[M"] = "@function.outer",
["[]"] = "@class.outer",
},
goto_next = {
["]e"] = "@conditional.outer",
},
goto_previous = {
["[e"] = "@conditional.outer",
}
},
swap = {
enable = true,
swap_next = {
["<leader>x"] = "@parameter.inner",
},
swap_previous = {
["<leader>X"] = "@parameter.inner",
},
},
lsp_interop = {
enable = true,
border = 'none',
floating_preview_opts = {},
peek_definition_code = {
["<leader>lm"] = "@function.outer",
["<leader>lM"] = "@class.outer",
},
},
},
}
-- Environment-specific Overrides
if not Config.isNixCats then
opts.auto_install = true
opts.ensure_installed = Config.treesitter_helpers.default_parsers
else
opts.auto_install = false
-- Nix handles installation, so ensure_installed is skipped/empty
end
-- Manual parser check for non-Nix users
if not Config.isNixCats then
local installed_check = function(lang)
return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0
end
local to_install = vim.tbl_filter(installed_check, opts.ensure_installed)
if #to_install > 0 then
require("nvim-treesitter").install(to_install)
end
end
local configs = require("nvim-treesitter.configs")
configs.setup(opts)
require 'treesitter-context'.setup {
enable = true,
multiwindow = false, -- Enable multiwindow support.
max_lines = 30, -- How many lines the window should span. Values <= 0 mean no limit.
min_window_height = 70, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
line_numbers = true,
multiline_threshold = 10, -- Maximum number of lines to show for a single context
trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline'
-- Separator between context and content. Should be a single character string, like '-'.
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
separator = '-',
zindex = 20, -- The Z-index of the context window
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
end)
-- zk
now_if_args(function()
require("zk").setup({
picker = "minipick",
lsp = {
-- `config` is passed to `vim.lsp.start_client(config)`
config = {
cmd = { "zk", "lsp" },
name = "zk",
-- on_attach = ...
-- etc, see `:h vim.lsp.start_client()`
},
-- automatically attach buffers in a zk notebook that match the given filetypes
auto_attach = {
enabled = true,
filetypes = { "markdown" },
},
},
})
end)

104
plugin/21_datascience.lua Normal file
View file

@ -0,0 +1,104 @@
local now = MiniDeps.now
local now_if_args = Config.now_if_args
local later = MiniDeps.later
local add = Config.add
local nix = require('config.nix')
if not Config.isNixCats then
local m_add = MiniDeps.add
now(function()
m_add({ source = "R-nvim/R.nvim" })
end)
now_if_args(function()
m_add({ source = "jmbuhr/otter.nvim" })
end)
later(function()
m_add({ source = "jpalardy/vim-slime" })
end)
end
-- terminal
later(function()
vim.g.slime_target = "neovim"
vim.g.slime_no_mappings = true
add("vim-slime")
vim.g.slime_cell_delimiter = vim.g.slime_cell_delimiter or "# %%"
vim.g.slime_bracketed_paste = Config.opt_bracket
vim.g.slime_input_pid = false
vim.g.slime_suggest_default = true
vim.g.slime_menu_config = false
vim.g.slime_neovim_ignore_unlisted = false
-- Define standard slime mappings
vim.keymap.set("v", "<CR>", "<Plug>SlimeRegionSend", { noremap = true })
vim.keymap.set("v", "<localleader><localleader>", "<Plug>SlimeRegionSend", { noremap = true })
vim.keymap.set("n", "<localleader><localleader>", "<Plug>SlimeLineSend", { noremap = true })
-- Standardize on C-c C-c as well (common convention)
vim.keymap.set("v", "<C-c><C-c>", "<Plug>SlimeRegionSend", { noremap = true })
vim.keymap.set("n", "<C-c><C-c>", "<Plug>SlimeParagraphSend", { noremap = true })
end)
-- r
now(function()
if nix.get_cat("r", false) then
vim.g.rout_follow_colorscheme = true
require("r").setup({
-- Create a table with the options to be passed to setup()
R_args = { "--quiet", "--no-save" },
auto_start = "no",
objbr_auto_start = false,
objbr_place = 'console,below',
rconsole_width = 120,
min_editor_width = 80,
rconsole_height = 20,
nvimpager = "split_h",
pdfviewer = "zathura",
})
end
end)
-- Quarto
now(function()
vim.treesitter.language.register("markdown", { "quarto", "rmd" })
vim.api.nvim_create_autocmd("FileType", {
pattern = { "quarto" },
callback = function()
require("otter").activate()
end,
})
require("otter").setup({
lsp = {
diagnostic_update_events = { "BufWritePost", "InsertLeave" },
},
buffers = {
set_filetype = true,
write_to_disk = true,
},
})
end)
later(function()
require("quarto").setup({
lspFeatures = {
enabled = true,
languages = { "r", "python", "julia" },
diagnostics = {
enabled = true,
triggers = { "BufWrite" },
},
completion = {
enabled = true,
},
},
codeRunner = {
enabled = true,
default_method = "slime",
},
})
end)

53
plugin/22_languages.lua Normal file
View file

@ -0,0 +1,53 @@
local add = Config.add
local now_if_args = Config.now_if_args
local later = MiniDeps.later
if not Config.isNixCats then
local m_add = MiniDeps.add
later(function()
m_add({ source = "Bilal2453/luvit-meta" })
m_add({ source = "folke/lazydev.nvim" })
end)
end
-- lua
later(function()
add("luvit-meta")
add("lazydev")
require("lazydev").setup({
library = {
-- See the configuration section for more details
-- Load luvit types when the `vim.uv` word is found
"lua",
"mini.nvim",
"MiniDeps",
{ path = "luvit-meta/library", words = { "vim%.uv" } },
{ path = "${3rd}/luv/library", words = { "vim%.uv" } },
},
})
end)
-- Markdown
now_if_args(function()
add("render-markdown.nvim")
require('render-markdown').setup({
-- completions = { blink = { enabled = true } },
file_types = { 'markdown', 'quarto', 'rmd', 'codecompanion', },
link = {
wiki = {
body = function(ctx)
local diagnostics = vim.diagnostic.get(ctx.buf, {
lnum = ctx.row,
severity = vim.diagnostic.severity.HINT,
})
for _, diagnostic in ipairs(diagnostics) do
if diagnostic.source == 'marksman' then
return diagnostic.message
end
end
return nil
end,
},
},
})
end)

348
plugin/23_editor.lua Normal file
View file

@ -0,0 +1,348 @@
local later = MiniDeps.later
local add = Config.add
if not Config.isNixCats then
local m_add = MiniDeps.add
later(function()
m_add("stevearc/conform.nvim")
end)
end
-- Formatting
later(function()
add("conform.nvim")
require("conform").setup({
-- Map of filetype to formatters
formatters_by_ft = {
javascript = { "prettier" },
json = { "prettier" },
python = { "black" },
nix = { "alejandra" },
-- r = { "my_styler" },
rmd = { "injected" },
quarto = { "injected" },
},
lsp_format = "fallback",
formatters = {
my_styler = {
command = "R",
-- A list of strings, or a function that returns a list of strings
-- Return a single string instead of a list to run the command in a shell
args = { "-s", "-e", "styler::style_file(commandArgs(TRUE)[1])", "--args", "$FILENAME" },
stdin = false,
},
},
})
end)
-- Edit
later(function()
local ai = require("mini.ai")
local spec_treesitter = ai.gen_spec.treesitter
ai.setup({
search_method = "cover",
n_lines = 1000,
})
end)
later(function()
require("mini.align").setup()
end)
later(function()
require("mini.animate").setup({ scroll = { enable = false } })
end)
later(function()
require("mini.bracketed").setup({
diagnostic = {
options = {
float = false,
},
},
})
end)
later(function()
require("mini.bufremove").setup()
end)
later(function()
require("mini.comment").setup()
end)
later(function()
require("mini.cursorword").setup({ delay = 1000 })
end)
later(function()
require("mini.diff").setup({
view = {
style = "sign",
},
mappings = {
apply = "<leader>ga",
reset = "<leader>gr",
textobject = "o",
},
options = {
linematch = 1000,
algorithm = 'myers',
},
})
end)
later(function()
require("mini.files").setup({
windows = {
preview = true,
width_focus = 80,
width_preview = 90,
},
mappings = {
mark_goto = "'",
synchronize = ':',
}
})
local minifiles_augroup = vim.api.nvim_create_augroup("ec-mini-files", {})
vim.api.nvim_create_autocmd("User", {
group = minifiles_augroup,
pattern = "MiniFilesExplorerOpen",
callback = function()
MiniFiles.set_bookmark("h", os.getenv("HOME") or vim.env.HOME, { desc = "Home" })
MiniFiles.set_bookmark("c", vim.fn.stdpath("config"), { desc = "Config" })
MiniFiles.set_bookmark("w", vim.fn.getcwd, { desc = "Working directory" })
MiniFiles.set_bookmark("z", os.getenv("ZK_NOTEBOOK_DIR") or vim.env.HOME, { desc = "ZK" })
end,
})
-- Set focused directory as current working directory
local function remove_string(string1, string2)
return string2:gsub(string1, "", 1)
end
local set_cwd = function()
local path = (MiniFiles.get_fs_entry() or {}).path
if path == nil then
return vim.notify("Cursor is not on valid entry")
end
local pwd = vim.fs.dirname(path)
vim.notify("PWD: " .. '.' .. vim.fn.pathshorten(pwd, 6))
vim.fn.chdir(pwd)
end
-- Yank in register full path of entry under cursor
local yank_path = function()
local path = (MiniFiles.get_fs_entry() or {}).path
if path == nil then
return vim.notify("Cursor is not on valid entry")
end
vim.notify("Yanked: " .. path)
vim.fn.setreg(vim.v.register, path)
end
-- Yank in register relative path of entry under cursor
local yank_relpath = function()
local path = (MiniFiles.get_fs_entry() or {}).path
local cwd = vim.fn.getcwd() .. '/'
local relpath = remove_string(cwd, path)
if path == nil then
return vim.notify("Cursor is not on valid entry")
end
vim.notify("Yanked: " .. relpath)
vim.fn.setreg(vim.v.register, relpath)
end
local ui_open = function()
vim.ui.open(MiniFiles.get_fs_entry().path)
end
vim.api.nvim_create_autocmd("User", {
pattern = "MiniFilesBufferCreate",
callback = function(args)
local b = args.data.buf_id
vim.keymap.set("n", "g~", set_cwd, { buffer = b, desc = "Set cwd" })
vim.keymap.set("n", "gX", ui_open, { buffer = b, desc = "Open UI" })
vim.keymap.set("n", "gY", yank_path, { buffer = b, desc = "Yank path" })
vim.keymap.set("n", "gy", yank_relpath, { buffer = b, desc = "Yank relpath" })
end,
})
end)
later(function()
require("mini.git").setup()
end)
later(function()
require("mini.extra").setup()
end)
later(function()
local hipatterns = require("mini.hipatterns")
local hi_words = MiniExtra.gen_highlighter.words
hipatterns.setup({
highlighters = {
fixme = hi_words({ "FIXME", "Fixme", "fixme" }, "MiniHipatternsFixme"),
hack = hi_words({ "HACK", "Hack", "hack" }, "MiniHipatternsHack"),
todo = hi_words({ "TODO", "Todo", "todo" }, "MiniHipatternsTodo"),
note = hi_words({ "NOTE", "Note", "note" }, "MiniHipatternsNote"),
hex_color = hipatterns.gen_highlighter.hex_color(),
},
})
end)
later(function()
require("mini.indentscope").setup()
end)
later(function()
require("mini.jump").setup()
end)
later(function()
local jump2d = require("mini.jump2d")
jump2d.setup({
spotter = jump2d.gen_spotter.pattern("[^%s%p]+"),
allowed_lines = {
blank = false,
cursor_at = false
},
labels = "asdfghjklweruiopzxcnm,;",
view = { dim = true, n_steps_ahead = 2 },
mappings = {
start_jumping = "sj",
},
})
vim.keymap.set({ "n", "x", "o" }, "<leader><CR>", function()
MiniJump2d.start(MiniJump2d.builtin_opts.single_character)
end)
end)
later(function()
local minikeymap = require("mini.keymap")
minikeymap.setup()
local map_multistep = minikeymap.map_multistep
local tab_steps = {
"blink_next",
"pmenu_next",
"increase_indent",
"jump_after_close",
}
map_multistep("i", "<Tab>", tab_steps)
local shifttab_steps = {
"blink_prev",
"pmenu_prev",
"decrease_indent",
"jump_before_open",
}
map_multistep("i", "<S-Tab>", shifttab_steps)
map_multistep("i", "<CR>", {
"blink_accept",
"pmenu_accept",
"minipairs_cr",
})
map_multistep("i", "<BS>", { "hungry_bs", "minipairs_bs" })
local tab_steps_n = {
"minisnippets_next",
"jump_after_tsnode",
"jump_after_close",
}
map_multistep("n", "<Tab>", tab_steps_n)
local shifttab_steps_n = {
"minisnippets_prev",
"jump_before_tsnode",
"jump_before_open",
}
map_multistep("n", "<S-Tab>", shifttab_steps_n)
end)
later(function()
require("mini.move").setup({ options = { reindent_linewise = false } })
end)
later(function()
require("mini.operators").setup({
replace = {
prefix = "gl"
},
})
end)
later(function()
require("mini.pairs").setup({
mappings = {
['"'] = { neigh_pattern = '[^%a\\"].' },
["'"] = { neigh_pattern = "[^%a\\'#]." },
},
modes = {
insert = true,
command = true,
terminal = true
}
})
end)
later(function()
require("mini.misc").setup({ make_global = { "put", "put_text", "stat_summary", "bench_time" } })
-- MiniMisc.setup_auto_root()
MiniMisc.setup_termbg_sync()
MiniMisc.setup_restore_cursor()
end)
later(function()
local choose_all = function()
local mappings = MiniPick.get_picker_opts().mappings
vim.api.nvim_input(mappings.mark_all .. mappings.choose_marked)
end
require("mini.pick").setup({
mappings = {
choose_marked = '<C-CR>',
choose_all = { char = '<C-q>', func = choose_all },
}
})
vim.ui.select = MiniPick.ui_select
-- vim.api.nvim_set_hl(0, "MiniPickMatchCurrent", { bg = "#fe640b", bold = true })
end)
later(function()
local snippets = require("mini.snippets")
local gen_loader = snippets.gen_loader
local lang_patterns = {
markdown_inline = { "quarto.json" },
}
snippets.setup({
snippets = {
-- Load custom file with global snippets first (adjust for Windows)
gen_loader.from_file(vim.fn.stdpath('config') .. "/snippets/global.json"),
-- Load snippets based on current language by reading files from
-- "snippets/" subdirectories from 'runtimepath' directories.
gen_loader.from_lang({ lang_patterns = lang_patterns }),
},
-- expand = { match = match_strict },
})
end)
later(function()
require("mini.splitjoin").setup()
end)
later(function()
require("mini.surround").setup()
-- Disable `s` shortcut (use `cl` instead) for safer usage of 'mini.surround'
vim.keymap.set({ "n", "x" }, "s", "<Nop>")
end)
later(function()
require("mini.trailspace").setup()
end)
later(function()
require("mini.visits").setup()
end)

351
plugin/24_completion.lua Normal file
View file

@ -0,0 +1,351 @@
local add = Config.add
local later = MiniDeps.later
local now_if_args = Config.now_if_args
-- Constants
local BLINK_VERSION = "v1.4.1"
-- Plugin sources configuration
local PLUGIN_SOURCES = {
"hrsh7th/cmp-cmdline",
"xzbdmw/colorful-menu.nvim",
"zbirenbaum/copilot.lua",
"jmbuhr/cmp-pandoc-references",
"fang2hou/blink-copilot",
"olimorris/codecompanion.nvim"
}
local PLUGIN_ADDS = {
"cmp-cmdline",
"blink.compat",
"colorful-menu.nvim",
"cmp-pandoc-references",
}
-- Helper functions
local function create_system_prompt(role_description)
return function(context)
return "I want you to act as a senior " .. context.filetype .. " developer. " .. role_description
end
end
local function get_code_block(context)
local text = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
return "```" .. context.filetype .. "\n" .. text .. "\n```"
end
local function create_common_opts(mapping, short_name)
return {
mapping = mapping,
modes = { "v" },
short_name = short_name,
auto_submit = true,
stop_context_insertion = true,
user_prompt = true,
}
end
local function get_mini_icons_highlight(ctx)
local _, hl, _ = require("mini.icons").get("lsp", ctx.kind)
return hl
end
local function get_blink_fuzzy_setting()
local setting = {
sorts = { "exact", "score", "sort_text" }
}
if not Config.isNixCats then
setting.prebuilt_binary = { force_version = BLINK_VERSION }
end
return setting
end
-- Plugin loading
if not Config.isNixCats then
local m_add = MiniDeps.add
now_if_args(function()
m_add({
source = "saghen/blink.cmp",
depends = { "rafamadriz/friendly-snippets" },
checkout = BLINK_VERSION,
})
end)
later(function()
for _, source in ipairs(PLUGIN_SOURCES) do
m_add({ source = source })
end
end)
end
local function get_codecompanion_config()
return {
adapters = {
http = {
copilot = function()
return require("codecompanion.adapters").extend("copilot", {
schema = {
model = { default = "gemini-3-pro-preview" }
}
})
end,
}
},
display = {
chat = {
show_settings = false,
window = {
layout = "horizontal",
position = "bottom",
height = 0.33,
},
},
},
prompt_library = {
["Code Expert"] = {
strategy = "chat",
description = "Get expert advice from an LLM",
opts = create_common_opts("<localleader>ae", "expert"),
prompts = {
{
role = "system",
content = create_system_prompt(
"I will ask you specific questions and I want you to return concise explanations and codeblock examples."
),
},
{
role = "user",
content = function(context)
return "I have the following code:\n\n" .. get_code_block(context) .. "\n\n"
end,
opts = { contains_code = true },
},
},
},
["Code Fixer"] = {
strategy = "chat",
description = "Fix code errors with expert guidance",
opts = create_common_opts("<localleader>af", "afixer"),
prompts = {
{
role = "system",
content = create_system_prompt(
"I have a block of code that is not working and will give you a hint about the error. I want you to return the corrected code and a concise explanation of the corrections."
),
},
{
role = "user",
content = function(context)
return "The following code has an error:\n\n" .. get_code_block(context) .. "\n\nThe error is:"
end,
opts = { contains_code = true },
},
},
},
["Suggest"] = {
strategy = "chat",
description = "Suggest improvements to the buffer",
opts = {
mapping = "<localleader>as",
modes = { "v" },
short_name = "suggest",
auto_submit = true,
user_prompt = false,
stop_context_insertion = false,
},
prompts = {
{
role = "system",
content = create_system_prompt(
"When asked to improve code, follow these steps:\n" ..
"1. Identify the programming language.\n" ..
"2. Think separately for each function or significant block of code and think about possible improvements (e.g., for better readability or speed) in the context of the language.\n" ..
"3. Think about the whole document and think about possible improvements.\n" ..
"4. Provide the improved code.\n" ..
"5. Provide a concise explanation of the improvements."
),
},
{
role = "user",
content = function(context)
return "Please improve the following code:\n\n" .. get_code_block(context)
end,
opts = { contains_code = true },
},
},
},
}
}
end
-- Batch add simple plugins
later(function()
for _, plugin in ipairs(PLUGIN_ADDS) do
add(plugin)
end
end)
-- Configure plugins with setup
later(function()
add("copilot.lua")
require("copilot").setup({
suggestion = { enabled = false },
panel = { enabled = false },
filetypes = {
help = true,
julia = true,
lua = true,
markdown = true,
nix = true,
python = true,
r = true,
sh = function()
if string.match(vim.fs.basename(vim.api.nvim_buf_get_name(0)), '^%.env.*') then
-- disable for .env files
return false
end
return true
end,
["."] = false
},
server_opts_overrides = {
settings = {
telemetry = { telemetryLevel = 'off' }
}
},
should_attach = function(_, bufname)
if string.match(bufname, "env") then
return false
end
return true
end
})
end)
later(function()
add("blink-copilot")
require("blink-copilot").setup({
max_completions = 1,
})
end)
later(function()
add("codecompanion.nvim")
-- now use function
require("codecompanion").setup(get_codecompanion_config())
vim.cmd([[cab cc CodeCompanion]])
end)
now_if_args(function()
add("blink.cmp")
require("blink.cmp").setup({
keymap = {
preset = "default",
["<C-space>"] = { "show", "select_next" },
["<C-l>"] = { "accept" },
},
cmdline = {
enabled = true,
keymap = {
preset = "inherit",
["<Tab>"] = { "show", "select_next" },
["<S-Tab>"] = { "show", "select_prev" },
["<C-l>"] = { "accept" },
},
completion = {
menu = { auto_show = true },
list = {
selection = { preselect = false, auto_insert = true }
},
},
sources = function()
local cmd_type = vim.fn.getcmdtype()
if cmd_type == "/" or cmd_type == "?" then
return { "buffer" }
elseif cmd_type == ":" or cmd_type == "@" then
return { "cmdline", "cmp_cmdline" }
end
return {}
end,
},
fuzzy = get_blink_fuzzy_setting(),
signature = {
enabled = true,
window = { show_documentation = true }
},
completion = {
menu = {
draw = {
treesitter = { "lsp" },
components = {
label = {
text = function(ctx)
return require("colorful-menu").blink_components_text(ctx)
end,
highlight = function(ctx)
return require("colorful-menu").blink_components_highlight(ctx)
end,
},
kind_icon = { highlight = get_mini_icons_highlight },
kind = { highlight = get_mini_icons_highlight },
},
},
},
list = {
selection = { preselect = false, auto_insert = true }
},
documentation = { auto_show = true },
trigger = { show_in_snippet = false },
},
snippets = { preset = "mini_snippets" },
sources = {
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot", "codecompanion" },
providers = {
path = {
score_offset = 50,
opts = {
get_cwd = function(_)
return vim.fn.getcwd()
end,
},
},
lsp = { score_offset = 40 },
snippets = { score_offset = 0 },
cmp_cmdline = {
name = "cmp_cmdline",
module = "blink.compat.source",
enabled = false,
score_offset = 10,
opts = { cmp_name = "cmdline" }
},
cmp_r = {
name = "cmp_r",
module = "blink.compat.source",
},
copilot = {
name = "copilot",
module = "blink-copilot",
score_offset = 45,
async = true,
},
codecompanion = {
name = "CodeCompanion",
module = "codecompanion.providers.completion.blink",
score_offset = 45,
async = true,
},
references = {
name = "pandoc_references",
module = "cmp-pandoc-references.blink",
score_offset = 50,
},
},
},
})
end)

89
plugin/25_lsp.lua Normal file
View file

@ -0,0 +1,89 @@
local now_if_args = Config.now_if_args
if not Config.isNixCats then
local m_add = MiniDeps.add
now_if_args(function()
m_add("neovim/nvim-lspconfig")
end)
end
now_if_args(function()
local servers = {
clangd = {},
basedpyright = {},
ruff = {},
marksman = {
filetypes = { "markdown", "markdown_inline", "codecompanion" },
},
r_language_server = {
filetypes = { 'r', 'rmd', 'rmarkdown' },
settings = {
['r_language_server'] = {
lsp = {
rich_documentation = true,
enable = true,
},
},
}
},
julials = {
settings = {
julia = {
format = {
indent = 2,
},
lsp = {
autoStart = true,
provideFormatter = true,
},
},
},
},
lua_ls = {
settings = {
Lua = {
completion = {
callSnippet = "Replace",
},
runtime = {
version = "LuaJIT",
},
diagnostics = {
disable = { "trailing-space" },
},
workspace = {
checkThirdParty = false,
},
doc = {
privateName = { "^_" },
},
telemetry = {
enable = false,
},
},
},
},
}
local lsp_flags = {
allow_incremental_sync = true,
}
if vim.fn.has("nvim-0.11") == 1 then
-- Neovim 0.11+ Native LSP Configuration
for name, config in pairs(servers) do
vim.lsp.config(name, config)
end
vim.lsp.config('*', { flags = lsp_flags })
-- Enable all defined servers
vim.lsp.enable(vim.tbl_keys(servers))
else
-- Fallback for Neovim < 0.11 (using nvim-lspconfig)
local lspconfig = require('lspconfig')
for name, config in pairs(servers) do
local final_config = vim.tbl_extend("force", { flags = lsp_flags }, config)
lspconfig[name].setup(final_config)
end
end
end)