Пример #1
0
    def on_query_context(self, key, _operator, operand, _match_all):
        global MAX_LEN
        global PREVIOUS_INDEX

        if key != "side.signature_help":
            PREVIOUS_INDEX = 0
            return False  # Let someone else handle this key binding.

        if self.view.is_popup_visible():
            # We use the "operand" for the number -1 or +1. See the key bindings.
            if PREVIOUS_INDEX is None:
                PREVIOUS_INDEX = 0

            # if enter is pressed
            if operand == 0:
                point = self.view.sel()[0].begin()

                # user types a function name
                # user types a (
                # a signature help is automatically shown on (
                # a user press enter
                # user expect the cursor to bellow one line
                # actual behavior
                # the user is navigated to the function definition
                # so handle that case
                last_char = self.view.substr(point - 1)
                if last_char == '(':
                    return False

                word = get_function_name(self.view, point)
                locations = definition(word, self.view)
                location = locations[PREVIOUS_INDEX]

                # sublime crashes if window.focus_view is called
                # setting a timeout, fixes is
                # I don't know why this is the case
                def fix_window_focus_view_crash():
                    open_view(location, self.view)
                    self.view.hide_popup()

                sublime.set_timeout(fix_window_focus_view_crash, 0)
                return True

            # else up or down is pressed
            new_index = PREVIOUS_INDEX + operand

            # # clamp signature index
            new_index = max(0, min(new_index, MAX_LEN - 1))

            # # only update when changed
            if new_index != PREVIOUS_INDEX or (PREVIOUS_INDEX == 0
                                               and operand == 1
                                               and MAX_LEN != 1):
                self.view.run_command('side_show_signature',
                                      {'index': new_index})
                PREVIOUS_INDEX = new_index

            return True  # We handled this key binding.
        else:
            return False
Пример #2
0
    def show_signature_help(self, point, word):
        locations = definition(word, self.view)

        self.view.run_command('side_show_signature', {
            'locations': locations,
            'point': point
        })
Пример #3
0
    def run(self, edit):
        """ index - if specified goto that index location. """
        window = sublime.active_window()
        point = self.view.sel()[0].begin()
        word = get_word(self.view, point)
        locations = definition(word, self.view)

        if len(locations) == 0:
            symbols = find_symbols(self.view)            
            word_regions = self.view.find_all(r"\b{}\b".format(word))

            between_symbols_region = get_region_between_symbols(point, symbols, self.view)
            words_between_regions = filter_regions_by_region(word_regions, between_symbols_region)
            scope_name = self.view.scope_name(point)
            words_between_regions = filter_regions_by_scope_name(words_between_regions, scope_name, self.view)  

            # make sure that there is at least one item in list
            if len(words_between_regions) < 1:
                return 

            definition_point = words_between_regions[0].begin()
            file_name = self.view.file_name()
            row, col = self.view.rowcol(definition_point)
            row += 1
            col += 1
            location = (file_name, None, (row, col))
            open_view(location, self.view)
            return

        if len(locations) == 1:
            open_view(locations[0], self.view)
            return
        
        if len(locations) > 1:
            chose_one_location_from_many(locations, self.view)
Пример #4
0
    def handle_hover(self, point, is_class=False):
        word = get_word(self.view, point)
        locations = definition(word, self.view)

        self.view.run_command('side_show_signature', {
            'locations': locations,
            'point': point
        })
Пример #5
0
    def on_load(self):
        global panel_state
        window = sublime.active_window()
        debug('on_load', self.view.id())
        # select all unique references
        references = self.view.indexed_references()
        words = list(set(map(lambda x: x[1], references)))

        files_to_index = set()
        for word in words:
            definitions = definition(word, self.view)
            if len(definitions) == 1:
                # add the absolute file name
                absolute_file_path = definitions[0][0]

                if not window.find_open_file(absolute_file_path):
                    debug('added [ {} ] files_to_index because of symbol {}'.format(absolute_file_path, word))
                    files_to_index.add(absolute_file_path)

        # indexing
        for absolute_file_path in files_to_index:
            panel_name = absolute_file_path
            with open(absolute_file_path) as file:  
                panel = window.find_output_panel(panel_name)
                # if it is indexed continue
                if panel:
                    # keep track of it
                    debug("[ {} ] panel already exist".format(panel_name))
                    panel_state[panel_name].add(self.view.id())
                    debug('panel_state when panel exist', panel_state)
                    continue
                # else index it
                content = file.read() 
                debug('read file')

                # trigger index command
                self.view.run_command('side_index_file', {
                        'content': content,
                        'panel_name': panel_name
                    })

                # keep track of it
                if not panel_state.get(panel_name):
                    debug('create state for [ {} ]'.format(panel_name))
                    panel_state[panel_name] = set()
                panel_state[panel_name].add(self.view.id())
                debug('panel_state after creating state', panel_state)
Пример #6
0
    def handle_selection_modified(self):
        global phantom_sets_by_buffer

        buffer_id = self.view.buffer_id()
        phantom_set = phantom_sets_by_buffer.get(buffer_id)
        if not phantom_set:
            phantom_set = sublime.PhantomSet(self.view, 'references_phantom')
            phantom_sets_by_buffer[buffer_id] = phantom_set
    
        point = self.view.sel()[0].begin()
        word_region = self.view.word(point)

        word = self.view.substr(word_region)
        scope_name = self.view.scope_name(word_region.begin())

        phantoms = []
        if is_function(scope_name) or is_class(scope_name):

            text = []

            reference_count = len(reference(word, self.view))
            if reference_count == 1:
                text.append("{} reference".format(reference_count))
            else:
                text.append("{} references".format(reference_count))

            definition_count = len(definition(word, self.view))
            if definition_count == 1:
                text.append("{} definition".format(definition_count))
            else:
                text.append("{} definitions".format(definition_count))
           
            content = """
            <body id="side-references" style="color: color(var(--foreground) alpha(0.4))">
                <small style="margin:0;padding:0;">{}</small>
            </body>
            """.format(" | ".join(text))

            phantoms.append(sublime.Phantom(word_region, content, sublime.LAYOUT_BELOW))
            phantom_set.update(phantoms)
        else: 
            # outside of function word
            phantom_sets_by_buffer.pop(buffer_id, None)
Пример #7
0
    def run(self, edit, locations=None, point=None, index=None):
        """ index - when specified show the current location. """
        global MAX_LEN
        global PREVIOUS_INDEX
        # restart the counter of signature help to 0
        PREVIOUS_INDEX = 0

        if point is None:
            point = self.view.sel()[0].begin()

        word = None
        if locations is None:
            word = get_function_name(self.view, point)
            locations = definition(word, self.view)

        if len(locations) == 0:
            return

        MAX_LEN = len(locations)

        # display the reference count
        if len(locations) > 1 and index is None:
            self.view.run_command('side_show_signature', {
                'locations': locations,
                'point': point,
                'index': 0
            })
            return

        location = None
        if index:
            location = locations[index]
        else:
            location = locations[0]

        file_path, relative_file_path, row_col = location
        row, _col = row_col  # signature row

        function_line = get_line(self.view, file_path, row).strip()

        signature, row = self.get_signature(function_line, file_path, row)
        # prettify signature
        signature = signature.strip('{').strip(':')

        docs = self.get_docs(file_path, row_col)

        if docs:
            docs = """
            <div style="padding: 7px; 
                        border-top: 1px solid color(var(--foreground) alpha(0.1))">
                {}
            </div>""".format(docs)

        # prettify file origin
        if len(relative_file_path) > 70:
            relative_file_path = '...' + relative_file_path[-50:]

        if len(locations) == 1:
            range_count = ''
        else:
            current_index = 1 if index is None else index + 1
            range_count = "[{}-{}]".format(current_index, len(locations))
        origin = """
        <div style="padding: 7px; 
                    border-top: 1px solid color(var(--foreground) alpha(0.1));
                    color: color(var(--foreground) alpha(0.7))">
            {} {}
        </div>""".format(range_count, relative_file_path)

        content = """
        <body id="side-hover" style="margin:0">
            <div style="color: var(--orangish); 
                        padding: 7px;">
                {}
            </div>
            {} 
            {}
        </body>""".format(escape(signature, False), origin, docs)
        if index is not None:
            self.view.update_popup(content)

        self._show_popup(content, point)
        # end of command execution
        # perfect place to clear the linecache
        linecache.clearcache()