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

'nowrapscan' breaks searching within fold

Expand Messages
  • Wiktor Ruben
    I use Vim 7.3.715. Let s create sample fold: vim -u NONE -N ... i {{{1 foo bar zaz foo bar zaz gg0za Let s try search for foo : /foo . Fold
    Message 1 of 6 , Jan 9, 2013
    • 0 Attachment
      I use Vim 7.3.715. Let's create sample fold:

      vim -u NONE -N

      :set foldmethod=marker
      i
      {{{1<CR>
      foo bar zaz<CR>
      foo bar zaz<Esc>gg0za

      Let's try search for 'foo': '/foo<CR>'. Fold will open and cursor will
      be placed at the beginning of 'foo'. Great. Now, let's go back where
      we started with 'gg0', close the fold with 'za' and set 'nowrapscan'
      option. Do the search again. The fold won't open and the pattern won't
      be found even though we are the very beginning of our file and there
      is no need to wrap to find the pattern.

      --
      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
    • Ben Fritz
      ... This seems to be related to the cursor being within the fold. If I insert a blank line above your fold, a search properly finds the first foo if the
      Message 2 of 6 , Jan 9, 2013
      • 0 Attachment
        On Wednesday, January 9, 2013 12:05:13 PM UTC-6, Wiktor Ruben wrote:
        > I use Vim 7.3.715. Let's create sample fold:
        >
        >
        >
        > vim -u NONE -N
        >
        >
        >
        > :set foldmethod=marker
        >
        > i
        >
        > {{{1<CR>
        >
        > foo bar zaz<CR>
        >
        > foo bar zaz<Esc>gg0za
        >
        >
        >
        > Let's try search for 'foo': '/foo<CR>'. Fold will open and cursor will
        >
        > be placed at the beginning of 'foo'. Great. Now, let's go back where
        >
        > we started with 'gg0', close the fold with 'za' and set 'nowrapscan'
        >
        > option. Do the search again. The fold won't open and the pattern won't
        >
        > be found even though we are the very beginning of our file and there
        >
        > is no need to wrap to find the pattern.

        This seems to be related to the cursor being within the fold.

        If I insert a blank line above your fold, a search properly finds the first "foo" if the cursor is placed on that blank line.

        If the cursor is instead on the 2nd line which opens the fold, I get the same results. I.e. "foo" is not found.

        Ending the folded region with a }}}1 does not change anything either.

        I agree it looks like a bug.

        --
        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
      • Christian Brabandt
        Hi Ben! ... Yes, the source code says this: /* If the cursor is in a closed fold, don t find another match in the same * fold. */ if (dirc == / ) { if
        Message 3 of 6 , Jan 9, 2013
        • 0 Attachment
          Hi Ben!

          On Mi, 09 Jan 2013, Ben Fritz wrote:

          > This seems to be related to the cursor being within the fold.

          Yes, the source code says this:

          /* If the cursor is in a closed fold, don't find another match in the same
          * fold. */
          if (dirc == '/')
          {
          if (hasFolding(pos.lnum, NULL, &pos.lnum))
          pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
          }

          This means, the search starts actually after the fold. Because wrapscan
          applies, Vim will start searching from the beginning of the file again
          and find the match and open the fold. If wrapscan is not set, this will
          abort since the pattern is not found.

          I am thinking, there should at least be an check for 'foldopen', e.g.
          something like this:

          diff --git a/src/search.c b/src/search.c
          --- a/src/search.c
          +++ b/src/search.c
          @@ -1126,15 +1126,18 @@
          #ifdef FEAT_FOLDING
          /* If the cursor is in a closed fold, don't find another match in the same
          * fold. */
          - if (dirc == '/')
          + if ((fdo_flags & FDO_SEARCH) == 0)
          {
          - if (hasFolding(pos.lnum, NULL, &pos.lnum))
          - pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
          - }
          - else
          - {
          - if (hasFolding(pos.lnum, &pos.lnum, NULL))
          - pos.col = 0;
          + if (dirc == '/')
          + {
          + if (hasFolding(pos.lnum, NULL, &pos.lnum))
          + pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
          + }
          + else
          + {
          + if (hasFolding(pos.lnum, &pos.lnum, NULL))
          + pos.col = 0;
          + }
          }
          #endif


          regards,
          Christian
          --
          Man kann einem Mann nichts abgewöhnen, aber man kann ihm angewöhnen,
          daß er sich etwas abgewöhnt.
          -- Cathérine Deneuve

          --
          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
        • Bram Moolenaar
          ... I would argue that the current behavior is correct. Suppose there are no folds and there is one occurrence of foo . Then /foo moves to that foo when
          Message 4 of 6 , Jan 11, 2013
          • 0 Attachment
            Christian Brabandt wrote:

            > On Mi, 09 Jan 2013, Ben Fritz wrote:
            >
            > > This seems to be related to the cursor being within the fold.
            >
            > Yes, the source code says this:
            >
            > /* If the cursor is in a closed fold, don't find another match in the same
            > * fold. */
            > if (dirc == '/')
            > {
            > if (hasFolding(pos.lnum, NULL, &pos.lnum))
            > pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */
            > }
            >
            > This means, the search starts actually after the fold. Because wrapscan
            > applies, Vim will start searching from the beginning of the file again
            > and find the match and open the fold. If wrapscan is not set, this will
            > abort since the pattern is not found.

            I would argue that the current behavior is correct. Suppose there are
            no folds and there is one occurrence of "foo". Then /foo moves to that
            "foo" when 'wrapscan' is set, also when the search is repeated. When
            'wrapscan' is off then the second search fails.

            In a closed fold it's like the cursor is already at the "foo" inside it.
            When 'wrapscan' is set /foo finds it again. When 'wrapscan' is off it
            doesn't find another foo and fails.

            --
            If VIM were a woman, I'd marry her. Slim, organized, helpful
            and beautiful; what's not to like? --David A. Rogers

            /// 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
          • Ben Fritz
            ... I don t like this, it s very unexpected. Especially if searching opens folds, users expect that searching looks inside folds. Also, we can get to some
            Message 5 of 6 , Jan 11, 2013
            • 0 Attachment
              On Friday, January 11, 2013 3:24:24 PM UTC-6, Bram Moolenaar wrote:
              > Christian Brabandt wrote:
              >
              > > This means, the search starts actually after the fold. Because wrapscan
              >
              > > applies, Vim will start searching from the beginning of the file again
              >
              > > and find the match and open the fold. If wrapscan is not set, this will
              >
              > > abort since the pattern is not found.
              >
              >
              >
              > I would argue that the current behavior is correct. Suppose there are
              >
              > no folds and there is one occurrence of "foo". Then /foo moves to that
              >
              > "foo" when 'wrapscan' is set, also when the search is repeated. When
              >
              > 'wrapscan' is off then the second search fails.
              >
              >
              > In a closed fold it's like the cursor is already at the "foo" inside it.
              >
              > When 'wrapscan' is set /foo finds it again. When 'wrapscan' is off it
              >
              > doesn't find another foo and fails.
              >


              I don't like this, it's very unexpected. Especially if searching opens folds, users expect that searching looks inside folds.

              Also, we can get to some paradoxical behavior with 'nowrapscan' set.

              Create a file with "foo" only in one place. Fold the text surrounding "foo". Place the cursor on the fold and search for "foo". Search hits bottom without matches, and with your explanation above, I suppose that's expected. Searching again with "n" obviously finds nothing again.

              But the cursor doesn't move. So searching with N also will fail, hitting the top with no matches.

              So now we have a situation where "foo" exists in the file but can never be found by a search in either direction without first moving the cursor off the fold.

              I think it is far less surprising, and more helpful, to start forward searches just before the fold, and backward searches just after the fold, to find anything inside the fold right away.

              Also note that the search() function does NOT act in this way. Placing the cursor on the fold and doing :call search("foo") does not open the fold, but doing zv after that shows the cursor is now on the match inside the fold. I think it is also more intuitive if the search() function does the same as / searches as much as possible.

              --
              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
            • Ingo Karkat
              ... I agree. In my mental model, folding is just a visual grouping that may affect the scope of certain modifications (e.g. :.substitute works on all lines of
              Message 6 of 6 , Jan 14, 2013
              • 0 Attachment
                On 12-Jan-13 08:36:38 +0900, Ben Fritz wrote:

                > On Friday, January 11, 2013 3:24:24 PM UTC-6, Bram Moolenaar wrote:
                >> Christian Brabandt wrote:
                >>
                >>> This means, the search starts actually after the fold. Because
                >>> wrapscan
                >>
                >>> applies, Vim will start searching from the beginning of the file
                >>> again
                >>
                >>> and find the match and open the fold. If wrapscan is not set, this
                >>> will
                >>
                >>> abort since the pattern is not found.
                >>
                >>
                >>
                >> I would argue that the current behavior is correct. Suppose there
                >> are
                >>
                >> no folds and there is one occurrence of "foo". Then /foo moves to
                >> that
                >>
                >> "foo" when 'wrapscan' is set, also when the search is repeated. When
                >>
                >> 'wrapscan' is off then the second search fails.
                >>
                >>
                >> In a closed fold it's like the cursor is already at the "foo" inside
                >> it.
                >>
                >> When 'wrapscan' is set /foo finds it again. When 'wrapscan' is off
                >> it
                >>
                >> doesn't find another foo and fails.
                >
                > I don't like this, it's very unexpected. Especially if searching opens
                > folds, users expect that searching looks inside folds.
                >
                > Also, we can get to some paradoxical behavior with 'nowrapscan' set.
                >
                > Create a file with "foo" only in one place. Fold the text surrounding
                > "foo". Place the cursor on the fold and search for "foo". Search hits
                > bottom without matches, and with your explanation above, I suppose
                > that's expected. Searching again with "n" obviously finds nothing
                > again.
                >
                > But the cursor doesn't move. So searching with N also will fail,
                > hitting the top with no matches.
                >
                > So now we have a situation where "foo" exists in the file but can
                > never be found by a search in either direction without first moving
                > the cursor off the fold.
                >
                > I think it is far less surprising, and more helpful, to start forward
                > searches just before the fold, and backward searches just after the
                > fold, to find anything inside the fold right away.
                >
                > Also note that the search() function does NOT act in this way. Placing
                > the cursor on the fold and doing :call search("foo") does not open the
                > fold, but doing zv after that shows the cursor is now on the match
                > inside the fold. I think it is also more intuitive if the search()
                > function does the same as / searches as much as possible.

                I agree. In my mental model, folding is just a visual grouping that may affect
                the scope of certain modifications (e.g. :.substitute works on all lines of the
                current fold), but it never actually hides text from commands, just from view.
                I'd also except a search to always find text inside a fold.

                -- 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
              Your message has been successfully submitted and would be delivered to recipients shortly.