<commit_before>import os
import re

import sublime
import sublime_plugin

from ..behave_command import BehaveCommand
from ..utils.scope import is_gherkin


class BstGoToStepDefinition(sublime_plugin.TextCommand, BehaveCommand):

    '''
    Go to step definition for the step under the cursor.
    '''

    def run(self, edit):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        # TODO: Maybe extract this functionality to a mixin
        current_root = self.view.window().folders()[0]
        current_file = os.path.relpath(self.view.file_name(), current_root)
        current_line_number = self.view.rowcol(
            self.view.sel()[0].begin())[0] + 1

        step = '%s:%s' % (current_file, current_line_number)

        output = self.behave(self.view.file_name(),
                             '--dry-run',
                             '--format',
                             'steps.usage',
                             '--no-summary',
                             '--no-snippets')

        undefined_offset = output.find('UNDEFINED STEPS')
        offset = output.find(step)

        # If UNDEFINED STEPS is found, make sure we have a valid offset
        if undefined_offset != -1:
            if offset > undefined_offset or offset == -1:
                sublime.status_message('Definition not found for "%s"' % step)
                return

        output = output[:offset]

        p = re.compile('(^@.*)', re.MULTILINE)
        last_match = re.findall(p, output)[-1]
        m = re.search('^@.*#(.*)$', last_match)

        file_path = m.group(1).strip()

        absolute_path = os.path.join(
            current_root,
            file_path)

        self.view.window().open_file(
            absolute_path, sublime.ENCODED_POSITION)

        # TODO: Move the cursor position to highlight the step definition
        # better

    def is_enabled(self):
        '''
        Enable only for Gherkin
        '''
        return is_gherkin(self.view)<commit_msg>Use new API for go_to_step_definition<commit_after>import os

import sublime
import sublime_plugin

from ..behave_command import BehaveCommand
from ..utils import parser
from ..utils.scope import is_gherkin


class BstGoToStepDefinition(sublime_plugin.TextCommand, BehaveCommand):
    """Go to step definition for the step under the cursor"""

    def run(self, edit):
        sublime.set_timeout_async(self.run_async, 0)

    def run_async(self):
        # TODO: Maybe extract this functionality to a mixin
        current_root = self.view.window().folders()[0]
        current_file = os.path.relpath(self.view.file_name(), current_root)
        current_line_number = self.view.rowcol(
            self.view.sel()[0].begin())[0] + 1

        query_location = '%s:%s' % (current_file, current_line_number)

        step_data = self._get_step_data()

        used_steps = parser.parse_used_steps(step_data)
        unused_steps = parser.parse_unused_steps(step_data)

        all_steps = used_steps + unused_steps

        matched_step = None
        for step in all_steps:
            if matched_step:
                break
            for usage in step.usages:
                usage_location = '%s:%d' % (usage.path, usage.line)
                if usage_location == query_location:
                    matched_step = step
                    break

        if matched_step:
            absolute_path = os.path.join(
                current_root,
                matched_step.path)

            absolute_path += ':%d' % matched_step.line

            self.view.window().open_file(absolute_path,
                                         sublime.ENCODED_POSITION)
        else:
            sublime.status_message(
                'Definition not found for: "%s"' % query_location)

    def is_enabled(self):
        """Enable only for Gherkin"""
        return is_gherkin(self.view)
{'fraction_non_alphanumeric': 0.10056584362139917, 'fraction_numerical': 0.00360082304526749, 'mean_word_length': 2.010061919504644, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7479882', 'n_tokens_mistral': 1154, 'n_tokens_neox': 1101, 'n_words': 257}