Git Product home page Git Product logo

neoscroll.nvim's Introduction

Neoscroll: a smooth scrolling neovim plugin written in lua

Demo

demo.mp4

Features

  • Smooth scrolling for window movement commands (mappings optional): <C-u>, <C-d>, <C-b>, <C-f>, <C-y>, <C-e>, zt, zz and zb.
  • Takes into account folds.
  • A single scrolling function that accepts either the number of lines or the percentage of the window to scroll.
  • Cursor is hidden while scrolling (optional) for a more pleasing scrolling experience.
  • Customizable scrolling behaviour.
  • Use custom easing functions for the scrolling animation.
  • Performance mode that turns off syntax highlighting while scrolling for slower machines or files with heavy regex syntax highlighting.

Installation

You will need neovim 0.5 for this plugin to work. Install it using your favorite plugin manager:

  • With Packer: use 'karb94/neoscroll.nvim'

  • With vim-plug: Plug 'karb94/neoscroll.nvim'

IMPORTANT: Neoscroll uses the value of the scrolloff option to behave as expected. If the local scope of this variable is not explicitly set it will store a garbage random value instead of inheriting the global value of the option. This is a reported Neovim bug. Therefore Neoscroll will use the the global scrolloff value by default.. If you want Neoscroll to use the local scrolloff value then set the Neoscroll option use_local_scrolloff to true but make sure you set the local scrolloff explicitly either in you init file or at runtime.

Quickstart

Add the setup() function to your init file.

For init.lua:

require('neoscroll').setup()

For init.vim:

lua require('neoscroll').setup()

Options

Setup function with all the options and their default values:

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
})

Custom mappings

You can create your own scrolling mappings using the following lua functions:

  • scroll(lines, move_cursor, time[, easing])
  • zt(half_win_time[, easing])
  • zz(half_win_time[, easing])
  • zb(half_win_time[, easing])

Read the documentation for more details on how to use each function.

You can use the following syntactic sugar in your init.lua to define lua function mappings in normal, visual and select modes:

require('neoscroll').setup({
    -- Set any options as needed
})

-- Syntax scrolling function: `scroll(lines, move_cursor, time[, easing_function_name])`
local t = {}
-- Syntax: t[keys] = {function, {function arguments}}
t['<C-u>'] = {'scroll', {'-vim.wo.scroll', 'true', '250'}}
t['<C-d>'] = {'scroll', { 'vim.wo.scroll', 'true', '250'}}
t['<C-b>'] = {'scroll', {'-vim.api.nvim_win_get_height(0)', 'true', '450'}}
t['<C-f>'] = {'scroll', { 'vim.api.nvim_win_get_height(0)', 'true', '450'}}
t['<C-y>'] = {'scroll', {'-0.10', 'false', '100'}}
t['<C-e>'] = {'scroll', { '0.10', 'false', '100'}}
t['zt']    = {'zt', {'250'}}
t['zz']    = {'zz', {'250'}}
t['zb']    = {'zb', {'250'}}

require('neoscroll.config').set_mappings(t)

Easing functions

By default the scrolling animation has a constant speed, i.e. the time between each line scroll is constant. If you want to smooth the start and/or end of the scrolling animation you can pass the name of one of the easing functions that Neoscroll provides to the scroll() function. You can use any of the following easing functions: quadratic, cubic, quartic, quintic, circular, sine. Neoscroll will then adjust the time between each line scroll using the selected easing function. This dynamic time adjustment can make animations more pleasing to the eye.

To learn more about easing functions here are some useful links:

Examples

Using the same syntactic sugar introduced in Custom mappings we can write the following config:

require('neoscroll').setup({
    easing_function = "quadratic" -- Default easing function
    -- Set any other options as needed
})

local t = {}
-- Syntax: t[keys] = {function, {function arguments}}
-- Use the "sine" easing function
t['<C-u>'] = {'scroll', {'-vim.wo.scroll', 'true', '350', [['sine']]}}
t['<C-d>'] = {'scroll', { 'vim.wo.scroll', 'true', '350', [['sine']]}}
-- Use the "circular" easing function
t['<C-b>'] = {'scroll', {'-vim.api.nvim_win_get_height(0)', 'true', '500', [['circular']]}}
t['<C-f>'] = {'scroll', { 'vim.api.nvim_win_get_height(0)', 'true', '500', [['circular']]}}
-- Pass "nil" to disable the easing animation (constant scrolling speed)
t['<C-y>'] = {'scroll', {'-0.10', 'false', '100', nil}}
t['<C-e>'] = {'scroll', { '0.10', 'false', '100', nil}}
-- When no easing function is provided the default easing function (in this case "quadratic") will be used
t['zt']    = {'zt', {'300'}}
t['zz']    = {'zz', {'300'}}
t['zb']    = {'zb', {'300'}}

require('neoscroll.config').set_mappings(t)

Known issues

  • Because of a Neovim bug Neoscroll has to use the global scrolloff value by default. Related issues: #11 and #28.
  • <C-u>, <C-d>, <C-b>, <C-f> mess up macros (issue).

Acknowledgements

This plugin was inspired by vim-smoothie and neo-smooth-scroll.nvim. Big thank you to their authors!

neoscroll.nvim's People

Contributors

bbenzikry avatar gshpychka avatar haooodev avatar karb94 avatar numtostr avatar scrouthtv avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.