Scroll offset (vimscript)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite












When you jump to a search result in Vim, your cursor can end up near the bottom (or top) of the window, making it difficult to see the surrounding context.



Some people like to automatically center the cursor after such a jump, but I find that to be too drastic, since it means even small jumps cause scrolling.



There's also a 'scrolloff' option you can set, which keeps the cursor some fixed number of lines away from the top/bottom of the window at all times, except when near the start or end of the file.



I like to keep 'scrolloff' set to a low value most of the time. It's only after certain navigation jumps that I want to apply a larger offset. So I wrote a vimscript function that applies a given offset.



The first implimentation increased 'scrolloff', redrew the screen, then returned 'scrolloff' to its original value, but this caused an annoying flicker each time the screen was redrawn.



I've reimplemented it to calculate and apply the necessary scroll operations. The interesting part was tuning the calculations so that edge-cases were considered.



The desired offset decreases gradually as you approach the start / end of the file. The offset is also scaled down as necessary if the window is too small to accomodate the given value.



func! Nudge(o) abort
let offset = min([a:o, winheight(0)/2])

let bot_want = min([offset, line('$') - line('.')])
let bot_have = winheight(0) - winline()
if bot_want > bot_have
call s:nudge_bot(bot_want - bot_have)
else
let top_want = min([offset, line('.') - 1])
let top_have = winline() - 1
if top_want > top_have
call s:nudge_top(top_want - top_have)
endif
endif
endf

func! s:nudge_bot(count)
exec 'normal!' a:count . "<C-E>"
endf

func! s:nudge_top(count)
exec 'normal!' a:count . "<C-Y>"
endf


Vimscript is never pretty, but it was fun to work through this one.







share|improve this question



























    up vote
    3
    down vote

    favorite












    When you jump to a search result in Vim, your cursor can end up near the bottom (or top) of the window, making it difficult to see the surrounding context.



    Some people like to automatically center the cursor after such a jump, but I find that to be too drastic, since it means even small jumps cause scrolling.



    There's also a 'scrolloff' option you can set, which keeps the cursor some fixed number of lines away from the top/bottom of the window at all times, except when near the start or end of the file.



    I like to keep 'scrolloff' set to a low value most of the time. It's only after certain navigation jumps that I want to apply a larger offset. So I wrote a vimscript function that applies a given offset.



    The first implimentation increased 'scrolloff', redrew the screen, then returned 'scrolloff' to its original value, but this caused an annoying flicker each time the screen was redrawn.



    I've reimplemented it to calculate and apply the necessary scroll operations. The interesting part was tuning the calculations so that edge-cases were considered.



    The desired offset decreases gradually as you approach the start / end of the file. The offset is also scaled down as necessary if the window is too small to accomodate the given value.



    func! Nudge(o) abort
    let offset = min([a:o, winheight(0)/2])

    let bot_want = min([offset, line('$') - line('.')])
    let bot_have = winheight(0) - winline()
    if bot_want > bot_have
    call s:nudge_bot(bot_want - bot_have)
    else
    let top_want = min([offset, line('.') - 1])
    let top_have = winline() - 1
    if top_want > top_have
    call s:nudge_top(top_want - top_have)
    endif
    endif
    endf

    func! s:nudge_bot(count)
    exec 'normal!' a:count . "<C-E>"
    endf

    func! s:nudge_top(count)
    exec 'normal!' a:count . "<C-Y>"
    endf


    Vimscript is never pretty, but it was fun to work through this one.







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      When you jump to a search result in Vim, your cursor can end up near the bottom (or top) of the window, making it difficult to see the surrounding context.



      Some people like to automatically center the cursor after such a jump, but I find that to be too drastic, since it means even small jumps cause scrolling.



      There's also a 'scrolloff' option you can set, which keeps the cursor some fixed number of lines away from the top/bottom of the window at all times, except when near the start or end of the file.



      I like to keep 'scrolloff' set to a low value most of the time. It's only after certain navigation jumps that I want to apply a larger offset. So I wrote a vimscript function that applies a given offset.



      The first implimentation increased 'scrolloff', redrew the screen, then returned 'scrolloff' to its original value, but this caused an annoying flicker each time the screen was redrawn.



      I've reimplemented it to calculate and apply the necessary scroll operations. The interesting part was tuning the calculations so that edge-cases were considered.



      The desired offset decreases gradually as you approach the start / end of the file. The offset is also scaled down as necessary if the window is too small to accomodate the given value.



      func! Nudge(o) abort
      let offset = min([a:o, winheight(0)/2])

      let bot_want = min([offset, line('$') - line('.')])
      let bot_have = winheight(0) - winline()
      if bot_want > bot_have
      call s:nudge_bot(bot_want - bot_have)
      else
      let top_want = min([offset, line('.') - 1])
      let top_have = winline() - 1
      if top_want > top_have
      call s:nudge_top(top_want - top_have)
      endif
      endif
      endf

      func! s:nudge_bot(count)
      exec 'normal!' a:count . "<C-E>"
      endf

      func! s:nudge_top(count)
      exec 'normal!' a:count . "<C-Y>"
      endf


      Vimscript is never pretty, but it was fun to work through this one.







      share|improve this question













      When you jump to a search result in Vim, your cursor can end up near the bottom (or top) of the window, making it difficult to see the surrounding context.



      Some people like to automatically center the cursor after such a jump, but I find that to be too drastic, since it means even small jumps cause scrolling.



      There's also a 'scrolloff' option you can set, which keeps the cursor some fixed number of lines away from the top/bottom of the window at all times, except when near the start or end of the file.



      I like to keep 'scrolloff' set to a low value most of the time. It's only after certain navigation jumps that I want to apply a larger offset. So I wrote a vimscript function that applies a given offset.



      The first implimentation increased 'scrolloff', redrew the screen, then returned 'scrolloff' to its original value, but this caused an annoying flicker each time the screen was redrawn.



      I've reimplemented it to calculate and apply the necessary scroll operations. The interesting part was tuning the calculations so that edge-cases were considered.



      The desired offset decreases gradually as you approach the start / end of the file. The offset is also scaled down as necessary if the window is too small to accomodate the given value.



      func! Nudge(o) abort
      let offset = min([a:o, winheight(0)/2])

      let bot_want = min([offset, line('$') - line('.')])
      let bot_have = winheight(0) - winline()
      if bot_want > bot_have
      call s:nudge_bot(bot_want - bot_have)
      else
      let top_want = min([offset, line('.') - 1])
      let top_have = winline() - 1
      if top_want > top_have
      call s:nudge_top(top_want - top_have)
      endif
      endif
      endf

      func! s:nudge_bot(count)
      exec 'normal!' a:count . "<C-E>"
      endf

      func! s:nudge_top(count)
      exec 'normal!' a:count . "<C-Y>"
      endf


      Vimscript is never pretty, but it was fun to work through this one.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Apr 15 at 4:25
























      asked Apr 15 at 4:04









      ivan

      44328




      44328

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192084%2fscroll-offset-vimscript%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192084%2fscroll-offset-vimscript%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?