Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index files as they are modified #2342

Closed

Conversation

vinistock
Copy link
Member

Motivation

Closes #1908

Index files as they are modified rather than waiting until they are saved. This better reflects the state of the codebase as the user is coding.

Implementation

The idea is the following:

  1. If a document is changed, without being managed by the client (that is, the file was never opened in the editor and it's not present in our Store), nothing changes. We still index the changes based on their file path
  2. If the document is already managed by the client, then we simply add the declaration listener as part of all of the others in the combined requests and re-index the file as we are providing other features

The only extra thing is that we need to be able to handle ancestor changes even if the user hasn't saved the file, so I created a way to track those.

Automated Tests

Added some tests to ensure that we index declarations in unsaved files as they are being modified and also to ensure that we don't accidentally create duplicate entries, which is a risk if we accidentally forget to clean things up.

Manual Tests

  1. Create a new file in the UI without saving it
  2. Change the language mode to Ruby
  3. Add a class declaration
  4. Verify you get completion for the newly created class

@vinistock vinistock added enhancement New feature or request server This pull request should be included in the server gem's release notes labels Jul 22, 2024
@vinistock vinistock self-assigned this Jul 22, 2024
@vinistock vinistock requested a review from a team as a code owner July 22, 2024 20:41
@vinistock vinistock requested review from andyw8 and st0012 July 22, 2024 20:41
@vinistock vinistock force-pushed the vs/index_files_as_they_are_modified branch from ae415aa to d619b2c Compare July 22, 2024 20:53
uri = indexable.to_uri.to_s
original_entries = @uris_to_entries[uri]
sig { params(uri: URI::Generic, indexable: IndexablePath).void }
def handle_change(uri, indexable)
Copy link
Member

@st0012 st0012 Jul 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there cases where the uri would be different than indexable.to_uri? If there are, can we capture them in test cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also perhaps we can swap the arguments order, and have uri default to indexable.uri?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think we need to change IndexablePath to be simply an Indexable and then include the URI there. I was just trying to avoid parsing the same URI twice, but the code is ugly.

@andyw8
Copy link
Contributor

andyw8 commented Jul 23, 2024

Do we need to consider the case where someone saves a file outside of the current workspace?

@vinistock
Copy link
Member Author

Do we need to consider the case where someone saves a file outside of the current workspace?

I don't believe so. If the document is not opened in the editor and it's outside of the current workspace, how would we know that it is relevant for the current project? Or in other words, how could we know which files to watch (we wouldn't want to watch all Ruby files in the computer)?

Note

I'm afraid that this PR is going to degrade performance very significantly. I'm going to re-think this and #2341 to ensure that we're not making the experience worse.

@andyw8
Copy link
Contributor

andyw8 commented Jul 23, 2024

Here's a reproduction of what I'm thinking of:

  • Create new unsaved file (VS Code will recognize it as Ruby):
# typed: strict
# frozen_string_literal: true

module RubyLsp
  class Foo
  end
end
  • Save it outside of workspace, e.g. to the Desktop as foo.rb
  • Observe that completion is offered for RubyLsp::Foo from foo.rb

@vinistock
Copy link
Member Author

I don't think we need to support that use case. Under what circumstances would someone want to do that? You can't even require that file without the full file path because Desktop is not going to be a part of your $LOAD_PATH.

Copy link
Contributor

@andyw8 andyw8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I know changes are planned, just marking as reviewed so GitHub stops pinging me).

@vinistock
Copy link
Member Author

Closing this for now. We need to re-think the approach.

@vinistock vinistock closed this Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request server This pull request should be included in the server gem's release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants