1

Background

I'm using vi with a php/laravel code base.. I ran ctags and see what happens:

filename: app/Http/Controllers/RetailerApproveController.php

use App\Repositories\ApproveOrderRepo;

...

        $repo = new ApproveOrderRepo();

when I do my tags shortcut (ctrl]) I jump straight to the use line above, rather than the actual file that contains the definition of ApproveOrderRepo.

notice that if i'm in the file RetailerApproveController and I run :Tags I get a list, and it autocompletes as I type ApproveOrderRepo like so:

enter image description here

which begins like this:

namespace App\Repositories;

use App\Order;
...

class ApproveOrderRepo
{
    use DispatchesJobs;

Question

How do I make the the key mapping automatically jump the class definition file, rather than the use statement or some other file?

for reference, this is what i have in my tags file:

ApproveOrderRepo        app/Http/Controllers/EnRouteToClientController.php      /^use App\\Repositories\\ApproveOrderRepo;$/;"  a       namespace:App\\Http\\Controllers        typeref:unknown:App\\Repositories\\ApproveOrderRepo
ApproveOrderRepo        app/Http/Controllers/RetailerApproveController.php      /^use App\\Repositories\\ApproveOrderRepo;$/;"  a       namespace:App\\Http\\Controllers        typeref:unknown:App\\Repositories\\ApproveOrderRepo
ApproveOrderRepo        app/Repositories/ApproveOrderRepo.php   /^class ApproveOrderRepo$/;"    c       namespace:App\\Repositories
ApproveOrderRepo        tests/ApproveOrderTest.php      /^use App\\Repositories\\ApproveOrderRepo;$/;"  a       typeref:unknown:App\\Repositories\\ApproveOrderRepo
3

What's happening

When there are multiple matches for a tag, Vim uses the following list of priorities (listed at :help tag-priority).

  1. "FSC" A full matching static tag for the current file.
  2. "F C" A full matching global tag for the current file.
  3. "F " A full matching global tag for another file.
  4. "FS " A full matching static tag for another file.
  5. [...]

(These priorities are displayed when using Vim's :tselect command.)

You have no static tags in your tags file (these are indicated by the presence of file or file:... fields towards the end of the line, so Vim will select "A full matching global tag for the current file" as its first match (and hence the one you jump to with a :tag command or Ctrl+]).

The only matching tag in your current file is the use line that Vim therefore jumps to.

How to alter this

You have several options for altering this behaviour:

1. Just select the desired tag manually

Instead of using Ctrl+], you could use (or map) the :tselect command:

:ts <c-r><c-w><cr>

This allows you to type a number to select the specific tag you want to jump to.

2. Remove the extra tags entirely

I can't see much benefit in having the use lines in your tags file. These are being included as an a kind (see the fourth tab-separated value on each line), so you could regenerate your tags file without these by adding the following argument to your ctags invokation:

--kinds-php=-a

You could also store that kind in a separate file and alter the 'tags' option on-the-fly to include or not include that file, as described by ldog on Stack Overflow.

3. Use fzf's functionality to skip certain kinds

You're currently using fzf's :Tags function. You could create a new command that generates a PHP tags file on the fly which skips the a kind, as described by icc97 on Stack Overflow.

command! BTagsEnhanced
    \ call fzf#vim#buffer_tags(<q-args>, [
    \ printf('ctags -f - --sort=no --php-kinds=-a --excmd=number
    \ --language-force=%s %s', &filetype, expand('%:S'))], {})

4. Write a new function to intelligently select a tag match

You could write a function that uses taglist() to access the tags and then uses the logic of your choosing to pick the "best" one. See Andrew Radev's answer on Stack Overflow for a template function that does this.

5. Post process your tags file

You could re-sort your tags file according to your desired priority. I wouldn't recommend this option.

  • 1
    option 2 was the fastest and easiest – abbood Nov 2 '17 at 16:43

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.