Sublime Forum

Problem with GoTo defintion

#1

I have some trouble getting Goto defintions(F12) containing “.” to work for a custom syntax.
Goto Symbol / Goto symbol in Project however works (for namespaced “.” functions too).

function defs looks like;
function:{ // stuff // }
.namespace.function:{ // stuff // }

calling functions:
function[] <-- F12 correctly jumps to above definition!
.namespace.function[] <-- F12 does not work here

tmPref file contains this;

 <dict>
   <key>scope</key>
   <string>entity.name.function.q </string>
   <key>settings</key>
   <dict>
      <key>showInSymbolList</key>
      <integer>1</integer>
      <key>showInIndexedSymbolList</key>
      <integer>1</integer>
   </dict>
</dict>

and my tmLanguage capture for function defintions is this;

<!-- function names (defs) -->
<dict>
	<key>captures</key>
	<dict>
	<key>1</key>
	<dict>
		<key>name</key>
		<string>entity.name.function.q</string>
	</dict>
</dict>
	<key>comment</key>
	<string>function declaration</string>
	<key>match</key>
	<string>([\w.]+):{</string>
</dict>

and function calls;

<!-- function calls -->
<dict>
	<key>captures</key>
	<dict>
	<key>1</key>
	<dict>
		<key>name</key>
		<string>support.function.call.q</string>
	</dict>
</dict>
<key>comment</key>
<string>function call</string>
<key>match</key>
<string>([\w.]+)(\[)</string>
</dict>

any help or insights much appreciated…

edit: code markup

0 Likes

#2

You guessed it? https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet :tada:

0 Likes

#3

I suspect this is because Goto Definition treats . as a word separator. Does it work if you select the .namespace.function before the [] and then try F12?

0 Likes

#4

unfortunately, no - that does not work either.

is there a way to hack up/customize the Goto Definition function?

0 Likes

#5

No other ideas?

It seems as if making a GoTo plugin wont work either as I am unable to get access to the project symbol-list (only see symbols in the current view).

Maybe this should be reported as a bug instead ?

0 Likes

#6

It looks to me like the core of your issue is indeed that the default functionality for this assumes that . is a word separator. Confusingly however, I can’t replicate your results from above; as @kingkeith mentioned, selecting the text first allows it to work with no modifications.

In particular, I created a sublime-syntax version of your language spec as outlined above (primarily because XML gives me hives ;)), plus a tmPreferences file to include the symbols in the index and a sample source file. The files that I’m working with are contained in this gist:

With this in place, indeed putting the cursor in one of the parts of the filename and pressing F12 does not find the symbol in question. If you watch the status line, you can see it specifically saying “Unable to find function” and “Unable to find name1”.

However, if I select the entirety of the symbol before pressing F12, the definition is found and the cursor jumps there.

The code that’s doing this is in Packages\Default\symbol.py. In particular, note that the command GotoDefinition contains this:

        if not symbol:
            pt = v.sel()[0]
            symbol, locations = symbol_at_point(v, pt)
        else:
            locations = lookup_symbol(self.window, symbol)

That is, if you haven’t provided a symbol explicitly it tries to find it based on the cursor position, otherwise it assumes you’ve given it a valid one and just finds places where it exists. Further investigation inside of symbol_at_point shows this:

symbol = view.substr(view.expand_by_class(pt, sublime.CLASS_WORD_START | sublime.CLASS_WORD_END, "[]{}()<>:."))

That is, it is expanding the selection to word boundaries on either end along with a hard coded set of word delimiters, one of which is the dreaded period character. Thus the expansion stops at the period and the symbol can’t be found.

If you modify that line to remove the period, then the F12 key works as expected.

I can’t say why selecting the text first doesn’t work for you though, because it seems like it should.

As seen here, it’s possible to modify the built in handling for this, which is decidedly a terrible idea. Probably a better idea would be to use that code as the basis for your own version of the command that’s custom tailored for your language. You could then create your own key binding with a context that makes it apply for your language to make it seamless.

Arguably it would be better if the default code did something like respect the current setting of word_separators or some other such setting, so that it could be overridden in syntax specific settings. However I’m not familiar enough with how all this stuff hangs together to know how good or bad of an idea that might be.

3 Likes

#7

You can’t ask Sublime for a complete list of all symbols everywhere, but I assume that’s because the list would potentially be massive.

You can however look up all of the locations that a symbol exists for your project assuming you already know what the name of it is via the sublime.Window.lookup_symbol_in_index method.

1 Like

#8

Thank you for your replies! I will take a closer look tomorrow, but it definitely looks like I can get this functionality working!

(turns out, that if i try F12 on a name-selected function like “function.name1[]” it works, but not “.namespace.function[]” - will have to get to the bottom of that too.)

0 Likes

#9

Thanks OdatNurd, I created my own Goto Def script&binding to work with this plugin!

0 Likes

#10

Is there a way to override the autocomplete behavior too?
(would like for autocomplete to only complete full-namspace paths)

0 Likes