declancm / cinnamon.nvim

Smooth scrolling for ANY command ๐Ÿคฏ. A Neovim plugin written in Lua!
322 stars 6 forks source link

Blinking second cursor when scrolling with virtual text #38

Closed NicolasGB closed 2 days ago

NicolasGB commented 1 week ago

Hi, I've noticed some artifacts when enabling scroll with "j" and "k", often a second cursor blinks somewhere near the text. See the video. Whenever i disable the scroll the behavior goes away.

Tried to see if there's a pattern, my guess is something related to the virtual text. When inlay hints are disabled, the blinking goes away.

https://github.com/declancm/cinnamon.nvim/assets/17547539/a0b61af3-cc57-474f-ab01-8d056968d656

Also, when going up into virtual text the cursor scrolls the text in order to reach the real text, I'm not sure if it's intended but reporting it in case it's related to the previous bug.

https://github.com/declancm/cinnamon.nvim/assets/17547539/4e7778e5-9275-486d-ac58-18b76c847dd5

Let me know if i can provide more information.

declancm commented 1 week ago

That second one is definitely an issue ๐Ÿ˜…

declancm commented 1 week ago

I haven't been able to re-create the issue using builtin lsp inlay_hint. Is that what you're using here for the virtual text? If possible, is there a minimal config which can trigger this issue?

declancm commented 1 week ago

I'm thinking the virtualtext option might be getting changing during the scroll which could cause this

NicolasGB commented 3 days ago

Hey, thanks for your indications, i've been investigating, your comment about another plugin impacting the redraw made me wonder what plugins could be doing this. It looks like one called vim-illuminate was causing the issue, since i've taken it i haven't been able to reproduce the blinking whereas before, i could easily do so.

Also, i think that the one with the virtual text scroll (2nd video) is fixed, it isn't happening anymore cursor moves correctly to the end/start of the real text.

Thanks for your help!

(i've been having problems with oil.nvim and cinnamon with scroll timeouts but i've seen you have already open another issue regarding this problem)

Feel free to close this issue as it seems resolved to me :)

declancm commented 3 days ago

Great! The above commit should fix your issue with Oil

NicolasGB commented 2 days ago

Yes it does!

Thank you :smile:

NicolasGB commented 2 days ago

Hey, i'm comming back because i've managed to reproduce some blinking, now it's very visible in oil, although it's not happening in other buffers (or way less, sometimes i think i see some blinking but i can't reproduce it when i try), maybe the root cause is the same.

https://github.com/declancm/cinnamon.nvim/assets/17547539/151efbc7-cd73-4d3f-a697-ec3252cd6e95

Here's a trimmed kickstart.nvim where i can reproduce it:

vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

-- Set to true if you have a Nerd Font installed and selected in the terminal
vim.g.have_nerd_font = false

-- Make line numbers default
vim.opt.number = true

-- Enable mouse mode, can be useful for resizing splits for example!
vim.opt.mouse = 'a'

-- Don't show the mode, since it's already in the status line
vim.opt.showmode = false

-- Sync clipboard between OS and Neovim.
--  Remove this option if you want your OS clipboard to remain independent.
--  See `:help 'clipboard'`
vim.opt.clipboard = 'unnamedplus'

-- Enable break indent
vim.opt.breakindent = true

-- Save undo history
vim.opt.undofile = true

-- Case-insensitive searching UNLESS \C or one or more capital letters in the search term
vim.opt.ignorecase = true
vim.opt.smartcase = true

-- Keep signcolumn on by default
vim.opt.signcolumn = 'yes'

-- Decrease update time
vim.opt.updatetime = 250

-- Decrease mapped sequence wait time
-- Displays which-key popup sooner
vim.opt.timeoutlen = 300

-- Configure how new splits should be opened
vim.opt.splitright = true
vim.opt.splitbelow = true

-- Sets how neovim will display certain whitespace characters in the editor.
--  See `:help 'list'`
--  and `:help 'listchars'`
vim.opt.list = true
vim.opt.listchars = { tab = 'ยป ', trail = 'ยท', nbsp = 'โฃ' }

-- Preview substitutions live, as you type!
vim.opt.inccommand = 'split'

-- Show which line your cursor is on
vim.opt.cursorline = true

-- Minimal number of screen lines to keep above and below the cursor.
vim.opt.scrolloff = 10

-- [[ Basic Keymaps ]]
--  See `:help vim.keymap.set()`

-- Set highlight on search, but clear on pressing <Esc> in normal mode
vim.opt.hlsearch = true
vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')

-- Diagnostic keymaps
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous [D]iagnostic message' })
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next [D]iagnostic message' })
vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float, { desc = 'Show diagnostic [E]rror messages' })
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })

-- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier
-- for people to discover. Otherwise, you normally need to press <C-\><C-n>, which
-- is not what someone will guess without a bit more experience.
--
-- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping
-- or just use <C-\><C-n> to exit terminal mode
vim.keymap.set('t', '<Esc><Esc>', '<C-\\><C-n>', { desc = 'Exit terminal mode' })

--  See `:help wincmd` for a list of all window commands
vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' })
vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' })

-- [[ Basic Autocommands ]]
--  See `:help lua-guide-autocommands`

-- Highlight when yanking (copying) text
--  Try it with `yap` in normal mode
--  See `:help vim.highlight.on_yank()`
vim.api.nvim_create_autocmd('TextYankPost', {
  desc = 'Highlight when yanking (copying) text',
  group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }),
  callback = function()
    vim.highlight.on_yank()
  end,
})

-- [[ Install `lazy.nvim` plugin manager ]]
--    See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info
local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
  vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath }
end ---@diagnostic disable-next-line: undefined-field
vim.opt.rtp:prepend(lazypath)

require('lazy').setup({
  'tpope/vim-sleuth', -- Detect tabstop and shiftwidth automatically

  { 'numToStr/Comment.nvim', opts = {} },

  { -- Adds git related signs to the gutter, as well as utilities for managing changes
    'lewis6991/gitsigns.nvim',
    opts = {
      signs = {
        add = { text = '+' },
        change = { text = '~' },
        delete = { text = '_' },
        topdelete = { text = 'โ€พ' },
        changedelete = { text = '~' },
      },
    },
  },

  { -- Useful plugin to show you pending keybinds.
    'folke/which-key.nvim',
    event = 'VimEnter', -- Sets the loading event to 'VimEnter'
    config = function() -- This is the function that runs, AFTER loading
      require('which-key').setup()

      -- Document existing key chains
      require('which-key').register {
        ['<leader>c'] = { name = '[C]ode', _ = 'which_key_ignore' },
        ['<leader>d'] = { name = '[D]ocument', _ = 'which_key_ignore' },
        ['<leader>r'] = { name = '[R]ename', _ = 'which_key_ignore' },
        ['<leader>s'] = { name = '[S]earch', _ = 'which_key_ignore' },
        ['<leader>w'] = { name = '[W]orkspace', _ = 'which_key_ignore' },
        ['<leader>t'] = { name = '[T]oggle', _ = 'which_key_ignore' },
        ['<leader>h'] = { name = 'Git [H]unk', _ = 'which_key_ignore' },
      }
      -- visual mode
      require('which-key').register({
        ['<leader>h'] = { 'Git [H]unk' },
      }, { mode = 'v' })
    end,
  },
  { -- Fuzzy Finder (files, lsp, etc)
    'nvim-telescope/telescope.nvim',
    event = 'VimEnter',
    branch = '0.1.x',
    dependencies = {
      'nvim-lua/plenary.nvim',
      { -- If encountering errors, see telescope-fzf-native README for installation instructions
        'nvim-telescope/telescope-fzf-native.nvim',

        -- `build` is used to run some command when the plugin is installed/updated.
        -- This is only run then, not every time Neovim starts up.
        build = 'make',

        -- `cond` is a condition used to determine whether this plugin should be
        -- installed and loaded.
        cond = function()
          return vim.fn.executable 'make' == 1
        end,
      },
      { 'nvim-telescope/telescope-ui-select.nvim' },

      -- Useful for getting pretty icons, but requires a Nerd Font.
      { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font },
    },
    config = function()
      require('telescope').setup {
        extensions = {
          ['ui-select'] = {
            require('telescope.themes').get_dropdown(),
          },
        },
      }

      -- Enable Telescope extensions if they are installed
      pcall(require('telescope').load_extension, 'fzf')
      pcall(require('telescope').load_extension, 'ui-select')

      -- See `:help telescope.builtin`
      local builtin = require 'telescope.builtin'
      vim.keymap.set('n', '<leader>sh', builtin.help_tags, { desc = '[S]earch [H]elp' })
      vim.keymap.set('n', '<leader>sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' })
      vim.keymap.set('n', '<leader>sf', builtin.find_files, { desc = '[S]earch [F]iles' })
      vim.keymap.set('n', '<leader>ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' })
      vim.keymap.set('n', '<leader>sw', builtin.grep_string, { desc = '[S]earch current [W]ord' })
      vim.keymap.set('n', '<leader>sg', builtin.live_grep, { desc = '[S]earch by [G]rep' })
      vim.keymap.set('n', '<leader>sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' })
      vim.keymap.set('n', '<leader>sr', builtin.resume, { desc = '[S]earch [R]esume' })
      vim.keymap.set('n', '<leader>s.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' })
      vim.keymap.set('n', '<leader><leader>', builtin.buffers, { desc = '[ ] Find existing buffers' })

      -- Slightly advanced example of overriding default behavior and theme
      vim.keymap.set('n', '<leader>/', function()
        -- You can pass additional configuration to Telescope to change the theme, layout, etc.
        builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown {
          winblend = 10,
          previewer = false,
        })
      end, { desc = '[/] Fuzzily search in current buffer' })

      -- It's also possible to pass additional configuration options.
      --  See `:help telescope.builtin.live_grep()` for information about particular keys
      vim.keymap.set('n', '<leader>s/', function()
        builtin.live_grep {
          grep_open_files = true,
          prompt_title = 'Live Grep in Open Files',
        }
      end, { desc = '[S]earch [/] in Open Files' })

      -- Shortcut for searching your Neovim configuration files
      vim.keymap.set('n', '<leader>sn', function()
        builtin.find_files { cwd = vim.fn.stdpath 'config' }
      end, { desc = '[S]earch [N]eovim files' })
    end,
  },
  {
    'stevearc/oil.nvim',
    opts = {},
    -- Optional dependencies
    dependencies = { 'nvim-tree/nvim-web-devicons' },
    config = function()
      local oil = require 'oil'
      oil.setup {
        default_file_explorer = false, -- If i get used to might activate it later
        keymaps = {
          ['<C-s>'] = vim.cmd.w,
          ['q'] = 'actions.close',
          ['<A-u>'] = 'actions.parent',
          ['<C-h>'] = 'actions.select_vsplit',
        },
        view_options = {
          show_hidden = true,
        },
        float = {
          max_width = 75,
          max_height = 50,
        },
      }
      vim.keymap.set('n', '<leader>pv', oil.open_float, { desc = 'Open parent directory' })
    end,
  },

  {
    'declancm/cinnamon.nvim',
    config = function()
      require('cinnamon').setup {
        keymaps = { extra = true },
      }
      local cinnamon = require 'cinnamon'

      -- Centered scrolling:
      vim.keymap.set('n', '<C-u>', function()
        cinnamon.scroll '<C-u>zz'
      end)
      vim.keymap.set({ 'n', 'x' }, '<C-d>', function()
        cinnamon.scroll '<C-d>zz'
      end)
      vim.keymap.set({ 'n', 'x' }, 'G', function()
        cinnamon.scroll 'Gzz'
      end)

      -- Line scroll
      vim.keymap.set({ 'n', 'v' }, 'H', function()
        cinnamon.scroll '^'
      end)
      vim.keymap.set({ 'n', 'v' }, 'L', function()
        cinnamon.scroll '$'
      end)
      vim.keymap.set({ 'n', 'x' }, '0', function()
        cinnamon.scroll '0'
      end)
      vim.keymap.set({ 'n', 'x' }, 'j', function()
        cinnamon.scroll 'j'
      end)
      vim.keymap.set({ 'n', 'x' }, 'k', function()
        cinnamon.scroll 'k'
      end)
    end,
  },
  { -- Autoformat
    'stevearc/conform.nvim',
    lazy = false,
    keys = {
      {
        '<leader>f',
        function()
          require('conform').format { async = true, lsp_fallback = true }
        end,
        mode = '',
        desc = '[F]ormat buffer',
      },
    },
    opts = {
      notify_on_error = false,
      format_on_save = function(bufnr)
        -- Disable "format_on_save lsp_fallback" for languages that don't
        -- have a well standardized coding style. You can add additional
        -- languages here or re-enable it for the disabled ones.
        local disable_filetypes = { c = true, cpp = true }
        return {
          timeout_ms = 500,
          lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype],
        }
      end,
      formatters_by_ft = {
        lua = { 'stylua' },
        -- Conform can also run multiple formatters sequentially
        -- python = { "isort", "black" },
        --
        -- You can use a sub-list to tell conform to run *until* a formatter
        -- is found.
        -- javascript = { { "prettierd", "prettier" } },
      },
    },
  },

  { -- You can easily change to a different colorscheme.
    -- Change the name of the colorscheme plugin below, and then
    -- change the command in the config to whatever the name of that colorscheme is.
    --
    -- If you want to see what colorschemes are already installed, you can use `:Telescope colorscheme`.
    'folke/tokyonight.nvim',
    priority = 1000, -- Make sure to load this before all the other start plugins.
    init = function()
      -- Load the colorscheme here.
      -- Like many other themes, this one has different styles, and you could load
      -- any other, such as 'tokyonight-storm', 'tokyonight-moon', or 'tokyonight-day'.
      vim.cmd.colorscheme 'tokyonight-night'

      -- You can configure highlights by doing something like:
      vim.cmd.hi 'Comment gui=none'
    end,
  },

  -- Highlight todo, notes, etc in comments
  { -- Highlight, edit, and navigate code
    'nvim-treesitter/nvim-treesitter',
    build = ':TSUpdate',
    opts = {
      ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'vim', 'vimdoc' },
      -- Autoinstall languages that are not installed
      auto_install = true,
      highlight = {
        enable = true,
        -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules.
        --  If you are experiencing weird indenting issues, add the language to
        --  the list of additional_vim_regex_highlighting and disabled languages for indent.
        additional_vim_regex_highlighting = { 'ruby' },
      },
      indent = { enable = true, disable = { 'ruby' } },
    },
    config = function(_, opts)
      -- [[ Configure Treesitter ]] See `:help nvim-treesitter`

      -- Prefer git instead of curl in order to improve connectivity in some environments
      require('nvim-treesitter.install').prefer_git = true
      ---@diagnostic disable-next-line: missing-fields
      require('nvim-treesitter.configs').setup(opts)
    end,
  },
}, {
  ui = {
    -- If you are using a Nerd Font: set icons to an empty table which will use the
    -- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table
    icons = vim.g.have_nerd_font and {} or {
      cmd = 'โŒ˜',
      config = '๐Ÿ› ',
      event = '๐Ÿ“…',
      ft = '๐Ÿ“‚',
      init = 'โš™',
      keys = '๐Ÿ—',
      plugin = '๐Ÿ”Œ',
      runtime = '๐Ÿ’ป',
      require = '๐ŸŒ™',
      source = '๐Ÿ“„',
      start = '๐Ÿš€',
      task = '๐Ÿ“Œ',
      lazy = '๐Ÿ’ค ',
    },
  },
})

