Sublime Forum

How Do include the path in Python symbols?

#1

Hi,

I use the Go to Symbol (Ctrl+Shift+R) a lot, but I would like to change its behaviour to be able to include the path of the symbol in the search. I will explain with one example:
Imagine I have two classes CardPayment in two different paths within a project:

src/domain/payments/creditcard.py::CardPayment
src/domain/billing/creditcard.py::CardPayment

Right now, using the Go To Symbol (Global) functionality makes me enter CardPayment first, and then select the source file. I would like to do it in one step, so typing “billing CardPayment” filters (or orders) to set src.domain.billing.creditcard.py::CardPayment as the top choice.

I think this is related to how the symbols are indexed, and right now for python the meta.function and meta.class are used, but I don’t have enough knowledge to modify it so I can also filter by paths…

I found this functionality in other editors like Pycharm, and I found it very useful because it is like a mix of looking for a file (ctrl+p) and looking for a symbol (ctrl+shift+r)

0 Likes

#2

Save the following stuff in a python file in your user package directory (Preference -> browse package to find it):

import sublime
import sublime_plugin
import os

from Default import symbol as sublime_symbol

class MyGotoDefinition(sublime_plugin.WindowCommand):
    def run(self, event=None, symbol=None, kind=None, side_by_side=False):
        v = self.window.active_view()

        if not symbol and not v:
            return

        if not symbol:
            if event:
                pt = v.window_to_text((event["x"], event["y"]))
            else:
                pt = v.sel()[0]

            symbol, locations = sublime_symbol.symbol_at_point(v, pt)
        else:
            locations = sublime_symbol.lookup_symbol(self.window, symbol, kind)

        # Look for a location with same path
        locations_filt = []
        if len(locations) > 1:
            local_path = os.path.dirname(v.file_name())
            for l in locations :
                fname,_,_ = l
                if os.path.dirname(fname) == local_path :
                    locations_filt.append(l)            

        if len(locations_filt) == 1 :
            sublime_symbol.open_location(v.window(), locations_filt[0], side_by_side)
        elif len(locations_filt) > 1 :
            sublime_symbol.navigate_to_symbol(v, symbol, locations_filt, side_by_side)
        else :
            sublime_symbol.navigate_to_symbol(v, symbol, locations, side_by_side)

And now bind a key to the command my_goto_definition, and it should do the trick.

Basically what I did is : copy the original sublime goto_definition from the default package and added a part to filter every file with the same path as the current file. Up to you to tweak it if it does not match exactly your need, but it should get you started.

0 Likes

#3

Hi Clams,

Thank you very much for taking the time for the response.
I’m afraid I have explained horribly.

What I want is to tweak the Go To Symbol functionality (the one that is accessed trough ctrl+shift+r) to be able to filter by symbol and python path at the same time (instead of sequentially).
In my example, hitting ctrl+shift+r and typing “CardPayment” finds the Symbol, but after hitting enter, another panel is open to choose between the two files that contain a class with the same name.
What I try to do is making sublime to index two different symbols by adding the path to the symbol string:
src.domain.billing.creditcard.CardPayment
src.domain.payments.creditcard.CardPayment

So when I type “payments CardPayment” in the panel that opens by hitting “ctrl+shift+r”, I can access the one I intend to access in one step.

Thank you in advance

0 Likes

#4

I don’t think it’s possible for you to modify the symbols in the project symbol list in this manner; however it should still be possible to narrow in on the symbol that you want if you want to use file names in your search.

For background, the symbols in the symbol list are a result of the syntax definition that you’re using recognizing constructs in code and some metadata information that says which of those constructs is interesting enough to be in the index.

Although it’s possible to modify the symbol, that modification can only adjust the text that’s already there or add static strings; so unless the class name in your file also includes the name of the file the information is not available for the transform to happen.

The normal use of the symbol list would be to either look up symbols in the current file or look up symbols across the project, which is what you’re doing here. The utility there is that you generally know what the symbol is but not neccessarily where it is (particularly when it appears multiple times).

If you know ahead of time what file you want the symbol from, use Goto Anything instead of Goto Symbol in Project, apply a filter that allows you to pick the file that you want, and then manually type @, which will switch the panel to symbol mode, but show you the symbols for the file that you just selected. You can then narrow down to the symbol you want and select the file to jump there directly:

0 Likes

#5

OdaNurd,

Thank you for your response.
Yes, what you explain in your response is what I’m currently doing. I just wanted to optimize the process, so only one step is required, but mostly I wanted to improve it for those occasions when you know the symbol name and maybe a folder (an area) that could contain it, but not the filename.

0 Likes