EmmyLua / IntelliJ-EmmyLua

Lua IDE/Debugger Plugin for IntelliJ IDEA
https://emmylua.github.io
Apache License 2.0
1.72k stars 287 forks source link

Make LuaFileAdditionalResolver return file in project folder first. #498

Closed AnduFalaH closed 6 months ago

AnduFalaH commented 1 year ago

This pull request wants to change the LuaFileAdditionalResolver.find behaviour. Suppose that there are many directories in LuaSettings.additionalSourcesRoot. Now, LuaFileAdditionalResolver.find will return the first not-null result VirtualFileManager.getInstance().findFileByUrl returned. Here, I want to change it to return the first result in project folder. If there is no VirtualFileManager.getInstance().findFileByUrl result in project folder, like before, it will return first not-null result. Below is the reason I make this change.

The order of luaFileResolver used in ILuaFileResolver.findLuaFile is defined in emmylua-core.xml:

<luaFileResolver implementation="com.tang.intellij.lua.ext.LuaFileSourcesRootResolver" id="base"/>
<luaFileResolver implementation="com.tang.intellij.lua.ext.LuaFileAdditionalResolver" id="additional"/>
<luaFileResolver implementation="com.tang.intellij.lua.ext.LuaFileAbsoluteResolver" id="absolute"/>
<luaFileResolver implementation="com.tang.intellij.lua.ext.LuaFileFuzzyResolver" id="fuzzy"/>

image

If we mark the root folder as souces root, and file can be found by LuaFileSourcesRootResolver. As Lua is widely used in Unity game development, it would be convenient to use Rider to edit C# and Lua code in one IDE. However, if we use Rider, there is no menu like that in Idea or Pycharm (at least I have not found it...). This leads to ILuaFileResolver.findLuaFile using LuaFileAdditionalResolver. In normal cases, it works well. But additionalSourcesRoot is a global setting, it means all of projects will share it. If we have many projects with similar folder structure (for example, many subversion branches of one project in the computer), we must add all of "sources root" in additionalSourcesRoot. Suppose that we want to go to a file of a LuaRequireReference, as files are similar in each additional source root, VirtualFileManager.findFileByUrl can find the target file in each of it. Here, LuaFileAdditionalResolver.find will return the first not-null result. However, this file may be in another project folder. If we want to jump to edit the reference file in this project folder, there is only two way:

  1. Use Ctrl+Shift+N hotkeys to navigate the file. This is a little bothering.
  2. Remove other folders in additionalSourcesRoot, and then Go To will work. But it is still bothering when we change to edit another project.

So here, I want to change LuaFileAdditionalResolver.find in this PR. For matching the previous behaviour, variable firstMatch record the first not-null result. And then, it will check the found file's canonicalPath and project.basePath. If this file is in project folder (I'm not sure whether there is a better way except string matching), this function will directly return the file. If no any result in project folder, this function returns firstMatch, which could be null when no file is found. After this change, LuaFileAdditionalResolver.find will return matched file in project folder firstly. Thus, LuaRequireReference can navigate to the project file in above case.

(It is my first time to read and write Java/Kotlin code. It will be welcome to point out any inappropriate code in this PR.)