2-ui.lua

  1-- User interface
  2-- Things that make the GUI better.
  3
  4--    Sections:
  5--       -> tokyonight                  [theme]
  6--       -> astrotheme                  [theme]
  7--       -> alpha-nvim                  [greeter]
  8--       -> nvim-notify                 [notifications]
  9--       -> mini.indentscope            [guides]
 10--       -> heirline-components.nvim    [ui components]
 11--       -> heirline                    [ui components]
 12--       -> telescope                   [search]
 13--       -> telescope-fzf-native.nvim   [search backend]
 14--       -> smart-splits                [window-dimming]
 15--       -> dressing.nvim               [better ui elements]
 16--       -> noice.nvim                  [better cmd/search line]
 17--       -> nvim-web-devicons           [icons | ui]
 18--       -> lspkind.nvim                [icons | lsp]
 19--       -> nvim-scrollbar              [scrollbar]
 20--       -> mini.animate                [animations]
 21--       -> highlight-undo              [highlights]
 22--       -> which-key                   [on-screen keybinding]
 23
 24local utils = require "base.utils"
 25local is_windows = vim.fn.has('win32') == 1         -- true if on windows
 26local is_android = vim.fn.isdirectory('/data') == 1 -- true if on android
 27
 28return {
 29
 30  -- tokyonight [theme]
 31  -- https://github.com/folke/tokyonight.nvim
 32  {
 33    "zeioth/tokyonight.nvim",
 34    event = "User LoadColorSchemes",
 35    opts = {
 36      dim_inactive = false,
 37      styles = {
 38        comments = { italic = true },
 39        keywords = { italic = true },
 40      },
 41    }
 42  },
 43
 44  --  astrotheme [theme]
 45  --  https://github.com/AstroNvim/astrotheme
 46  {
 47    "AstroNvim/astrotheme",
 48    event = "User LoadColorSchemes",
 49    opts = {
 50      palette = "astrodark",
 51      plugins = { ["dashboard-nvim"] = true },
 52    },
 53  },
 54
 55  --  alpha-nvim [greeter]
 56  --  https://github.com/goolord/alpha-nvim
 57  {
 58    "goolord/alpha-nvim",
 59    cmd = "Alpha",
 60    -- setup header and buttonts
 61    opts = function()
 62      local dashboard = require("alpha.themes.dashboard")
 63
 64      -- Header
 65      -- dashboard.section.header.val = {
 66      --   "                                                                     ",
 67      --   "       ████ ██████           █████      ██                     ",
 68      --   "      ███████████             █████                             ",
 69      --   "      █████████ ███████████████████ ███   ███████████   ",
 70      --   "     █████████  ███    █████████████ █████ ██████████████   ",
 71      --   "    █████████ ██████████ █████████ █████ █████ ████ █████   ",
 72      --   "  ███████████ ███    ███ █████████ █████ █████ ████ █████  ",
 73      --   " ██████  █████████████████████ ████ █████ █████ ████ ██████ ",
 74      -- }
 75      -- dashboard.section.header.val = {
 76      --   '                                        ▟▙            ',
 77      --   '                                        ▝▘            ',
 78      --   '██▃▅▇█▆▖  ▗▟████▙▖   ▄████▄   ██▄  ▄██  ██  ▗▟█▆▄▄▆█▙▖',
 79      --   '██▛▔ ▝██  ██▄▄▄▄██  ██▛▔▔▜██  ▝██  ██▘  ██  ██▛▜██▛▜██',
 80      --   '██    ██  ██▀▀▀▀▀▘  ██▖  ▗██   ▜█▙▟█▛   ██  ██  ██  ██',
 81      --   '██    ██  ▜█▙▄▄▄▟▊  ▀██▙▟██▀   ▝████▘   ██  ██  ██  ██',
 82      --   '▀▀    ▀▀   ▝▀▀▀▀▀     ▀▀▀▀       ▀▀     ▀▀  ▀▀  ▀▀  ▀▀',
 83      -- }
 84      -- dashboard.section.header.val = {
 85      --   '                    ▟▙            ',
 86      --   '                    ▝▘            ',
 87      --   '██▃▅▇█▆▖  ██▄  ▄██  ██  ▗▟█▆▄▄▆█▙▖',
 88      --   '██▛▔ ▝██  ▝██  ██▘  ██  ██▛▜██▛▜██',
 89      --   '██    ██   ▜█▙▟█▛   ██  ██  ██  ██',
 90      --   '██    ██   ▝████▘   ██  ██  ██  ██',
 91      --   '▀▀    ▀▀     ▀▀     ▀▀  ▀▀  ▀▀  ▀▀',
 92      -- }
 93      -- Generated with https://www.fancytextpro.com/BigTextGenerator/Larry3D
 94      -- dashboard.section.header.val = {
 95      --   [[ __  __                  __  __                     ]],
 96      --   [[/\ \/\ \                /\ \/\ \  __                ]],
 97      --   [[\ \ `\\ \     __    ___ \ \ \ \ \/\_\    ___ ___    ]],
 98      --   [[ \ \ , ` \  /'__`\ / __`\\ \ \ \ \/\ \ /' __` __`\  ]],
 99      --   [[  \ \ \`\ \/\  __//\ \L\ \\ \ \_/ \ \ \/\ \/\ \/\ \ ]],
100      --   [[   \ \_\ \_\ \____\ \____/ \ `\___/\ \_\ \_\ \_\ \_\]],
101      --   [[    \/_/\/_/\/____/\/___/   `\/__/  \/_/\/_/\/_/\/_/]],
102      -- }
103      --  dashboard.section.header.val = {
104      --   '                                                     ',
105      --   '  ███╗   ██╗███████╗ ██████╗ ██╗   ██╗██╗███╗   ███╗ ',
106      --   '  ████╗  ██║██╔════╝██╔═══██╗██║   ██║██║████╗ ████║ ',
107      --   '  ██╔██╗ ██║█████╗  ██║   ██║██║   ██║██║██╔████╔██║ ',
108      --   '  ██║╚██╗██║██╔══╝  ██║   ██║╚██╗ ██╔╝██║██║╚██╔╝██║ ',
109      --   '  ██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║ ',
110      --   '  ╚═╝  ╚═══╝╚══════╝ ╚═════╝   ╚═══╝  ╚═╝╚═╝     ╚═╝ ',
111      --   '                                                     ',
112      -- }
113      -- dashboard.section.header.val = {
114      --   [[                __                ]],
115      --   [[  ___   __  __ /\_\    ___ ___    ]],
116      --   [[/' _ `\/\ \/\ \\/\ \ /' __` __`\  ]],
117      --   [[/\ \/\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]],
118      --   [[\ \_\ \_\ \___/  \ \_\ \_\ \_\ \_\]],
119      --   [[ \/_/\/_/\/__/    \/_/\/_/\/_/\/_/]],
120      -- }
121
122      if is_android then
123        dashboard.section.header.val = {
124          [[         __                ]],
125          [[ __  __ /\_\    ___ ___    ]],
126          [[/\ \/\ \\/\ \ /' __` __`\  ]],
127          [[\ \ \_/ |\ \ \/\ \/\ \/\ \ ]],
128          [[ \ \___/  \ \_\ \_\ \_\ \_\]],
129          [[  \/__/    \/_/\/_/\/_/\/_/]],
130        }
131      else
132        dashboard.section.header.val = {
133          [[888b      88                                                           88]],
134          [[8888b     88                                                           88]],
135          [[88 `8b    88                                                           88]],
136          [[88  `8b   88   ,adPPYba,   8b,dPPYba,  88,dPYba,,adPYba,   ,adPPYYba,  88]],
137          [[88   `8b  88  a8"     "8a  88P'   "Y8  88P'   "88"    "8a  ""     `Y8  88]],
138          [[88    `8b 88  8b       d8  88          88      88      88  ,adPPPPP88  88]],
139          [[88     `8888  "8a,   ,a8"  88          88      88      88  88,    ,88  88]],
140          [[88      `888   `"YbbdP"'   88          88      88      88  `"8bbdP"Y8  88]],
141          [[                                    __                ]],
142          [[                      ___   __  __ /\_\    ___ ___    ]],
143          [[                    /' _ `\/\ \/\ \\/\ \ /' __` __`\  ]],
144          [[                    /\ \/\ \ \ \_/ |\ \ \/\ \/\ \/\ \ ]],
145          [[                    \ \_\ \_\ \___/  \ \_\ \_\ \_\ \_\]],
146          [[                     \/_/\/_/\/__/    \/_/\/_/\/_/\/_/]],
147        }
148      end
149
150      dashboard.section.header.opts.hl = "DashboardHeader"
151      vim.cmd "highlight DashboardHeader guifg=#F7778F"
152
153      -- If on windows, don't show the 'ranger' button
154      local ranger_button = dashboard.button("r", "🐍 Ranger  ", "<cmd>RnvimrToggle<CR>")
155      if is_windows then ranger_button = nil end
156
157      -- Buttons
158      dashboard.section.buttons.val = {
159        dashboard.button("n", "📄 New     ", "<cmd>ene<CR>"),
160        dashboard.button("e", "🌺 Recent  ", "<cmd>Telescope oldfiles<CR>"),
161        ranger_button,
162        dashboard.button(
163          "s",
164          "🔎 Sessions",
165          "<cmd>SessionManager! load_session<CR>"
166        ),
167        dashboard.button("p", "💼 Projects", "<cmd>Telescope projects<CR>"),
168        dashboard.button("", ""),
169        dashboard.button("q", "   Quit", "<cmd>exit<CR>"),
170        --  --button("LDR f '", "  Bookmarks  "),
171      }
172
173      -- Vertical margins
174      dashboard.config.layout[1].val =
175          vim.fn.max { 2, vim.fn.floor(vim.fn.winheight(0) * 0.10) } -- Above header
176      dashboard.config.layout[3].val =
177          vim.fn.max { 2, vim.fn.floor(vim.fn.winheight(0) * 0.10) } -- Above buttons
178
179      -- Disable autocmd and return
180      dashboard.config.opts.noautocmd = true
181      return dashboard
182    end,
183    config = function(_, opts)
184      -- Footer
185      require("alpha").setup(opts.config)
186      vim.api.nvim_create_autocmd("User", {
187        pattern = "LazyVimStarted",
188        desc = "Add Alpha dashboard footer",
189        once = true,
190        callback = function()
191          local stats = require("lazy").stats()
192          stats.real_cputime = not is_windows
193          local ms = math.floor(stats.startuptime * 100 + 0.5) / 100
194          opts.section.footer.val = {
195            " ",
196            " ",
197            " ",
198            "Loaded " .. stats.loaded .. " plugins  in " .. ms .. "ms",
199            ".............................",
200          }
201          opts.section.footer.opts.hl = "DashboardFooter"
202          vim.cmd "highlight DashboardFooter guifg=#D29B68"
203          pcall(vim.cmd.AlphaRedraw)
204        end,
205      })
206    end,
207  },
208
209  --  [notifications]
210  --  https://github.com/rcarriga/nvim-notify
211  {
212    "rcarriga/nvim-notify",
213    event = "User BaseDefered",
214    opts = function()
215      local fps
216      if is_android then fps = 30 else fps = 144 end
217
218      return {
219        timeout = 2500,
220        fps = fps,
221        max_height = function() return math.floor(vim.o.lines * 0.75) end,
222        max_width = function() return math.floor(vim.o.columns * 0.75) end,
223        on_open = function(win)
224          -- enable markdown support on notifications
225          vim.api.nvim_win_set_config(win, { zindex = 175 })
226          if not vim.g.notifications_enabled then
227            vim.api.nvim_win_close(win, true)
228          end
229          if not package.loaded["nvim-treesitter"] then
230            pcall(require, "nvim-treesitter")
231          end
232          vim.wo[win].conceallevel = 3
233          local buf = vim.api.nvim_win_get_buf(win)
234          if not pcall(vim.treesitter.start, buf, "markdown") then
235            vim.bo[buf].syntax = "markdown"
236          end
237          vim.wo[win].spell = false
238        end,
239      }
240    end,
241    config = function(_, opts)
242      local notify = require("notify")
243      notify.setup(opts)
244      vim.notify = notify
245    end,
246  },
247
248  --  mini.indentscope [guides]
249  --  https://github.com/echasnovski/mini.indentscope
250  {
251    "echasnovski/mini.indentscope",
252    event = { "BufReadPre", "BufNewFile" },
253    opts = {
254      draw = { delay = 0, animation = function() return 0 end },
255      options = { border = "top", try_as_border = true },
256      symbol = "",
257    },
258    config = function(_, opts)
259      require("mini.indentscope").setup(opts)
260
261      -- Disable for certain filetypes
262      vim.api.nvim_create_autocmd({ "FileType" }, {
263        desc = "Disable indentscope for certain filetypes",
264        callback = function()
265          local ignored_filetypes = {
266            "aerial",
267            "dashboard",
268            "help",
269            "lazy",
270            "leetcode.nvim",
271            "mason",
272            "neo-tree",
273            "NvimTree",
274            "neogitstatus",
275            "notify",
276            "startify",
277            "toggleterm",
278            "Trouble",
279            "calltree",
280            "coverage"
281          }
282          if vim.tbl_contains(ignored_filetypes, vim.bo.filetype) then
283            vim.b.miniindentscope_disable = true
284          end
285        end,
286      })
287    end
288  },
289
290  -- heirline-components.nvim [ui components]
291  -- https://github.com/zeioth/heirline-components.nvim
292  -- Collection of components to use on your heirline config.
293  {
294    "zeioth/heirline-components.nvim",
295    opts = {
296      icons = require("base.icons.nerd_font")
297    }
298  },
299
300  --  heirline [ui components]
301  --  https://github.com/rebelot/heirline.nvim
302  --  Use it to customize the components of your user interface,
303  --  Including tabline, winbar, statuscolumn, statusline.
304  --  Be aware some components are positional. Read heirline documentation.
305  {
306    "rebelot/heirline.nvim",
307    dependencies = { "zeioth/heirline-components.nvim" },
308    event = "User BaseDefered",
309    opts = function()
310      local lib = require "heirline-components.all"
311      return {
312        opts = {
313          disable_winbar_cb = function(args) -- We do this to avoid showing it on the greeter.
314            local is_disabled = not require("heirline-components.buffer").is_valid(args.buf) or
315                lib.condition.buffer_matches({
316                  buftype = { "terminal", "prompt", "nofile", "help", "quickfix" },
317                  filetype = { "NvimTree", "neo%-tree", "dashboard", "Outline", "aerial" },
318                }, args.buf)
319            return is_disabled
320          end,
321        },
322        tabline = { -- UI upper bar
323          lib.component.tabline_conditional_padding(),
324          lib.component.tabline_buffers(),
325          lib.component.fill { hl = { bg = "tabline_bg" } },
326          lib.component.tabline_tabpages()
327        },
328        winbar = { -- UI breadcrumbs bar
329          init = function(self) self.bufnr = vim.api.nvim_get_current_buf() end,
330          fallthrough = false,
331          -- Winbar for terminal, neotree, and aerial.
332          {
333            condition = function() return not lib.condition.is_active() end,
334            {
335              lib.component.neotree(),
336              lib.component.compiler_play(),
337              lib.component.fill(),
338              lib.component.compiler_redo(),
339              lib.component.aerial(),
340            },
341          },
342          -- Regular winbar
343          {
344            lib.component.neotree(),
345            lib.component.compiler_play(),
346            lib.component.fill(),
347            lib.component.breadcrumbs(),
348            lib.component.fill(),
349            lib.component.compiler_redo(),
350            lib.component.aerial(),
351          }
352        },
353        statuscolumn = { -- UI left column
354          init = function(self) self.bufnr = vim.api.nvim_get_current_buf() end,
355          lib.component.foldcolumn(),
356          lib.component.numbercolumn(),
357          lib.component.signcolumn(),
358        } or nil,
359        statusline = { -- UI statusbar
360          hl = { fg = "fg", bg = "bg" },
361          lib.component.mode(),
362          lib.component.git_branch(),
363          lib.component.file_info(),
364          lib.component.git_diff(),
365          lib.component.diagnostics(),
366          lib.component.fill(),
367          lib.component.cmd_info(),
368          lib.component.fill(),
369          lib.component.lsp(),
370          lib.component.compiler_state(),
371          lib.component.virtual_env(),
372          lib.component.nav(),
373          lib.component.mode { surround = { separator = "right" } },
374        },
375      }
376    end,
377    config = function(_, opts)
378      local heirline = require("heirline")
379      local heirline_components = require "heirline-components.all"
380
381      -- Setup
382      heirline_components.init.subscribe_to_events()
383      heirline.load_colors(heirline_components.hl.get_colors())
384      heirline.setup(opts)
385    end,
386  },
387
388  --  Telescope [search] + [search backend] dependency
389  --  https://github.com/nvim-telescope/telescope.nvim
390  --  https://github.com/nvim-telescope/telescope-fzf-native.nvim
391  --  https://github.com/debugloop/telescope-undo.nvim
392  --  NOTE: Normally, plugins that depend on Telescope are defined separately.
393  --  But its Telescope extension is added in the Telescope 'config' section.
394  {
395    "nvim-telescope/telescope.nvim",
396    dependencies = {
397      {
398        "debugloop/telescope-undo.nvim",
399        cmd = "Telescope",
400      },
401      {
402        "nvim-telescope/telescope-fzf-native.nvim",
403        enabled = vim.fn.executable "make" == 1,
404        build = "make",
405      },
406    },
407    cmd = "Telescope",
408    opts = function()
409      local get_icon = require("base.utils").get_icon
410      local actions = require("telescope.actions")
411      local mappings = {
412        i = {
413          ["<C-n>"] = actions.cycle_history_next,
414          ["<C-p>"] = actions.cycle_history_prev,
415          ["<C-j>"] = actions.move_selection_next,
416          ["<C-k>"] = actions.move_selection_previous,
417          ["<ESC>"] = actions.close,
418          ["<C-c>"] = false,
419        },
420        n = { ["q"] = actions.close },
421      }
422      return {
423        defaults = {
424          prompt_prefix = get_icon("Selected", 1),
425          selection_caret = get_icon("Selected", 1),
426          multi_icon = get_icon("selected", 1),
427          path_display = { "truncate" },
428          sorting_strategy = "ascending",
429          layout_config = {
430            horizontal = {
431              prompt_position = "top",
432              preview_width = 0.50,
433            },
434            vertical = {
435              mirror = false,
436            },
437            width = 0.87,
438            height = 0.80,
439            preview_cutoff = 120,
440          },
441          mappings = mappings,
442        },
443        extensions = {
444          undo = {
445            use_delta = true,
446            side_by_side = true,
447            diff_context_lines = 0,
448            entry_format = "󰣜 #$ID, $STAT, $TIME",
449            layout_strategy = "horizontal",
450            layout_config = {
451              preview_width = 0.65,
452            },
453            mappings = {
454              i = {
455                ["<cr>"] = require("telescope-undo.actions").yank_additions,
456                ["<S-cr>"] = require("telescope-undo.actions").yank_deletions,
457                ["<C-cr>"] = require("telescope-undo.actions").restore,
458              },
459            },
460          },
461        },
462      }
463    end,
464    config = function(_, opts)
465      local telescope = require("telescope")
466      telescope.setup(opts)
467      -- Here we define the Telescope extension for all plugins.
468      -- If you delete a plugin, you can also delete its Telescope extension.
469      if utils.is_available("nvim-notify") then telescope.load_extension("notify") end
470      if utils.is_available("telescope-fzf-native.nvim") then telescope.load_extension("fzf") end
471      if utils.is_available("telescope-undo.nvim") then telescope.load_extension("undo") end
472      if utils.is_available("project.nvim") then telescope.load_extension("projects") end
473      if utils.is_available("LuaSnip") then telescope.load_extension("luasnip") end
474      if utils.is_available("aerial.nvim") then telescope.load_extension("aerial") end
475      if utils.is_available("nvim-neoclip.lua") then
476        telescope.load_extension("neoclip")
477        telescope.load_extension("macroscope")
478      end
479    end,
480  },
481
482  --  [better ui elements]
483  --  https://github.com/stevearc/dressing.nvim
484  {
485    "stevearc/dressing.nvim",
486    event = "User BaseDefered",
487    opts = {
488      input = { default_prompt = "" },
489      select = { backend = { "telescope", "builtin" } },
490    }
491  },
492
493  --  Noice.nvim [better cmd/search line]
494  --  https://github.com/folke/noice.nvim
495  --  We use it for:
496  --  * cmdline: Display treesitter for :
497  --  * search: Display a magnifier instead of /
498  --
499  --  We don't use it for:
500  --  * LSP status: We use a heirline component for this.
501  --  * Search results: We use a heirline component for this.
502  {
503    "folke/noice.nvim",
504    event = "User BaseDefered",
505    opts = function()
506      local enable_conceal = false          -- Hide command text if true
507      return {
508        presets = { bottom_search = true }, -- The kind of popup used for /
509        cmdline = {
510          view = "cmdline",                 -- The kind of popup used for :
511          format = {
512            cmdline = { conceal = enable_conceal },
513            search_down = { conceal = enable_conceal },
514            search_up = { conceal = enable_conceal },
515            filter = { conceal = enable_conceal },
516            lua = { conceal = enable_conceal },
517            help = { conceal = enable_conceal },
518            input = { conceal = enable_conceal },
519          }
520        },
521
522        -- Disable every other noice feature
523        messages = { enabled = false },
524        lsp = {
525          hover = { enabled = false },
526          signature = { enabled = false },
527          progress = { enabled = false },
528          message = { enabled = false },
529          smart_move = { enabled = false },
530        },
531      }
532    end
533  },
534
535  --  UI icons [icons]
536  --  https://github.com/nvim-tree/nvim-web-devicons
537  {
538    "nvim-tree/nvim-web-devicons",
539    enabled = vim.g.icons_enabled,
540    event = "User BaseDefered",
541    opts = {
542      override = {
543        default_icon = {
544          icon = require("base.utils").get_icon("DefaultFile"),
545          name = "default"
546        },
547        deb = { icon = "", name = "Deb" },
548        lock = { icon = "󰌾", name = "Lock" },
549        mp3 = { icon = "󰎆", name = "Mp3" },
550        mp4 = { icon = "", name = "Mp4" },
551        out = { icon = "", name = "Out" },
552        ["robots.txt"] = { icon = "󰚩", name = "Robots" },
553        ttf = { icon = "", name = "TrueTypeFont" },
554        rpm = { icon = "", name = "Rpm" },
555        woff = { icon = "", name = "WebOpenFontFormat" },
556        woff2 = { icon = "", name = "WebOpenFontFormat2" },
557        xz = { icon = "", name = "Xz" },
558        zip = { icon = "", name = "Zip" },
559      },
560    },
561    config = function(_, opts)
562      require("nvim-web-devicons").setup(opts)
563      pcall(vim.api.nvim_del_user_command, "NvimWebDeviconsHiTest")
564    end
565  },
566
567  --  LSP icons [icons]
568  --  https://github.com/onsails/lspkind.nvim
569  {
570    "onsails/lspkind.nvim",
571    opts = {
572      mode = "symbol",
573      symbol_map = {
574        Array = "󰅪",
575        Boolean = "",
576        Class = "󰌗",
577        Constructor = "",
578        Key = "󰌆",
579        Namespace = "󰅪",
580        Null = "NULL",
581        Number = "#",
582        Object = "󰀚",
583        Package = "󰏗",
584        Property = "",
585        Reference = "",
586        Snippet = "",
587        String = "󰀬",
588        TypeParameter = "󰊄",
589        Unit = "",
590      },
591      menu = {},
592    },
593    enabled = vim.g.icons_enabled,
594    config = function(_, opts)
595      require("lspkind").init(opts)
596    end,
597  },
598
599  --  nvim-scrollbar [scrollbar]
600  --  https://github.com/petertriho/nvim-scrollbar
601  {
602    "petertriho/nvim-scrollbar",
603    event = "User BaseFile",
604    opts = {
605      handlers = {
606        gitsigns = true, -- gitsigns integration (display hunks)
607        ale = true,      -- lsp integration (display errors/warnings)
608        search = false,  -- hlslens integration (display search result)
609      },
610      excluded_filetypes = {
611        "cmp_docs",
612        "cmp_menu",
613        "noice",
614        "prompt",
615        "TelescopePrompt",
616        "alpha",
617      },
618    },
619  },
620
621  --  mini.animate [animations]
622  --  https://github.com/echasnovski/mini.animate
623  --  HINT: if one of your personal keymappings fail due to mini.animate, try to
624  --        disable it during the keybinding using vim.g.minianimate_disable = true
625  {
626    "echasnovski/mini.animate",
627    event = "User BaseFile",
628    enabled = not is_android,
629    opts = function()
630      -- don't use animate when scrolling with the mouse
631      local mouse_scrolled = false
632      for _, scroll in ipairs { "Up", "Down" } do
633        local key = "<ScrollWheel" .. scroll .. ">"
634        vim.keymap.set({ "", "i" }, key, function()
635          mouse_scrolled = true
636          return key
637        end, { expr = true })
638      end
639
640      local animate = require("mini.animate")
641      return {
642        open = { enable = false }, -- true causes issues on nvim-spectre
643        resize = {
644          timing = animate.gen_timing.linear { duration = 33, unit = "total" },
645        },
646        scroll = {
647          timing = animate.gen_timing.linear { duration = 50, unit = "total" },
648          subscroll = animate.gen_subscroll.equal {
649            predicate = function(total_scroll)
650              if mouse_scrolled then
651                mouse_scrolled = false
652                return false
653              end
654              return total_scroll > 1
655            end,
656          },
657        },
658        cursor = {
659          enable = false, -- We don't want cursor ghosting
660          timing = animate.gen_timing.linear { duration = 26, unit = "total" },
661        },
662      }
663    end,
664  },
665
666  --  highlight-undo
667  --  https://github.com/tzachar/highlight-undo.nvim
668  --  This plugin only flases on redo.
669  --  But we also have a autocmd to flash on yank.
670  {
671    "tzachar/highlight-undo.nvim",
672    event = "User BaseDefered",
673    opts = {
674      hlgroup = "CurSearch",
675      duration = 150,
676      keymaps = {
677        { "n", "u",     "undo", {} }, -- If you remap undo/redo, change this
678        { "n", "<C-r>", "redo", {} },
679      },
680    },
681    config = function(_, opts)
682      require("highlight-undo").setup(opts)
683
684      -- Also flash on yank.
685      vim.api.nvim_create_autocmd("TextYankPost", {
686        desc = "Highlight yanked text",
687        pattern = "*",
688        callback = function() vim.highlight.on_yank() end,
689      })
690    end,
691  },
692
693  --  which-key.nvim [on-screen keybindings]
694  --  https://github.com/folke/which-key.nvim
695  {
696    "folke/which-key.nvim",
697    event = "User BaseDefered",
698    opts = {
699      icons = { group = vim.g.icons_enabled and "" or "+", separator = "" },
700      disable = { filetypes = { "TelescopePrompt" } },
701    },
702    config = function(_, opts)
703      require("which-key").setup(opts)
704      require("base.utils").which_key_register()
705    end,
706  },
707
708
709} -- end of return