Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

tag selection redundancy #235

Closed
jeroendv opened this Issue · 20 comments

3 participants

@jeroendv

I have a project where two methods with the dame name are implemented in different files.
Searching for that method in tag mode then gives both hits. At which point I can select the right one based on the filename in which the method is contained and press enter to open it.

However on pressing enter, vim will then present me with a dialog mentioning both tags, again asking me to choose one of them to open.

Is this intended/expected behaviour?

With kind regards,

Jeroen

@kien
Owner

That dialog is a Vim's built-in feature that's triggered automatically. See :help tag-matchlist and check the example output under :tselect. And because these commands only accept the tag name, it's really hard to differentiate 2 tags with the same name in different files.

The tag extension has a workaround for this, but apparently it doesn't always work.

Can you provide a test case including the tag names, the filenames, the tag files and their locations?

@jeroendv

$ mkdir CTrlPtest
$ cd CTrlPtest/
$ echo "function foo()" > file1.m
$ echo "function foo()" > file2.m

$ ctags --languages=Matlab -R ./

$ ll
total 12
-rw-rw-r--. 1 jeroendv jeroendv 15 Jul 12 13:38 file1.m
-rw-rw-r--. 1 jeroendv jeroendv 15 Jul 12 13:38 file2.m
-rw-rw-r--. 1 jeroendv jeroendv 406 Jul 12 13:39 tags

$ cat tags
!_TAG_FILE_FORMAT2/extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED1/0=unsorted, 1=sorted, 2=formatldcase/
!_TAG_PROGRAM_AUTHORDarren Hiebert/dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAMEExuberant Ctags//
!_TAG_PROGRAM_URLhttp://ctags.sourceforge.net/official site/
!_TAG_PROGRAM_VERSION5.8//
foo./file1.m/^function foo()$/;"f
foo./file2.m/^function foo()$/;"f

$ vim

If I then invoke CtrlP, switch to Tag mode and search for foo, I'll get two results.
I can select either using <c-n> and <c-p> but when I press enter vim will invariable show me a tag-matchlist and ask me to choose on of them.

@kien
Owner

Let me know if this patch fixes it:

diff --git a/autoload/ctrlp/tag.vim b/autoload/ctrlp/tag.vim
index c54d5ad..f3efbb8 100644
--- a/autoload/ctrlp/tag.vim
+++ b/autoload/ctrlp/tag.vim
@@ -23,8 +23,9 @@ let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
 " Utilities {{{1
 fu! s:findcount(str)
    let [tg, fname] = split(a:str, '\t\+\ze[^\t]\+$')
-   let [fname, tgs] = [expand(fname, 1), taglist('^'.tg.'$')]
-   if empty(tgs) | retu [1, 1] | en
+   let tgs = taglist('^'.tg.'$')
+   if tgs == [] | retu [1, 1] | en
+   let fname = fnamemodify(simplify(fname), ':s?^[.\/]\+??:p:.')
    let [fnd, ct, pos] = [0, 0, 0]
    for each in tgs
        let ct += 1
@jeroendv

hmm, coudl there have been something wrong with the pathc?
see line 5: @@ -23,8 +23,9 @@ let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
Anyhow I ended up patching it manually

Anyway, although I now no longer get a tag-matchlist it now does something very weird.
after invoking CtrlP, switch to Tag mode and search for foo, I'll get two results which looks like this:

> foo ./file2.m /^function fo()$/;" f
> foo ./file1.m /^function fo()$/;" f


prt path <mru>={tags}=<bft> <-v
>>> foo

I select either one and all works as expected. The tag is openen in the file that I selected

But If reopen CrlP in tag mode again and try to select the other file weird thing start happening.
trying to open the tag in file1.m does nothing while opening the tag in file2.m switches the showed file.
So if i repeatedly open CtrlP in tag mode and select the tag foo in file2.m that it vim will repeatedly switch between file1.m and file2.m.

Selecting the tag in file1.m does nothing though.

very weird :-s

Jeroen

@kien
Owner

OK, I was able to reproduce the switching problem. This fixes it for me:

diff --git a/autoload/ctrlp/tag.vim b/autoload/ctrlp/tag.vim
index c54d5ad..34d5043 100644
--- a/autoload/ctrlp/tag.vim
+++ b/autoload/ctrlp/tag.vim
@@ -23,9 +23,20 @@ let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
 " Utilities {{{1
 fu! s:findcount(str)
    let [tg, fname] = split(a:str, '\t\+\ze[^\t]\+$')
