On Thu, Nov 6, 2008 at 3:03 AM, Bram Moolenaar <Bram@...>
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.