ctags, vim and python code

17,652

Use ctags from universal-ctags, it has resolved this issue, and many other fixes.

a tag which universal-ctags generated:

branch  tagbar_bug.py   /^    branch = models.ForeignKey($/;"   v       class:Employee
Share:
17,652

Related videos on Youtube

DmitrySemenov
Author by

DmitrySemenov

Updated on June 04, 2022

Comments

  • DmitrySemenov
    DmitrySemenov almost 2 years

    I generate ctags with the following command

    ctags -R --fields=+l --languages=python --python-kinds=-iv -f ./tags apps/employees/models.py
    

    and this is my code

    from django.contrib.auth.models import AbstractUser
    from django.contrib.postgres.fields import HStoreField
    from django.core.validators import MaxValueValidator, MinValueValidator
    from django.db import models
    from django.utils import timezone
    from django.utils.translation import ugettext_lazy as _
    
    from author.decorators import with_author
    from django_extensions.db.models import TimeStampedModel
    from django_fsm import FSMField
    from imagekit import models as imagekitmodels
    from imagekit.processors import ResizeToFill
    from phonenumber_field.modelfields import PhoneNumberField
    from timezone_field import TimeZoneField
    
    from libs import utils
    
    # Solution to avoid unique_together for email
    AbstractUser._meta.get_field('email')._unique = True
    
    
    def upload_user_media_to(instance, filename):
        """Upload media files to this folder"""
        return '{}/{}/{}'.format(
            instance.__class__.__name__.lower(), instance.id,
            utils.get_random_filename(filename))
    
    
    __all__ = [
        'Employee']
    
    
    @with_author
    class Employee(AbstractUser, TimeStampedModel):
        """Custom user model.
    
        Attributes:
            department (Department): What department the employee is in
            avatar (file): user's avatar, cropeed to fill 300x300 px
            notifications (dict): settings for notifications to user
            first_name (str): first name
            last_name (str): last name
            email (str): email (should be unique), this is our username field
            is_staff (bool): designates whether the user can log into
                this admin site
            is_active (bool): designates whether this user should be
                treated as active
            date_joined (datetime): when user joined
        """
    
        HIRED = 'H'
        ACTIVE = 'A'
        SICK = 'S'
        VACATION = 'V'
        PTO = 'P'
        FIRED = 'F'
    
        STATUSES = (
            (HIRED, 'hired'),
            (ACTIVE, 'active'),
            (SICK, 'sick'),
            (VACATION, 'vacation'),
            (PTO, 'pto'),
            (FIRED, 'fired'),
        )
    
        status = FSMField(
            default=HIRED,
            choices=STATUSES,
            protected=True)
    
        branch = models.ForeignKey(
            'company.Branch',
            null=True,
            related_name='employees',
            editable=True)
    
        department = models.ForeignKey(
            'company.Department',
            help_text='What department the employee is in',
            null=True,
            related_name='employees',
            editable=True)
    
        worktype = models.ForeignKey(
            'company.Worktype',
            null=True,
            related_name='employees',
            editable=True)
    
        recruiter = models.ForeignKey(
            'Employee',
            null=True,
            related_name='recruits',
            editable=True)
    
        # direct supervisor of the employee
        supervisor = models.ForeignKey(
            'Employee',
            null=True,
            related_name='supervisees',
            editable=True)
    
        # other people interested in this employee
        # activities
        followers = models.ManyToManyField(
            'self',
            related_name='following')
    
        username_ldap = models.CharField(
            max_length=255,
            null=True)
    
        is_utilized = models.BooleanField(
            default=True)
    
        is_contractor = models.BooleanField(
            default=False)
    
        is_daily_report_required = models.BooleanField(
            default=True)
    
        utilization = models.IntegerField(
            default=100,
            validators=[
                MinValueValidator(0),
                MaxValueValidator(100)])
    
        avatar = imagekitmodels.ProcessedImageField(
            upload_to=upload_user_media_to,
            processors=[ResizeToFill(300, 300)],
            format='PNG',
            options={'quality': 100},
            editable=True,
            null=True,
            blank=False)
    
        date_start = models.DateTimeField(
            _('date started'),
            null=True,
            default=timezone.now)
    
        address = models.CharField(
            max_length=255,
            blank=True)
    
        city = models.CharField(
            max_length=255,
            blank=True)
    
        state = models.CharField(
            max_length=50,
            blank=True)
    
        zip_code = models.CharField(
            max_length=20,
            blank=True)
    
        phone_number = PhoneNumberField(
            blank=True)
    
        cell_number = PhoneNumberField(
            blank=True)
    
        skype = models.CharField(
            max_length=255,
            blank=True)
    
        linkedin = models.CharField(
            max_length=255,
            blank=True)
    
        twitter = models.CharField(
            max_length=255,
            blank=True)
    
        instagram = models.CharField(
            max_length=255,
            blank=True)
    
        facebook = models.CharField(
            max_length=255,
            blank=True)
    
        website = models.CharField(
            max_length=255,
            blank=True)
    
        timezone = TimeZoneField()
    
        birthdate = models.DateField(
            null=True)
    
        is_birthdate_hidden = models.BooleanField(
            default=False)
    
        comment = models.TextField(
            blank=True)
    
        bucket_default_job = models.CharField(
            max_length=255,
            blank=True)
    
        notifications = HStoreField(
            null=True)
    
        # so authentication happens by email instead of username
        # and username becomes sort of nick
        USERNAME_FIELD = 'email'
    
        # Make sure to exclude email from required fields if authentication
        # is done by email
        REQUIRED_FIELDS = ['username']
    
        def __str__(self):
            return self.username
    
        class Meta:
            verbose_name = 'Employee'
            verbose_name_plural = 'Employees'
    

    VIM shows a lot of bad tags (blank, defaults, editable etc) which is method arguments (field definition)

    I'm using TagBar plugin: https://github.com/majutsushi/tagbar

    Question

    And it seems the problem is in ctags, how should I configure ctags so that it only outputs class attributes and not their definition params?

  • Seb D.
    Seb D. over 5 years
    +1 I came across this post for an unrelated issue of exhuberant ctags which was solved with this most recent fork universal-ctags.
  • baxx
    baxx over 3 years
    could you give an example of how to generate tags using universal ctags for a python project please?