diff --git a/after/ftplugin/haskell.lua b/after/ftplugin/haskell.lua new file mode 100644 index 00000000000..8cce36fd19b --- /dev/null +++ b/after/ftplugin/haskell.lua @@ -0,0 +1,17 @@ +-- local ht = require 'haskell-tools' +-- local bufnr = vim.api.nvim_get_current_buf() +-- local base_opts = { noremap = true, silent = true, buffer = bufnr } +-- +-- vim.keymap.set('n', 'cl', vim.lsp.codelens.run, vim.tbl_extend('force', base_opts, { desc = 'Run all code lenses (e.g. eval, add signature)' })) +-- +-- vim.keymap.set('n', 'hs', ht.hoogle.hoogle_signature, vim.tbl_extend('force', base_opts, { desc = 'Hoogle search for type signature under cursor' })) +-- +-- vim.keymap.set('n', 'ea', ht.lsp.buf_eval_all, vim.tbl_extend('force', base_opts, { desc = 'Evaluate all code snippets in buffer' })) +-- +-- vim.keymap.set('n', 'rr', ht.repl.toggle, vim.tbl_extend('force', base_opts, { desc = 'Toggle GHCi repl for current package' })) +-- +-- vim.keymap.set('n', 'rf', function() +-- ht.repl.toggle(vim.api.nvim_buf_get_name(0)) +-- end, vim.tbl_extend('force', base_opts, { desc = 'Toggle GHCi repl for current buffer' })) +-- +-- vim.keymap.set('n', 'rq', ht.repl.quit, vim.tbl_extend('force', base_opts, { desc = 'Quit GHCi repl' })) diff --git a/after/ftplugin/markdown.lua b/after/ftplugin/markdown.lua new file mode 100644 index 00000000000..99d36c62e1e --- /dev/null +++ b/after/ftplugin/markdown.lua @@ -0,0 +1,35 @@ +-- Add the key mappings only for Markdown files in a zk notebook. +if require('zk.util').notebook_root(vim.fn.expand '%:p') ~= nil then + local function map(...) + vim.api.nvim_buf_set_keymap(0, ...) + end + local opts = { noremap = true, silent = false } + + -- Open the link under the caret. + map('n', '', 'lua vim.lsp.buf.definition()', opts) + + -- Create a new note after asking for its title. + -- This overrides the global `zn` mapping to create the note in the same directory as the current buffer. + map('n', 'zn', "ZkNew { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", opts) + -- Create a new note in the same directory as the current buffer, using the current selection for title. + map('v', 'znt', ":'<,'>ZkNewFromTitleSelection { dir = vim.fn.expand('%:p:h') }", opts) + -- Create a new note in the same directory as the current buffer, using the current selection for note content and asking for its title. + map('v', 'znc', ":'<,'>ZkNewFromContentSelection { dir = vim.fn.expand('%:p:h'), title = vim.fn.input('Title: ') }", opts) + + -- Open notes linking to the current buffer. + map('n', 'zb', 'ZkBacklinks', opts) + -- Alternative for backlinks using pure LSP and showing the source context. + --map('n', 'zb', 'lua vim.lsp.buf.references()', opts) + -- Open notes linked by the current buffer. + map('n', 'zl', 'ZkLinks', opts) + + -- Preview a linked note. + map('n', 'K', 'lua vim.lsp.buf.hover()', opts) + -- Open the code actions for a visual selection. + map('v', 'za', ":'<,'>lua vim.lsp.buf.range_code_action()", opts) + + -- Insert a link to a note. + map('n', 'zi', 'ZkInsertLink', opts) + -- Insert a link to a note using the current selection for the link text. + map('v', 'zil', ":'<,'>ZkInsertLinkAtSelection", opts) +end diff --git a/after/ftplugin/rust.lua b/after/ftplugin/rust.lua new file mode 100644 index 00000000000..f5818293575 --- /dev/null +++ b/after/ftplugin/rust.lua @@ -0,0 +1,13 @@ +local bufnr = vim.api.nvim_get_current_buf() +vim.keymap.set('n', 'a', function() + vim.cmd.RustLsp 'codeAction' -- supports rust-analyzer's grouping + -- or vim.lsp.buf.codeAction() if you don't want grouping. +end, { silent = true, buffer = bufnr }) +vim.keymap.set( + 'n', + 'K', -- Override Neovim's built-in hover keymap with rustaceanvim's hover actions + function() + vim.cmd.RustLsp { 'hover', 'actions' } + end, + { silent = true, buffer = bufnr } +) diff --git a/init.lua b/init.lua index ed50b69d7f3..f96bdfd62df 100644 --- a/init.lua +++ b/init.lua @@ -91,7 +91,7 @@ vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' -- Set to true if you have a Nerd Font installed and selected in the terminal -vim.g.have_nerd_font = false +vim.g.have_nerd_font = true -- [[ Setting options ]] -- See `:help vim.o` @@ -344,6 +344,7 @@ require('lazy').setup({ -- instead of just disabling it here, to keep your config clean. enabled = true, event = 'VimEnter', + tag = 'v0.2.0', dependencies = { 'nvim-lua/plenary.nvim', { -- If encountering errors, see telescope-fzf-native README for installation instructions @@ -641,6 +642,80 @@ require('lazy').setup({ Lua = {}, }, }, + bashls = { + -- cmd = {}, + filetypes = { 'bash', 'zsh', 'sh' }, + -- capabilities = {}, + -- settings = {}, + }, + yamlls = {}, + taplo = { -- for TOML + cmd = { 'taplo', 'lsp', 'stdio' }, + filetypes = { 'toml' }, + capabilities = {}, + settings = {}, + }, + rust_analyzer = { + cmd = {}, + filetypes = {}, + capabilities = {}, + settings = { + ['rust-analyzer'] = { + checkOnSave = { + enable = true, + }, + diagnostics = { + enable = true, + underline = false, + }, + imports = { + granularity = { + group = 'module', + }, + prefix = 'self', + }, + cargo = { + buildScripts = { + enable = true, + }, + }, + procMacro = { + enable = true, + }, + }, + }, + }, + hls = { + cmd = { 'haskell-language-server-wrapper', '--lsp' }, + filetypes = { 'haskell', 'lhaskell', 'cabal' }, + capabilities = {}, + root_dir = function(bufnr, on_dir) + local fname = vim.api.nvim_buf_get_name(bufnr) + local util = require 'neovim.util' + on_dir(util.root_pattern('hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml')(fname)) + end, + settings = { + haskell = { + cabalFormattingProvider = 'cabalfmt', + formattingProvider = 'ormolu', + }, + }, + }, + tinymist = { + cmd = { 'tinymist' }, + filetypes = { 'typ' }, + settings = { + formatterMode = 'typStyle', + exportPdf = 'onType', + semanticTokens = 'disable', + }, + }, + -- vale_ls = { + -- cmd = { 'vale', 'lsp' }, + -- filetypes = { 'markdown', 'mdx' }, + -- capabilities = {}, + -- settings = {}, + -- }, } -- Ensure the servers and tools above are installed @@ -652,7 +727,11 @@ require('lazy').setup({ -- You can press `g?` for help in this menu. local ensure_installed = vim.tbl_keys(servers or {}) vim.list_extend(ensure_installed, { - -- You can add other tools here that you want Mason to install + 'stylua', -- Used to format Lua code + 'beautysh', + 'markdownlint', + 'hlint', + 'tinymist', }) require('mason-tool-installer').setup { ensure_installed = ensure_installed } @@ -696,6 +775,7 @@ require('lazy').setup({ end, formatters_by_ft = { lua = { 'stylua' }, + markdown = { 'markdownlint' }, -- Conform can also run multiple formatters sequentially -- python = { "isort", "black" }, -- @@ -874,7 +954,7 @@ require('lazy').setup({ branch = 'main', -- [[ Configure Treesitter ]] See `:help nvim-treesitter-intro` config = function() - local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc' } + local parsers = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc', 'd2' } require('nvim-treesitter').install(parsers) vim.api.nvim_create_autocmd('FileType', { callback = function(args) @@ -920,7 +1000,7 @@ require('lazy').setup({ -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. - -- { import = 'custom.plugins' }, + { import = 'custom.plugins' }, -- -- For additional information with loading, sourcing and examples see `:help lazy.nvim-🔌-plugin-spec` -- Or use telescope! diff --git a/lua/custom/plugins/amp.lua b/lua/custom/plugins/amp.lua new file mode 100644 index 00000000000..19f70b0bafa --- /dev/null +++ b/lua/custom/plugins/amp.lua @@ -0,0 +1,6 @@ +return { + 'sourcegraph/amp.nvim', + branch = 'main', + lazy = false, + opts = { auto_start = true, log_level = 'info' }, +} diff --git a/lua/custom/plugins/better-escape.lua b/lua/custom/plugins/better-escape.lua new file mode 100644 index 00000000000..1d588fbc6ea --- /dev/null +++ b/lua/custom/plugins/better-escape.lua @@ -0,0 +1,7 @@ +-- lua with lazy.nvim +return { + 'max397574/better-escape.nvim', + config = function() + require('better_escape').setup() + end, +} diff --git a/lua/custom/plugins/bg.lua b/lua/custom/plugins/bg.lua new file mode 100644 index 00000000000..3195cf43e1a --- /dev/null +++ b/lua/custom/plugins/bg.lua @@ -0,0 +1,5 @@ +return { + 'typicode/bg.nvim', + lazy = false, + priority = 1000, +} diff --git a/lua/custom/plugins/bufferline.lua b/lua/custom/plugins/bufferline.lua new file mode 100644 index 00000000000..726bb63abc4 --- /dev/null +++ b/lua/custom/plugins/bufferline.lua @@ -0,0 +1,9 @@ +return { + 'akinsho/bufferline.nvim', + lazy = false, + version = '*', + dependencies = 'nvim-tree/nvim-web-devicons', + config = function() + require('bufferline').setup {} + end, +} diff --git a/lua/custom/plugins/catpuccin.lua b/lua/custom/plugins/catpuccin.lua new file mode 100644 index 00000000000..24afc752e55 --- /dev/null +++ b/lua/custom/plugins/catpuccin.lua @@ -0,0 +1,58 @@ +return { + 'catppuccin/nvim', + name = 'catppuccin', + priority = 1000, + config = function() + require('catppuccin').setup { + flavour = 'auto', -- latte, frappe, macchiato, mocha + background = { -- :h background + light = 'latte', + dark = 'mocha', + }, + transparent_background = false, -- disables setting the background color. + show_end_of_buffer = false, -- shows the '~' characters after the end of buffers + term_colors = false, -- sets terminal colors (e.g. `g:terminal_color_0`) + dim_inactive = { + enabled = false, -- dims the background color of inactive window + shade = 'dark', + percentage = 0.15, -- percentage of the shade to apply to the inactive window + }, + no_italic = false, -- Force no italic + no_bold = false, -- Force no bold + no_underline = false, -- Force no underline + styles = { -- Handles the styles of general hi groups (see `:h highlight-args`): + comments = { 'italic' }, -- Change the style of comments + conditionals = { 'italic' }, + loops = {}, + functions = {}, + keywords = {}, + strings = {}, + variables = {}, + numbers = {}, + booleans = {}, + properties = {}, + types = {}, + operators = {}, + -- miscs = {}, -- Uncomment to turn off hard-coded styles + }, + color_overrides = {}, + custom_highlights = {}, + default_integrations = true, + integrations = { + cmp = true, + gitsigns = true, + nvimtree = true, + treesitter = true, + notify = false, + mini = { + enabled = true, + indentscope_color = '', + }, + -- For more plugins integrations please scroll down (https://github.com/catppuccin/nvim#integrations) + }, + } + + -- setup must be called before loading + -- vim.cmd.colorscheme 'catppuccin' + end, +} diff --git a/lua/custom/plugins/ccc.lua b/lua/custom/plugins/ccc.lua new file mode 100644 index 00000000000..91bca4a9d3a --- /dev/null +++ b/lua/custom/plugins/ccc.lua @@ -0,0 +1,7 @@ +return { + 'uga-rosa/ccc.nvim', + event = 'VeryLazy', + config = function() + require('ccc').setup {} + end, +} diff --git a/lua/custom/plugins/claudecode.lua b/lua/custom/plugins/claudecode.lua new file mode 100644 index 00000000000..04440d7b26c --- /dev/null +++ b/lua/custom/plugins/claudecode.lua @@ -0,0 +1,67 @@ +return { + 'coder/claudecode.nvim', + dependencies = { 'folke/snacks.nvim' }, + config = true, + opts = { + -- Server Configuration + port_range = { min = 10000, max = 65535 }, + auto_start = true, + log_level = 'info', -- "trace", "debug", "info", "warn", "error" + terminal_cmd = nil, -- Custom terminal command (default: "claude") + -- For local installations: "~/.claude/local/claude" + -- For native binary: use output from 'which claude' + + -- Send/Focus Behavior + -- When true, successful sends will focus the Claude terminal if already connected + focus_after_send = false, + + -- Selection Tracking + track_selection = true, + visual_demotion_delay_ms = 50, + + -- Terminal Configuration + terminal = { + split_side = 'right', -- "left" or "right" + split_width_percentage = 0.30, + provider = 'auto', -- "auto", "snacks", "native", "external", "none", or custom provider table + auto_close = true, + snacks_win_opts = {}, -- Opts to pass to `Snacks.terminal.open()` - see Floating Window section below + + -- Provider-specific options + provider_opts = { + -- Command for external terminal provider. Can be: + -- 1. String with %s placeholder: "alacritty -e %s" (backward compatible) + -- 2. String with two %s placeholders: "alacritty --working-directory %s -e %s" (cwd, command) + -- 3. Function returning command: function(cmd, env) return "alacritty -e " .. cmd end + external_terminal_cmd = nil, + }, + }, + + -- Diff Integration + diff_opts = { + auto_close_on_accept = true, + vertical_split = true, + open_in_current_tab = true, + keep_terminal_focus = false, -- If true, moves focus back to terminal after diff opens + }, + }, + keys = { + { 'a', nil, desc = 'AI/Claude Code' }, + { 'ac', 'ClaudeCode', desc = 'Toggle Claude' }, + { 'af', 'ClaudeCodeFocus', desc = 'Focus Claude' }, + { 'ar', 'ClaudeCode --resume', desc = 'Resume Claude' }, + { 'aC', 'ClaudeCode --continue', desc = 'Continue Claude' }, + { 'am', 'ClaudeCodeSelectModel', desc = 'Select Claude model' }, + { 'ab', 'ClaudeCodeAdd %', desc = 'Add current buffer' }, + { 'as', 'ClaudeCodeSend', mode = 'v', desc = 'Send to Claude' }, + { + 'as', + 'ClaudeCodeTreeAdd', + desc = 'Add file', + ft = { 'NvimTree', 'neo-tree', 'oil', 'minifiles', 'netrw' }, + }, + -- Diff management + { 'aa', 'ClaudeCodeDiffAccept', desc = 'Accept diff' }, + { 'ad', 'ClaudeCodeDiffDeny', desc = 'Deny diff' }, + }, +} diff --git a/lua/custom/plugins/copilot.lua b/lua/custom/plugins/copilot.lua new file mode 100644 index 00000000000..39d90bed900 --- /dev/null +++ b/lua/custom/plugins/copilot.lua @@ -0,0 +1,96 @@ +return { + 'zbirenbaum/copilot.lua', + enabled = true, + event = 'InsertEnter', + requires = { + 'copilotlsp/copilot-lsp.nvim', + }, + config = function() + require('copilot').setup { + panel = { + enabled = true, + auto_refresh = true, + keymap = { + jump_prev = '[[', + jump_next = ']]', + accept = '', + refresh = 'gr', + open = '', + }, + layout = { + position = 'right', -- | top | left | right | bottom | + ratio = 0.4, + }, + }, + suggestion = { + enabled = true, + auto_trigger = true, + hide_during_completion = true, + debounce = 100, + trigger_on_accept = false, + keymap = { + accept = '', + accept_word = false, + accept_line = false, + next = '', + prev = '', + dismiss = '', + }, + }, + filetypes = { + yaml = false, + markdown = false, + help = false, + gitcommit = true, + gitrebase = true, + hgcommit = false, + svn = false, + cvs = false, + ['.'] = false, + }, + nes = { + enabled = false, -- requires copilot-lsp as a dependency + auto_trigger = false, + keymap = { + accept_and_goto = false, + accept = false, + dismiss = false, + }, + }, + auth_provider_url = nil, -- URL to authentication provider, if not "https://github.com/" + logger = { + file = vim.fn.stdpath 'log' .. '/copilot-lua.log', + file_log_level = vim.log.levels.OFF, + print_log_level = vim.log.levels.WARN, + trace_lsp = 'off', -- "off" | "messages" | "verbose" + trace_lsp_progress = false, + log_lsp_messages = false, + }, + copilot_node_command = 'node', -- Node.js version must be > 20 + workspace_folders = {}, + copilot_model = '', + root_dir = function() + return vim.fs.dirname(vim.fs.find('.git', { upward = true })[1]) + end, + should_attach = function(_, _) + local logger = require 'copilot.logger' + if not vim.bo.buflisted then + logger.debug "not attaching, buffer is not 'buflisted'" + return false + end + + if vim.bo.buftype ~= '' then + logger.debug("not attaching, buffer 'buftype' is " .. vim.bo.buftype) + return false + end + + return true + end, + server = { + type = 'nodejs', -- "nodejs" | "binary" + custom_server_filepath = nil, + }, + server_opts_overrides = {}, + } + end, +} diff --git a/lua/custom/plugins/d2-vim.lua b/lua/custom/plugins/d2-vim.lua new file mode 100644 index 00000000000..de55aa9cee3 --- /dev/null +++ b/lua/custom/plugins/d2-vim.lua @@ -0,0 +1,22 @@ +return { + 'terrastruct/d2-vim', + enable = true, + event = { 'BufReadPre', 'BufNewFile' }, + ft = { 'd2', 'md', 'mdx', 'txt' }, + config = function() + vim.g.d2_ascii_autorender = 0 + vim.g.d2_ascii_command = 'd2' + vim.g.d2_ascii_preview_width = vim.o.columns / 2 + vim.g.d2_ascii_mode = 'extended' + vim.g.d2_fmt_autosave = 1 + vim.g.d2_fmt_command = 'd2 fmt' + vim.g.d2_fmt_fail_silently = 0 + vim.g.d2_validate_autosave = 0 + vim.g.d2_validate_command = 'd2 validate' + vim.g.d2_list_type = 'quickfix' + vim.g.d2_fail_silently = 0 + vim.g.d2_play_command = 'd2 play' + vim.g.d2_play_theme = 0 + vim.g.d2_play_sketch = 0 + end, +} diff --git a/lua/custom/plugins/github-nvim-theme.lua b/lua/custom/plugins/github-nvim-theme.lua new file mode 100644 index 00000000000..2485f647314 --- /dev/null +++ b/lua/custom/plugins/github-nvim-theme.lua @@ -0,0 +1,54 @@ +return { + 'projekt0n/github-nvim-theme', + name = 'github-theme', + lazy = false, -- make sure we load this during startup if it is your main colorscheme + priority = 1000, -- make sure to load this before all the other start plugins + config = function() + require('github-theme').setup { + options = { + -- Compiled file's destination location + compile_path = vim.fn.stdpath 'cache' .. '/github-theme', + compile_file_suffix = '_compiled', -- Compiled file suffix + hide_end_of_buffer = true, -- Hide the '~' character at the end of the buffer for a cleaner look + hide_nc_statusline = true, -- Override the underline style for non-active statuslines + transparent = false, -- Disable setting bg (make neovim's background transparent) + terminal_colors = true, -- Set terminal colors (vim.g.terminal_color_*) used in `:terminal` + dim_inactive = false, -- Non focused panes set to alternative background + module_default = true, -- Default enable value for modules + styles = { -- Style to be applied to different syntax groups + comments = 'NONE', -- Value is any valid attr-list value `:help attr-list` + functions = 'NONE', + keywords = 'NONE', + variables = 'NONE', + conditionals = 'NONE', + constants = 'NONE', + numbers = 'NONE', + operators = 'NONE', + strings = 'NONE', + types = 'NONE', + }, + inverse = { -- Inverse highlight for different types + match_paren = false, + visual = false, + search = false, + }, + darken = { -- Darken floating windows and sidebar-like windows + floats = true, + sidebars = { + enable = true, + list = {}, -- Apply dark background to specific windows + }, + }, + modules = { -- List of various plugins and additional options + -- ... + }, + }, + palettes = {}, + specs = {}, + groups = {}, + } + + -- -- setup must be called before loading + -- vim.cmd 'colorscheme github_dark' + end, +} diff --git a/lua/custom/plugins/haskell-tools.lua b/lua/custom/plugins/haskell-tools.lua new file mode 100644 index 00000000000..71f23bc16cd --- /dev/null +++ b/lua/custom/plugins/haskell-tools.lua @@ -0,0 +1,6 @@ +return { + 'mrcjkb/haskell-tools.nvim', + version = '^6', -- Recommended + lazy = false, -- This plugin is already lazy + enabled = true, +} diff --git a/lua/custom/plugins/im-select.lua b/lua/custom/plugins/im-select.lua new file mode 100644 index 00000000000..77340a5d126 --- /dev/null +++ b/lua/custom/plugins/im-select.lua @@ -0,0 +1,40 @@ +return { + 'keaising/im-select.nvim', + lazy = false, + config = function() + require('im_select').setup { + -- IM will be set to `default_im_select` in `normal` mode + -- For Windows/WSL, default: "1033", aka: English US Keyboard + -- For macOS, default: "com.apple.keylayout.ABC", aka: US + -- For Linux, default: + -- "keyboard-us" for Fcitx5 + -- "1" for Fcitx + -- "xkb:us::eng" for ibus + -- You can use `im-select` or `fcitx5-remote -n` to get the IM's name + default_im_select = 'com.apple.keylayout.Australian', + + -- Can be binary's name, binary's full path, or a table, e.g. 'im-select', + -- '/usr/local/bin/im-select' for binary without extra arguments, + -- or { "AIMSwitcher.exe", "--imm" } for binary need extra arguments to work. + -- For Windows/WSL, default: "im-select.exe" + -- For macOS, default: "macism" + -- For Linux, default: "fcitx5-remote" or "fcitx-remote" or "ibus" + default_command = 'macism', + + -- Restore the default input method state when the following events are triggered + set_default_events = { 'VimEnter', 'FocusGained', 'InsertLeave', 'CmdlineLeave' }, + + -- Restore the previous used input method state when the following events + -- are triggered, if you don't want to restore previous used im in Insert mode, + -- e.g. deprecated `disable_auto_restore = 1`, just let it empty + -- as `set_previous_events = {}` + set_previous_events = { 'InsertEnter' }, + + -- Show notification about how to install executable binary when binary missed + keep_quiet_on_no_binary = false, + + -- Async run `default_command` to switch IM or not + async_switch_im = true, + } + end, +} diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index b3ddcfdd3aa..5a8e4db3043 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -5,4 +5,124 @@ ---@module 'lazy' ---@type LazySpec + +vim.cmd 'language en_GB.UTF-8' + +vim.opt.encoding = 'utf-8' +vim.opt.fileencoding = 'utf-8' +vim.opt.fileencodings = { 'utf-8' } + +vim.opt.termguicolors = true + +vim.opt.winblend = 0 +vim.opt.pumblend = 0 + +vim.g.background = 'dark' + +vim.opt.wrap = true + +vim.diagnostic.config { + update_in_insert = true, + underline = false, +} + +vim.cmd 'filetype plugin on' + +-- NOTE: keymaps +local map = vim.keymap.set +local opts = { noremap = true, silent = true } + +-- basic function +map('n', ';', ':', { desc = '' }) +-- buffer control +map('n', '', 'bnext', { desc = 'Next buffer' }) +map('n', 'x', function() + local cur_win = vim.api.nvim_get_current_win() + local cur_buf = vim.api.nvim_get_current_buf() + local cur_ft = vim.bo[cur_buf].filetype + + local wins = vim.api.nvim_tabpage_list_wins(0) + local non_float = {} + for _, win in ipairs(wins) do + if vim.api.nvim_win_get_config(win).relative == '' then + non_float[#non_float + 1] = win + end + end + + local function is_neotree_win(win) + local buf = vim.api.nvim_win_get_buf(win) + return vim.bo[buf].filetype == 'neo-tree' + end + + if cur_ft == 'neo-tree' then + if #non_float <= 1 then + vim.cmd 'enew' + return + end + vim.api.nvim_win_close(cur_win, true) + return + end + + if #non_float == 2 then + local other = non_float[1] == cur_win and non_float[2] or non_float[1] + if is_neotree_win(other) then + vim.api.nvim_win_close(other, true) + end + end + + vim.cmd 'bdelete' +end, { desc = 'Delete buffer' }) + +-- telescope +map('n', 'tc', 'Telescope colorscheme', { desc = '[T]elescope [C]olorscheme' }) + +-- toggleterm +map('n', 'H', 'ToggleTerm size=16 direction=horizontal', { desc = 'Open Terminal Horizontal' }) +-- map('t', 'H', 'ToggleTerm size=20 direction=horizontal', { desc = 'Open Terminal Horizontal' }) +map('n', 'V', 'ToggleTerm size=80 direction=vertical', { desc = 'Open Terminal Vertical' }) +-- map('t', 'V', 'ToggleTerm size=80 direction=vertical', { desc = 'Open Terminal Vertical' }) +map('n', '', 'ToggleTerm direction=float', { desc = 'Open Terminal floating' }) +map('t', '', 'ToggleTerm direction=float', { desc = 'Open Terminal floating' }) + +-- NOTE: macos like keybindings for text editing in insert mode + +-- map('i', '', '^', opts) +-- map('i', '', '$', opts) +-- map('i', '', 'D', opts) +-- map('i', '', 'd0', opts) +-- map('i', '', '', opts) +-- map('i', '', '', opts) +-- map('i', '', '', opts) +-- map('i', '', '', opts) +-- map('i', '', '', opts) +-- map('i', '', '', opts) + +-- NOTE: keymaps end + +-- NOTE: neovide +local function set_ime(args) + if args.event:match 'Enter$' then + vim.g.neovide_input_ime = true + else + vim.g.neovide_input_ime = false + end +end + +local ime_input = vim.api.nvim_create_augroup('ime_input', { clear = true }) + +vim.api.nvim_create_autocmd({ 'InsertEnter', 'InsertLeave' }, { + group = ime_input, + pattern = '*', + callback = set_ime, +}) + +vim.api.nvim_create_autocmd({ 'CmdlineEnter', 'CmdlineLeave' }, { + group = ime_input, + pattern = '[/\\?]', + callback = set_ime, +}) + +vim.g.neovide_cursor_animation_length = 0.1 +-- NOTE: neovide end + return {} diff --git a/lua/custom/plugins/lean.lua b/lua/custom/plugins/lean.lua new file mode 100644 index 00000000000..ebbe3cb4653 --- /dev/null +++ b/lua/custom/plugins/lean.lua @@ -0,0 +1,24 @@ +return { + 'Julian/lean.nvim', + event = { 'BufReadPre *.lean', 'BufNewFile *.lean' }, + + dependencies = { + 'neovim/nvim-lspconfig', + 'nvim-lua/plenary.nvim', + + -- optional dependencies: + + -- a completion engine + -- hrsh7th/nvim-cmp or Saghen/blink.cmp are popular choices + + 'nvim-telescope/telescope.nvim', -- for 2 Lean-specific pickers + 'andymass/vim-matchup', -- for enhanced % motion behavior + 'andrewradev/switch.vim', -- for switch support + 'tomtom/tcomment_vim', -- for commenting + }, + + ---@type lean.Config + opts = { -- see below for full configuration options + mappings = true, + }, +} diff --git a/lua/custom/plugins/mcp-hub.lua b/lua/custom/plugins/mcp-hub.lua new file mode 100644 index 00000000000..c254a75fd8c --- /dev/null +++ b/lua/custom/plugins/mcp-hub.lua @@ -0,0 +1,92 @@ +return { + 'ravitemer/mcphub.nvim', + dependencies = { + 'nvim-lua/plenary.nvim', + }, + build = 'bundled_build.lua', + config = function() + require('mcphub').setup { + --- `mcp-hub` binary related options------------------- + config = vim.fn.expand '~/.config/mcphub/servers.json', -- Absolute path to MCP Servers config file (will create if not exists) + port = 37373, -- The port `mcp-hub` server listens to + shutdown_delay = 5 * 60 * 000, -- Delay in ms before shutting down the server when last instance closes (default: 5 minutes) + use_bundled_binary = true, -- Use local `mcp-hub` binary (set this to true when using build = "bundled_build.lua") + mcp_request_timeout = 60000, --Max time allowed for a MCP tool or resource to execute in milliseconds, set longer for long running tasks + global_env = {}, -- Global environment variables available to all MCP servers (can be a table or a function returning a table) + workspace = { + enabled = true, -- Enable project-local configuration files + look_for = { '.mcphub/servers.json', '.vscode/mcp.json', '.cursor/mcp.json' }, -- Files to look for when detecting project boundaries (VS Code format supported) + reload_on_dir_changed = true, -- Automatically switch hubs on DirChanged event + port_range = { min = 40000, max = 41000 }, -- Port range for generating unique workspace ports + get_port = nil, -- Optional function returning custom port number. Called when generating ports to allow custom port assignment logic + }, + + ---Chat-plugin related options----------------- + auto_approve = false, -- Auto approve mcp tool calls + auto_toggle_mcp_servers = true, -- Let LLMs start and stop MCP servers automatically + extensions = { + avante = { + make_slash_commands = true, -- make /slash commands from MCP server prompts + }, + copilotchat = { + enabled = true, + convert_tools_to_functions = true, -- Convert MCP tools to CopilotChat functions + convert_resources_to_functions = true, -- Convert MCP resources to CopilotChat functions + add_mcp_prefix = false, -- Add "mcp_" prefix to function names + }, + }, + + --- Plugin specific options------------------- + native_servers = {}, -- add your custom lua native servers here + builtin_tools = { + edit_file = { + parser = { + track_issues = true, + extract_inline_content = true, + }, + locator = { + fuzzy_threshold = 0.8, + enable_fuzzy_matching = true, + }, + ui = { + go_to_origin_on_complete = true, + keybindings = { + accept = '.', + reject = ',', + next = 'n', + prev = 'p', + accept_all = 'ga', + reject_all = 'gr', + }, + }, + }, + }, + ui = { + window = { + width = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) + height = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) + align = 'center', -- "center", "top-left", "top-right", "bottom-left", "bottom-right", "top", "bottom", "left", "right" + relative = 'editor', + zindex = 50, + border = 'rounded', -- "none", "single", "double", "rounded", "solid", "shadow" + }, + wo = { -- window-scoped options (vim.wo) + winhl = 'Normal:MCPHubNormal,FloatBorder:MCPHubBorder', + }, + }, + json_decode = nil, -- Custom JSON parser function (e.g., require('json5').parse for JSON5 support) + on_ready = function(hub) + -- Called when hub is ready + end, + on_error = function(err) + -- Called on errors + end, + log = { + level = vim.log.levels.WARN, + to_file = false, + file_path = nil, + prefix = 'MCPHub', + }, + } + end, +} diff --git a/lua/custom/plugins/nerdy.lua b/lua/custom/plugins/nerdy.lua new file mode 100644 index 00000000000..4e43753063e --- /dev/null +++ b/lua/custom/plugins/nerdy.lua @@ -0,0 +1,13 @@ +return { + '2kabhishek/nerdy.nvim', + dependencies = { + 'folke/snacks.nvim', + }, + cmd = 'Nerdy', + opts = { + max_recents = 30, -- Configure recent icons limit + add_default_keybindings = true, -- Add default keybindings + copy_to_clipboard = false, -- Copy glyph to clipboard instead of inserting + copy_register = '+', -- Register to use for copying (if `copy_to_clipboard` is true) + }, +} diff --git a/lua/custom/plugins/nightfox.lua b/lua/custom/plugins/nightfox.lua new file mode 100644 index 00000000000..edefa260183 --- /dev/null +++ b/lua/custom/plugins/nightfox.lua @@ -0,0 +1,53 @@ +return { + 'EdenEast/nightfox.nvim', + lazy = false, + priority = 1000, + config = function() + require('nightfox').setup { + options = { + -- Compiled file's destination location + compile_path = vim.fn.stdpath 'cache' .. '/nightfox', + compile_file_suffix = '_compiled', -- Compiled file suffix + transparent = true, -- Disable setting background + terminal_colors = true, -- Set terminal colors (vim.g.terminal_color_*) used in `:terminal` + dim_inactive = false, -- Non focused panes set to alternative background + module_default = true, -- Default enable value for modules + colorblind = { + enable = false, -- Enable colorblind support + simulate_only = false, -- Only show simulated colorblind colors and not diff shifted + severity = { + protan = 0, -- Severity [0,1] for protan (red) + deutan = 0, -- Severity [0,1] for deutan (green) + tritan = 0, -- Severity [0,1] for tritan (blue) + }, + }, + styles = { -- Style to be applied to different syntax groups + comments = 'NONE', -- Value is any valid attr-list value `:help attr-list` + conditionals = 'NONE', + constants = 'NONE', + functions = 'NONE', + keywords = 'NONE', + numbers = 'NONE', + operators = 'NONE', + strings = 'NONE', + types = 'NONE', + variables = 'NONE', + }, + inverse = { -- Inverse highlight for different types + match_paren = false, + visual = false, + search = false, + }, + modules = { -- List of various plugins and additional options + -- ... + }, + }, + palettes = {}, + specs = {}, + groups = {}, + } + + -- setup must be called before loading + -- vim.cmd 'colorscheme dayfox' + end, +} diff --git a/lua/custom/plugins/nvim-autopairs.lua b/lua/custom/plugins/nvim-autopairs.lua new file mode 100644 index 00000000000..395463473e3 --- /dev/null +++ b/lua/custom/plugins/nvim-autopairs.lua @@ -0,0 +1,28 @@ +return { + 'windwp/nvim-autopairs', + event = 'InsertEnter', + config = true, + -- use opts = {} for passing setup options + -- this is equivalent to setup({}) function + opts = { + enabled = function(bufnr) + return true + end, -- control if auto-pairs should be enabled when attaching to a buffer + disable_filetype = { 'TelescopePrompt', 'spectre_panel', 'snacks_picker_input' }, + disable_in_macro = true, -- disable when recording or executing a macro + disable_in_visualblock = false, -- disable when insert after visual block mode + disable_in_replace_mode = true, + ignored_next_char = [=[[%w%%%'%[%"%.%`%$]]=], + enable_moveright = true, + enable_afterquote = true, -- add bracket pairs after quote + enable_check_bracket_line = true, --- check bracket in same line + enable_bracket_in_quote = true, -- + enable_abbr = false, -- trigger abbreviation + break_undo = true, -- switch for basic rule break undo sequence + check_ts = false, + map_cr = true, + map_bs = true, -- map the key + map_c_h = false, -- Map the key to delete a pair + map_c_w = false, -- map to delete a pair if possible + }, +} diff --git a/lua/custom/plugins/opencode.lua b/lua/custom/plugins/opencode.lua new file mode 100644 index 00000000000..d55cf2c90d3 --- /dev/null +++ b/lua/custom/plugins/opencode.lua @@ -0,0 +1,47 @@ +return { + 'NickvanDyke/opencode.nvim', + dependencies = { + -- Recommended for `ask()` and `select()`. + -- Required for `snacks` provider. + ---@module 'snacks' <- Loads `snacks.nvim` types for configuration intellisense. + { 'folke/snacks.nvim', opts = { input = {}, picker = {}, terminal = {} } }, + }, + config = function() + ---@type opencode.Opts + vim.g.opencode_opts = { + -- Your configuration, if any — see `lua/opencode/config.lua`, or "goto definition" on the type or field. + } + + -- Required for `opts.events.reload`. + vim.o.autoread = true + + -- Recommended/example keymaps. + vim.keymap.set({ 'n', 'x' }, '', function() + require('opencode').ask('@this: ', { submit = true }) + end, { desc = 'Ask opencode…' }) + vim.keymap.set({ 'n', 'x' }, '', function() + require('opencode').select() + end, { desc = 'Execute opencode action…' }) + vim.keymap.set({ 'n', 't' }, '', function() + require('opencode').toggle() + end, { desc = 'Toggle opencode' }) + + vim.keymap.set({ 'n', 'x' }, 'go', function() + return require('opencode').operator '@this ' + end, { desc = 'Add range to opencode', expr = true }) + vim.keymap.set('n', 'goo', function() + return require('opencode').operator '@this ' .. '_' + end, { desc = 'Add line to opencode', expr = true }) + + vim.keymap.set('n', '', function() + require('opencode').command 'session.half.page.up' + end, { desc = 'Scroll opencode up' }) + vim.keymap.set('n', '', function() + require('opencode').command 'session.half.page.down' + end, { desc = 'Scroll opencode down' }) + + -- You may want these if you stick with the opinionated "" and "" above — otherwise consider "o…". + vim.keymap.set('n', '+', '', { desc = 'Increment under cursor', noremap = true }) + vim.keymap.set('n', '-', '', { desc = 'Decrement under cursor', noremap = true }) + end, +} diff --git a/lua/custom/plugins/peek.lua b/lua/custom/plugins/peek.lua new file mode 100644 index 00000000000..c21ed5b2721 --- /dev/null +++ b/lua/custom/plugins/peek.lua @@ -0,0 +1,31 @@ +return { + 'toppair/peek.nvim', + event = { 'VeryLazy' }, + build = 'deno task --quiet build:fast', + config = function() + require('peek').setup { + auto_load = true, -- whether to automatically load preview when + -- entering another markdown buffer + close_on_bdelete = true, -- close preview window on buffer delete + + syntax = true, -- enable syntax highlighting, affects performance + + theme = 'light', -- 'dark' or 'light' + + update_on_change = true, + + app = 'webview', -- 'webview', 'browser', string or a table of strings + -- explained below + + filetype = { 'markdown' }, -- list of filetypes to recognize as markdown + + -- relevant if update_on_change is true + throttle_at = 200000, -- start throttling when file exceeds this + -- amount of bytes in size + throttle_time = 'auto', -- minimum amount of time in milliseconds + -- that has to pass before starting new render + } + vim.api.nvim_create_user_command('PeekOpen', require('peek').open, {}) + vim.api.nvim_create_user_command('PeekClose', require('peek').close, {}) + end, +} diff --git a/lua/custom/plugins/render-markdown.lua b/lua/custom/plugins/render-markdown.lua new file mode 100644 index 00000000000..7139a38b6d2 --- /dev/null +++ b/lua/custom/plugins/render-markdown.lua @@ -0,0 +1,53 @@ +return { + 'MeanderingProgrammer/render-markdown.nvim', + dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-mini/mini.nvim' }, -- if you use the mini.nvim suite + -- dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-mini/mini.icons' }, -- if you use standalone mini plugins + -- dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' }, -- if you prefer nvim-web-devicons + ---@module 'render-markdown' + ---@type render.md.UserConfig + opts = { + checkbox = { + enabled = true, + render_modes = false, + bullet = false, + left_pad = 0, + right_pad = 1, + unchecked = { + icon = '󰄱 ', + highlight = 'RenderMarkdownUnchecked', + scope_highlight = nil, + }, + checked = { + icon = '󰱒 ', + highlight = 'RenderMarkdownChecked', + scope_highlight = nil, + }, + custom = { + doing = { raw = '[d]', rendered = ' ', highlight = 'RenderMarkdownTodo', scope_highlight = nil }, + pending = { raw = '[p]', rendered = '󰥔 ', highlight = 'RenderMarkdownTodo', scope_highlight = nil }, + asking = { raw = '[a]', rendered = '󱜺 ', highlight = 'RenderMarkDownTodo', scope_highlight = nil }, + }, + scope_priority = nil, + }, + }, + html = { + -- Turn on / off all HTML rendering. + enabled = true, + -- Additional modes to render HTML. + render_modes = false, + comment = { + -- Turn on / off HTML comment concealing. + conceal = false, + -- Optional text to inline before the concealed comment. + text = nil, + -- Highlight for the inlined text. + highlight = 'RenderMarkdownHtmlComment', + }, + -- HTML tags whose start and end will be hidden and icon shown. + -- The key is matched against the tag name, value type below. + -- | icon | optional icon inlined at start of tag | + -- | highlight | optional highlight for the icon | + -- | scope_highlight | optional highlight for item associated with tag | + tag = {}, + }, +} diff --git a/lua/custom/plugins/rose-pine.lua b/lua/custom/plugins/rose-pine.lua new file mode 100644 index 00000000000..27cfd345b51 --- /dev/null +++ b/lua/custom/plugins/rose-pine.lua @@ -0,0 +1,92 @@ +-- lua/plugins/rose-pine.lua +return { + 'rose-pine/neovim', + lazy = false, + priority = 1000, + name = 'rose-pine', + config = function() + require('rose-pine').setup { + variant = 'auto', -- auto, main, moon, or dawn + dark_variant = 'main', -- main, moon, or dawn + dim_inactive_windows = false, + extend_background_behind_borders = true, + + enable = { + terminal = true, + legacy_highlights = true, -- Improve compatibility for previous versions of Neovim + migrations = true, -- Handle deprecated options automatically + }, + + styles = { + bold = true, + italic = true, + transparency = false, + }, + + groups = { + border = 'muted', + link = 'iris', + panel = 'surface', + + error = 'love', + hint = 'iris', + info = 'foam', + note = 'pine', + todo = 'rose', + warn = 'gold', + + git_add = 'foam', + git_change = 'rose', + git_delete = 'love', + git_dirty = 'rose', + git_ignore = 'muted', + git_merge = 'iris', + git_rename = 'pine', + git_stage = 'iris', + git_text = 'rose', + git_untracked = 'subtle', + + h1 = 'iris', + h2 = 'foam', + h3 = 'rose', + h4 = 'gold', + h5 = 'pine', + h6 = 'foam', + }, + + palette = { + -- Override the builtin palette per variant + -- moon = { + -- base = '#18191a', + -- overlay = '#363738', + -- }, + }, + + -- NOTE: Highlight groups are extended (merged) by default. Disable this + -- per group via `inherit = false` + highlight_groups = { + -- Comment = { fg = "foam" }, + -- StatusLine = { fg = "love", bg = "love", blend = 15 }, + -- VertSplit = { fg = "muted", bg = "muted" }, + -- Visual = { fg = "base", bg = "text", inherit = false }, + }, + + before_highlight = function(group, highlight, palette) + -- Disable all undercurls + -- if highlight.undercurl then + -- highlight.undercurl = false + -- end + -- + -- Change palette colour + -- if highlight.fg == palette.pine then + -- highlight.fg = palette.foam + -- end + end, + } + + -- vim.cmd 'colorscheme rose-pine' + -- vim.cmd("colorscheme rose-pine-main") + -- vim.cmd("colorscheme rose-pine-moon") + -- vim.cmd("colorscheme rose-pine-dawn") + end, +} diff --git a/lua/custom/plugins/rustaceanvim.lua b/lua/custom/plugins/rustaceanvim.lua new file mode 100644 index 00000000000..eb83332c81d --- /dev/null +++ b/lua/custom/plugins/rustaceanvim.lua @@ -0,0 +1,5 @@ +return { + 'mrcjkb/rustaceanvim', + version = '^6', -- Recommended + lazy = false, -- This plugin is already lazy +} diff --git a/lua/custom/plugins/snacks.lua b/lua/custom/plugins/snacks.lua new file mode 100644 index 00000000000..127b322012b --- /dev/null +++ b/lua/custom/plugins/snacks.lua @@ -0,0 +1,206 @@ +local function titleize(action) + if type(action) ~= 'string' then + return nil + end + if action == '' then + return nil + end + local out = action:gsub('_', ' ') + return out:sub(1, 1):upper() .. out:sub(2) +end + +local function action_desc(action) + if type(action) == 'string' then + return titleize(action) + end + if type(action) == 'function' then + return 'Custom action' + end + if type(action) ~= 'table' then + return nil + end + + if action.desc then + return action.desc + end + + if action.action then + return action_desc(action.action) + end + + local is_list = vim.islist or vim.tbl_islist + if is_list and is_list(action) then + local parts = {} + for _, item in ipairs(action) do + local desc = action_desc(item) + if desc then + parts[#parts + 1] = desc + end + end + if #parts > 0 then + return table.concat(parts, ', ') + end + end + + return nil +end + +local function add_desc_to_picker_keys(opts) + local function apply(keys) + if not keys then + return + end + for _, spec in pairs(keys) do + if type(spec) == 'table' and spec.desc == nil then + local action = spec[1] or spec[2] + local desc = action_desc(action) + if desc then + spec.desc = desc + end + end + end + end + + for _, win in pairs(opts.win or {}) do + apply(win.keys) + end + for _, source in pairs(opts.sources or {}) do + if type(source) == 'table' and source.win then + for _, win in pairs(source.win) do + apply(win.keys) + end + end + end +end + +local function ensure_dashboard_desc_keymaps() + if vim.g.snacks_dashboard_desc_keymaps then + return + end + vim.g.snacks_dashboard_desc_keymaps = true + + local group = vim.api.nvim_create_augroup('snacks_dashboard_desc', { clear = true }) + vim.api.nvim_create_autocmd('FileType', { + group = group, + pattern = 'snacks_dashboard', + callback = function(ev) + vim.keymap.set('n', 'q', 'bd', { buffer = ev.buf, silent = true, desc = 'Close dashboard' }) + local cfg = vim.api.nvim_win_get_config(0) + if cfg and cfg.relative ~= '' then + vim.keymap.set('n', '', 'bd', { buffer = ev.buf, silent = true, desc = 'Close dashboard' }) + end + end, + }) +end + +return { + 'folke/snacks.nvim', + priority = 1000, + lazy = false, + ---@type snacks.Config + opts = { + -- your configuration comes here + -- or leave it empty to use the default settings + -- refer to the configuration section below + bigfile = { enabled = true }, + dashboard = { + enabled = true, + config = function() + ensure_dashboard_desc_keymaps() + end, + }, + explorer = { enabled = true }, + indent = { enabled = true }, + input = { enabled = true }, + picker = { + enabled = true, + config = function(opts) + add_desc_to_picker_keys(opts) + end, + }, + notifier = { + enabled = true, + top_down = false, + }, + quickfile = { enabled = true }, + scope = { enabled = true }, + scroll = { enabled = false }, + statuscolumn = { enabled = false }, + words = { enabled = true }, + + styles = { + input = { + keys = { + n_esc = { + '', + { 'cmp_close', 'cancel' }, + mode = 'n', + expr = true, + desc = 'Cancel input', + }, + i_esc = { + '', + { 'cmp_close', 'stopinsert' }, + mode = 'i', + expr = true, + desc = 'Cancel input', + }, + i_cr = { + '', + { 'cmp_accept', 'confirm' }, + mode = { 'i', 'n' }, + expr = true, + desc = 'Confirm input', + }, + i_tab = { + '', + { 'cmp_select_next', 'cmp' }, + mode = 'i', + expr = true, + desc = 'Next completion', + }, + i_ctrl_w = { + '', + '', + mode = 'i', + expr = true, + desc = 'Delete word', + }, + i_up = { + '', + { 'hist_up' }, + mode = { 'i', 'n' }, + desc = 'History up', + }, + i_down = { + '', + { 'hist_down' }, + mode = { 'i', 'n' }, + desc = 'History down', + }, + q = { 'q', 'cancel', desc = 'Cancel input' }, + }, + }, + terminal = { + keys = { + q = { 'q', 'hide', desc = 'Hide terminal' }, + gf = { + 'gf', + function(self) + local f = vim.fn.findfile(vim.fn.expand '', '**') + if f == '' then + Snacks.notify.warn 'No file under cursor' + else + self:hide() + vim.schedule(function() + vim.cmd('e ' .. f) + end) + end + end, + desc = 'Open file under cursor', + }, + }, + }, + }, + }, +} diff --git a/lua/custom/plugins/tiny-inline-diagnostic.lua b/lua/custom/plugins/tiny-inline-diagnostic.lua new file mode 100644 index 00000000000..6ee610ea553 --- /dev/null +++ b/lua/custom/plugins/tiny-inline-diagnostic.lua @@ -0,0 +1,138 @@ +return { + 'rachartier/tiny-inline-diagnostic.nvim', + event = 'VeryLazy', -- `LspAttach`,`VeryLazy` + priority = 1000, -- needs to be loaded in first + config = function() + require('tiny-inline-diagnostic').setup { + -- Style preset for diagnostic messages + -- Available options: + -- "modern", "classic", "minimal", "powerline", + -- "ghost", "simple", "nonerdfont", "amongus" + preset = 'modern', + + transparent_bg = true, -- Set the background of the diagnostic to transparent + + hi = { + error = 'DiagnosticError', -- Highlight group for error messages + warn = 'DiagnosticWarn', -- Highlight group for warning messages + info = 'DiagnosticInfo', -- Highlight group for informational messages + hint = 'DiagnosticHint', -- Highlight group for hint or suggestion messages + arrow = 'NonText', -- Highlight group for diagnostic arrows + + -- Background color for diagnostics + -- Can be a highlight group or a hexadecimal color (#RRGGBB) + background = 'CursorLine', + + -- Color blending option for the diagnostic background + -- Use "None" or a hexadecimal color (#RRGGBB) to blend with another color + mixing_color = 'None', + }, + + options = { + -- Display the source of the diagnostic (e.g., basedpyright, vsserver, lua_ls etc.) + show_source = true, + + -- Use icons defined in the diagnostic configuration + use_icons_from_diagnostic = true, + + -- Set the arrow icon to the same color as the first diagnostic severity + set_arrow_to_diag_color = false, + + -- Add messages to diagnostics when multiline diagnostics are enabled + -- If set to false, only signs will be displayed + add_messages = true, + + -- Time (in milliseconds) to throttle updates while moving the cursor + -- Increase this value for better performance if your computer is slow + -- or set to 0 for immediate updates and better visual + throttle = 20, + + -- Minimum message length before wrapping to a new line + softwrap = 30, + + -- Configuration for multiline diagnostics + -- Can either be a boolean or a table with the following options: + -- multilines = { + -- enabled = false, + -- always_show = false, + -- } + -- If it set as true, it will enable the feature with this options: + -- multilines = { + -- enabled = true, + -- always_show = false, + -- } + multilines = { + -- Enable multiline diagnostic messages + enabled = true, + + -- Always show messages on all lines for multiline diagnostics + always_show = true, + }, + + -- Display all diagnostic messages on the cursor line + show_all_diags_on_cursorline = true, + + -- Enable diagnostics in Insert mode + -- If enabled, it is better to set the `throttle` option to 0 to avoid visual artifacts + enable_on_insert = true, + + -- Enable diagnostics in Select mode (e.g when auto inserting with Blink) + enable_on_select = true, + + overflow = { + -- Manage how diagnostic messages handle overflow + -- Options: + -- "wrap" - Split long messages into multiple lines + -- "none" - Do not truncate messages + -- "oneline" - Keep the message on a single line, even if it's long + mode = 'wrap', + + -- Trigger wrapping to occur this many characters earlier when mode == "wrap". + -- Increase this value appropriately if you notice that the last few characters + -- of wrapped diagnostics are sometimes obscured. + padding = 0, + }, + + -- Configuration for breaking long messages into separate lines + break_line = { + -- Enable the feature to break messages after a specific length + enabled = true, + + -- Number of characters after which to break the line + after = 30, + }, + + -- Custom format function for diagnostic messages + -- Example: + -- format = function(diagnostic) + -- return diagnostic.message .. " [" .. diagnostic.source .. "]" + -- end + format = nil, + + virt_texts = { + -- Priority for virtual text display + priority = 2048, + }, + + -- Filter diagnostics by severity + -- Available severities: + -- vim.diagnostic.severity.ERROR + -- vim.diagnostic.severity.WARN + -- vim.diagnostic.severity.INFO + -- vim.diagnostic.severity.HINT + severity = { + vim.diagnostic.severity.ERROR, + vim.diagnostic.severity.WARN, + vim.diagnostic.severity.INFO, + vim.diagnostic.severity.HINT, + }, + + -- Events to attach diagnostics to buffers + -- You should not change this unless the plugin does not work with your configuration + overwrite_events = nil, + }, + disabled_ft = {}, -- List of filetypes to disable the plugin + } + vim.diagnostic.config { virtual_text = false } -- Only if needed in your configuration, if you already have native LSP diagnostics + end, +} diff --git a/lua/custom/plugins/toggleterm.lua b/lua/custom/plugins/toggleterm.lua new file mode 100644 index 00000000000..c14cedb55b4 --- /dev/null +++ b/lua/custom/plugins/toggleterm.lua @@ -0,0 +1,6 @@ +return { + 'akinsho/toggleterm.nvim', + version = '*', + config = true, + opts = {}, +} diff --git a/lua/custom/plugins/tree-sitter-d2.lua b/lua/custom/plugins/tree-sitter-d2.lua new file mode 100644 index 00000000000..c7ea87b7457 --- /dev/null +++ b/lua/custom/plugins/tree-sitter-d2.lua @@ -0,0 +1,9 @@ +return { + 'ravsii/tree-sitter-d2', + lazy = 'VeryLazy', + enable = true, + ft = { 'd2', 'md' }, + version = '*', + dependencies = { 'nvim-treesitter/nvim-treesitter' }, + build = 'make nvim-install', +} diff --git a/lua/custom/plugins/typescript-tools.lua b/lua/custom/plugins/typescript-tools.lua new file mode 100644 index 00000000000..ba7fb2046e7 --- /dev/null +++ b/lua/custom/plugins/typescript-tools.lua @@ -0,0 +1,5 @@ +return { + 'pmizio/typescript-tools.nvim', + dependencies = { 'nvim-lua/plenary.nvim', 'neovim/nvim-lspconfig' }, + opts = {}, +} diff --git a/lua/custom/plugins/typst-preview.lua b/lua/custom/plugins/typst-preview.lua new file mode 100644 index 00000000000..767d724e09b --- /dev/null +++ b/lua/custom/plugins/typst-preview.lua @@ -0,0 +1,7 @@ +return { + 'chomosuke/typst-preview.nvim', + lazy = false, -- or ft = 'typst' + ft = 'typst', + version = '1.*', + opts = {}, -- lazy.nvim will implicitly calls `setup {}` +} diff --git a/lua/custom/plugins/typst.lua b/lua/custom/plugins/typst.lua new file mode 100644 index 00000000000..5677bbb62c7 --- /dev/null +++ b/lua/custom/plugins/typst.lua @@ -0,0 +1,8 @@ +return { + 'kaarmu/typst.vim', + ft = 'typst', + lazy = false, + config = function() + vim.g.typst_pdf_viewer = 'skim' + end, +} diff --git a/lua/custom/plugins/zk-nvim.lua b/lua/custom/plugins/zk-nvim.lua new file mode 100644 index 00000000000..c5b086e785b --- /dev/null +++ b/lua/custom/plugins/zk-nvim.lua @@ -0,0 +1,30 @@ +return { + 'zk-org/zk-nvim', + config = function() + require('zk').setup { + -- Can be "telescope", "fzf", "fzf_lua", "minipick", "snacks_picker", + -- or select" (`vim.ui.select`). + picker = 'select', + + highlight = { + additional_vim_regex_highlighting = true, + }, + + lsp = { + -- `config` is passed to `vim.lsp.start(config)` + config = { + name = 'zk', + cmd = { 'zk', 'lsp' }, + filetypes = { 'markdown' }, + -- on_attach = ... + -- etc, see `:h vim.lsp.start()` + }, + + -- automatically attach buffers in a zk notebook that match the given filetypes + auto_attach = { + enabled = true, + }, + }, + } + end, +} diff --git a/lua/kickstart/plugins/lint.lua b/lua/kickstart/plugins/lint.lua index 326fc3f6a3a..5c40ee9f481 100644 --- a/lua/kickstart/plugins/lint.lua +++ b/lua/kickstart/plugins/lint.lua @@ -1,15 +1,26 @@ -- Linting - ---@module 'lazy' ---@type LazySpec -return { - 'mfussenegger/nvim-lint', - event = { 'BufReadPre', 'BufNewFile' }, - config = function() - local lint = require 'lint' - lint.linters_by_ft = { - markdown = { 'markdownlint' }, - } + { -- Linting + 'mfussenegger/nvim-lint', + event = { 'BufReadPre', 'BufNewFile' }, + config = function() + local lint = require 'lint' + lint.linters_by_ft = { + markdown = { 'markdownlint' }, + mdx = { 'markdownlint' }, + haskell = { 'hlint' }, + typ = { 'tinymist' }, + } + local markdownlint = require 'lint.linters.markdownlint' + markdownlint.args = { + '--disable', + 'MD013', -- Line length + 'MD024', -- Multiple headers with the same content + 'MD025', -- Multiple top level headers in the same document + 'MD033', -- Inline HTML + -- 'MD041', -- First line in file should be a top level header + } -- To allow other plugins to add linters to require('lint').linters_by_ft, -- instead set linters_by_ft like this: diff --git a/lua/kickstart/plugins/neo-tree.lua b/lua/kickstart/plugins/neo-tree.lua index af8d4495650..732680adc20 100644 --- a/lua/kickstart/plugins/neo-tree.lua +++ b/lua/kickstart/plugins/neo-tree.lua @@ -20,10 +20,281 @@ return { opts = { filesystem = { window = { + position = 'left', + width = 40, + mapping_options = { + noremap = true, + nowait = true, + }, mappings = { - ['\\'] = 'close_window', + [''] = { + 'toggle_node', + nowait = false, -- disable `nowait` if you have existing combos starting with this char that you want to use + }, + ['<2-LeftMouse>'] = 'open', + [''] = 'open', + [''] = 'cancel', -- close preview or floating neo-tree window + ['P'] = { + 'toggle_preview', + config = { + use_float = true, + use_snacks_image = true, + use_image_nvim = true, + }, + }, + -- Read `# Preview Mode` for more information + ['l'] = 'focus_preview', + ['S'] = 'open_split', + ['s'] = 'open_vsplit', + -- ["S"] = "split_with_window_picker", + -- ["s"] = "vsplit_with_window_picker", + ['t'] = 'open_tabnew', + -- [""] = "open_drop", + -- ["t"] = "open_tab_drop", + ['w'] = 'open_with_window_picker', + --["P"] = "toggle_preview", -- enter preview mode, which shows the current node without focusing + ['C'] = 'close_node', + -- ['C'] = 'close_all_subnodes', + ['z'] = 'close_all_nodes', + --["Z"] = "expand_all_nodes", + --["Z"] = "expand_all_subnodes", + ['a'] = { + 'add', + -- this command supports BASH style brace expansion ("x{a,b,c}" -> xa,xb,xc). see `:h neo-tree-file-actions` for details + -- some commands may take optional config options, see `:h neo-tree-mappings` for details + config = { + show_path = 'none', -- "none", "relative", "absolute" + }, + }, + ['A'] = 'add_directory', -- also accepts the optional config.show_path option like "add". this also supports BASH style brace expansion. + ['d'] = 'delete', + ['r'] = 'rename', + ['b'] = 'rename_basename', + ['y'] = 'copy_to_clipboard', + ['x'] = 'cut_to_clipboard', + ['p'] = 'paste_from_clipboard', + [''] = 'clear_clipboard', + ['c'] = 'copy', -- takes text input for destination, also accepts the optional config.show_path option like "add": + -- ["c"] = { + -- "copy", + -- config = { + -- show_path = "none" -- "none", "relative", "absolute" + -- } + --} + ['m'] = 'move', -- takes text input for destination, also accepts the optional config.show_path option like "add". + ['q'] = 'close_window', + ['R'] = 'refresh', + ['?'] = 'show_help', + ['<'] = 'prev_source', + ['>'] = 'next_source', + ['i'] = 'show_file_details', + -- ["i"] = { + -- "show_file_details", + -- -- format strings of the timestamps shown for date created and last modified (see `:h os.date()`) + -- -- both options accept a string or a function that takes in the date in seconds and returns a string to display + -- -- config = { + -- -- created_format = "%Y-%m-%d %I:%M %p", + -- -- modified_format = "relative", -- equivalent to the line below + -- -- modified_format = function(seconds) return require('neo-tree.utils').relative_date(seconds) end + -- -- } + -- }, }, }, + nesting_rules = {}, + filesystem = { + filtered_items = { + visible = false, -- when true, they will just be displayed differently than normal items + hide_dotfiles = true, + hide_gitignored = true, + hide_ignored = true, -- hide files that are ignored by other gitignore-like files + -- other gitignore-like files, in descending order of precedence. + ignore_files = { + '.neotreeignore', + '.ignore', + -- ".rgignore" + }, + hide_hidden = true, -- only works on Windows for hidden files/directories + hide_by_name = { + --"node_modules" + }, + hide_by_pattern = { -- uses glob style patterns + --"*.meta", + --"*/src/*/tsconfig.json", + }, + always_show = { -- remains visible even if other settings would normally hide it + --".gitignored", + }, + always_show_by_pattern = { -- uses glob style patterns + --".env*", + }, + never_show = { -- remains hidden even if visible is toggled to true, this overrides always_show + --".DS_Store", + --"thumbs.db" + }, + never_show_by_pattern = { -- uses glob style patterns + --".null-ls_*", + }, + }, + follow_current_file = { + enabled = false, -- This will find and focus the file in the active buffer every time + -- -- the current file is changed while the tree is open. + leave_dirs_open = false, -- `false` closes auto expanded dirs, such as with `:Neotree reveal` + }, + group_empty_dirs = false, -- when true, empty folders will be grouped together + hijack_netrw_behavior = 'open_default', -- netrw disabled, opening a directory opens neo-tree + -- in whatever position is specified in window.position + -- "open_current", -- netrw disabled, opening a directory opens within the + -- window like netrw would, regardless of window.position + -- "disabled", -- netrw left alone, neo-tree does not handle opening dirs + use_libuv_file_watcher = false, -- This will use the OS level file watchers to detect changes + -- instead of relying on nvim autocmd events. + hide_by_name = { + 'node_modules', + '.DS_Store', + }, + window = { + mappings = { + [''] = 'navigate_up', + ['.'] = 'set_root', + ['H'] = 'toggle_hidden', + ['/'] = 'fuzzy_finder', + ['D'] = 'fuzzy_finder_directory', + ['#'] = 'fuzzy_sorter', -- fuzzy sorting using the fzy algorithm + -- ["D"] = "fuzzy_sorter_directory", + ['f'] = 'filter_on_submit', + [''] = 'clear_filter', + ['[g'] = 'prev_git_modified', + [']g'] = 'next_git_modified', + ['o'] = { + 'show_help', + nowait = false, + config = { title = 'Order by', prefix_key = 'o' }, + }, + ['oc'] = { 'order_by_created', nowait = false }, + ['od'] = { 'order_by_diagnostics', nowait = false }, + ['og'] = { 'order_by_git_status', nowait = false }, + ['om'] = { 'order_by_modified', nowait = false }, + ['on'] = { 'order_by_name', nowait = false }, + ['os'] = { 'order_by_size', nowait = false }, + ['ot'] = { 'order_by_type', nowait = false }, + -- [''] = function(state) ... end, + ['\\'] = 'close_window', + ['e'] = 'close_window', + }, + fuzzy_finder_mappings = { -- define keymaps for filter popup window in fuzzy_finder_mode + [''] = 'move_cursor_down', + [''] = 'move_cursor_down', + [''] = 'move_cursor_up', + [''] = 'move_cursor_up', + [''] = 'close', + [''] = 'close_keep_filter', + [''] = 'close_clear_filter', + [''] = { '', raw = true }, + { + -- normal mode mappings + n = { + ['j'] = 'move_cursor_down', + ['k'] = 'move_cursor_up', + [''] = 'close_keep_filter', + [''] = 'close_clear_filter', + [''] = 'close', + }, + }, + -- [""] = "noop", -- if you want to use normal mode + -- ["key"] = function(state, scroll_padding) ... end, + }, + }, + + commands = {}, -- Add a custom command or override a global one using the same function name + }, + buffers = { + follow_current_file = { + enabled = true, -- This will find and focus the file in the active buffer every time + -- -- the current file is changed while the tree is open. + leave_dirs_open = false, -- `false` closes auto expanded dirs, such as with `:Neotree reveal` + }, + group_empty_dirs = true, -- when true, empty folders will be grouped together + show_unloaded = true, + window = { + mappings = { + ['d'] = 'buffer_delete', + ['bd'] = 'buffer_delete', + [''] = 'navigate_up', + ['.'] = 'set_root', + ['o'] = { + 'show_help', + nowait = false, + config = { title = 'Order by', prefix_key = 'o' }, + }, + ['oc'] = { 'order_by_created', nowait = false }, + ['od'] = { 'order_by_diagnostics', nowait = false }, + ['om'] = { 'order_by_modified', nowait = false }, + ['on'] = { 'order_by_name', nowait = false }, + ['os'] = { 'order_by_size', nowait = false }, + ['ot'] = { 'order_by_type', nowait = false }, + }, + }, + }, + git_status = { + window = { + position = 'float', + mappings = { + ['A'] = 'git_add_all', + ['gu'] = 'git_unstage_file', + ['gU'] = 'git_undo_last_commit', + ['ga'] = 'git_add_file', + ['gt'] = 'git_toggle_file_stage', + ['gr'] = 'git_revert_file', + ['gc'] = 'git_commit', + ['gp'] = 'git_push', + ['gg'] = 'git_commit_and_push', + ['o'] = { + 'show_help', + nowait = false, + config = { title = 'Order by', prefix_key = 'o' }, + }, + ['oc'] = { 'order_by_created', nowait = false }, + ['od'] = { 'order_by_diagnostics', nowait = false }, + ['om'] = { 'order_by_modified', nowait = false }, + ['on'] = { 'order_by_name', nowait = false }, + ['os'] = { 'order_by_size', nowait = false }, + ['ot'] = { 'order_by_type', nowait = false }, + }, + }, + }, + }, + keys = { + { '\\', ':Neotree reveal position=right', desc = 'NeoTree reveal', silent = true }, + { 'e', ':Neotree reveal position=right', desc = 'NeoTree reveal', silent = true }, }, }, + { + 'antosha417/nvim-lsp-file-operations', + dependencies = { + 'nvim-lua/plenary.nvim', + 'nvim-neo-tree/neo-tree.nvim', -- makes sure that this loads after Neo-tree. + }, + config = function() + require('lsp-file-operations').setup() + end, + }, + { + 's1n7ax/nvim-window-picker', + version = '2.*', + config = function() + require('window-picker').setup { + filter_rules = { + include_current_win = false, + autoselect_one = true, + -- filter using buffer options + bo = { + -- if the file type is one of following, the window will be ignored + filetype = { 'neo-tree', 'neo-tree-popup', 'notify' }, + -- if the buffer type is one of following, the window will be ignored + buftype = { 'terminal', 'quickfix' }, + }, + }, + } + end, + }, }