diff --git a/plugins/astrocore/autocmds.nix b/plugins/astrocore/autocmds.nix new file mode 100644 index 0000000..e6627ae --- /dev/null +++ b/plugins/astrocore/autocmds.nix @@ -0,0 +1,358 @@ +# https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua +{ + autoGroups = { + auto_quit.clear = true; + autoview.clear = true; + bufferline.clear = true; + checktime.clear = true; + create_dir.clear = true; + editorconfig_filetype.clear = true; + file_user_events.clear = true; + highlighturl.clear = true; + highlightyank.clear = true; + large_buf_settings.clear = true; + q_close_windows.clear = true; + terminal_settings.clear = true; + unlist_quickfix.clear = true; + }; + + autoCmd = [ + # auto_quit + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L18-L46 + { + event = "BufEnter"; + desc = "Quit neovim if more than one window is open and only sidebar windows are list"; + group = "auto_quit"; + + callback.__raw = '' + function() + local wins = vim.api.nvim_tabpage_list_wins(0) + -- Both neo-tree and aerial will auto-quit if there is only a single window left + if #wins <= 1 then return end + local sidebar_fts = { aerial = true, ["neo-tree"] = true } + for _, winid in ipairs(wins) do + if vim.api.nvim_win_is_valid(winid) then + local bufnr = vim.api.nvim_win_get_buf(winid) + local filetype = vim.bo[bufnr].filetype + -- If any visible windows are not sidebars, early return + if not sidebar_fts[filetype] then + return + -- If the visible window is a sidebar + else + -- only count filetypes once, so remove a found sidebar from the detection + sidebar_fts[filetype] = nil + end + end + end + if #vim.api.nvim_list_tabpages() > 1 then + vim.cmd.tabclose() + else + vim.cmd.qall() + end + end + ''; + } + + # autoview + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L49-L70 + { + event = [ "BufWinLeave" "BufWritePost" "WinLeave" ]; + desc = "Save view with mkview for real files"; + group = "autoview"; + + callback.__raw = '' + function(event) + if vim.b[event.buf].view_activated then vim.cmd.mkview { mods = { emsg_silent = true } } end + end + ''; + } + { + event = "BufWinEnter"; + desc = "Try to load file view if available and enable view saving for real files"; + group = "autoview"; + + callback.__raw = '' + function(event) + if not vim.b[event.buf].view_activated then + local filetype = vim.bo[event.buf].filetype + local buftype = vim.bo[event.buf].buftype + local ignore_filetypes = { "gitcommit", "gitrebase", "svg", "hgcommit" } + if buftype == "" and filetype and filetype ~= "" and not vim.tbl_contains(ignore_filetypes, filetype) then + vim.b[event.buf].view_activated = true + vim.cmd.loadview { mods = { emsg_silent = true } } + end + end + end + ''; + } + + # bufferline + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L73-L115 + { + event = [ "BufAdd" "BufEnter" "TabNewEntered" ]; + desc = "Update buffers when adding new buffers"; + group = "bufferline"; + + callback.__raw = '' + function(args) + local buf_utils = require "astrocore.buffer" + if not vim.t.bufs then vim.t.bufs = {} end + if not buf_utils.is_valid(args.buf) then return end + if args.buf ~= buf_utils.current_buf then + buf_utils.last_buf = buf_utils.is_valid(buf_utils.current_buf) and buf_utils.current_buf or nil + buf_utils.current_buf = args.buf + end + local bufs = vim.t.bufs + if not vim.tbl_contains(bufs, args.buf) then + table.insert(bufs, args.buf) + vim.t.bufs = bufs + end + vim.t.bufs = vim.tbl_filter(buf_utils.is_valid, vim.t.bufs) + require("astrocore").event "BufsUpdated" + end + ''; + } + { + event = [ "BufDelete" "TermClose" ]; + desc = "Update buffers when deleting buffers"; + group = "bufferline"; + + callback.__raw = '' + function(args) + local removed + for _, tab in ipairs(vim.api.nvim_list_tabpages()) do + local bufs = vim.t[tab].bufs + if bufs then + for i, bufnr in ipairs(bufs) do + if bufnr == args.buf then + removed = true + table.remove(bufs, i) + vim.t[tab].bufs = bufs + break + end + end + end + end + vim.t.bufs = vim.tbl_filter(require("astrocore.buffer").is_valid, vim.t.bufs) + if removed then require("astrocore").event "BufsUpdated" end + vim.cmd.redrawtabline() + end + ''; + } + + # checktime + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L118-L122 + { + event = [ "FocusGained" "TermClose" "TermLeave" ]; + desc = "Check if buffers changed on editor focus"; + group = "checktime"; + command = "checktime"; + } + + # create_dir + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L125-L132 + { + event = "BufWritePre"; + desc = "Automatically create parent directories if they don't exist when saving a file"; + group = "create_dir"; + + callback.__raw = '' + function(args) + if not require("astrocore.buffer").is_valid(args.buf) then return end + vim.fn.mkdir(vim.fn.fnamemodify(vim.loop.fs_realpath(args.match) or args.match, ":p:h"), "p") + end + ''; + } + + # editorconfig_filetype + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L135-L144 + { + event = "FileType"; + desc = "configure editorconfig after filetype detection to override `ftplugin`s"; + group = "editorconfig_filetype"; + + callback.__raw = '' + function(args) + if vim.F.if_nil(vim.b.editorconfig, vim.g.editorconfig, true) then + local editorconfig_avail, editorconfig = pcall(require, "editorconfig") + if editorconfig_avail then editorconfig.config(args.buf) end + end + end + ''; + } + + # file_user_events + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L147-L177 + { + event = [ "BufReadPost" "BufNewFile" "BufWritePost" ]; + desc = "AstroNvim user events for file detection (AstroFile and AstroGitFile)"; + group = "file_user_events"; + + callback.__raw = '' + function(args) + if vim.b[args.buf].astrofile_checked then return end + vim.b[args.buf].astrofile_checked = true + vim.schedule(function() + if not vim.api.nvim_buf_is_valid(args.buf) then return end + local astro = require "astrocore" + local current_file = vim.api.nvim_buf_get_name(args.buf) + if vim.g.vscode or not (current_file == "" or vim.bo[args.buf].buftype == "nofile") then + astro.event "File" + local folder = vim.fn.fnamemodify(current_file, ":p:h") + if vim.fn.has "win32" == 1 then folder = ('"%s"'):format(folder) end + if vim.fn.executable "git" == 1 then + if astro.cmd({ "git", "-C", folder, "rev-parse" }, false) or astro.file_worktree() then + astro.event "GitFile" + pcall(vim.api.nvim_del_augroup_by_name, "file_user_events") + end + else + pcall(vim.api.nvim_del_augroup_by_name, "file_user_events") + end + vim.schedule(function() + if require("astrocore.buffer").is_valid(args.buf) then + vim.api.nvim_exec_autocmds(args.event, { buffer = args.buf, data = args.data }) + end + end) + end + end) + end + ''; + } + + # highlighturl + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L180-L203 + { + event = [ "VimEnter" "FileType" "BufEnter" "WinEnter" ]; + desc = "URL Highlighting"; + group = "highlighturl"; + + callback.__raw = '' + function(args) + for _, win in ipairs(vim.api.nvim_list_wins()) do + if + vim.api.nvim_win_get_buf(win) == args.buf + and vim.tbl_get(require "astrocore", "config", "features", "highlighturl") + and not vim.w[win].highlighturl_enabled + then + require("astrocore").set_url_match(win) + end + end + end + ''; + } + { + event = [ "VimEnter" "User" ]; + desc = "Set up the default HighlightURL highlight group"; + group = "highlighturl"; + + callback.__raw = '' + function(args) + if args.event == "VimEnter" or args.match == "AstroColorScheme" then + vim.api.nvim_set_hl(0, "HighlightURL", { default = true, underline = true }) + end + end + ''; + } + + # highlightyank + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L206-L211 + { + event = "TextYankPost"; + desc = "Highlight yanked text"; + group = "highlightyank"; + pattern = "*"; + + callback.__raw = '' + function() + vim.highlight.on_yank() + end + ''; + } + + # large_buf_settings + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L214-L239 + { + event = "User"; + desc = "Disable certain functionality on very large files"; + group = "large_buf_settings"; + pattern = "AstroLargeBuf"; + + callback.__raw = '' + function(args) + vim.opt_local.wrap = true -- enable wrap, long lines in vim are slow + vim.opt_local.list = false -- disable list chars + vim.b[args.buf].autoformat = false -- disable autoformat on save + vim.b[args.buf].cmp_enabled = false -- disable completion + vim.b[args.buf].miniindentscope_disable = true -- disable indent scope + vim.b[args.buf].matchup_matchparen_enabled = 0 -- disable vim-matchup + local astrocore = require "astrocore" + if vim.tbl_get(astrocore.config, "features", "highlighturl") then + astrocore.config.features.highlighturl = false + vim.tbl_map(function(win) + if vim.w[win].highlighturl_enabled then astrocore.delete_url_match(win) end + end, vim.api.nvim_list_wins()) + end + local ibl_avail, ibl = pcall(require, "ibl") -- disable indent-blankline + if ibl_avail then ibl.setup_buffer(args.buf, { enabled = false }) end + local illuminate_avail, illuminate = pcall(require, "illuminate.engine") -- disable vim-illuminate + if illuminate_avail then illuminate.stop_buf(args.buf) end + local rainbow_avail, rainbow = pcall(require, "rainbow-delimiters") -- disable rainbow-delimiters + if rainbow_avail then rainbow.disable(args.buf) end + end + ''; + } + + # q_close_windows + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L242-L255 + { + event = "BufWinEnter"; + desc = "Make q close help, man, quickfix, dap floats"; + group = "q_close_windows"; + + callback.__raw = '' + function(event) + if vim.tbl_contains({ "help", "nofile", "quickfix" }, vim.bo[event.buf].buftype) then + vim.keymap.set("n", "q", "close", { + desc = "Close window", + buffer = event.buf, + silent = true, + nowait = true, + }) + end + end + ''; + } + + # terminal_settings + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L258-L266 + { + event = "TermOpen"; + desc = "Disable line number/fold column/sign column for terminals"; + group = "terminal_settings"; + + callback.__raw = '' + function() + vim.opt_local.number = false + vim.opt_local.relativenumber = false + vim.opt_local.foldcolumn = "0" + vim.opt_local.signcolumn = "no" + end + ''; + } + + # unlist_quickfix + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L270-L275 + { + event = "FileType"; + desc = "Unlist quickfix buffers"; + group = "unlist_quickfix"; + pattern = "qf"; + + callback.__raw = '' + function() + vim.opt_local.buflisted = false + end + ''; + } + ]; +} diff --git a/plugins/astrocore/default.nix b/plugins/astrocore/default.nix index 15da6c5..d94995c 100644 --- a/plugins/astrocore/default.nix +++ b/plugins/astrocore/default.nix @@ -1,27 +1,45 @@ # homepage: https://github.com/AstroNvim/astrocore -{ lib, pkgs, ... }: +{ helpers, icons, lib, pkgs, ... }: +let + autocmds = import ./autocmds.nix; + diagnostics = import ./diagnostics.nix { inherit icons; }; + features = import ./features.nix; + mappings = import ./mappings.nix; + options = import ./options.nix { inherit lib; }; + rooter = import ./rooter.nix; + sessions = import ./sessions.nix; +in { extra = { packages = [ (import ./package { inherit lib pkgs; }) ]; - # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_options.lua#L49-L53 config = '' - local g = {} - g.markdown_recommended_style = 0 - - if not vim.t.bufs then vim.t.bufs = vim.api.nvim_list_bufs() end -- initialize buffer list - require('astrocore').setup({ - g = { - markdown_recommended_style = 0, - }, - t = { - bufs = vim.t.bufs, + diagnostics = ${helpers.toLuaObject diagnostics}, + features = ${helpers.toLuaObject features}, + options = ${helpers.toLuaObject options.astrocore}, + rooter = ${helpers.toLuaObject rooter}, + sessions = ${helpers.toLuaObject sessions}, + on_keys = { + auto_hlsearch = { + function(char) + if vim.fn.mode() == "n" then + local new_hlsearch = vim.tbl_contains({ "", "n", "N", "*", "#", "?", "/" }, vim.fn.keytrans(char)) + if vim.opt.hlsearch:get() ~= new_hlsearch then vim.opt.hlsearch = new_hlsearch end + end + end, + }, }, }) ''; }; + + rootOpts = { + inherit (autocmds) autoGroups autoCmd; + inherit (mappings) keymaps; + inherit (options) opts; + }; } diff --git a/plugins/astrocore/diagnostics.nix b/plugins/astrocore/diagnostics.nix new file mode 100644 index 0000000..c227e1d --- /dev/null +++ b/plugins/astrocore/diagnostics.nix @@ -0,0 +1,33 @@ +# https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore.lua#L40-L61 +{ icons, ... }: + +{ + diagnostics = { + underline = true; + update_in_insert = true; + severity_sort = true; + virtual_text = true; + + float = { + focused = false; + style = "minimal"; + border = "rounded"; + source = "always"; + header = ""; + prefix = ""; + }; + + signs = { + text = { + # vim.diagnostic.severity.ERROR + "1" = icons.DiagnosticError; + # vim.diagnostic.severity.WARN + "2" = icons.DiagnosticWarn; + # vim.diagnostic.severity.INFO + "3" = icons.DiagnosticInfo; + # vim.diagnostic.severity.HINT + "4" = icons.DiagnosticHint; + }; + }; + }; +} diff --git a/plugins/astrocore/features.nix b/plugins/astrocore/features.nix new file mode 100644 index 0000000..d9800ac --- /dev/null +++ b/plugins/astrocore/features.nix @@ -0,0 +1,25 @@ +# https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore.lua#L32-L39 +{ + features = { + # Enable autopairs at start + autopairs = true; + + # Enable completion at start + cmp = true; + + # Enable diagnostics by default + diagnostics_mode = 3; + + # Highlight URLs by default + highlighturl = true; + + # Disable notifications + notifications = true; + + # Set global limits for large files + large_buf = { + lines = 10000; + size = 1024 * 500; + }; + }; +} diff --git a/plugins/astrocore/mappings.nix b/plugins/astrocore/mappings.nix new file mode 100644 index 0000000..225753a --- /dev/null +++ b/plugins/astrocore/mappings.nix @@ -0,0 +1,565 @@ +let + forceWrite = { + action = "silent! update! | redraw"; + options.desc = "Force write"; + }; +in +{ + keymaps = [ + # Standard operations + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_mappings.lua#L27-L44 + { + key = "j"; + mode = [ "n" "x" ]; + action = "v:count == 0 ? 'gj' : 'j'"; + + options = { + desc = "Move cursor down"; + expr = true; + silent = true; + }; + } + { + key = "k"; + mode = [ "n" "x" ]; + action = "v:count == 0 ? 'gk' : 'k'"; + + options = { + desc = "Move cursor up"; + expr = true; + silent = true; + }; + } + { + key = "w"; + action = "w"; + options.desc = "Save"; + } + { + key = "q"; + action = "confirm q"; + options.desc = "Quit window"; + } + { + key = "Q"; + action = "confirm qall"; + options.desc = "Exit neovim"; + } + { + key = "n"; + action = "enew"; + options.desc = "New file"; + } + { + inherit (forceWrite) action options; + key = ""; + } + { + inherit (forceWrite) options; + key = ""; + mode = [ "i" "x" ]; + action = "" + forceWrite.action; + } + { + key = ""; + action = "q!"; + options.desc = "Force quit"; + } + { + key = "|"; + action = "vsplit"; + options.desc = "Vertical split"; + } + { + key = "\\\\"; + action = "split"; + options.desc = "Horizontal split"; + } + { + key = "gx"; + action.__raw = "require('astrocore').system_open"; + options.desc = "Open the file under cursor with system app"; + } + + # Manage buffers + # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_mappings.lua#L56-L89 + { + key = "c"; + options.desc = "Close buffer"; + + action.__raw = '' + function() + require("astrocore.buffer").close() + end + ''; + } + { + key = "C"; + options.desc = "Force close buffer"; + + action.__raw = '' + function() + require("astrocore.buffer").close(0, true) + end + ''; + } + { + key = "]b"; + options.desc = "Next buffer in tabline"; + + action.__raw = '' + function() + require("astrocore.buffer").nav(vim.v.count1) + end + ''; + } + { + key = "[b"; + options.desc = "Previous buffer in tabline"; + + action.__raw = '' + function() + require("astrocore.buffer").nav(-vim.v.count1) + end + ''; + } + { + key = ">b"; + options.desc = "Move buffer tab right"; + + action.__raw = '' + function() + require("astrocore.buffer").move(vim.v.count1) + end + ''; + } + { + key = "