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

Two issues with incomplete input #1550

Merged
merged 1 commit into from
Aug 29, 2023
Merged

Two issues with incomplete input #1550

merged 1 commit into from
Aug 29, 2023

Conversation

jneem
Copy link
Member

@jneem jneem commented Aug 28, 2023

This fixes an off-by-one error in the handling of incomplete input. It also makes import resolution in incomplete input more reliable -- previously it would only work when the file being opened is in the current working directory.

This fixes an off-by-one error in the handling of incomplete input.
It also makes import resolution in incomplete input more reliable --
previously it would only work when the file being opened is in the
current working directory.
@github-actions github-actions bot temporarily deployed to pull request August 28, 2023 18:16 Inactive
// is the same as the real file.
let mut path = PathBuf::from(server.cache.files().name(range.src_id));
path.pop();
path.push("<incomplete-input>");
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this isn't worth worrying about, but is it possible to have a file whose name is <incomplete-input>?

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, it's a fair point. We have various other inputs (like "") following the same pattern, but I'll check how much effort it is to have an enum separating synthetic inputs from real files.

Comment on lines +719 to +726
// The way indexing works here is that if the input file is
//
// foo‸
//
// then the cursor (denoted by ‸) is at index 3 and the span of foo is [0,
// 3), which does not contain the cursor. For most purposes we're interested
// in querying information about foo, so to do that we use the position just
// *before* the cursor.
Copy link
Member

Choose a reason for hiding this comment

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

does this mean that if the cursor is over the first letter of a variable name, we won't get completion for that variable (unless it's the first character of the line)?

Copy link
Member Author

@jneem jneem Aug 28, 2023

Choose a reason for hiding this comment

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

I think it should be fine, basically because we're using the surrounding context to provide completion; we don't actually care about the identifier under the cursor.

To be specific, In the context of a record path you should get completion, because if the input is foo.bar and the cursor is "over" the b then you'll get the list of completions implied by foo.. (This is the usual behavior for LSP; the editor is in charge of doing any filtering based on prefixes etc.)

In the context of a "bare" variable name, like the foo in { foo = 1 } | { foobar | Number } it should also be fine, because we'll see that we're inside a record and use that record's fields and annotations for completion.


let term = server.lookup_term_by_position(pos)?.cloned();
let sanitized_term = term
.as_ref()
.and_then(|rt| sanitize_term_for_completion(rt, pos, server));
.and_then(|rt| sanitize_term_for_completion(rt, cursor, server));
Copy link
Member

Choose a reason for hiding this comment

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

why is this using cursor rather than pos?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was the off-by-one error. The sanitize_term_for_completion function passes the range [error_start, cursor) to get reparsed. It's an exclusive end (like most ranges in rust), and so using pos instead of cursor drops one character too many.

### position = { line = 12, character = 30 }
### position = { line = 12, character = 26 }
Copy link
Member

Choose a reason for hiding this comment

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

are we just changing what these test are testing for here? should we add new tests rather than replacing these ones, or are these ones not serving a useful purpose?

Copy link
Member Author

@jneem jneem Aug 28, 2023

Choose a reason for hiding this comment

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

The change shouldn't have an effect: it's moving the cursor test location from (import "included.ncl").lala‸ to (import "included.ncl").‸lala to check that off-by-one behavior. One could argue that we should test both, but most of the test cases have the cursor at the end so that case is pretty well covered already...

Copy link
Member

@yannham yannham left a comment

Choose a reason for hiding this comment

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

Beside agreement with some of @Radvendii 's comment, LGTM

@jneem jneem added this pull request to the merge queue Aug 29, 2023
Merged via the queue into master with commit 028695d Aug 29, 2023
4 checks passed
@jneem jneem deleted the off-by-one branch August 29, 2023 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants