From 5a46cb5f69213f780b40dd40400fe7e11620be41 Mon Sep 17 00:00:00 2001 From: Tomas Mirchev Date: Fri, 24 Oct 2025 17:13:50 +0300 Subject: [PATCH] feat: remove lazy --- init.lua | 139 +++++++++++--- lazy-lock.json | 11 -- lsp/eslint.lua | 29 ++- lsp/tailwindcss.lua | 29 ++- lua/config/autocmds.lua | 77 -------- lua/config/options.lua | 109 ----------- lua/config/terminal.lua | 65 ------- lua/plugins/colorscheme.lua | 36 ---- lua/plugins/filetree.lua | 147 --------------- lua/{custom => plugins}/language-manager.lua | 62 +++++-- lua/{custom => plugins}/navigation.lua | 0 lua/plugins/syntax.lua | 67 ------- lua/{custom => plugins}/tabline.lua | 5 +- lua/setup/init.lua | 1 + lua/{custom => setup}/lm-cmds.lua | 0 lua/{config => triimd}/diagnostics.lua | 0 lua/triimd/filetree.lua | 127 +++++++++++++ lua/{config => triimd}/keymaps.lua | 1 + lua/triimd/syntax.lua | 26 +++ lua/utils.lua | 33 ---- nvim-pack-lock.json | 43 +++++ plugin/colorscheme.lua | 29 +++ plugin/events.lua | 180 +++++++++++++++++++ plugin/packages.lua | 8 + 24 files changed, 635 insertions(+), 589 deletions(-) delete mode 100644 lazy-lock.json delete mode 100644 lua/config/autocmds.lua delete mode 100644 lua/config/options.lua delete mode 100644 lua/config/terminal.lua delete mode 100644 lua/plugins/colorscheme.lua delete mode 100644 lua/plugins/filetree.lua rename lua/{custom => plugins}/language-manager.lua (65%) rename lua/{custom => plugins}/navigation.lua (100%) delete mode 100644 lua/plugins/syntax.lua rename lua/{custom => plugins}/tabline.lua (90%) create mode 100644 lua/setup/init.lua rename lua/{custom => setup}/lm-cmds.lua (100%) rename lua/{config => triimd}/diagnostics.lua (100%) create mode 100644 lua/triimd/filetree.lua rename lua/{config => triimd}/keymaps.lua (98%) create mode 100644 lua/triimd/syntax.lua delete mode 100644 lua/utils.lua create mode 100644 nvim-pack-lock.json create mode 100644 plugin/colorscheme.lua create mode 100644 plugin/events.lua create mode 100644 plugin/packages.lua diff --git a/init.lua b/init.lua index 93b7bfc..243a33a 100644 --- a/init.lua +++ b/init.lua @@ -1,29 +1,112 @@ -local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' -if not (vim.uv or vim.loop).fs_stat(lazypath) then - local lazyrepo = 'https://github.com/folke/lazy.nvim.git' - local out = - vim.fn.system({ 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }) - if vim.v.shell_error ~= 0 then - vim.api.nvim_echo({ - { 'Failed to clone lazy.nvim:\n', 'ErrorMsg' }, - { out, 'WarningMsg' }, - { '\nPress any key to exit...' }, - }, true, {}) - vim.fn.getchar() - os.exit(1) - end -end -vim.opt.rtp:prepend(lazypath) +-- Map Leader +vim.g.mapleader = ' ' +vim.g.maplocalleader = ' ' -require('config.options') -require('config.keymaps') -require('config.autocmds') -require('config.terminal') -require('custom.navigation') -require('custom.tabline').setup() -require('lazy').setup({ - spec = { { import = 'plugins' } }, - install = { missing = false }, - change_detection = { notify = false }, - rocks = { enabled = false }, -}) +-- Disable built-in plugins +vim.loader.enable() +vim.g.loaded_gzip = 1 +vim.g.loaded_tar = 1 +vim.g.loaded_tarPlugin = 1 +vim.g.loaded_zip = 1 +vim.g.loaded_zipPlugin = 1 +vim.g.loaded_getscript = 1 +vim.g.loaded_getscriptPlugin = 1 +vim.g.loaded_vimball = 1 +vim.g.loaded_vimballPlugin = 1 +vim.g.loaded_matchit = 1 +vim.g.loaded_2html_plugin = 1 +vim.g.loaded_rrhelper = 1 +vim.g.loaded_matchparen = 1 +vim.g.loaded_tutor_mode_plugin = 1 +vim.g.loaded_spellfile_plugin = 1 +vim.g.loaded_logipat = 1 +vim.g.loaded_rplugin = 1 +vim.g.loaded_netrw = 1 -- use nvim-tree instead +vim.g.loaded_netrwPlugin = 1 + +-- UI +vim.g.have_nerd_font = true +vim.opt.termguicolors = false + +vim.opt.textwidth = 100 +vim.opt.colorcolumn = '+0' + +vim.opt.signcolumn = 'no' +vim.opt.number = true +vim.opt.relativenumber = true +vim.opt.cursorline = true +vim.opt.ruler = false +vim.opt.winborder = 'rounded' +vim.opt.guicursor = 'n-v-i-c:block' + +vim.opt.laststatus = 3 +vim.opt.statusline = '── %f %h%w%m%r %= [%l,%c-%L] ──' +vim.opt.fillchars = { + stl = '─', + stlnc = '─', + horiz = '─', + horizdown = '─', + horizup = '─', + vert = '│', + vertleft = '│', + vertright = '│', + verthoriz = '│', +} + +-- Wrap +vim.opt.wrap = false +vim.opt.linebreak = true +vim.opt.breakindent = true + +-- Indent +vim.opt.shiftwidth = 2 -- Number of spaces to use for (auto)indent +vim.opt.tabstop = 2 -- Number of spaces that a in file counts for +vim.opt.softtabstop = 2 -- Number of spaces when pressing in insert mode +vim.opt.expandtab = true -- Use spaces instead of literal tab characters +vim.opt.autoindent = true -- Copy indent from the current line when starting a new one +vim.opt.smartindent = true -- Automatically inserts indents in code blocks (for C-like languages) + +-- Scroll and mouse +vim.opt.scrolloff = 10 +vim.opt.sidescrolloff = 5 +vim.opt.mousescroll = 'hor:1,ver:5' +vim.opt.mouse = 'a' -- Enable mouse support + +-- Search +vim.opt.ignorecase = true +vim.opt.smartcase = true -- Override ignorecase if search contains upper case chars +vim.opt.inccommand = 'split' -- Live substitution preview +vim.opt.completeopt = { 'fuzzy', 'menuone', 'popup', 'noselect' } + +-- Splits +vim.opt.splitright = true +vim.opt.splitbelow = true + +-- Persistence +vim.opt.undofile = true +vim.opt.swapfile = false + +-- Tweaks +vim.opt.updatetime = 1000 +vim.opt.timeout = true +vim.opt.ttimeout = true +vim.opt.timeoutlen = 500 +vim.opt.ttimeoutlen = 10 + +-- Clipboard +if vim.env.CONTAINER then + vim.g.clipboard = { + name = 'osc52', + copy = { + ['+'] = require('vim.ui.clipboard.osc52').copy('+'), + ['*'] = require('vim.ui.clipboard.osc52').copy('*'), + }, + paste = { + ['+'] = require('vim.ui.clipboard.osc52').paste('+'), + ['*'] = require('vim.ui.clipboard.osc52').paste('*'), + }, + } +end + +-- require('custom.navigation') +-- require('custom.tabline').setup() diff --git a/lazy-lock.json b/lazy-lock.json deleted file mode 100644 index 2f44ad4..0000000 --- a/lazy-lock.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "conform.nvim": { "branch": "master", "commit": "9fd3d5e0b689ec1bf400c53cbbec72c6fdf24081" }, - "invero.nvim": { "branch": "main", "commit": "6acdefa2f2fdf544b53b5786e748be0ae8e9fd23" }, - "lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" }, - "mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" }, - "nvim-autopairs": { "branch": "master", "commit": "7a2c97cccd60abc559344042fefb1d5a85b3e33b" }, - "nvim-lint": { "branch": "master", "commit": "9da1fb942dd0668d5182f9c8dee801b9c190e2bb" }, - "nvim-tree.lua": { "branch": "master", "commit": "7c0f7e906ab6f11b61eec52171eaf7dc06726ef1" }, - "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, - "nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" } -} diff --git a/lsp/eslint.lua b/lsp/eslint.lua index f80694c..4770e1f 100644 --- a/lsp/eslint.lua +++ b/lsp/eslint.lua @@ -1,3 +1,31 @@ +local utils = {} + +function utils.root_markers_with_field(root_files, new_names, field, fname) + local path = vim.fn.fnamemodify(fname, ':h') + local found = vim.fs.find(new_names, { path = path, upward = true }) + + for _, f in ipairs(found or {}) do + -- Match the given `field`. + for line in io.lines(f) do + if line:find(field) then + root_files[#root_files + 1] = vim.fs.basename(f) + break + end + end + end + + return root_files +end + +function utils.insert_package_json(root_files, field, fname) + return utils.root_markers_with_field( + root_files, + { 'package.json', 'package.json5' }, + field, + fname + ) +end + --- @brief --- --- https://github.com/hrsh7th/vscode-langservers-extracted @@ -39,7 +67,6 @@ --- --- /!\ When using flat config files, you need to use them across all your packages in your monorepo, as it's a global setting for the server. -local utils = require('utils') local lsp = vim.lsp local eslint_config_files = { diff --git a/lsp/tailwindcss.lua b/lsp/tailwindcss.lua index 3c432cd..1d523b6 100644 --- a/lsp/tailwindcss.lua +++ b/lsp/tailwindcss.lua @@ -1,10 +1,37 @@ +local utils = {} + +function utils.root_markers_with_field(root_files, new_names, field, fname) + local path = vim.fn.fnamemodify(fname, ':h') + local found = vim.fs.find(new_names, { path = path, upward = true }) + + for _, f in ipairs(found or {}) do + -- Match the given `field`. + for line in io.lines(f) do + if line:find(field) then + root_files[#root_files + 1] = vim.fs.basename(f) + break + end + end + end + + return root_files +end + +function utils.insert_package_json(root_files, field, fname) + return utils.root_markers_with_field( + root_files, + { 'package.json', 'package.json5' }, + field, + fname + ) +end + ---@brief --- https://github.com/tailwindlabs/tailwindcss-intellisense --- --- Tailwind CSS Language Server can be installed via npm: --- --- npm install -g @tailwindcss/language-server -local utils = require('utils') ---@type vim.lsp.Config return { diff --git a/lua/config/autocmds.lua b/lua/config/autocmds.lua deleted file mode 100644 index 53255d5..0000000 --- a/lua/config/autocmds.lua +++ /dev/null @@ -1,77 +0,0 @@ --- Automatically create a scratch buffer if Neovim starts with no files -vim.api.nvim_create_autocmd('VimEnter', { - callback = function() - -- Only trigger if no file arguments are passed - if vim.fn.argc() == 0 then - vim.cmd('enew') - vim.bo.buftype = 'nofile' - vim.bo.bufhidden = 'wipe' - vim.bo.swapfile = false - end - end, -}) - --- Highlight when yanking (copying) text -vim.api.nvim_create_autocmd('TextYankPost', { - callback = function() - vim.highlight.on_yank() - end, -}) - --- Disable comment continuation only when using 'o'/'O', but keep it for -vim.api.nvim_create_autocmd('FileType', { - pattern = '*', - callback = function() - vim.opt_local.formatoptions:remove('o') - end, -}) - --- Show cursor line only in active window -vim.api.nvim_create_autocmd({ 'WinEnter', 'InsertLeave' }, { - callback = function() - if vim.w.auto_cursorline then - vim.wo.cursorline = true - vim.w.auto_cursorline = nil - end - end, -}) - -vim.api.nvim_create_autocmd({ 'WinLeave', 'InsertEnter' }, { - callback = function() - if vim.bo.filetype == 'NvimTree' then - return - end - if vim.wo.cursorline then - vim.w.auto_cursorline = true - vim.wo.cursorline = false - end - end, -}) - --- Autocompletion -vim.api.nvim_create_autocmd('LspAttach', { - group = vim.api.nvim_create_augroup('minimal_lsp', { clear = true }), - callback = function(ev) - local client = vim.lsp.get_client_by_id(ev.data.client_id) - if not client then - return - end - - -- Enable native completion - if client:supports_method('textDocument/completion') then - vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true }) - end - end, -}) -vim.lsp.handlers['textDocument/completion'] = function(err, result, ctx, config) - if err or not result then - return - end - for _, item in ipairs(result.items or result) do - if item.kind then - local kind = vim.lsp.protocol.CompletionItemKind[item.kind] or '' - item.menu = '[' .. kind .. ']' - end - end - return vim.lsp.completion._on_completion_result(err, result, ctx, config) -end diff --git a/lua/config/options.lua b/lua/config/options.lua deleted file mode 100644 index 4c3d5ce..0000000 --- a/lua/config/options.lua +++ /dev/null @@ -1,109 +0,0 @@ --- Map Leader -vim.g.mapleader = ' ' -vim.g.maplocalleader = ' ' - --- Disable built-in plugins -vim.loader.enable() -vim.g.loaded_gzip = 1 -vim.g.loaded_tar = 1 -vim.g.loaded_tarPlugin = 1 -vim.g.loaded_zip = 1 -vim.g.loaded_zipPlugin = 1 -vim.g.loaded_getscript = 1 -vim.g.loaded_getscriptPlugin = 1 -vim.g.loaded_vimball = 1 -vim.g.loaded_vimballPlugin = 1 -vim.g.loaded_matchit = 1 -vim.g.loaded_2html_plugin = 1 -vim.g.loaded_rrhelper = 1 -vim.g.loaded_matchparen = 1 -vim.g.loaded_tutor_mode_plugin = 1 -vim.g.loaded_spellfile_plugin = 1 -vim.g.loaded_logipat = 1 -vim.g.loaded_rplugin = 1 -vim.g.loaded_netrw = 1 -- use nvim-tree instead -vim.g.loaded_netrwPlugin = 1 - --- UI -vim.g.have_nerd_font = true -vim.opt.termguicolors = false - -vim.opt.textwidth = 100 -vim.opt.colorcolumn = '+0' - -vim.opt.signcolumn = 'no' -vim.opt.number = true -vim.opt.relativenumber = true -vim.opt.cursorline = true -vim.opt.ruler = false -vim.opt.winborder = 'rounded' -vim.opt.guicursor = 'n-v-i-c:block' - -vim.opt.laststatus = 3 -vim.opt.statusline = '── %f %h%w%m%r %= [%l,%c-%L] ──' -vim.opt.fillchars = { - stl = '─', - stlnc = '─', - horiz = '─', - horizdown = '─', - horizup = '─', - vert = '│', - vertleft = '│', - vertright = '│', - verthoriz = '│', -} - --- Wrap -vim.opt.wrap = false -vim.opt.linebreak = true -vim.opt.breakindent = true - --- Indent -vim.opt.shiftwidth = 2 -- Number of spaces to use for (auto)indent -vim.opt.tabstop = 2 -- Number of spaces that a in file counts for -vim.opt.softtabstop = 2 -- Number of spaces when pressing in insert mode -vim.opt.expandtab = true -- Use spaces instead of literal tab characters -vim.opt.autoindent = true -- Copy indent from the current line when starting a new one -vim.opt.smartindent = true -- Automatically inserts indents in code blocks (for C-like languages) - --- Scroll and mouse -vim.opt.scrolloff = 10 -vim.opt.sidescrolloff = 5 -vim.opt.mousescroll = 'hor:1,ver:5' -vim.opt.mouse = 'a' -- Enable mouse support - --- Search -vim.opt.ignorecase = true -vim.opt.smartcase = true -- Override ignorecase if search contains upper case chars -vim.opt.inccommand = 'split' -- Live substitution preview -vim.opt.completeopt = { 'fuzzy', 'menuone', 'popup', 'noselect' } - --- Splits -vim.opt.splitright = true -vim.opt.splitbelow = true - --- Persistence -vim.opt.undofile = true -vim.opt.swapfile = false - --- Tweaks -vim.opt.updatetime = 1000 -vim.opt.timeout = true -vim.opt.ttimeout = true -vim.opt.timeoutlen = 500 -vim.opt.ttimeoutlen = 10 - --- Clipboard -if vim.env.CONTAINER then - vim.g.clipboard = { - name = 'osc52', - copy = { - ['+'] = require('vim.ui.clipboard.osc52').copy('+'), - ['*'] = require('vim.ui.clipboard.osc52').copy('*'), - }, - paste = { - ['+'] = require('vim.ui.clipboard.osc52').paste('+'), - ['*'] = require('vim.ui.clipboard.osc52').paste('*'), - }, - } -end diff --git a/lua/config/terminal.lua b/lua/config/terminal.lua deleted file mode 100644 index 675262e..0000000 --- a/lua/config/terminal.lua +++ /dev/null @@ -1,65 +0,0 @@ -local term_group = vim.api.nvim_create_augroup('custom-term', { clear = true }) - --- Custom terminal -vim.api.nvim_create_autocmd('TermOpen', { - group = term_group, - callback = function() - vim.opt_local.number = false - vim.opt_local.relativenumber = false - vim.opt_local.scrolloff = 0 - vim.bo.filetype = 'terminal' - vim.cmd.startinsert() - end, -}) - --- Insert when re-entering a terminal window (after switching back) -vim.api.nvim_create_autocmd('BufEnter', { - group = term_group, - pattern = 'term://*', - callback = function() - if vim.bo.buftype == 'terminal' and vim.fn.mode() ~= 'i' then - vim.cmd.startinsert() - end - end, -}) - --- Close all terminal buffers before quitting -vim.api.nvim_create_autocmd('QuitPre', { - group = term_group, - callback = function() - for _, buf in ipairs(vim.api.nvim_list_bufs()) do - if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == 'terminal' then - vim.api.nvim_buf_delete(buf, { force = true }) - end - end - end, -}) - -local commands = { - TermDefault = function() - vim.cmd('terminal') - end, - - TermRelative = function() - local shell = vim.o.shell or 'zsh' - local dir = vim.fn.expand('%:p:h') - vim.cmd(string.format('edit term://%s//%s', dir, shell)) - end, - - TermSplit = function() - vim.cmd('new') - vim.cmd('wincmd J') - vim.api.nvim_win_set_height(0, 12) - vim.wo.winfixheight = true - vim.cmd('term') - end, - - TermVSplit = function() - vim.cmd('vsplit') - vim.cmd('term') - end, -} - -for name, fn in pairs(commands) do - vim.api.nvim_create_user_command(name, fn, {}) -end diff --git a/lua/plugins/colorscheme.lua b/lua/plugins/colorscheme.lua deleted file mode 100644 index 65c3568..0000000 --- a/lua/plugins/colorscheme.lua +++ /dev/null @@ -1,36 +0,0 @@ -return { - 'triimdev/invero.nvim', - lazy = false, - priority = 1000, - config = function() - vim.api.nvim_create_user_command('ReloadInvero', function() - require('invero').invalidate_cache() - vim.cmd('Lazy reload invero.nvim') - end, {}) - - require('invero').setup({ - highlights = function(c, tool) - c.bg_float = tool(152) - return { - ModeMsg = { fg = c.yellow, bg = c.none, bold = true }, - WinSeparator = { fg = c.outline, bg = c.base }, - StatusLine = { fg = c.outline, bg = c.base }, - StatusLineNC = { fg = c.text, bg = c.base, bold = true }, - TabLine = { fg = c.muted, bg = c.none }, - TabLineSel = { fg = c.text, bg = c.none, bold = true }, - TabLineFill = { fg = c.outline_light, bg = c.none }, - - Pmenu = { fg = c.text, bg = c.surface }, - PmenuSel = { fg = c.text, bg = c.accent_light }, - QuickFixLine = { fg = c.accent, bg = c.none, bold = true }, - -- PmenuSbar = { bg = c.surface }, - -- PmenuThumb = { bg = c.outline }, - -- PmenuBorder = { fg = c.outline }, - } - end, - }) - - vim.o.background = 'light' - vim.cmd.colorscheme('invero') - end, -} diff --git a/lua/plugins/filetree.lua b/lua/plugins/filetree.lua deleted file mode 100644 index 01acb31..0000000 --- a/lua/plugins/filetree.lua +++ /dev/null @@ -1,147 +0,0 @@ -local function my_on_attach(bufnr) - local api = require('nvim-tree.api') - local opts = { buffer = bufnr } - - -- basics: copy/cut/paste/create/rename/remove - vim.keymap.set('n', 'c', api.fs.copy.node, opts) - vim.keymap.set('n', 'x', api.fs.cut, opts) - vim.keymap.set('n', 'p', api.fs.paste, opts) - vim.keymap.set('n', 'a', api.fs.create, opts) - vim.keymap.set('n', 'r', api.fs.rename, opts) - vim.keymap.set('n', 'R', api.fs.rename_basename, opts) - vim.keymap.set('n', 'd', api.fs.remove, opts) - - -- bulk mark and delete/move - vim.keymap.set('n', 's', api.marks.toggle, opts) - vim.keymap.set('n', 'S', api.marks.clear, opts) - vim.keymap.set('n', 'bd', api.marks.bulk.delete, opts) - vim.keymap.set('n', 'bm', api.marks.bulk.move, opts) - - -- copy filename/path - vim.keymap.set('n', 'y', api.fs.copy.filename, opts) - vim.keymap.set('n', 'Y', api.fs.copy.relative_path, opts) - vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts) - vim.keymap.set('n', 'ge', api.fs.copy.basename, opts) - - -- expand/collapse - vim.keymap.set('n', 'e', api.tree.expand_all, opts) - vim.keymap.set('n', 'E', api.tree.collapse_all, opts) - - -- filter - vim.keymap.set('n', 'f', api.live_filter.start, opts) - vim.keymap.set('n', 'F', api.live_filter.clear, opts) - - -- navigate - vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts) - vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts) - vim.keymap.set('n', 'P', api.node.navigate.parent, opts) - - -- open - vim.keymap.set('n', '', api.node.open.edit, opts) - vim.keymap.set('n', 'o', api.node.open.edit, opts) - vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts) - - -- miscellaneous - vim.keymap.set('n', 'K', api.node.show_info_popup, opts) - vim.keymap.set('n', 'U', api.tree.reload, opts) -end - -return { - 'https://gitea.tomastm.com/tomas.mirchev/nvim-tree.lua', - branch = 'master', - opts = { - on_attach = my_on_attach, - view = { signcolumn = 'no' }, - actions = { file_popup = { open_win_config = { border = 'rounded' } } }, - renderer = { - root_folder_label = false, - -- root_folder_label = function(path) - -- return '-- ' .. vim.fn.fnamemodify(path, ':t') .. ' --' - -- end, - special_files = {}, - - highlight_hidden = 'all', - highlight_clipboard = 'all', - - indent_markers = { - enable = true, - inline_arrows = false, - icons = { corner = '│', none = '│', bottom = ' ' }, - }, - icons = { - bookmarks_placement = 'after', - git_placement = 'after', - show = { - file = false, - folder = false, - folder_arrow = false, -- KEEP FALSE - git = true, - modified = false, - hidden = false, - diagnostics = false, - bookmarks = true, - }, - glyphs = { - -- default = '•', - default = ' ', - symlink = '', - bookmark = '󰆤', - modified = '●', - hidden = '󰜌', - folder = { - arrow_closed = '', - arrow_open = '', - default = '▸', - open = '▾', - empty = '', - empty_open = '', - symlink = '', - symlink_open = '', - }, - - git = { - unstaged = '◇', -- '✗', - staged = '', - unmerged = '', - renamed = '', - untracked = '', - deleted = '', -- '󰧧', - ignored = '', - }, - }, - }, - }, - - hijack_cursor = true, - prefer_startup_root = true, - update_focused_file = { - enable = true, - update_root = { enable = true, ignore_list = {} }, - exclude = false, - }, - modified = { enable = true, show_on_dirs = true, show_on_open_dirs = true }, - filters = { - enable = true, - git_ignored = true, - dotfiles = false, - git_clean = false, - no_buffer = false, - no_bookmark = false, - custom = {}, - exclude = {}, - }, - filesystem_watchers = { - enable = true, - debounce_delay = 50, - ignore_dirs = { - '/.git', - '/.DS_Store', - '/build', - '/dist', - '/public', - '/node_modules', - '/target', - }, - }, - }, -} diff --git a/lua/custom/language-manager.lua b/lua/plugins/language-manager.lua similarity index 65% rename from lua/custom/language-manager.lua rename to lua/plugins/language-manager.lua index 48d86f0..a65a6f2 100644 --- a/lua/custom/language-manager.lua +++ b/lua/plugins/language-manager.lua @@ -8,7 +8,16 @@ lm.delete_cache() lm.enable() --]] + +vim.pack.add({ 'https://github.com/mason-org/mason.nvim' }) + local M = {} +M.lsp = {} +M.ts = {} +M.lint = {} +M.format = {} + +M.group = vim.api.nvim_create_augroup('language-manager', { clear = true }) local function wrap(item) if type(item) == 'string' then @@ -35,19 +44,19 @@ local function create_set() end local function create_spec() - local M = {} + local S = {} local unique = create_set() local specs = {} - function M.set(item, group) + function S.set(item, group) specs[group] = item end - function M.get() + function S.get() return specs end - function M.add(list, ...) + function S.add(list, ...) local groups = { ... } local ref = table.concat(groups, '.') local pointer = specs @@ -74,7 +83,7 @@ local function create_spec() end end - return M + return S end function M.generate_specs(specs_raw) @@ -104,25 +113,58 @@ function M.generate_specs(specs_raw) return M.general end -M.lsp = {} -function M.lsp.enable() +function M.lsp.setup() + require('mason').setup() local registry = require('mason-registry') - local lsp_configs = {} for _, lsp in ipairs(M.general.language_servers) do if registry.has_package(lsp) then local pkg = registry.get_package(lsp) local spec = pkg.spec and pkg.spec.neovim local lsp_name = (spec and spec.lspconfig) or lsp - table.insert(lsp_configs, lsp_name) vim.lsp.enable(lsp_name) else vim.notify('Unknown LSP: ' .. lsp, vim.log.levels.WARN) end end +end - vim.notify('Enabled LSPs: ' .. table.concat(lsp_configs, ', '), vim.log.levels.INFO) +function M.ts.setup() + require('nvim-treesitter.configs').setup({ + highlight = { enable = true }, + incremental_selection = { enable = true }, + }) +end + +function M.lint.setup() + vim.api.nvim_create_autocmd({ 'BufReadPre', 'BufNewFile' }, { + group = M.group, + callback = function() + local lint = require('lint') + lint.linters_by_ft = M.general.linters_by_ft + vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { + group = vim.api.nvim_create_augroup('language-manager.lint', { clear = true }), + callback = function() + lint.try_lint() + end, + }) + end, + }) +end + +function M.format.setup() + vim.api.nvim_create_autocmd('BufWritePre', { + group = M.group, + once = true, + callback = function() + require('conform').setup({ + format_on_save = { timeout_ms = 500, lsp_format = 'fallback' }, + default_format_opts = { stop_after_first = true }, + formatters_by_ft = M.general.formatters_by_ft, + }) + end, + }) end return M diff --git a/lua/custom/navigation.lua b/lua/plugins/navigation.lua similarity index 100% rename from lua/custom/navigation.lua rename to lua/plugins/navigation.lua diff --git a/lua/plugins/syntax.lua b/lua/plugins/syntax.lua deleted file mode 100644 index 3ca2f6f..0000000 --- a/lua/plugins/syntax.lua +++ /dev/null @@ -1,67 +0,0 @@ -local lm = require('custom.language-manager') -local language_specs = { - { ts = { 'yaml', 'toml', 'sql', 'diff', 'dockerfile', 'gitcommit', 'gitignore' } }, - { ts = { 'c', 'cpp', 'go', 'rust', 'python' } }, - - { ft = 'markdown', ts = { 'markdown', 'markdown_inline' }, format = 'prettier' }, - { ft = 'bash', lsp = 'bash-language-server', lint = 'shellcheck', format = 'shfmt' }, - { ft = 'lua', lsp = 'lua-language-server', lint = 'luacheck', format = 'stylua' }, - { ft = { 'json', 'jsonc' }, lsp = 'json-lsp' }, - { ft = 'html', lsp = 'html-lsp' }, - { ft = 'css', lsp = { 'css-lsp', 'tailwindcss-language-server' } }, - { - ft = { 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' }, - ts = { 'javascript', 'typescript', 'tsx' }, - lsp = { 'vtsls', 'eslint-lsp' }, - format = { 'prettierd', 'prettier' }, - }, -} - -local general = lm.generate_specs(language_specs) - -return { - { 'windwp/nvim-ts-autotag', config = true }, - { 'windwp/nvim-autopairs', event = 'InsertEnter', config = true }, - { - 'mason-org/mason.nvim', - config = function() - require('mason').setup() - lm.lsp.enable() - end, - }, - { - 'nvim-treesitter/nvim-treesitter', - build = ':TSUpdate', - main = 'nvim-treesitter.configs', - opts = { - highlight = { enable = true }, - incremental_selection = { enable = true }, - ensure_installed = general.ts_parsers, - }, - }, - { - 'mfussenegger/nvim-lint', - event = { 'BufReadPre', 'BufNewFile' }, - opts = { linters_by_ft = general.linters_by_ft }, - config = function(_, opts) - local lint = require('lint') - lint.linters_by_ft = opts.linters_by_ft - - vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, { - group = vim.api.nvim_create_augroup('lint_autocmd', { clear = true }), - callback = function() - lint.try_lint() - end, - }) - end, - }, - { - 'stevearc/conform.nvim', - event = { 'BufWritePre' }, - opts = { - format_on_save = { timeout_ms = 500, lsp_format = 'fallback' }, - default_format_opts = { stop_after_first = true }, - formatters_by_ft = general.formatters_by_ft, - }, - }, -} diff --git a/lua/custom/tabline.lua b/lua/plugins/tabline.lua similarity index 90% rename from lua/custom/tabline.lua rename to lua/plugins/tabline.lua index 411024a..129273e 100644 --- a/lua/custom/tabline.lua +++ b/lua/plugins/tabline.lua @@ -1,6 +1,3 @@ --- ~/.config/nvim/lua/custom/tabline.lua --- Custom Lua tabline with proper modified/unsaved and window count handling - local M = {} -- Helper to get label for each tab page @@ -80,7 +77,7 @@ end function M.setup() vim.o.showtabline = 1 - vim.o.tabline = "%!v:lua.require'custom.tabline'.tabline()" + vim.o.tabline = "%!v:lua.require'plugins.tabline'.tabline()" end return M diff --git a/lua/setup/init.lua b/lua/setup/init.lua new file mode 100644 index 0000000..8aa769a --- /dev/null +++ b/lua/setup/init.lua @@ -0,0 +1 @@ +vim.pack.add({ 'https://github.com/mason-org/mason.nvim' }) diff --git a/lua/custom/lm-cmds.lua b/lua/setup/lm-cmds.lua similarity index 100% rename from lua/custom/lm-cmds.lua rename to lua/setup/lm-cmds.lua diff --git a/lua/config/diagnostics.lua b/lua/triimd/diagnostics.lua similarity index 100% rename from lua/config/diagnostics.lua rename to lua/triimd/diagnostics.lua diff --git a/lua/triimd/filetree.lua b/lua/triimd/filetree.lua new file mode 100644 index 0000000..0daf633 --- /dev/null +++ b/lua/triimd/filetree.lua @@ -0,0 +1,127 @@ +vim.pack.add({ + { src = 'https://gitea.tomastm.com/tomas.mirchev/nvim-tree.lua', version = 'master' }, +}) + +local function my_on_attach(bufnr) + local api = require('nvim-tree.api') + local opts = { buffer = bufnr } + + -- basics: copy/cut/paste/create/rename/remove + vim.keymap.set('n', 'c', api.fs.copy.node, opts) + vim.keymap.set('n', 'x', api.fs.cut, opts) + vim.keymap.set('n', 'p', api.fs.paste, opts) + vim.keymap.set('n', 'a', api.fs.create, opts) + vim.keymap.set('n', 'r', api.fs.rename, opts) + vim.keymap.set('n', 'R', api.fs.rename_basename, opts) + vim.keymap.set('n', 'd', api.fs.remove, opts) + + -- bulk mark and delete/move + vim.keymap.set('n', 's', api.marks.toggle, opts) + vim.keymap.set('n', 'S', api.marks.clear, opts) + vim.keymap.set('n', 'bd', api.marks.bulk.delete, opts) + vim.keymap.set('n', 'bm', api.marks.bulk.move, opts) + + -- copy filename/path + vim.keymap.set('n', 'y', api.fs.copy.filename, opts) + vim.keymap.set('n', 'Y', api.fs.copy.relative_path, opts) + vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts) + vim.keymap.set('n', 'ge', api.fs.copy.basename, opts) + + -- expand/collapse + vim.keymap.set('n', 'e', api.tree.expand_all, opts) + vim.keymap.set('n', 'E', api.tree.collapse_all, opts) + + -- filter + vim.keymap.set('n', 'f', api.live_filter.start, opts) + vim.keymap.set('n', 'F', api.live_filter.clear, opts) + + -- navigate + vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts) + vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts) + vim.keymap.set('n', 'P', api.node.navigate.parent, opts) + + -- open + vim.keymap.set('n', '', api.node.open.edit, opts) + vim.keymap.set('n', 'o', api.node.open.edit, opts) + vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts) + + -- miscellaneous + vim.keymap.set('n', 'K', api.node.show_info_popup, opts) + vim.keymap.set('n', 'U', api.tree.reload, opts) +end + +require('nvim-tree').setup({ + on_attach = my_on_attach, + view = { signcolumn = 'no' }, + actions = { file_popup = { open_win_config = { border = 'rounded' } } }, + renderer = { + root_folder_label = false, + special_files = {}, + + highlight_hidden = 'all', + highlight_clipboard = 'all', + + indent_markers = { + enable = true, + inline_arrows = false, + icons = { corner = '│', none = '│', bottom = ' ' }, + }, + icons = { + bookmarks_placement = 'after', + git_placement = 'after', + show = { + file = false, + folder = false, + folder_arrow = false, + git = true, + modified = false, + hidden = false, + diagnostics = false, + bookmarks = true, + }, + glyphs = { + git = { + unstaged = '◇', + staged = '', + unmerged = '', + renamed = '', + untracked = '', + deleted = '', + ignored = '', + }, + }, + }, + }, + + hijack_cursor = true, + prefer_startup_root = true, + update_focused_file = { + enable = true, + update_root = { enable = true, ignore_list = {} }, + exclude = false, + }, + modified = { enable = true, show_on_dirs = true, show_on_open_dirs = true }, + filters = { + enable = true, + git_ignored = true, + dotfiles = false, + git_clean = false, + no_buffer = false, + no_bookmark = false, + custom = {}, + exclude = {}, + }, + filesystem_watchers = { + enable = true, + debounce_delay = 50, + ignore_dirs = { + '/.git', + '/.DS_Store', + '/build', + '/dist', + '/public', + '/node_modules', + '/target', + }, + }, +}) diff --git a/lua/config/keymaps.lua b/lua/triimd/keymaps.lua similarity index 98% rename from lua/config/keymaps.lua rename to lua/triimd/keymaps.lua index 837f9a4..54ef101 100644 --- a/lua/config/keymaps.lua +++ b/lua/triimd/keymaps.lua @@ -9,6 +9,7 @@ end -- QOL map('i', 'jk', '') +map('i', '', '') map('n', '', cmd('nohlsearch')) map('n', 'q:', '') diff --git a/lua/triimd/syntax.lua b/lua/triimd/syntax.lua new file mode 100644 index 0000000..c1a2a46 --- /dev/null +++ b/lua/triimd/syntax.lua @@ -0,0 +1,26 @@ +local language_specs = { + { ts = { 'yaml', 'toml', 'sql', 'diff', 'dockerfile', 'gitcommit', 'gitignore' } }, + { ts = { 'c', 'cpp', 'go', 'rust', 'python' } }, + + { ft = 'markdown', ts = { 'markdown', 'markdown_inline' }, format = 'prettier' }, + { ft = 'bash', lsp = 'bash-language-server', lint = 'shellcheck', format = 'shfmt' }, + { ft = 'lua', lsp = 'lua-language-server', lint = 'luacheck', format = 'stylua' }, + { ft = { 'json', 'jsonc' }, lsp = 'json-lsp' }, + { ft = 'html', lsp = 'html-lsp' }, + { ft = 'css', lsp = { 'css-lsp', 'tailwindcss-language-server' } }, + { + ft = { 'javascript', 'typescript', 'javascriptreact', 'typescriptreact' }, + ts = { 'javascript', 'typescript', 'tsx' }, + lsp = { 'vtsls', 'eslint-lsp' }, + format = { 'prettierd', 'prettier' }, + }, +} + +local lm = require('plugins.language-manager') + +lm.generate_specs(language_specs) + +lm.ts.setup() +lm.lsp.setup() +lm.lint.setup() +lm.format.setup() diff --git a/lua/utils.lua b/lua/utils.lua deleted file mode 100644 index 6105bde..0000000 --- a/lua/utils.lua +++ /dev/null @@ -1,33 +0,0 @@ -local M = {} - ---- Appends `new_names` to `root_files` if `field` is found in any such file in any ancestor of `fname`. ---- ---- NOTE: this does a "breadth-first" search, so is broken for multi-project workspaces: ---- https://github.com/neovim/nvim-lspconfig/issues/3818#issuecomment-2848836794 ---- ---- @param root_files string[] List of root-marker files to append to. ---- @param new_names string[] Potential root-marker filenames (e.g. `{ 'package.json', 'package.json5' }`) to inspect for the given `field`. ---- @param field string Field to search for in the given `new_names` files. ---- @param fname string Full path of the current buffer name to start searching upwards from. -function M.root_markers_with_field(root_files, new_names, field, fname) - local path = vim.fn.fnamemodify(fname, ':h') - local found = vim.fs.find(new_names, { path = path, upward = true }) - - for _, f in ipairs(found or {}) do - -- Match the given `field`. - for line in io.lines(f) do - if line:find(field) then - root_files[#root_files + 1] = vim.fs.basename(f) - break - end - end - end - - return root_files -end - -function M.insert_package_json(root_files, field, fname) - return M.root_markers_with_field(root_files, { 'package.json', 'package.json5' }, field, fname) -end - -return M diff --git a/nvim-pack-lock.json b/nvim-pack-lock.json new file mode 100644 index 0000000..2f2f13b --- /dev/null +++ b/nvim-pack-lock.json @@ -0,0 +1,43 @@ +{ + "plugins": { + "conform.nvim": { + "rev": "9fd3d5e", + "src": "https://github.com/stevearc/conform.nvim" + }, + "invero.nvim": { + "rev": "6acdefa", + "src": "https://github.com/triimd/invero.nvim" + }, + "mason.nvim": { + "rev": "ad7146a", + "src": "https://github.com/mason-org/mason.nvim" + }, + "nvim-autopairs": { + "rev": "7a2c97c", + "src": "https://github.com/windwp/nvim-autopairs" + }, + "nvim-lint": { + "rev": "9da1fb9", + "src": "https://github.com/mfussenegger/nvim-lint" + }, + "nvim-tree": { + "rev": "7c0f7e9", + "src": "https://gitea.tomastm.com/tomas.mirchev/nvim-tree.lua", + "version": "'master'" + }, + "nvim-tree.lua": { + "rev": "7c0f7e9", + "src": "https://gitea.tomastm.com/tomas.mirchev/nvim-tree.lua", + "version": "'master'" + }, + "nvim-treesitter": { + "rev": "42fc28ba", + "src": "https://github.com/nvim-treesitter/nvim-treesitter", + "version": "'master'" + }, + "nvim-ts-autotag": { + "rev": "c4ca798", + "src": "https://github.com/windwp/nvim-ts-autotag" + } + } +} \ No newline at end of file diff --git a/plugin/colorscheme.lua b/plugin/colorscheme.lua new file mode 100644 index 0000000..9eb9dcd --- /dev/null +++ b/plugin/colorscheme.lua @@ -0,0 +1,29 @@ +vim.pack.add({ 'https://github.com/triimd/invero.nvim' }) + +require('invero').setup({ + highlights = function(c, tool) + c.bg_float = tool(152) + return { + ModeMsg = { fg = c.yellow, bg = c.none, bold = true }, + WinSeparator = { fg = c.outline, bg = c.base }, + StatusLine = { fg = c.outline, bg = c.base }, + StatusLineNC = { fg = c.text, bg = c.base, bold = true }, + TabLine = { fg = c.muted, bg = c.none }, + TabLineSel = { fg = c.text, bg = c.none, bold = true }, + TabLineFill = { fg = c.outline_light, bg = c.none }, + Pmenu = { fg = c.text, bg = c.surface }, + PmenuSel = { fg = c.text, bg = c.accent_light }, + QuickFixLine = { fg = c.accent, bg = c.none, bold = true }, + } + end, +}) + +vim.o.background = 'light' +vim.cmd.colorscheme('invero') + +vim.api.nvim_create_user_command('ReloadInvero', function() + require('invero').invalidate_cache() + package.loaded['invero'] = nil + require('invero') + vim.cmd.colorscheme('invero') +end, {}) diff --git a/plugin/events.lua b/plugin/events.lua new file mode 100644 index 0000000..ff11e0d --- /dev/null +++ b/plugin/events.lua @@ -0,0 +1,180 @@ +local api = vim.api +local au = api.nvim_create_autocmd +local group = api.nvim_create_augroup('triimd.events', { clear = true }) + +-- Automatically create a scratch buffer if Neovim starts with no files +au('VimEnter', { + group = group, + callback = function() + -- Only trigger if no file arguments are passed + if vim.fn.argc() == 0 then + vim.cmd('enew') + vim.bo.buftype = 'nofile' + vim.bo.bufhidden = 'wipe' + vim.bo.swapfile = false + end + end, +}) + +-- Highlight when yanking (copying) text +au('TextYankPost', { + group = group, + callback = function() + vim.highlight.on_yank({ timeout = 400 }) + end, +}) + +-- Disable comment continuation only when using 'o'/'O', but keep it for +au('FileType', { + group = group, + pattern = '*', + callback = function() + vim.opt_local.formatoptions:remove('o') + end, +}) + +-- Show cursor line only in active window +au({ 'WinEnter', 'InsertLeave' }, { + group = group, + callback = function() + if vim.w.auto_cursorline then + vim.wo.cursorline = true + vim.w.auto_cursorline = nil + end + end, +}) + +au({ 'WinLeave', 'InsertEnter' }, { + group = group, + callback = function() + if vim.bo.filetype == 'NvimTree' then + return + end + if vim.wo.cursorline then + vim.w.auto_cursorline = true + vim.wo.cursorline = false + end + end, +}) + +-- Autocompletion +au('LspAttach', { + group = group, + callback = function(ev) + local client = vim.lsp.get_client_by_id(ev.data.client_id) + if not client then + return + end + + -- Enable native completion + if client:supports_method('textDocument/completion') then + vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true }) + end + end, +}) +vim.lsp.handlers['textDocument/completion'] = function(err, result, ctx, config) + if err or not result then + return + end + for _, item in ipairs(result.items or result) do + if item.kind then + local kind = vim.lsp.protocol.CompletionItemKind[item.kind] or '' + item.menu = '[' .. kind .. ']' + end + end + return vim.lsp.completion._on_completion_result(err, result, ctx, config) +end + +-- Custom terminal +au('TermOpen', { + group = group, + callback = function() + vim.opt_local.number = false + vim.opt_local.relativenumber = false + vim.opt_local.scrolloff = 0 + vim.bo.filetype = 'terminal' + vim.cmd.startinsert() + end, +}) + +-- Insert when re-entering a terminal window (after switching back) +au('BufEnter', { + group = group, + pattern = 'term://*', + callback = function() + if vim.bo.buftype == 'terminal' and vim.fn.mode() ~= 'i' then + vim.cmd.startinsert() + end + end, +}) + +-- Close all terminal buffers before quitting +au('QuitPre', { + group = group, + callback = function() + for _, buf in ipairs(vim.api.nvim_list_bufs()) do + if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == 'terminal' then + vim.api.nvim_buf_delete(buf, { force = true }) + end + end + end, +}) + +au('InsertEnter', { + group = group, + once = true, + callback = function() + require('nvim-ts-autotag').setup() + require('nvim-autopairs').setup() + end, +}) + +au('UIEnter', { + group = group, + once = true, + callback = function() + vim.schedule(function() + -- start ----- + + local commands = { + TermDefault = function() + vim.cmd('terminal') + end, + + TermRelative = function() + local shell = vim.o.shell or 'zsh' + local dir = vim.fn.expand('%:p:h') + vim.cmd(string.format('edit term://%s//%s', dir, shell)) + end, + + TermSplit = function() + vim.cmd('new') + vim.cmd('wincmd J') + vim.api.nvim_win_set_height(0, 12) + vim.wo.winfixheight = true + vim.cmd('term') + end, + + TermVSplit = function() + vim.cmd('vsplit') + vim.cmd('term') + end, + } + + for name, fn in pairs(commands) do + vim.api.nvim_create_user_command(name, fn, {}) + end + + require('triimd.keymaps') + require('triimd.filetree') + require('triimd.syntax') + require('triimd.diagnostics') + + require('plugins.navigation') + require('plugins.tabline').setup() + + + -- end ----- + end) + end, +}) diff --git a/plugin/packages.lua b/plugin/packages.lua new file mode 100644 index 0000000..ced32bd --- /dev/null +++ b/plugin/packages.lua @@ -0,0 +1,8 @@ +vim.pack.add({ + 'https://github.com/windwp/nvim-ts-autotag', + 'https://github.com/windwp/nvim-autopairs', + + { src = 'https://github.com/nvim-treesitter/nvim-treesitter', version = 'master' }, + 'https://github.com/mfussenegger/nvim-lint', + 'https://github.com/stevearc/conform.nvim', +})