To reproduce it simply open a project and then <space>pv to open the project view with oil in a floating buffer and then i simply j and k around and it directly happens.

Let me know if you manage to reproduce it

declancm commented 2 days ago

What version of Neovim are you using? I'm using your config and haven't replicated the issue yet Also what is the output of :autocmd CursorMoved from within your Oil buffer?

NicolasGB commented 2 days ago

I have to apologize! It looks like the root cause is Zellij, i always always dev in it.

Your comment made me wonder if it was nvim (i'm on nighlty), but i had the same behavior on stable.

I use Wezterm and thought it might be the terminal but openning it in another terminal had the same effect of flickering.

My last possibility was zellij, and it indeed is the root cause of the problem.

With zellij:

https://github.com/declancm/cinnamon.nvim/assets/17547539/b218f273-8f8c-476d-a5cf-92878d00b5ed

Without (same project same config):

https://github.com/declancm/cinnamon.nvim/assets/17547539/85998b63-9cf2-4770-8417-24796f689064

And looking into the issues of zellij it looks like other people were having the same issue and it got fixed 2 weeks ago (got to wait release though) https://github.com/zellij-org/zellij/issues/3208

I apologize for the time taken, next time i'll beck my tools before !

declancm commented 2 days ago

No worries! I'm glad the root cause was found!