{
  pkgs,
  config,
  ...
}: let
  user = config.home.username;
in {

  imports = [
    ./cmp.nix
    ./colorizer.nix
    ./conform.nix
    ./gitsigns.nix
    ./harpoon.nix
    ./lsp.nix
    ./lualine.nix
    ./luasnip.nix
    ./nvim-tree.nix
    ./surround.nix
    ./telescope.nix
    ./treesitter.nix
    ./fold.nix
    ./todo-comments.nix
    ./oil.nix
    ./comment.nix
  ];

  # Load Plugins that aren't provided as modules by nixvim
  programs.nixvim.extraPlugins = [
    pkgs.vimPlugins.vim-numbertoggle
    pkgs.vimPlugins.vimwiki
    pkgs.vimPlugins.vim-dadbod
    pkgs.vimPlugins.vim-dadbod-ui
    pkgs.vimPlugins.vim-dadbod-completion
    pkgs.vimPlugins.fugitive

    (pkgs.vimUtils.buildVimPlugin
      {
        name = "glow.nvim";
        src = pkgs.fetchFromGitHub {
          owner = "ellisonleao";
          repo = "glow.nvim";
          rev = "238070a";
          sha256 = "sha256-GsNcASzVvY0066kak2nvUY5luzanoBclqcUOsODww8g=";
        };
      })

    (pkgs.vimUtils.buildVimPlugin
      {
        name = "buffer_manager.nvim";
        src = pkgs.fetchFromGitHub {
          owner = "j-morano";
          repo = "buffer_manager.nvim";
          rev = "fd36131";
          sha256 = "sha256-abe9ZGmL7U9rC+LxC3LO5/bOn8lHke1FCKO0V3TZGs0=";
        };
      })

    (pkgs.vimUtils.buildVimPlugin
      {
        name = "vimwiki-sync";
        src = pkgs.fetchFromGitHub {
          owner = "michal-h21";
          repo = "vimwiki-sync";
          rev = "99eeab3";
          sha256 = "sha256-cz0dSFphIbQAI4AOqwIUpDBTuj/3xlOkhSlIVMdgsqM=";
        };
      })

    # Keep vim-devicons as last entry
    pkgs.vimPlugins.vim-devicons
  ];
  programs.nixvim.extraConfigLua = ''
    -- function to read api key from secrets file
     local function read_api_key(file_path)
     	local file = io.open(file_path, "r")
     	if file then
     		local api_key = file:read("*all")
     		file:close()
     		return api_key
     	else
     		error("Failed to open file: " .. file_path)
     	end
     end

    -- buffer_manager.nvim
    local opts = {noremap = true}

    require("buffer_manager").setup(
      {
        line_keys = "1234567890",
        select_menu_item_commands = {
          edit = {
            key = "<CR>",
            command = "edit"
          }
        },
        focus_alternate_buffer = true,
        short_file_names = false,
        short_term_names = true,
        height = 15,
        width = 0.8,
        loop_nav = true,
        highlight = "",
        win_extra_options = {},
        borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
        order_buffers = "lastused",
        show_indicators = "before",
      }
    )

    require('glow').setup({
        border = "shadow",
        style = "dark",
        pager = false,
        width = 80,
        height = 100,
        width_ratio = 0.7,
        height_ratio = 0.7,
    })

    -- Custom color for modified buffers
    vim.api.nvim_set_hl(0, "BufferManagerModified", { fg = "#988100" })

    local bmui = require("buffer_manager.ui")
    vim.keymap.set('n', '<leader>b', bmui.toggle_quick_menu, opts)
    vim.keymap.set('n', '<leader>n', bmui.nav_next, opts)
    vim.keymap.set('n', '<leader>p', bmui.nav_prev, opts)

    local keys="1234567890"
    for i = 1, #keys do
      local key = keys:sub(i,i)
      vim.keymap.set('n', string.format('<leader>%s', key),
        function () bmui.nav_file(i) end,
        opts
      )
    end

    -- Setup vimwiki

    vim.g.vimwiki_list = {
        {
            syntax = "markdown",
            ext = ".md",
            path = "/home/${user}/.local/share/notes",
        },
    }

    -- Format function for conform.nvim
    vim.api.nvim_create_user_command("Format", function(args)
      local range = nil
      if args.count ~= -1 then
        local end_line = vim.api.nvim_buf_get_lines(0, args.line2 - 1, args.line2, true)[1]
        range = {
          start = { args.line1, 0 },
          ["end"] = { args.line2, end_line:len() },
        }
      end
      require("conform").format({ async = true, lsp_format = "fallback", range = range })
    end, { range = true })
  '';
}