sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
814 stars 40 forks source link

Goto Definition should prioritize symbols in the current file #14

Closed iamntz closed 4 years ago

iamntz commented 11 years ago

I do frontend coding mostly. And It happen fairly often for me to have the following structure:

javascripts/
--dist/foo.js
--dist/foo.min.js
--src/foo.js

The problem appear when i try to go to a definition inside of src/foo.js: a popup will be displayed that give me the choice to pick which file should i go to, with current file being... not first :)

I don't mind having multiple files listed there, but i guess the current file should be first, the other to follow.

FichteFoll commented 11 years ago

See also http://www.sublimetext.com/forum/viewtopic.php?f=2&t=12379&start=0

gerardroche commented 10 years ago

Similar to https://github.com/SublimeText/Issues/issues/341, https://github.com/SublimeText/Issues/issues/340 & https://github.com/SublimeText/Issues/issues/335

FichteFoll commented 10 years ago

Taking over suggestion from #341:

the current file's editor selection could be loosly selected in the items list so that you only need to be press enter to select it.

gerardroche commented 10 years ago

@FichteFoll y, the current selection doesn't need to be at the top of the list, but being able to just press enter would be good.

Essentially, it's about trying to anticipate what you most probably want when you press Goto Symbol.... Symbols generally have a priority:

  1. current scope / current file / sorted closest-to-current-line
  2. current scope / other files
  3. other scopes / current file
  4. other scopes / other files

I think the default should exclude other scope symbols. You could have an option to enable/disable, but rather than that I think it might be better to have a different command and shortcut for a Goto Definition (all scopes) or something like that. But the current scope I think should be default. I don't think I've ever wanted to jump to a symbol in another scope.

Narretz commented 10 years ago

To add on this, when you have the same file open in two views (New View into File), Goto Definition and Goto Symbol in Project will always switch to the first file in a group, as it considers this the best match. It works for Goto Symbol, though. Very annoying when you want to keep two different sections of the same file in focus.

wastedepository commented 7 years ago

Same issue encountered in C++. When I'm in a file and I use goto_definition to look up a class or function name, any definition which exists in the current file should appear first in the popup list, not somewhere in the middle.

Similarly, it would be nice if definitions from files in the current directory or nearby directories were preferred to those in far-off directories.

This is frequently a problem when lookup up common function names like Create() or something; there will be dozens of hits, and the one relevant one is buried somewhere in the middle.

Remillard commented 7 years ago

I just thought I'd chime in here. I had been working on adding symbol support for VHDL in my package and was showing off the capability to a colleague of mine. His first question was "does it go to the local file first?". We tried a few examples and it seems to order the drop down list by alphabetical directory order. It does not prefer the local file nor makes any visible distinction what the local file is in the list.

I strongly suggest that if there is a local version of the symbol in the definition list it should be the default selection in some way. Also bold text might be a good thing too but do not know how much formatting (if any) quick panel supports.

keith-hall commented 7 years ago

One can patch Packages/Default/symbol.py to change the sort order of the Goto Definition list: for example, the following diff will sort by active file first, followed by files that have not been saved to disk, followed by saved files. (With the symbol definitions in the same order they appear in the file, meaning if you press F12 on a definition and it isn't the first one in the current file, it will jump to the first one... One could tweak this if desired to sort by distance from the active view's first selection or something.)

Patch valid as at build 3150:

--- Shipped Packages/Default/symbol.py  2017-10-05 18:43:08
+++ Packages/Default/symbol.py  2017-10-17 10:27:31
@@ -31,10 +31,17 @@
             locations.append(l)

     for ofl in open_file_locations:
         if not file_in_location_list(ofl[0], ofl_ignore):
             locations.append(ofl)
+
+    # determine the "key" used in `lookup_symbol_in_open_files` for the active file (the file name if there is one, otherwise the buffer id)
+    active_file_key = window.active_view().file_name() or '<untitled {}>'.format(window.active_view().buffer_id());
+    # sort the locations
+    # - if the location is in the active file, sort by the beginning of the region where the symbol is defined
+    # - otherwise sort by `<z` (to ensure it comes after the active file, regardless of whether the file has been saved or the name starts with a number etc.), followed by the key, followed by the beginning of the region where the symbol is defined
+    locations = list(sorted(locations, key=lambda loc: str(loc[2][0]) if loc[0] == active_file_key else '<z' + loc[0] + str(loc[2][0])))

     return locations

 def lookup_references(window, symbol):

