8

Here is a file -- ChipBooter.cpp -- in my project(Omit some details that are not related to this question):

class ChipBooter {
public:   
    void Boot() {
        this->DpDetect();
    }
    void DpDetect() {}
}

When I hit g<C-]> to jump to the definition of DpDetect, Vim displayed a list with duplicate matching tags:

# pri kind tag               file
1 F C f    DpDetect          OMU/src/boot/src/ChipBooter.cpp
             class:ChipBooter
             void ChipBooter::DpDetect()
2 F C f    DpDetect          OMU/src/boot/src/ChipBooter.cpp
             class:ChipBooter
             void ChipBooter::DpDetect()

This is the same definition!

This problem happens every time I hit g<C-]> and always doubles the length of the list.


More Details

Exuberant Ctags version: 5.8. Vim version is 7.3

Here is a visual representation of my directory hierarchy:

Source
  `---tags
  |       
  `---OMU
       `---src
            `---boot
                 `---src
                      `---ChipBooter.cpp

I ran ctags -R in Source which contains the OMU directory to generate the tags file.

I launch vim using vim -u NONE -N; .vimrc and plugins is disabled.

There is only one entry about DpDetect in the tags file:

DpDetect    OMU/src/boot/src/ChipBooter.cpp /^void ChipBooter::DpDetect()$/;"   f   class:ChipBooter

tags is default value, because .vimrc is disabled.

:set tags?
tags=./tags,./TAGS,tags,TAGS

Update

@romainl said Vim seems to be using both two tags files: tags and TAGS.

:echo tagfiles()
['tags', 'TAGS']

If I change tags option to exclude TAGS file(:set tags=./tags,tags), duplicate tags problem does not exist.

Where is the TAGS file? There is only a tags file in my project directory.

$ find {My project root directory} -iname tags
./tags
  • 1
    What is the output of :echo tagfiles()? – romainl Dec 25 '15 at 16:27
  • 1
    Vim seems to be using two tags files, tags and TAGS. Do you have a TAGS file in /home/yufeng/mount/svncode/omu/zycp/Source/? Could it be a case-sensitivity issue? – romainl Dec 26 '15 at 10:08
  • 1
    @romainl I think you're on to something. Given that every vim newcomer nowadays is working on Mac OS X, this might help the OP: apple.stackexchange.com/questions/71357/… I would guess that Vim is assuming that in Unix all filesystems are case sensitive. – Vitor Dec 29 '15 at 14:01
  • @Vitor, I don't know much about Vim's guts but I can imagine it asking the file system for a tags file and then asking for a TAGS file. A case-sensitive FS would answer yes to both question, forcing Vim to search two times in the same file thinking there are two, while a case-insensitive FS would answer yes only to the first question. – romainl Dec 29 '15 at 14:41
  • Vitor's link tells you how for Mac OS X. Google will tell you for other OSes. – romainl Dec 29 '15 at 14:47
4

As @romainl said, It is indeed an FS(file system) case-sensitivity issue.

My project file is mounted from Window 7 to my Fedora using:

mount {Windows 7 Dir} {Fedora Dir} /local_folder -t cifs -o username=xxxx,password=xxxx

From the mount.cifs man page:

case sensitive is the default if the server supports it.

It means that the Mount will preserve the case-sensitivity of the server FS. If the server's FS is case-sensitive, these mounted files will be case-sensitive; If the server's FS is case-insensitive, they will be case-insensitive.

Windows 7 is case-insensitive, which makes these project files case-insensitive.

$ cd {My project root directory}
$ ls tags
tags
$ ls TAGS
TAGS

If 'tags' option includes both tags and TAGS:

:set tags=tags,TAGS

Vim will search the tags file twice: one for tags, another for TAGS. In both times, Vim finds that there is one fits. This makes Vim mistake one same tags file for two different files.

Consequently, Vim will use two tags files:

:echo tagfiles()
['tags', 'TAGS']

Thus, duplicate tags problem happened.

If 'tags' option includes only tags:

:set tags=tags

The problem will not exist.

  • BTW, why wouldn't Vim stop searching tags file when it has already found one? Thus, duplicate problem will not exist. – Feng Yu Dec 30 '15 at 13:56
  • In terms of files, some people break their projects into multiple parts. For example, my main source might be tagged in one file and a shared library tagged in another, but I'd want to be able to find a definition either way. In terms of continuing once a symbol is found in the tags files, sometimes a project might have variants, where there are two functions of the same name but only one or the other gets built/linked for a given variant. When jumping to a definition like that, you'd want to be able to pick which variant you care about right now from the list, rather than only the first one v – John O'M. Jan 1 '16 at 15:11
  • (Continued) Vim finds. – John O'M. Jan 1 '16 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.