Loading ...
Sorry, an error occurred while loading the content.

BUG: j motion doesn't use position set by setpos('.'), but that of the last insert

Expand Messages
  • Ingo Karkat
    Hello Vim developers, I have a custom surround function that basically does this: let save_cursor = getpos( . ) execute normal! eaXY call setpos( . ,
    Message 1 of 5 , May 26, 2014
    • 0 Attachment
      Hello Vim developers,

      I have a custom surround function that basically does this:

      let save_cursor = getpos('.')
      execute "normal! eaXY\<Esc>"
      call setpos('.', save_cursor)

      And this correctly restores the cursor to the original position. But
      when I move down a line (with "j", same with "k" btw.) immediately after
      triggering this, the cursor jumps to the column of the last insert (the
      "Y" in the example above). This does not happen when:
      - a (no-op) move within the same line is performed (e.g. "l" followed by
      "h") before the "j"
      - cursor() is used instead of setpos('.')

      I can reproduce this down to Vim version 7.0. Interestingly, in Vim
      7.0.000, the cursor() function is also affected, but that starts working
      in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
      Linux/x64, as well as Vim 7.4.264 on Windows/x64.

      You can reproduce this with the attached scriptlet:

      $ vim -N -u NONE -S bug-cursor-j.vim

      Or by executing this in the middle of some text:

      let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
      setpos('.', save_cursor)|normal! j

      The problematic call incorrectly positions the cursor (represented by |)
      on the last insert column, instead of the column of the "B" where the
      function was triggered:

      QuickBrownFoxJumpsOverMe |he he
      Quick|BrownFoxJumpsOverMe he he

      -- regards, ingo
      --
      -- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
      -- http://vim.sourceforge.net/account/profile.php?user_id=9713 --

      --
      --
      You received this message from the "vim_dev" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_dev" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/d/optout.
    • Christian Brabandt
      Hi Ingo! ... This has been discussed before: https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
      Message 2 of 5 , May 26, 2014
      • 0 Attachment
        Hi Ingo!

        On Mo, 26 Mai 2014, Ingo Karkat wrote:

        > Hello Vim developers,
        >
        > I have a custom surround function that basically does this:
        >
        > let save_cursor = getpos('.')
        > execute "normal! eaXY\<Esc>"
        > call setpos('.', save_cursor)
        >
        > And this correctly restores the cursor to the original position. But
        > when I move down a line (with "j", same with "k" btw.) immediately after
        > triggering this, the cursor jumps to the column of the last insert (the
        > "Y" in the example above). This does not happen when:
        > - a (no-op) move within the same line is performed (e.g. "l" followed by
        > "h") before the "j"
        > - cursor() is used instead of setpos('.')
        >
        > I can reproduce this down to Vim version 7.0. Interestingly, in Vim
        > 7.0.000, the cursor() function is also affected, but that starts working
        > in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
        > Linux/x64, as well as Vim 7.4.264 on Windows/x64.
        >
        > You can reproduce this with the attached scriptlet:
        >
        > $ vim -N -u NONE -S bug-cursor-j.vim
        >
        > Or by executing this in the middle of some text:
        >
        > let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
        > setpos('.', save_cursor)|normal! j
        >
        > The problematic call incorrectly positions the cursor (represented by |)
        > on the last insert column, instead of the column of the "B" where the
        > function was triggered:
        >
        > QuickBrownFoxJumpsOverMe |he he
        > Quick|BrownFoxJumpsOverMe he he

        This has been discussed before:
        https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
        https://groups.google.com/d/msg/vim_dev/o9GRXaJMwHg/9g8INNnNB9YJ

        As suggested by ZyX in one of the threads, here is a patch, that allows
        to explicitly set curswant by enhancing the winrestview() function call.

        This means, you have to add an additional call to winrestview() like
        this:
        :call winrestview({'curswant':5})
        to make Vim request to stay in column *6* on vertical movement. Yes,
        there is a difference between the column number getpos() and
        winsaveview() returns.

        Best,
        Christian
        --

        --
        --
        You received this message from the "vim_dev" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php

        ---
        You received this message because you are subscribed to the Google Groups "vim_dev" group.
        To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
        For more options, visit https://groups.google.com/d/optout.
      • Bram Moolenaar
        ... This patch has drifted way down in the todo list. I ll move it up. -- hundred-and-one symptoms of being an internet addict: 210. When you get a divorce,
        Message 3 of 5 , May 26, 2014
        • 0 Attachment
          Christian Brabandt wrote:

          > Hi Ingo!
          >
          > On Mo, 26 Mai 2014, Ingo Karkat wrote:
          >
          > > Hello Vim developers,
          > >
          > > I have a custom surround function that basically does this:
          > >
          > > let save_cursor = getpos('.')
          > > execute "normal! eaXY\<Esc>"
          > > call setpos('.', save_cursor)
          > >
          > > And this correctly restores the cursor to the original position. But
          > > when I move down a line (with "j", same with "k" btw.) immediately after
          > > triggering this, the cursor jumps to the column of the last insert (the
          > > "Y" in the example above). This does not happen when:
          > > - a (no-op) move within the same line is performed (e.g. "l" followed by
          > > "h") before the "j"
          > > - cursor() is used instead of setpos('.')
          > >
          > > I can reproduce this down to Vim version 7.0. Interestingly, in Vim
          > > 7.0.000, the cursor() function is also affected, but that starts working
          > > in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
          > > Linux/x64, as well as Vim 7.4.264 on Windows/x64.
          > >
          > > You can reproduce this with the attached scriptlet:
          > >
          > > $ vim -N -u NONE -S bug-cursor-j.vim
          > >
          > > Or by executing this in the middle of some text:
          > >
          > > let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
          > > setpos('.', save_cursor)|normal! j
          > >
          > > The problematic call incorrectly positions the cursor (represented by |)
          > > on the last insert column, instead of the column of the "B" where the
          > > function was triggered:
          > >
          > > QuickBrownFoxJumpsOverMe |he he
          > > Quick|BrownFoxJumpsOverMe he he
          >
          > This has been discussed before:
          > https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
          > https://groups.google.com/d/msg/vim_dev/o9GRXaJMwHg/9g8INNnNB9YJ
          >
          > As suggested by ZyX in one of the threads, here is a patch, that allows
          > to explicitly set curswant by enhancing the winrestview() function call.
          >
          > This means, you have to add an additional call to winrestview() like
          > this:
          > :call winrestview({'curswant':5})
          > to make Vim request to stay in column *6* on vertical movement. Yes,
          > there is a difference between the column number getpos() and
          > winsaveview() returns.

          This patch has drifted way down in the todo list. I'll move it up.

          --
          hundred-and-one symptoms of being an internet addict:
          210. When you get a divorce, you don't care about who gets the children,
          but discuss endlessly who can use the email address.

          /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
          /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
          \\\ an exciting new programming language -- http://www.Zimbu.org ///
          \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

          --
          --
          You received this message from the "vim_dev" maillist.
          Do not top-post! Type your reply below the text you are replying to.
          For more information, visit http://www.vim.org/maillist.php

          ---
          You received this message because you are subscribed to the Google Groups "vim_dev" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
          For more options, visit https://groups.google.com/d/optout.
        • Ingo Karkat
          ... Thanks Christian. The two referenced threads explain the current behavior indeed. Still, I think this could be highlighted better in the help. ... My
          Message 4 of 5 , May 26, 2014
          • 0 Attachment
            On 26-May-2014 18:14 +0200, Christian Brabandt wrote:

            > On Mo, 26 Mai 2014, Ingo Karkat wrote:
            >
            >> Hello Vim developers,
            >>
            >> I have a custom surround function that basically does this:
            >>
            >> let save_cursor = getpos('.')
            >> execute "normal! eaXY\<Esc>"
            >> call setpos('.', save_cursor)
            >>
            >> And this correctly restores the cursor to the original position. But
            >> when I move down a line (with "j", same with "k" btw.) immediately after
            >> triggering this, the cursor jumps to the column of the last insert (the
            >> "Y" in the example above). This does not happen when:
            >> - a (no-op) move within the same line is performed (e.g. "l" followed by
            >> "h") before the "j"
            >> - cursor() is used instead of setpos('.')
            >>
            >> I can reproduce this down to Vim version 7.0. Interestingly, in Vim
            >> 7.0.000, the cursor() function is also affected, but that starts working
            >> in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
            >> Linux/x64, as well as Vim 7.4.264 on Windows/x64.
            >>
            >> You can reproduce this with the attached scriptlet:
            >>
            >> $ vim -N -u NONE -S bug-cursor-j.vim
            >>
            >> Or by executing this in the middle of some text:
            >>
            >> let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
            >> setpos('.', save_cursor)|normal! j
            >>
            >> The problematic call incorrectly positions the cursor (represented by |)
            >> on the last insert column, instead of the column of the "B" where the
            >> function was triggered:
            >>
            >> QuickBrownFoxJumpsOverMe |he he
            >> Quick|BrownFoxJumpsOverMe he he
            >
            > This has been discussed before:
            > https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
            > https://groups.google.com/d/msg/vim_dev/o9GRXaJMwHg/9g8INNnNB9YJ
            >
            > As suggested by ZyX in one of the threads, here is a patch, that allows
            > to explicitly set curswant by enhancing the winrestview() function call.

            Thanks Christian. The two referenced threads explain the current
            behavior indeed. Still, I think this could be highlighted better in the
            help.

            > This means, you have to add an additional call to winrestview() like
            > this:
            > :call winrestview({'curswant':5})
            > to make Vim request to stay in column *6* on vertical movement. Yes,
            > there is a difference between the column number getpos() and
            > winsaveview() returns.

            My experiments show that calling cursor() instead of setpos('.') also
            has the desired effect, no need for patches or winrestview(). Is that
            correct, and can I rely on that? If so, I propose the following
            clarification to the help:

            diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
            --- a/runtime/doc/eval.txt
            +++ b/runtime/doc/eval.txt
            @@ -5327,7 +5327,9 @@ setpos({expr}, {list})
            Also see |getpos()|

            This does not restore the preferred column for moving
            - vertically. See |winrestview()| for that.
            + vertically; if you set the cursor position with this, |j| and
            + |k| motions will jump to previous columns! Use |cursor()| to
            + avoid that. Also see the "curswant" key in |winrestview()|.


            setqflist({list} [, {action}]) *setqflist()*

            -- regards, ingo

            --
            --
            You received this message from the "vim_dev" maillist.
            Do not top-post! Type your reply below the text you are replying to.
            For more information, visit http://www.vim.org/maillist.php

            ---
            You received this message because you are subscribed to the Google Groups "vim_dev" group.
            To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
            For more options, visit https://groups.google.com/d/optout.
          • Bram Moolenaar
            ... Thanks. I suppose not many users understand what preferred column means. -- hundred-and-one symptoms of being an internet addict: 214. Your MCI Circle
            Message 5 of 5 , May 27, 2014
            • 0 Attachment
              Ingo Karkat wrote:

              > On 26-May-2014 18:14 +0200, Christian Brabandt wrote:
              >
              > > On Mo, 26 Mai 2014, Ingo Karkat wrote:
              > >
              > >> Hello Vim developers,
              > >>
              > >> I have a custom surround function that basically does this:
              > >>
              > >> let save_cursor = getpos('.')
              > >> execute "normal! eaXY\<Esc>"
              > >> call setpos('.', save_cursor)
              > >>
              > >> And this correctly restores the cursor to the original position. But
              > >> when I move down a line (with "j", same with "k" btw.) immediately after
              > >> triggering this, the cursor jumps to the column of the last insert (the
              > >> "Y" in the example above). This does not happen when:
              > >> - a (no-op) move within the same line is performed (e.g. "l" followed by
              > >> "h") before the "j"
              > >> - cursor() is used instead of setpos('.')
              > >>
              > >> I can reproduce this down to Vim version 7.0. Interestingly, in Vim
              > >> 7.0.000, the cursor() function is also affected, but that starts working
              > >> in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
              > >> Linux/x64, as well as Vim 7.4.264 on Windows/x64.
              > >>
              > >> You can reproduce this with the attached scriptlet:
              > >>
              > >> $ vim -N -u NONE -S bug-cursor-j.vim
              > >>
              > >> Or by executing this in the middle of some text:
              > >>
              > >> let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
              > >> setpos('.', save_cursor)|normal! j
              > >>
              > >> The problematic call incorrectly positions the cursor (represented by |)
              > >> on the last insert column, instead of the column of the "B" where the
              > >> function was triggered:
              > >>
              > >> QuickBrownFoxJumpsOverMe |he he
              > >> Quick|BrownFoxJumpsOverMe he he
              > >
              > > This has been discussed before:
              > > https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
              > > https://groups.google.com/d/msg/vim_dev/o9GRXaJMwHg/9g8INNnNB9YJ
              > >
              > > As suggested by ZyX in one of the threads, here is a patch, that allows
              > > to explicitly set curswant by enhancing the winrestview() function call.
              >
              > Thanks Christian. The two referenced threads explain the current
              > behavior indeed. Still, I think this could be highlighted better in the
              > help.
              >
              > > This means, you have to add an additional call to winrestview() like
              > > this:
              > > :call winrestview({'curswant':5})
              > > to make Vim request to stay in column *6* on vertical movement. Yes,
              > > there is a difference between the column number getpos() and
              > > winsaveview() returns.
              >
              > My experiments show that calling cursor() instead of setpos('.') also
              > has the desired effect, no need for patches or winrestview(). Is that
              > correct, and can I rely on that? If so, I propose the following
              > clarification to the help:

              Thanks. I suppose not many users understand what "preferred column" means.

              --
              hundred-and-one symptoms of being an internet addict:
              214. Your MCI "Circle of Friends" are all Hayes-compatible.

              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
              /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
              \\\ an exciting new programming language -- http://www.Zimbu.org ///
              \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

              --
              --
              You received this message from the "vim_dev" maillist.
              Do not top-post! Type your reply below the text you are replying to.
              For more information, visit http://www.vim.org/maillist.php

              ---
              You received this message because you are subscribed to the Google Groups "vim_dev" group.
              To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
              For more options, visit https://groups.google.com/d/optout.
            Your message has been successfully submitted and would be delivered to recipients shortly.