Of course, if you plan to use this patch, don't forget to install https://packagecontrol.io/packages/OverrideAudit to know when your patch is out of date.

wastedepository commented 7 years ago

How do you use this patch? Using Sublime Text 3, build 3126, I do not see any Default directory in my Packages directory, and I cannot find symbol.py anywhere.

iamntz commented 7 years ago

@wastedepository until this is merged to ST core, here is how you can use it:

  1. Go to your installation path (on Windows that is C:\Program Files\Sublime Text 3;
  2. Here, you find a Packages folder. In that folder, you'll find Default.sublime-package;
  3. Open that Default.sublime-package with WinRar, 7Zip or whatever archive manager you're using;
  4. Extract symbol.py from this archive to your Sublime Settings folder. On Windows that is %appdata%\Sublime Text 3\Default\symbol.py

So, to sum it up:

C:\Program Files\Sublime Text 3\Packages\Default.sublime-package\symbol.py goes into %appdata%\Sublime Text 3\Default\symbol.py

On this file, around line 33, add the snippet above:

Couple of extra things:

  1. Python is indent aware (i.e. indent wrongly and you'll either get an error or will not work at all)
  2. On every update you must remember to check if the file had changed (hence the OverrideAudith recommendation above).
rohanc commented 7 years ago

What a breath of fresh air! I've been waiting so long for this problem to be addressed. Here's how to extract the file on OSX, where the file locations are different:

cd ~/Library/Application\ Support/Sublime\ Text\ 3/Packages/User/
unzip '/Applications/Sublime Text.app/Contents/MacOS/Packages/Default.sublime-package' symbol.py
keith-hall commented 7 years ago

The canonical way to do this is not to extract zip files manually, but just to use https://packagecontrol.io/packages/PackageResourceViewer to open the file that you want to override from the relevant package.

Remillard commented 7 years ago

Trying this out today. It definitely is putting the local file first! Also knowing where this happens, maybe we can make it more elaborate with various sorting methods. It currently is looking like it's purely alphabetical, but it might be better to make it project directory hierarchy then alphabetical. I'll have to experiment a little.

ianharper commented 6 years ago

I applied the patch and really like the result! I would love to see this incorporated in a future version.

ianharper commented 6 years ago

@keith-hall I've made a small enhancement to your patch. I moved it into it's own function so it could be used with lookup_references and I've made it sort by descending line number within a file: locations = list(sorted(locations, key=lambda loc: str(loc[2][0]).zfill(15) if loc[0] == active_file_key else '<z' + loc[0] + str(loc[2][0]).zfill(15)))

gwenzek commented 4 years ago

This is fixed in 4092 and probably since 4089. Hooray 🍾 !

karl-zylinski commented 2 months ago

This still happens in version 4180

image In the picture above I try go to symbol consume_comment while editing src/parser.cpp. There is a consume_comment symbol in that file. I put my cursor on a usage of consume_comment and press F12. It then shows core/parser.cpp as first symbol hit, i.e. the not the current file. core/parser.cpp some other file that also had a symbol with the same name.

Minimal repro

goto_symbol_repro.zip

To reproduce using the zip:

Extra repro info

I tried using two different file names in the repro, instead of naming both files parser.cpp. That doesn't change anything, it still always shows the file in core before the one in src.

karl-zylinski commented 2 months ago

@deathaxe Given my report above, can this be re-opened or should I make a new issue?

markersniffen commented 2 months ago

Just wanted to confirm this is happening for me as well in build 4180. It might be worth noting that the bug only appears for me when index_files is set to true in preferences. When file indexing is turned off, you obviously cannot jump to definitions inside of files that are closed, but if they are open in another tab and contain a definition you attempt to jump to, sublime will list all symbols in open files in the preferred order (current file first).

deathaxe commented 2 months ago

It is a regression in more recent builds between 4152 and 4169.

It is working as expected in ST4126 ... 4152 but no longer in 4169+.

So that's a new issue.

karl-zylinski commented 2 months ago

@deathaxe Thank you. I have downgraded to 4152 and now it is working correctly again.

I'll make a new, separate issue.