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

vim6: "fuzzy" regexp match, howto?

Expand Messages
  • Zdenek Sekera
    I have a regexp (may be a multiline and lots of times it is) and I need to find the starting point in the file where that regexp matches. That simple enough,
    Message 1 of 4 , Nov 2, 2000
    • 0 Attachment
      I have a regexp (may be a multiline and lots of times it is) and I need
      to
      find the starting point in the file where that regexp matches.
      That simple enough, however, I need to find it subject to the following
      condition: the cursor can be at the time of match anywhere in the file
      and I need to establish if the string matching the regexp can be found
      such that the cursor is *inside* the matched string (including first and
      last char of the matched string). And if so return the line and the
      starting
      char position of the matched string.

      Hence my term *fuzzy* regexp match.

      This calls for a function. The several I wrote work (at least to my
      needs,
      I am not sure how general they really are) but they are just slow,
      *very*
      slow, even on my machine (which is a fast SGI Octane).

      I am looking for some ideas on how to approach this (still staying
      within vim language only, which would be the best solution).

      Has anyone come accross such a problem? How did you solve it?

      Thanks.

      ---Zdenek
    • c928400@student.dtu.dk
      ... How about the functions below? The following command ... will simply echo a string of line col virtual-col of the start of the match that contains
      Message 2 of 4 , Nov 2, 2000
      • 0 Attachment
        Thus wrote Zdenek Sekera (zs@...) on [001102]:
        > I have a regexp (may be a multiline and lots of times it is) and I need
        > to
        > find the starting point in the file where that regexp matches.
        > That simple enough, however, I need to find it subject to the following
        > condition: the cursor can be at the time of match anywhere in the file
        > and I need to establish if the string matching the regexp can be found
        > such that the cursor is *inside* the matched string (including first and
        > last char of the matched string). And if so return the line and the
        > starting
        > char position of the matched string.

        How about the functions below?

        The following command

        :echo StartOffPatWithCurPos(pattern)

        will simply echo a string of "line col virtual-col" of the start of
        the match that contains current position - if any.

        You can use these numbers for further processing, of course.

        Peppe

        " --------------------------------------------------------------------
        fun! ByteOffsetCurPos(expr)
        " Returns byte number of position 'expr' ('expr' as with line())
        " This requires +byte_offset; return -1 if we don't have it.
        if has("byte_offset")
        return line2byte(a:expr) - 1 + col(a:expr)
        else
        return -1
        endif
        endfun

        fun! LineColCurPos(expr)
        " Returns the line, column and virtual column of position 'expr'
        " ('expr' as with line()).
        " The numbers are separated by spaces - should be ease to parse :-)
        return line(a:expr) . " " . col(a:expr) . " " . virtcol(a:expr)
        endfun

        fun! StartOffPatWithCurPos(pat)
        " Returns a string of 'line col virtcol' of the start of a match that
        " includes the current position.
        " The numbers are output from LineColCurPos()
        " If such a pattern cannot be found, return an empty string.
        let curpos = ByteOffsetCurPos(".")
        if curpos == -1
        return ""
        endif
        " test for existence of pattern in buffer.
        if search(a:pat, 1) == 0
        " search() brought us to the next match, so we can search backwards.
        let nexpatpos = ByteOffsetCurPos(".")
        let pat = escape(a:pat, "?")
        silent! exec "normal ?" . pat . "?e\<CR>"
        let endpos = ByteOffsetCurPos(".")
        exec "goto " . nexpatpos
        silent! exec "normal ?" . pat . "?\<CR>"
        let startpos = ByteOffsetCurPos(".")
        let startstr = LineColCurPos(".")
        exec "goto " . (curpos)
        if (curpos >= startpos && endpos >= curpos)
        return startstr
        endif
        endif
        return "foo"
        endfun
        " --------------------------------------------------------------------
      • Zdenek Sekera
        ... This is briliant! Thanks!
        Message 3 of 4 , Nov 2, 2000
        • 0 Attachment
          c928400@... wrote:
          >
          > Thus wrote Zdenek Sekera (zs@...) on [001102]:
          > > I have a regexp (may be a multiline and lots of times it is) and I need
          > > to
          > > find the starting point in the file where that regexp matches.
          > > That simple enough, however, I need to find it subject to the following
          > > condition: the cursor can be at the time of match anywhere in the file
          > > and I need to establish if the string matching the regexp can be found
          > > such that the cursor is *inside* the matched string (including first and
          > > last char of the matched string). And if so return the line and the
          > > starting
          > > char position of the matched string.
          >
          > How about the functions below?
          >
          > The following command
          >
          > :echo StartOffPatWithCurPos(pattern)
          >
          > will simply echo a string of "line col virtual-col" of the start of
          > the match that contains current position - if any.
          >


          This is briliant! Thanks!

          ---Zdenek
        • c928400@student.dtu.dk
          ... OK, Zdenek and I had a little talk, and I came up with the attached script. The aim of the main function is to locate a pattern that includes the current
          Message 4 of 4 , Nov 8, 2000
          • 0 Attachment
            Thus wrote Peppe paa DTU (c928400@...) on [001102]:
            > Thus wrote Zdenek Sekera (zs@...) on [001102]:
            > > I have a regexp (may be a multiline and lots of times it is) and I need
            > > to
            > > find the starting point in the file where that regexp matches.
            > > That simple enough, however, I need to find it subject to the following
            > > condition: the cursor can be at the time of match anywhere in the file
            > > and I need to establish if the string matching the regexp can be found
            > > such that the cursor is *inside* the matched string (including first and
            > > last char of the matched string). And if so return the line and the
            > > starting
            > > char position of the matched string.

            > How about the functions below?

            OK, Zdenek and I had a little talk, and I came up with the attached
            script.

            The aim of the main function is to locate a pattern that includes the
            current position and return information about the pattern and/or
            current position.

            This may sound as a strange thing to do, but see the documentation for
            an example with HTML.


            Btw, I like the idea of eg "dvj", where one uses v, V, or <C-V> to
            alter the behaviour of the motion afterwards. But it appears that no
            vmap's are carried out for this visual-like selection. Is there a way
            around this, or is it intended behaviour? (omaps does not seem to do
            the trick :-( ).

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