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

RE: g ignores range in diff mode

Expand Messages
  • John Beckett
    ... I ve had a look at this and confirm Gary s results. It looks like a bug. I don t follow all the complex interactions, but the following looks as if it is
    Message 1 of 6 , Aug 5 4:21 AM
      Gary Johnson wrote:
      > When vim is in diff mode and a BufWrite autocommand
      > containing a "<range>g" is executed, the g command appears to
      > ignore the range and act on the entire buffer.
      > ...

      I've had a look at this and confirm Gary's results. It looks like a bug.

      I don't follow all the complex interactions, but the following looks as if it is
      responsible.

      In file ex_docmd.c the function do_one_cmd() is invoked by the autocmd.
      Everything is good at entry. The command is:
      "1,100g/50$/s/$/\tchanged here/"

      and it is parsed correctly including:
      ea.line1 = 1
      ea.line2 = 100

      But then the following code is executed:
      if (((ea.argt & WHOLEFOLD) || ea.addr_count >= 2) && !global_busy)
      {
      /* Put the first line at the start of a closed fold, put the last line
      * at the end of a closed fold. */
      (void)hasFolding(ea.line1, &ea.line1, NULL);
      (void)hasFolding(ea.line2, NULL, &ea.line2);
      }

      The last line changes ea.line2 from 100 to 1000 (we previously did ':windo diffthis'
      which folded a lot of lines, ending at line 1000).

      Therefore the 'g' command is applied to the whole file and Gary's bug follows.

      John



      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Bram Moolenaar
      ... Not a bug. When folds are closed the operation applies to the whole fold. See :he E493 and scroll up a bit. Or :he fold-behavior . -- Why isn t there
      Message 2 of 6 , Aug 5 1:45 PM
        Gary Johnson wrote:

        > When vim is in diff mode and a BufWrite autocommand containing a
        > "<range>g" is executed, the g command appears to ignore the range
        > and act on the entire buffer.
        >
        > Here's an example.
        >
        > Create a file containing the integers from 1 to 1000, each on a
        > separate line:
        >
        > $ seq 1000 > seq1
        >
        > Create the following vim script and name it "test1.vim":
        >
        > au BufWrite * 1,100g/50$/s/$/\tchanged here/
        >
        > When that autocommand is triggered by writing the buffer, it should
        > append "\tchanged here" to every line in the range 1 to 100 ending
        > in "50". That is, it should change line 50 and only line 50.
        >
        > Now edit seq1 with vim, source the script, open a new buffer, and
        > read seq1 into that buffer:
        >
        > $ vim -N -u NONE -i NONE -c 'so test1.vim' -c 'vnew|r seq1|normal ggdd' seq1
        >
        > There's nothing magic about doing that on the command line--I just
        > got tired of typing all those vim commands as I worked on making the
        > example smaller.
        >
        > Now move the cursor to the right window (^W^W) and write the buffer
        > to the seq1 file by executing:
        >
        > :w
        >
        > Note that line 50 and only line 50 has changed to:
        >
        > 50 changed here
        >
        > This is as it should be.
        >
        > Now diff the two buffers:
        >
        > :windo diffthis
        >
        > and write the right buffer again:
        >
        > :w
        >
        > Note now that every line in the file ending in "50" (i.e., 150, 250,
        > 350, 450, 550, 650, 750, 850 and 950) has been appended with
        > "changed here". This appears to be a bug.

        Not a bug. When folds are closed the operation applies to the whole
        fold. See ":he E493" and scroll up a bit. Or ":he fold-behavior".

        --
        Why isn't there mouse-flavored cat food?

        /// 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://ICCF-Holland.org ///

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Gary Johnson
        ... Oh. I can see now that the behavior is intended, but it is certainly unexpected. I don t see the benefit of having an explicit range ignored just because
        Message 3 of 6 , Aug 5 2:51 PM
          On 2008-08-05, Bram Moolenaar <Bram@...> wrote:
          > Gary Johnson wrote:
          >
          > > When vim is in diff mode and a BufWrite autocommand containing a
          > > "<range>g" is executed, the g command appears to ignore the range
          > > and act on the entire buffer.
          > >
          > > Here's an example.
          > >
          > > Create a file containing the integers from 1 to 1000, each on a
          > > separate line:
          > >
          > > $ seq 1000 > seq1
          > >
          > > Create the following vim script and name it "test1.vim":
          > >
          > > au BufWrite * 1,100g/50$/s/$/\tchanged here/
          > >
          > > When that autocommand is triggered by writing the buffer, it should
          > > append "\tchanged here" to every line in the range 1 to 100 ending
          > > in "50". That is, it should change line 50 and only line 50.
          > >
          > > Now edit seq1 with vim, source the script, open a new buffer, and
          > > read seq1 into that buffer:
          > >
          > > $ vim -N -u NONE -i NONE -c 'so test1.vim' -c 'vnew|r seq1|normal ggdd' seq1
          > >
          > > There's nothing magic about doing that on the command line--I just
          > > got tired of typing all those vim commands as I worked on making the
          > > example smaller.
          > >
          > > Now move the cursor to the right window (^W^W) and write the buffer
          > > to the seq1 file by executing:
          > >
          > > :w
          > >
          > > Note that line 50 and only line 50 has changed to:
          > >
          > > 50 changed here
          > >
          > > This is as it should be.
          > >
          > > Now diff the two buffers:
          > >
          > > :windo diffthis
          > >
          > > and write the right buffer again:
          > >
          > > :w
          > >
          > > Note now that every line in the file ending in "50" (i.e., 150, 250,
          > > 350, 450, 550, 650, 750, 850 and 950) has been appended with
          > > "changed here". This appears to be a bug.
          >
          > Not a bug. When folds are closed the operation applies to the whole
          > fold. See ":he E493" and scroll up a bit. Or ":he fold-behavior".

          Oh. I can see now that the behavior is intended, but it is
          certainly unexpected. I don't see the benefit of having an explicit
          range ignored just because the range happens to be in a closed fold.

          The actual problem is that I wish to update a file's header comment
          with the modification date and time whenever the buffer is written.
          To this end, I have a function that's called by a BufWrite
          autocommand and which updates a line matching '^ \?\* *Modified:'
          in the file header. Most of the files I work on have only one such
          line, but some of the files I've been working on recently have the
          same string in each function header, so it's important to restrict
          the range to just the file header.

          Before checking a file into our revision control system, I diff the
          checked-out version with the previous version to make sure I haven't
          left any debug droppings. I usually write the file while the diff
          and folds are still enabled. The top of the file may not even
          on-screen at the time.

          So, is there any way to restrict a range within a closed fold?
          :folddopen and :folddoclosed don't seem to cut it since the range
          I'm interested in may span one or more fold boundaries. If there
          isn't a way, I suppose I could search for the bottom of the file
          header, note the line number, search for the first "Modified" line,
          note that line number, and compare line numbers before making the
          change. If I do that, it looks like I'll have to use getline() and
          setline() rather than :s for the reasons given in ":help
          fold-behavior".

          Regards,
          Gary


          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Tony Mechelynck
          ... You may want to open all folds before applying your range-command. And possibly to fold them afterwards, or (if possible) to save and restore the fold
          Message 4 of 6 , Aug 5 3:37 PM
            On 05/08/08 23:51, Gary Johnson wrote:
            > On 2008-08-05, Bram Moolenaar<Bram@...> wrote:
            >> Gary Johnson wrote:
            >>
            >>> When vim is in diff mode and a BufWrite autocommand containing a
            >>> "<range>g" is executed, the g command appears to ignore the range
            >>> and act on the entire buffer.
            >>>
            >>> Here's an example.
            >>>
            >>> Create a file containing the integers from 1 to 1000, each on a
            >>> separate line:
            >>>
            >>> $ seq 1000> seq1
            >>>
            >>> Create the following vim script and name it "test1.vim":
            >>>
            >>> au BufWrite * 1,100g/50$/s/$/\tchanged here/
            >>>
            >>> When that autocommand is triggered by writing the buffer, it should
            >>> append "\tchanged here" to every line in the range 1 to 100 ending
            >>> in "50". That is, it should change line 50 and only line 50.
            >>>
            >>> Now edit seq1 with vim, source the script, open a new buffer, and
            >>> read seq1 into that buffer:
            >>>
            >>> $ vim -N -u NONE -i NONE -c 'so test1.vim' -c 'vnew|r seq1|normal ggdd' seq1
            >>>
            >>> There's nothing magic about doing that on the command line--I just
            >>> got tired of typing all those vim commands as I worked on making the
            >>> example smaller.
            >>>
            >>> Now move the cursor to the right window (^W^W) and write the buffer
            >>> to the seq1 file by executing:
            >>>
            >>> :w
            >>>
            >>> Note that line 50 and only line 50 has changed to:
            >>>
            >>> 50 changed here
            >>>
            >>> This is as it should be.
            >>>
            >>> Now diff the two buffers:
            >>>
            >>> :windo diffthis
            >>>
            >>> and write the right buffer again:
            >>>
            >>> :w
            >>>
            >>> Note now that every line in the file ending in "50" (i.e., 150, 250,
            >>> 350, 450, 550, 650, 750, 850 and 950) has been appended with
            >>> "changed here". This appears to be a bug.
            >> Not a bug. When folds are closed the operation applies to the whole
            >> fold. See ":he E493" and scroll up a bit. Or ":he fold-behavior".
            >
            > Oh. I can see now that the behavior is intended, but it is
            > certainly unexpected. I don't see the benefit of having an explicit
            > range ignored just because the range happens to be in a closed fold.
            >
            > The actual problem is that I wish to update a file's header comment
            > with the modification date and time whenever the buffer is written.
            > To this end, I have a function that's called by a BufWrite
            > autocommand and which updates a line matching '^ \?\* *Modified:'
            > in the file header. Most of the files I work on have only one such
            > line, but some of the files I've been working on recently have the
            > same string in each function header, so it's important to restrict
            > the range to just the file header.
            >
            > Before checking a file into our revision control system, I diff the
            > checked-out version with the previous version to make sure I haven't
            > left any debug droppings. I usually write the file while the diff
            > and folds are still enabled. The top of the file may not even
            > on-screen at the time.
            >
            > So, is there any way to restrict a range within a closed fold?
            > :folddopen and :folddoclosed don't seem to cut it since the range
            > I'm interested in may span one or more fold boundaries. If there
            > isn't a way, I suppose I could search for the bottom of the file
            > header, note the line number, search for the first "Modified" line,
            > note that line number, and compare line numbers before making the
            > change. If I do that, it looks like I'll have to use getline() and
            > setline() rather than :s for the reasons given in ":help
            > fold-behavior".
            >
            > Regards,
            > Gary

            You may want to open all folds before applying your range-command. And
            possibly to fold them afterwards, or (if possible) to save and restore
            the fold level.


            Best regards,
            Tony.
            --
            hundred-and-one symptoms of being an internet addict:
            98. The Alta Vista administrators ask you what sites are missing
            in their index files.

            --~--~---------~--~----~------------~-------~--~----~
            You received this message from the "vim_dev" maillist.
            For more information, visit http://www.vim.org/maillist.php
            -~----------~----~----~----~------~----~------~--~---
          • Ben Schmidt
            ... Just set nofoldenable and then set foldenable when you re done. It s the standard way to temporarily disable folds. Ben.
            Message 5 of 6 , Aug 5 4:42 PM
              > The actual problem is that I wish to update a file's header comment
              > with the modification date and time whenever the buffer is written.
              > To this end, I have a function that's called by a BufWrite
              > autocommand and which updates a line matching '^ \?\* *Modified:'
              > in the file header. Most of the files I work on have only one such
              > line, but some of the files I've been working on recently have the
              > same string in each function header, so it's important to restrict
              > the range to just the file header.
              >
              > Before checking a file into our revision control system, I diff the
              > checked-out version with the previous version to make sure I haven't
              > left any debug droppings. I usually write the file while the diff
              > and folds are still enabled. The top of the file may not even
              > on-screen at the time.
              >
              > So, is there any way to restrict a range within a closed fold?

              Just set nofoldenable and then set foldenable when you're done. It's the
              standard way to temporarily disable folds.

              Ben.




              --~--~---------~--~----~------------~-------~--~----~
              You received this message from the "vim_dev" maillist.
              For more information, visit http://www.vim.org/maillist.php
              -~----------~----~----~----~------~----~------~--~---
            Your message has been successfully submitted and would be delivered to recipients shortly.