# 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
    {
      desc =
        "Quit neovim if more than one window is open and only sidebar windows are list";
      event = "BufEnter";
      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
    {
      desc = "Save view with mkview for real files";
      event = [ "BufWinLeave" "BufWritePost" "WinLeave" ];
      group = "autoview";

      callback.__raw = ''
        function(event)
          if vim.b[event.buf].view_activated then vim.cmd.mkview { mods = { emsg_silent = true } } end
        end
      '';
    }
    {
      desc =
        "Try to load file view if available and enable view saving for real files";
      event = "BufWinEnter";
      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
      '';
    }

    # checktime
    # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L118-L122
    {
      desc = "Check if buffers changed on editor focus";
      event = [ "FocusGained" "TermClose" "TermLeave" ];
      group = "checktime";
      command = "checktime";
    }

    # create_dir
    # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L125-L132
    {
      desc =
        "Automatically create parent directories if they don't exist when saving a file";
      event = "BufWritePre";
      group = "create_dir";

      callback.__raw = ''
        function(event)
                 if event.match:match("^%w%w+://") then
                   return
                 end
                 local file = vim.loop.fs_realpath(event.match) or event.match
                 vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p")
               end
      '';
    }

    # editorconfig_filetype
    # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L135-L144
    {
      desc =
        "Configure editorconfig after filetype detection to override `ftplugin`s";
      event = "FileType";
      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
      '';
    }

    {
      desc = "Set up the default HighlightURL highlight group";
      event = [ "VimEnter" "User" ];
      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
    {
      desc = "Highlight yanked text";
      event = "TextYankPost";
      group = "highlightyank";
      pattern = "*";

      callback.__raw = ''
        function()
          vim.highlight.on_yank()
        end
      '';
    }

    # q_close_windows
    # https://github.com/AstroNvim/AstroNvim/blob/v4.7.7/lua/astronvim/plugins/_astrocore_autocmds.lua#L242-L255
    {
      desc = "Make q close help, man, quickfix, dap floats";
      event = "BufWinEnter";
      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", "<Cmd>close<CR>", {
              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
    {
      desc = "Disable line number/fold column/sign column for terminals";
      event = "TermOpen";
      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
    {
      desc = "Unlist quickfix buffers";
      event = "FileType";
      group = "unlist_quickfix";
      pattern = "qf";

      callback.__raw = ''
        function()
          vim.opt_local.buflisted = false
        end
      '';
    }
    {
      desc = "Close these type of File";
      event = [ "FileType" ];
      pattern = [
        "PlenaryTestPopup"
        "help"
        "lspinfo"
        "man"
        "notify"
        "qf"
        "query"
        "spectre_panel"
        "startuptime"
        "tsplayground"
        "neotest-output"
        "checkhealth"
        "neotest-summary"
        "neotest-output-panel"
      ];

      callback = {
        __raw = ''
          function(event)
            vim.bo[event.buf].buflisted = false
            vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
          end
        '';
      };
    }
    {
      event = [ "CursorHold" ];
      desc = "lsp show diagnostics on CursorHold";
      callback = {
        __raw = ''
          function()
            local hover_opts = {
              focusable = false,
              close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
              border = "rounded",
              source = "always",
            }
            vim.diagnostic.open_float(nil, hover_opts)
          end
        '';
      };
    }

    {
      desc = "Save session";
      event = [ "BufWinLeave" ];
      pattern = [ "*.*" ];
      command = "mkview";
    }
    {
      desc = "Load session";
      event = [ "BufWinEnter" ];
      pattern = [ "*.*" ];
      command = "silent! loadview";
    }
  ];
}
