local plugins = {
    -- Open binary files in hex mode and edit them
    {
        "RaafatTurki/hex.nvim",
        config = true,
        lazy = false,
    },
    -- Auto-save files when in normal mode
    {
        "Pocco81/auto-save.nvim",
        lazy = false,
        config = function()
            require("auto-save").setup({})
        end,
    },
    -- Open every file where you left off 
    {
        "ethanholz/nvim-lastplace",
        event = "BufRead",
        config = function()
            require("nvim-lastplace").setup({
                lastplace_ignore_buftype = { "quickfix", "nofile", "help" },
                lastplace_ignore_filetype = { "gitcommit", "gitrebase", "svn", "hgcommit", },
                lastplace_open_folds = true,
            })
        end,
    },
    -- Map keys for better word movement
    {
        "chrisgrieser/nvim-spider",
        lazy = true,
    },
    -- Map keys for smooth scrolling 
    {
        "karb94/neoscroll.nvim",
        event = "WinScrolled",
        config = function()
            require('neoscroll').setup({
                -- All these keys will be mapped to their corresponding default scrolling animation
                mappings = { '<C-u>', '<C-d>', '<C-b>', '<C-f>', '<C-y>', '<C-e>', 'zt', 'zz', 'zb' },
                hide_cursor = true,          -- Hide cursor while scrolling
                stop_eof = true,             -- Stop at <EOF> when scrolling downwards
                use_local_scrolloff = false, -- Use the local scope of scrolloff instead of the global scope
                respect_scrolloff = false,   -- Stop scrolling when the cursor reaches the scrolloff margin of the file
                cursor_scrolls_alone = true, -- The cursor will keep on scrolling even if the window cannot scroll further
                easing_function = nil,        -- Default easing function
                pre_hook = nil,              -- Function to run before the scrolling animation starts
                post_hook = nil,              -- Function to run after the scrolling animation ends
            })
        end,
    },
    -- Underline current and matching word
    {
        "itchyny/vim-cursorword",
        event = {"BufEnter", "BufNewFile"},
        config = function()
            vim.api.nvim_command("augroup user_plugin_cursorword")
            vim.api.nvim_command("autocmd!")
            vim.api.nvim_command("autocmd FileType NvimTree,lspsagafinder,dashboard,vista let b:cursorword = 0")
            vim.api.nvim_command("autocmd WinEnter * if &diff || &pvw | let b:cursorword = 0 | endif")
            vim.api.nvim_command("autocmd InsertEnter * let b:cursorword = 0")
            vim.api.nvim_command("autocmd InsertLeave * let b:cursorword = 1")
            vim.api.nvim_command("augroup END")
        end,
    },
    -- Highlight the entire line in visual line mode  
    {
        "0xAdk/full_visual_line.nvim",
        keys = 'V',
        opts = {},
    },
    -- Display number of uses of a Function
    {
        'VidocqH/lsp-lens.nvim',
        event = "VeryLazy",
        opts = {
            setup = function()
                require('lsp-lens').setup()
            end,
        },
    },
    -- Split or join block of code 
    {
        "Wansmer/treesj",
        dependencies = { 'nvim-treesitter/nvim-treesitter' },
        config = function()
            require('treesj').setup({
                use_default_keymaps = false,
            })
        end,
    },
    -- Replace the UI for messages, cmdline, and the popupmenu
    {
        "folke/noice.nvim",
        event = "VeryLazy",
        config = function()
            require("noice").setup({
                lsp = {
                    override = {
                        ["vim.lsp.util.convert_input_to_markdown_lines"] = true,
                        ["vim.lsp.util.stylize_markdown"] = true,
                        ["cmp.entry.get_documentation"] = true,
                    },
                    signature = { enable = false },
                    hover = { enable = false },
                },
                presets = {
                    bottom_search = true,
                    command_palette = true,
                    long_message_to_split = true,
                    inc_rename = false,
                    lsp_doc_border = false,
                },
            })
        end,
        dependencies = {
            "MunifTanjim/nui.nvim",
            {
                "rcarriga/nvim-notify",
                opts = {
                    background_colour = "#000000",
                }
            },
        },
        opts = {
        },
    },
    -- Display the lsp diagnostics in a window
    {
      "folke/trouble.nvim",
      opts = {}, -- for default options, refer to the configuration section for custom setup.
      cmd = "Trouble",
      keys = {
        {
          "<leader>xx",
          "<cmd>Trouble diagnostics toggle<cr>",
          desc = "Diagnostics (Trouble)",
        },
        {
          "<leader>cs",
          "<cmd>Trouble symbols toggle focus=false<cr>",
          desc = "Symbols (Trouble)",
        },
      },
    },
    -- Minimap plugin
    {
        "gorbit99/codewindow.nvim",
        lazy = false,
        config = function()
            local codewindow = require("codewindow")
            -- vim.api.nvim_set_hl(0, "CodewindowBorder", {fg = "#928374"})
            codewindow.setup({
                auto_enable = true,
                minimap_width = 10,
                screen_bounds = "background",
                window_border = "none",
            })
            codewindow.apply_default_keybinds({})
        end,
    },
    -- Highlight the indent line and the current chunk
    {
        "shellRaining/hlchunk.nvim",
        event = { "UIEnter" },
        config = function()
            require("hlchunk").setup({
                chunk = {
                    enable = true,
                    chars = {
                        horizontal_line = "─",
                        vertical_line = "│",
                        left_top = "╭",
                        left_bottom = "╰",
                        right_arrow = ">",
                    },
                    style = {
                        { fg = "#FABD2F" },
                        { fg = "#c21f30" }, -- this fg is used to highlight wrong chunk
                    },
                },
                indent = {
                    enable = false,
                },
                line_num = {
                    enable = true,
                    style = "#FABD2F",
                },
                blank = {
                    enable = false,
                },
            })
        end
    },
    -- Integrate Github Copilot in NeoVim
    {
        "zbirenbaum/copilot.lua",
        lazy = false,
        cmd = "Copilot",
        event = "InsertEnter",
        config = function()
            require("copilot").setup({
                panel = {
                    enabled = true,
                    auto_refresh = true,
                    keymap = {
                        jump_prev = "[[",
                        jump_next = "]]",
                        accept = "<CR>",
                        refresh = "gr",
                        open = "<M-CR>"
                    },
                    layout = {
                        position = "bottom", -- | top | left | right
                        ratio = 0.4
                    },
                },
                suggestion = {
                    enabled = true,
                    auto_trigger = true,
                    debounce = 75,
                    keymap = {
                        accept = "<M-l>",
                        accept_word = false,
                        accept_line = false,
                        next = "<M-]>",
                        prev = "<M-[>",
                        dismiss = "<C-]>",
                    },
                },
                filetypes = {
                    yaml = false,
                    markdown = true,
                    help = false,
                    gitcommit = false,
                    gitrebase = false,
                    hgcommit = false,
                    svn = false,
                    cvs = false,
                    ["."] = false,
                },
                copilot_node_command = 'node', -- Node.js version must be > 18.x
                server_opts_overrides = {},
            })
        end,
    },
    -- Chat for copilot
    {
        "CopilotC-Nvim/CopilotChat.nvim",
        event = "VeryLazy",
        branch = "main",
        dependencies = {
            { "zbirenbaum/copilot.lua" }, -- or github/copilot.vim
            { "nvim-lua/plenary.nvim" }, -- for curl, log wrapper
            {
                'MeanderingProgrammer/render-markdown.nvim',
                dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' },
                ---@module 'render-markdown'
                ---@type render.md.UserConfig
                opts = {},
                config = function ()
                    require('render-markdown').setup({
                        file_types = { 'markdown', 'copilot-chat' },
                    })
                end
            },
        },
        build = "make tiktoken",
        opts = {
            debug = true, -- Enable debugging
            model = "claude-3.5-sonnet",
        },
        keys = {
            {
                "<leader>ccq",
                function()
                  local input = vim.fn.input("Quick Chat: ")
                  if input ~= "" then
                    require("CopilotChat").ask(input, { selection = require("CopilotChat.select").buffer })
                  end
                end,
                desc = "CopilotChat - Quick chat",
            },
            {
                "<leader>ccf",
                function()
                  require("CopilotChat").ask("Fix this, using the lsp diagnostics if needed", { selection = require("CopilotChat.select").visual })
                end,
                desc = "CopilotChat - Fix this",
            },
        },
        config = function ()
            require('CopilotChat').setup({
                highlight_headers = false,
                separator = '---',
                error_header = '> [!ERROR] Error',
            })
        end
    },
    -- Suspend unused lsp
    {
        "zeioth/garbage-day.nvim",
        dependencies = "neovim/nvim-lspconfig",
        event = "VeryLazy",
    },
    -- DAP and JTDLS (lsp) configuration for Java
    {
        "nvim-java/nvim-java",
        lazy = false,
        dependencies = {
            "nvim-java/lua-async-await",
            "nvim-java/nvim-java-core",
            "nvim-java/nvim-java-test",
            "nvim-java/nvim-java-dap",
            "nvim-java/nvim-java-refactor",
            "MunifTanjim/nui.nvim",
            "neovim/nvim-lspconfig",
            "mfussenegger/nvim-dap",
            {
                "williamboman/mason.nvim",
                opts = {
                        registries = {
                        "github:nvim-java/mason-registry",
                        "github:mason-org/mason-registry",
                    },
                },
            },
            {
                "williamboman/mason-lspconfig.nvim",
                opts = {
                    handlers = {
                        ["jdtls"] = function()
                            require("java").setup()
                            require("lspconfig").jdtls.setup({})
                        end,
                    },
                },
            },
        },
    }
}

return plugins
