[RFC] Add path completion support inside `require` calls
Motivation
I got inspired by the recently released Markdown Language Server doing completion for references to other files. I realized that we can match require strings against a list of files in the $LOAD_PATH and suggest completions like that.
Note: This is still missing some of the functionality, but since it is gated behind a feature flag that should be turned on by the VSCode extension, I think it is safe to land. The things that are missing are:
- There is no support for requires that start with a
.or..which make them relative requires. - There is no support for load paths that may be added by the application. For example, Rails applications add
Rails.root / "lib"andRails.root / "app/models", etc to the load paths, which this extension will not be able to see (since we don't boot the application we are running inside). - There is no support for
require_relative.
Implementation
- Register a completion provider that is triggered on the
/character - Handle the completion request and process it if (and only if) it is originating from the string argument of a
requirecall. - Match the completion prefix to the list of paths in
$LOAD_PATHand offer completions.
Automated Tests
Added a small automated test
Manual Tests
- Open the https://github.com/Shopify/vscode-ruby-lsp project.
- Add a
feature inside the"completion": { "description": "Enable code completion features", "type": "boolean", "default": true }package.jsonfile and a:
default"completion": true - Run the project
- Open the
ruby-lspproject in the Extension Host window. - Start typing some
requires and see autocompletion for paths.
This is awesome ❤️ . I wonder if it would be worth finding files in the current directory as well? For example, if you create a brand new file and want to require it, it won't be in the load path yet.
@Morriar and I reworked this PR so that it uses a more efficient Trie (which is also called a Prefix Tree) data structure to index files in the load path and brought it up to work against the changes in latest main.
@vinistock Currently we reindex the files on the load path for every request to completion, so we would be able to discover any newly added files. I know this is not the most efficient way of doing it, but based on my usage testing the responsiveness seems to be just fine for now.