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

RE: [PATCH] new flags for the search() function

Expand Messages
  • Zdenek Sekera
    ... I find them useful, too. I would have loved to have them for solving similar problems I had in my scripts (similar what Benji has posted). I d like to see
    Message 1 of 13 , Nov 23, 2005
    View Source
    • 0 Attachment
      > -----Original Message-----
      > From: Bram@... [mailto:Bram@...]
      > Sent: 23 November 2005 10:54
      > To: Benji Fisher
      > Cc: vim-dev@...
      > Subject: Re: [PATCH] new flags for the search() function
      >
      >
      > Benji Fisher wrote:
      >
      > > This is the first time I have written a patch for vim,
      > so someone
      > > please have a look and tell me if it looks reasonable.
      > (Please also try
      > > applying and compiling.)
      >
      > The format of the patch is OK.
      >
      > > I made this patch against the 12 October CVS snapshot of vim7.
      > > (Is there any way to determine a patch level when using CVS for
      > > downloads?)
      >
      > The date is a good indication of which snapshot you are using.
      >
      > > The patch adds three new flags to the search() function:
      > >
      > > 'a' allow a match that does not move the cursor
      > > 'e' move the cursor to the end of the match
      > > 'p' return number of matching subpattern
      >
      > I understand it returns the number of the first matching subpattern.
      > This is a bit strange, I don't think this is done anywhere else.
      >
      > > Motivation
      > > ==========
      > >
      > > When and if I update the matchit plugin (greatly
      > simplified thanks
      > > to the new List type!) I would like to be able to do things like
      > > (simplified example)
      > >
      > > :let whereami = search('\(if\)\|\(else\)\|\(endif\)', 'nape')
      > >
      > > to decide whether the cursor is on "if" or "else" or
      > "endif". (I just
      > > discovered an advantage to "flag bloat": you can have fun spelling
      > > things with the flags. I could have used 'apnea' instead.)
      > >
      > > Request for Comments
      > > ====================
      > >
      > > Can you suggest better names for the flags?
      > >
      > > Would you use this feature? If I am the only one who
      > ever uses the
      > > new feature, it is not worth adding to vim.
      >
      > The flags appear to be useful. I'll await comments before including
      > this.

      I find them useful, too. I would have loved to have them
      for solving similar problems I had in my scripts (similar
      what Benji has posted).
      I'd like to see them included in 7.

      ---Zdenek
    • Mikolaj Machowski
      ... Sorry, don t understand difference between a and n flags. Could you explain? m.
      Message 2 of 13 , Nov 23, 2005
      View Source
      • 0 Attachment
        Dnia środa, 23 listopada 2005 02:25, Benji Fisher napisał:
        > The patch adds three new flags to the search() function:
        >
        > 'a' allow a match that does not move the cursor

        Sorry, don't understand difference between a and n flags. Could you
        explain?

        m.
      • Benji Fisher
        ... Try it out with the cursor at the start of Line 1 of the following test buffer: 1 foo 2 bar ... If flags == n , then the bar in Line 2 is found, so
        Message 3 of 13 , Nov 23, 2005
        View Source
        • 0 Attachment
          On Wed, Nov 23, 2005 at 12:12:55PM +0100, Mikolaj Machowski wrote:
          > Dnia środa, 23 listopada 2005 02:25, Benji Fisher napisał:
          > > The patch adds three new flags to the search() function:
          > >
          > > 'a' allow a match that does not move the cursor
          >
          > Sorry, don't understand difference between a and n flags. Could you
          > explain?
          >
          > m.

          Try it out with the cursor at the start of Line 1 of the following
          test buffer:

          1 foo
          2 bar

          :echo search('foo\|bar', flags)

          If flags == 'n', then the "bar" in Line 2 is found, so the function
          returns 2. If flags == 'a', then the "foo" in Line 1 is found, so the
          function returns 1. In both cases, for different reasons, the cursor
          does not move.

          Would it be clearer if I wrote

          'a' allow a match at the current cursor position

          instead of the line quoted above?

          HTH --Benji Fisher
        • Benji Fisher
          ... How about an even longer paragraph that illustrates most of the flags? (Bram, if you like this explanation and it will save you some effort, I can make an
          Message 4 of 13 , Nov 24, 2005
          View Source
          • 0 Attachment
            On Thu, Nov 24, 2005 at 09:11:06AM +0100, Zdenek Sekera wrote:
            > >
            > > Would it be clearer if I wrote
            > >
            > > 'a' allow a match at the current cursor position
            > >
            > > instead of the line quoted above?
            >
            > I would think so. Though, to add the whole last paragraph
            > (the example) as an explanation wouldn't be too much either...
            > I find it very clear.
            >
            > ---Zdenek

            How about an even longer paragraph that illustrates most of the
            flags? (Bram, if you like this explanation and it will save you some
            effort, I can make an updated patch.)

            Example (goes over all files in the argument list): >
            :let n = 1
            :while n <= argc() " loop over all files in arglist
            : exe "argument " . n
            : " start at the last char in the file and wrap for the
            : " first search to find match at start of file
            : normal G$
            : let flags = "w"
            : while search("foo", flags) > 0
            : s/foo/bar/g
            : let flags = "W"
            : endwhile
            : update " write the file if modified
            : let n = n + 1
            :endwhile
            <
            Example of flags. Assume a test buffer with three lines: >
            foo
            bar
            foobar
            < With the cursor at the start of Line 1, try >
            :echo search('foo\|bar', flags)
            < If flags is "", then the search finds the "bar" on the second
            line and returns 2.
            If flags is "a" or "e", then the search finds the "foo" on
            Line 1 and returns 1.
            If flags is "bw", then the search finds the "bar" on the third
            line and returns 2.
            If flags is "bW", then the search fails. The cursor stays
            put, and the function returns 0.
            If flags is "n", the function returns 2 but does not move the
            cursor.
            If flags includes "p", then >
            :echo search('\(foo\)\|bar', flags)
            < returns 0 (no match), 1 ("bar"), or 2 ("foo"), depending on
            the other flags used.

            --Benji
          • Zdenek Sekera
            ... I am all in favor of good examples, even if they make the text longer. It s far more profitable to understand the subject immediately after reading a page
            Message 5 of 13 , Nov 25, 2005
            View Source
            • 0 Attachment
              > -----Original Message-----
              > From: Benji Fisher [mailto:benji@...]
              > Sent: 25 November 2005 01:33
              > To: vim-dev@...
              > Subject: Re: [PATCH] new flags for the search() function
              >
              > On Thu, Nov 24, 2005 at 09:11:06AM +0100, Zdenek Sekera wrote:
              > > >
              > > > Would it be clearer if I wrote
              > > >
              > > > 'a' allow a match at the current cursor position
              > > >
              > > > instead of the line quoted above?
              > >
              > > I would think so. Though, to add the whole last paragraph
              > > (the example) as an explanation wouldn't be too much either...
              > > I find it very clear.
              > >
              > > ---Zdenek
              >
              > How about an even longer paragraph that illustrates most of the
              > flags? (Bram, if you like this explanation and it will save you some
              > effort, I can make an updated patch.)
              >
              > Example (goes over all files in the argument list): >
              > :let n = 1
              > :while n <= argc() " loop over all
              > files in arglist
              > : exe "argument " . n
              > : " start at the last char in the file and
              > wrap for the
              > : " first search to find match at start of file
              > : normal G$
              > : let flags = "w"
              > : while search("foo", flags) > 0
              > : s/foo/bar/g
              > : let flags = "W"
              > : endwhile
              > : update " write the file if modified
              > : let n = n + 1
              > :endwhile
              > <
              > Example of flags. Assume a test buffer with
              > three lines: >
              > foo
              > bar
              > foobar
              > < With the cursor at the start of Line 1, try >
              > :echo search('foo\|bar', flags)
              > < If flags is "", then the search finds the "bar"
              > on the second
              > line and returns 2.
              > If flags is "a" or "e", then the search finds
              > the "foo" on
              > Line 1 and returns 1.
              > If flags is "bw", then the search finds the
              > "bar" on the third
              > line and returns 2.
              > If flags is "bW", then the search fails. The
              > cursor stays
              > put, and the function returns 0.
              > If flags is "n", the function returns 2 but
              > does not move the
              > cursor.
              > If flags includes "p", then >
              > :echo search('\(foo\)\|bar', flags)
              > < returns 0 (no match), 1 ("bar"), or 2 ("foo"),
              > depending on
              > the other flags used.
              >

              I am all in favor of good examples, even if they make the text
              longer. It's far more profitable to understand the subject
              immediately after reading a page than to start deciphering
              a cryptic short clever text and writing examples myself
              to understand what that one-liner is trying to say.
              All in all, I'd very much vote for the text above to be
              included.

              Cheers,

              ---Zdenek
            • Bram Moolenaar
              ... I find the example a bit long, takes a bit of reading to understand. And it looks like the action can be done with one command :%s/foo/bar/ge . Am I
              Message 6 of 13 , Nov 25, 2005
              View Source
              • 0 Attachment
                Benji Fisher wrote:

                > On Thu, Nov 24, 2005 at 09:11:06AM +0100, Zdenek Sekera wrote:
                > > >
                > > > Would it be clearer if I wrote
                > > >
                > > > 'a' allow a match at the current cursor position
                > > >
                > > > instead of the line quoted above?
                > >
                > > I would think so. Though, to add the whole last paragraph
                > > (the example) as an explanation wouldn't be too much either...
                > > I find it very clear.
                > >
                > > ---Zdenek
                >
                > How about an even longer paragraph that illustrates most of the
                > flags? (Bram, if you like this explanation and it will save you some
                > effort, I can make an updated patch.)

                I find the example a bit long, takes a bit of reading to understand.
                And it looks like the action can be done with one command
                ":%s/foo/bar/ge". Am I missing something? I'm sure it is possible to
                come up with a shorter example that shows the use of the flags.

                --
                hundred-and-one symptoms of being an internet addict:
                198. You read all the quotes at Netaholics Anonymous and keep thinking
                "What's wrong with that?"

                /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                \\\ download, build and distribute -- http://www.A-A-P.org ///
                \\\ help me help AIDS victims -- http://www.ICCF.nl ///
              • Benji Fisher
                ... I may not be able to satisfy both of you when it comes to documentation! My current suggestion includes a shorter, less comprehensive, more interesting
                Message 7 of 13 , Nov 30, 2005
                View Source
                • 0 Attachment
                  On Fri, Nov 25, 2005 at 11:25:25AM +0100, Bram Moolenaar wrote:
                  >
                  > Benji Fisher wrote:
                  >
                  > > On Thu, Nov 24, 2005 at 09:11:06AM +0100, Zdenek Sekera wrote:
                  > > > >
                  > > > > Would it be clearer if I wrote
                  > > > >
                  > > > > 'a' allow a match at the current cursor position
                  > > > >
                  > > > > instead of the line quoted above?
                  > > >
                  > > > I would think so. Though, to add the whole last paragraph
                  > > > (the example) as an explanation wouldn't be too much either...
                  > > > I find it very clear.
                  > > >
                  > > > ---Zdenek
                  > >
                  > > How about an even longer paragraph that illustrates most of the
                  > > flags? (Bram, if you like this explanation and it will save you some
                  > > effort, I can make an updated patch.)
                  >
                  > I find the example a bit long, takes a bit of reading to understand.
                  > And it looks like the action can be done with one command
                  > ":%s/foo/bar/ge". Am I missing something? I'm sure it is possible to
                  > come up with a shorter example that shows the use of the flags.

                  I may not be able to satisfy both of you when it comes to
                  documentation! My current suggestion includes a shorter, less
                  comprehensive, more interesting example:

                  Example of flags. >
                  :echo search('\<if\|\(else\)\|\(endif\)', 'nape')
                  < will search for the keywords "if", "else", and "endif" under
                  or after the cursor. Because of the 'p' flag, it returns 1,
                  2, or 3 depending on which keyword is found, or 0 if the
                  search fails. Without the 'a' and 'e' flags, this will not
                  find a keyword at the current cursor position; with the 'a'
                  flag but not the 'e' flag, it will not find the keyword under
                  the cursor if the cursor is in the middle or end of the word.
                  The 'n' flag tells the function not to move the cursor.

                  I have updated the patch to add Yet Another Flag: 'c' tells the
                  function (search() or searchpair()) to return the column number of the
                  match instead of the line number. (Give an error message if combined
                  with 'p' or 'm'.)

                  While I was testing the error message with searchpair(), I noticed
                  that it echoed the "skip" argument instead of the "flags" argument.
                  Please check my fix for this.

                  I have misplaced my copy of Kernighan and Ritchie, so I am not sure
                  if this is a problem. I have the assignment

                  rettv->vval.v_number = (flags & S_SUBPAT) ? subpatnum :
                  ((flags & SP_RETCOLUMN) ? 1 + pos.col : pos.lnum);

                  before I hacked it, it always assigned pos.lnum . If I follow the
                  typedef's correctly, then

                  variable defined type native type
                  v_number varnumber_T int or long (if SIZEOF_INT <= 3)
                  pos.lnum linenr_T long
                  pos.col colnr_T unsigned
                  subpatnum int

                  (The last one is my addition, and it matches the return type of the
                  searchit function.) Should there be a type cast or two in there, or
                  should varnumber_T always be defined as long, in case it has to hold a
                  line number?

                  --Benji Fisher
                • Bram Moolenaar
                  ... The example looks fine to me. But I m not sure if the explanation is clear, e.g., what keyword at the current cursor position means exactly. Perhaps a
                  Message 8 of 13 , Nov 30, 2005
                  View Source
                  • 0 Attachment
                    Benji Fisher wrote:

                    > I may not be able to satisfy both of you when it comes to
                    > documentation! My current suggestion includes a shorter, less
                    > comprehensive, more interesting example:

                    The example looks fine to me. But I'm not sure if the explanation is
                    clear, e.g., what "keyword at the current cursor position" means
                    exactly. Perhaps a few snippets of example text will help.

                    > I have updated the patch to add Yet Another Flag: 'c' tells the
                    > function (search() or searchpair()) to return the column number of the
                    > match instead of the line number. (Give an error message if combined
                    > with 'p' or 'm'.)

                    Alternative: add a new function that returns a list with both the line
                    and column number. Otherwise you would need to search twice to get
                    both.

                    :let [lnum, col] = search???()

                    > I have misplaced my copy of Kernighan and Ritchie, so I am not sure
                    > if this is a problem. I have the assignment
                    >
                    > rettv->vval.v_number = (flags & S_SUBPAT) ? subpatnum :
                    > ((flags & SP_RETCOLUMN) ? 1 + pos.col : pos.lnum);
                    >
                    > before I hacked it, it always assigned pos.lnum . If I follow the
                    > typedef's correctly, then
                    >
                    > variable defined type native type
                    > v_number varnumber_T int or long (if SIZEOF_INT <= 3)
                    > pos.lnum linenr_T long
                    > pos.col colnr_T unsigned
                    > subpatnum int
                    >
                    > (The last one is my addition, and it matches the return type of the
                    > searchit function.) Should there be a type cast or two in there, or
                    > should varnumber_T always be defined as long, in case it has to hold a
                    > line number?

                    Yes, casts are needed here to avoid a warning message from some
                    compilers.

                    --
                    hundred-and-one symptoms of being an internet addict:
                    268. You get up in the morning and go online before getting your coffee.

                    /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                    /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                    \\\ download, build and distribute -- http://www.A-A-P.org ///
                    \\\ help me help AIDS victims -- http://www.ICCF.nl ///
                  • Benji Fisher
                    ... OK, I will try another draft at the bottom of this note. ... That project is too ambitious for me (at least for now). ... I guess a file is not allowed to
                    Message 9 of 13 , Nov 30, 2005
                    View Source
                    • 0 Attachment
                      On Wed, Nov 30, 2005 at 08:29:40PM +0100, Bram Moolenaar wrote:
                      >
                      > Benji Fisher wrote:
                      >
                      > The example looks fine to me. But I'm not sure if the explanation is
                      > clear, e.g., what "keyword at the current cursor position" means
                      > exactly. Perhaps a few snippets of example text will help.

                      OK, I will try another draft at the bottom of this note.

                      > > I have updated the patch to add Yet Another Flag: 'c' tells the
                      > > function (search() or searchpair()) to return the column number of the
                      > > match instead of the line number. (Give an error message if combined
                      > > with 'p' or 'm'.)
                      >
                      > Alternative: add a new function that returns a list with both the line
                      > and column number. Otherwise you would need to search twice to get
                      > both.
                      >
                      > :let [lnum, col] = search???()

                      That project is too ambitious for me (at least for now).

                      > > rettv->vval.v_number = (flags & S_SUBPAT) ? subpatnum :
                      > > ((flags & SP_RETCOLUMN) ? 1 + pos.col : pos.lnum);
                      > >
                      > > v_number varnumber_T int or long (if SIZEOF_INT <= 3)
                      > > pos.lnum linenr_T long
                      >
                      > Yes, casts are needed here to avoid a warning message from some
                      > compilers.

                      I guess a file is not allowed to have more than 2^31 - 1 lines, so
                      there is not really a danger of truncation when assigning a long to an
                      int. I will leave this one alone.

                      Here is another attempt at documenting the new flags:

                      Example of flags. >
                      :echo search('\<if\|\(else\)\|\(endif\)', 'nape')
                      < will search for the keywords "if", "else", and "endif" under
                      or after the cursor. Because of the 'p' flag, it returns 1,
                      2, or 3 depending on which keyword is found, or 0 if the
                      search fails. With the cursor on the first word of the line >
                      if (foo == 0) | let foo = foo + 1 | endif
                      < the function returns 1. Without the 'a' flag, the function
                      finds the "endif" and returns 3. The same thing happens
                      without the 'e' flag if the cursor is on the "f" of "if".
                      The 'n' flag tells the function not to move the cursor.

                      --Benji Fisher
                    • Zdenek Sekera
                      ... You are doing all right, Benji! ... Yes, little harder to read, though not impossible, perhaps a few more simple(r) examples to go with it? ... I can t
                      Message 10 of 13 , Dec 1, 2005
                      View Source
                      • 0 Attachment
                        > From: Benji Fisher [mailto:benji@...]
                        ...
                        > > >
                        > > > How about an even longer paragraph that illustrates
                        > most of the
                        > > > flags? (Bram, if you like this explanation and it will
                        > save you some
                        > > > effort, I can make an updated patch.)
                        > >
                        > > I find the example a bit long, takes a bit of reading to understand.
                        > > And it looks like the action can be done with one command
                        > > ":%s/foo/bar/ge". Am I missing something? I'm sure it is
                        > possible to
                        > > come up with a shorter example that shows the use of the flags.
                        >
                        > I may not be able to satisfy both of you when it comes to
                        > documentation!

                        You are doing all right, Benji!

                        > My current suggestion includes a shorter, less
                        > comprehensive, more interesting example:
                        >
                        > Example of flags. >
                        > :echo search('\<if\|\(else\)\|\(endif\)', 'nape')
                        > < will search for the keywords "if", "else", and
                        > "endif" under
                        > or after the cursor. Because of the 'p' flag,
                        > it returns 1,
                        > 2, or 3 depending on which keyword is found, or 0 if the
                        > search fails. Without the 'a' and 'e' flags,
                        > this will not
                        > find a keyword at the current cursor position;
                        > with the 'a'
                        > flag but not the 'e' flag, it will not find the
                        > keyword under
                        > the cursor if the cursor is in the middle or
                        > end of the word.
                        > The 'n' flag tells the function not to move the cursor.
                        >

                        Yes, little harder to read, though not impossible, perhaps a few
                        more simple(r) examples to go with it?

                        > I have updated the patch to add Yet Another Flag: 'c' tells the
                        > function (search() or searchpair()) to return the column number of the
                        > match instead of the line number. (Give an error message if combined
                        > with 'p' or 'm'.)
                        >

                        I can't think at this minute when would I need to use it, however,
                        I would imagine that knowing both *line* and *column* of the match
                        should be *very* useful. I know it's not obvious to return two values,
                        perhaps 'line:column' format or similar?

                        Cheers,

                        ---Zdenek
                      • Zdenek Sekera
                        ... Hmmm, we agree (see my previous email) :-) ... Agreed again (see my previous email), what a day! :-):-)
                        Message 11 of 13 , Dec 1, 2005
                        View Source
                        • 0 Attachment
                          > -----Original Message-----
                          > From: Bram@... [mailto:Bram@...]
                          > Sent: 30 November 2005 20:30
                          > To: Benji Fisher
                          > Cc: vim-dev@...
                          > Subject: Re: [PATCH] new flags for the search() function
                          >
                          >
                          > Benji Fisher wrote:
                          >
                          > > I may not be able to satisfy both of you when it comes to
                          > > documentation! My current suggestion includes a shorter, less
                          > > comprehensive, more interesting example:
                          >
                          > The example looks fine to me. But I'm not sure if the explanation is
                          > clear, e.g., what "keyword at the current cursor position" means
                          > exactly. Perhaps a few snippets of example text will help.
                          >

                          Hmmm, we agree (see my previous email) :-)

                          > > I have updated the patch to add Yet Another Flag: 'c'
                          > tells the
                          > > function (search() or searchpair()) to return the column
                          > number of the
                          > > match instead of the line number. (Give an error message
                          > if combined
                          > > with 'p' or 'm'.)
                          >
                          > Alternative: add a new function that returns a list with both the line
                          > and column number. Otherwise you would need to search twice to get
                          > both.
                          >
                          > :let [lnum, col] = search???()
                          >

                          Agreed again (see my previous email), what a day! :-):-)

                          ---Zdenek
                        Your message has been successfully submitted and would be delivered to recipients shortly.