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

Bug report: :tags command changes tag match number, jumps to wrong location

Expand Messages
  • Erik Falor
    Given the source code listed at the end of this message, and a tags file generated from that source, I will demonstrate that a bug in the operation of the :tag
    Message 1 of 3 , Nov 5, 2008
    • 0 Attachment
      Given the source code listed at the end of this message, and a tags file
      generated from that source, I will demonstrate that a bug in the operation
      of the :tag command has been introduced after Vim 6.3, and persists today.

      When navigating the tag stack with the :tag and :pop commands, Vim is
      supposed to remember which one of many matching tags I previously
      selected, so that as I climb and descend the tag stack, I return to the
      same location I originally jumped to.

      The helpfile states that the tag match number won't change when using :pop
      or :tag. (tagsrch.txt for Vim version 7.1, line 130)

      However, I find that when I use the :tag command without arguments to
      climb the tag stack, the cursor jumps to the first tag entry in the match
      list instead of the one I selected.  The tag stack is updated so that the
      current entry points to the first matching tag instead of the one I chose.

      The relevant documentation is located at
      :help :pop
      :help :tag
      :help :tags

      I have reproduced this bug in several Vim versions ranging from 7.0 to a
      fully-patched 7.2, on both Windows XP and Linux.

      Steps to reproduce:
      1.  Generate a tags file from the source code below.

      2.  Open the file with `vim -u NONE main.c`

      3.  Position the cursor on the call to func1() in main() on line 32.
          Press 'g Ctrl-]' and choose to jump to the definition of func1() that
          takes an integer argument.  From there, jump to the definition of
          func2() that also takes an integer.  Finally, jump into the definition
          of func3().
          At this point, the output of :tags should look like this:

        # TO tag         FROM line  in file/text
        1  2 func1              32  func1(i);
        2  2 func2               5  func2(i);
        3  1 func3              15  func3(i);
      >

      4.  :3pop your way back to the bottom of the tag stack. 
          At this point, the output of :tags should look like this:

        # TO tag         FROM line  in file/text
      > 1  2 func1              32  func1(i);
        2  2 func2               5  func2(i);
        3  1 func3              15  func3(i);

          Notice that the tag number from the match list (the number beneath the
          heading "TO") hasn't changed.

      5.  If you are following these steps in Vim version <= 6.3, the :tag command
          will return you to the same definition of func1() that you had
          selected earlier, that is, your cursor will jump to the definition of
          func1(int i).
          If you are following along in a version of Vim > 6.3, the :tag command
          will instead jump the cursor to the first definition of func1() found
          in the tags file, func1(double d).
          In Vim > 6.3, the output of :tags now looks like this:

        # TO tag         FROM line  in file/text
        1  1 func1              32  func1(i);
      > 2  2 func2               5  func2(i);
        3  1 func3              15  func3(i);

          As I have stated before, this is incorrect because the :tag command
          should not modify the match number, and should return the cursor to
          the definition of func1(int)

      /* main.c */
      /* vim:set nofoldenable filetype=c: */

      void func1(int i) /* i want to come here FIRST */
      {
          func2(i);
      }

      void func1(double d)
      {
          func2(d);
      }

      void func2(int i)  /* i want to come here SECOND */
      {
          func3(i);
      }

      void func2(double d)
      {
          int i;
          func3(i);
      }

      void func3(int i)
      {
          i++;
      }

      int main(void)
      {
          int i;
          func1(i);
      }

      /* EOF */


      --
      Erik Falor
      Registered Linux User #445632 http://counter.li.org

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---

    • Bram Moolenaar
      ... [...] I ll add this to the todo list. -- hundred-and-one symptoms of being an internet addict: 180. You maintain more than six e-mail addresses. /// Bram
      Message 2 of 3 , Nov 6, 2008
      • 0 Attachment
        Erik Falor wrote:

        > Given the source code listed at the end of this message, and a tags file
        > generated from that source, I will demonstrate that a bug in the operation
        > of the :tag command has been introduced after Vim 6.3, and persists today.
        >
        > When navigating the tag stack with the :tag and :pop commands, Vim is
        > supposed to remember which one of many matching tags I previously
        > selected, so that as I climb and descend the tag stack, I return to the
        > same location I originally jumped to.
        >
        > The helpfile states that the tag match number won't change when using :pop
        > or :tag. (tagsrch.txt for Vim version 7.1, line 130)
        >
        > However, I find that when I use the :tag command without arguments to
        > climb the tag stack, the cursor jumps to the first tag entry in the match
        > list instead of the one I selected. The tag stack is updated so that the
        > current entry points to the first matching tag instead of the one I chose.
        >
        > The relevant documentation is located at
        > :help :pop
        > :help :tag
        > :help :tags
        >
        > I have reproduced this bug in several Vim versions ranging from 7.0 to a
        > fully-patched 7.2, on both Windows XP and Linux.
        >
        > Steps to reproduce:
        [...]

        I'll add this to the todo list.

        --
        hundred-and-one symptoms of being an internet addict:
        180. You maintain more than six e-mail addresses.

        /// 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
        -~----------~----~----~----~------~----~------~--~---
      • Erik Falor
        ... I sent this to Bram before the Holidays, but I forgot to CC the mailing list. Please take a look at this patch and tell me what you think. Here is a patch
        Message 3 of 3 , Jan 5, 2009
        • 0 Attachment
          On Thu, Nov 6, 2008 at 3:03 AM, Bram Moolenaar <Bram@...> wrote:

          Erik Falor wrote:

          > Given the source code listed at the end of this message, and a tags file
          > generated from that source, I will demonstrate that a bug in the operation
          > of the :tag command has been introduced after Vim 6.3, and persists today.
          >
          > When navigating the tag stack with the :tag and :pop commands, Vim is
          > supposed to remember which one of many matching tags I previously
          > selected, so that as I climb and descend the tag stack, I return to the
          > same location I originally jumped to.
          >
          > The helpfile states that the tag match number won't change when using :pop
          > or :tag. (tagsrch.txt for Vim version 7.1, line 130)
          >
          > However, I find that when I use the :tag command without arguments to
          > climb the tag stack, the cursor jumps to the first tag entry in the match
          > list instead of the one I selected.  The tag stack is updated so that the
          > current entry points to the first matching tag instead of the one I chose.
          >
          > The relevant documentation is located at
          > :help :pop
          > :help :tag
          > :help :tags
          >
          > I have reproduced this bug in several Vim versions ranging from 7.0 to a
          > fully-patched 7.2, on both Windows XP and Linux.
          >
          > Steps to reproduce:
          [...]

          I'll add this to the todo list.
          I sent this to Bram before the Holidays, but I forgot to CC the mailing list.  
          Please take a look at this patch and tell me what you think.
          Here is a patch to fix this bug.
          I found that the problem was caused because the :tag command behaves differently when given a tag name as an argument, and this difference wasn't being accounted for.
          ':2tag' jumps the cursor to the tag 2 positions above the current tag on the tagstack. This is analogous to the :pop command, and allows you to climb/descend the tagstack. This command should not modify the contents of the tagstack.
          ':2tag func1' jumps the cursor to the 2nd tag on the |tag-matchlist| named for func1, and modifies the tagstack by replacing all tags above the current tag on the stack with the newly chosen tag.
          tag.c was resetting the current match based upon the value of the count given to the command. Provided [count] is greater than zero, the current match is updated to [count]. However, a count of 1 is implied when not given by the user, and therefore the matching tag was always being changed to be the first.
          To determine whether or not to update the matching tag number, I have amended the if statement to check the length of the argument given to :tag. If the STRLEN() is zero, then the user invoked ':[count]tag', and the matching tag number must not be updated.
          As far as the original if statement goes, is it even possible to provide a count <= 0 to a command? Perhaps that condition can be completely removed.

          --
          Erik Falor
          Registered Linux User #445632 http://counter.li.org

          --~--~---------~--~----~------------~-------~--~----~
          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.