-   let [fname, tgs] = [expand(fname, 1), taglist('^'.tg.'$')]
-   if empty(tgs) | retu [1, 1] | en
-   let [fnd, ct, pos] = [0, 0, 0]
+   let tgs = taglist('^'.tg.'$')
+   if tgs == []
+       retu [1, 1]
+   en
+   let bname = fnamemodify(bufname('%'), ':p')
+   let fname = expand(fnamemodify(simplify(fname), ':s?^[.\/]\+??:p:.'), 1)
+   let [fnd, ct, pos, idx] = [0, 0, 0, 0]
+   wh idx < len(tgs)
+       if bname == fnamemodify(tgs[idx]["filename"], ':p')
+           cal insert(tgs, remove(tgs, idx))
+           brea
+       en
+       let idx += 1
+   endw
    for each in tgs
        let ct += 1
        let fulname = fnamemodify(each["filename"], ':p')

The patch was created with $ git format-patch -1 > test.patch and works fine when applying. But I haven't updated my git installation for more than a year, so maybe that's the reason.

@jeroendv

yup that seems to do it! :-)

thanks!!

Jeroen

Ps: it think the patching problems have to do with indenting, tab vs. spaces and how vim tends to retab files and how a tab is probably turning into a space when I copy the patch from this page into a textfile before applying it.

supplying the -l option to patch

-l Match patterns loosely, in case tabs or spaces have been munged in your files

did apply the patch succesfully but ended up screwing with the indentation of the patched lines.
I'm a bit baffeled, but then again I'm not a regular patch user :-s

@kien
Owner

Great, thanks! I'll push this to master soon once I'm sure there isn't any side effect.

@kien kien closed this issue from a commit
@kien Improve s:findcount()
Fixes #235
26c6f26
@kien kien closed this in 26c6f26
@jszakmeister

Hmmm... I still see this issue on master with the change. :-(

@kien
Owner

@jszakmeister can you provide a test case like Jeroen did in the 3rd comment?

@jszakmeister

Yes.

$ echo 'def formatError(msg):
    print "ERROR [file1]:", msg' > file1.py
$ echo 'import sys

def formatError(msg):
    print >>sys.stderr, "ERROR [file2]:", msg' > file2.py
$ ctags -R .
$ cat tags
!_TAG_FILE_FORMAT   2   /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED   1   /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Darren Hiebert  /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME  Exuberant Ctags //
!_TAG_PROGRAM_URL   http://ctags.sourceforge.net    /official site/
!_TAG_PROGRAM_VERSION   5.8 //
formatError file1.py    /^def formatError(msg):$/;" f
formatError file2.py    /^def formatError(msg):$/;" f
sys file2.py    /^import sys$/;"    i

Then:

gvim file1.py

Run:

:CtrlPTag

Select the formatError in file2.py and hit Enter. Vim will still bring up the taglist and ask you to choose, even though you selected the version in file2.py.

I created a gist for this too: https://gist.github.com/e722a7aef7a3e63513a4

@kien
Owner

Looks like you're using an older commit without the above fix. Make sure to update to HEAD of master, and let me know if you still see the issue.

@jszakmeister

I don't believe I'm running an old version. This is what git has to say:

$ git log -1
commit 675faa77f883df9025df1c947b5a7f07f14713fe
Author: Kien N <contact@ndkien.com>
Date:   Fri Dec 21 08:48:12 2012 +0700

    Fix for recognizing/expanding of environment variables

    Thanks to Simon Ruderich

That's in my ~/.vim/bundle/ctrlp.vim folder.

@kien
Owner

I still can't reproduce it by following the steps in your test. And oddly enough, the old version can also get the tag count from your tags file (meaning no Vim's tag-matchlist dialog).

What's the full path to file1.py and file2.py? And what does :pwd return after you open gVim?

@jszakmeister

:pwd returns /Users/jszakmeister/tmp/mulitple-tags.

file1.py is at /Users/jszakmeister/tmp/mulitple-tags/file1.py and file2.py is at /Users/jszakmeister/tmp/mulitple-tags/file2.py.

That is pretty odd. :-(

@kien
Owner

Please try starting gvim with this:

gvim --noplugin -u path/to/a/simple/.vimrc

Use this as the content of the above .vimrc:

set nocp
runtime! plugin/ctrlp.vim

Just make sure the parent directory of plugin is in your runtimepath, for example ~/.vim.

See if you still get the tag-matchlist.

@jszakmeister
@kien
Owner

It might be something that changes the tags option (see :help 'tags'), or the working directory. I'm honestly not sure.

@jszakmeister
@kien
Owner

Ah I see. Thanks! When cst is set, :tag uses :cstag which in turn performs :tjump. And :tjump always shows tag-matchlist when there are 2 or more similarly named tags.

Since tag.vim only works with tags files, it might be a good idea to reset that option when using :tag.

@jszakmeister
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.