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
fix: #115 : Infoview not working for external file #117
Conversation
If the user opens that When the user opens that file via go-to-definition, it would also be reasonable to associate it with the lean server from the other file. An argument for reusing servers is that find-references only works across the same server. |
Right I meant to say I would be looking for the usual package files |
… the helper functions used to do that.
@gebner ok, I did a big cleanup on when and how we walk directory looking for Lean package roots, they are now stateless helper functions. This also cleaned up some redundant calls to testLeanVersion that happen on first Lean extension activation - so the first lean file now gets to running LSP state a bit faster than before. I also implemented the adhoc directory walk which seems to be working nicely. For example, I do an adhoc open of a file deep in mathlib4 repo and it correctly finds the math4 root and opens only one LeanClient for all of mathlib4 which is the right thing to do. So I think this PR is in good state now and ready to merge. |
if (fs.existsSync(url)) { | ||
fs.readFile(url, { encoding: 'utf-8' }, (err, data) =>{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please stick to either async or sync. Reading a small local file is fast enough that sync would be okay, but mixing them is not really helpful (since it could still block). The exists
operation is also deprecated (and shouldn't be used together with readFile due to the race condition where the file is deleted between the exists and readFile calls).
So either:
try {
fs.readFileSync(url, {encoding: 'utf-8'}).toString()
// ...
} catch (err) {
// could check for err.code === 'ENOENT'
return null;
}
Or async, which is just as easy:
try {
(await fs.promises.readFile(url, {encoding: 'utf-8'})).toString()
// ...
} catch (err) {
// could check for err.code === 'ENOENT'
return null;
}
I would also try to drop the duplicate existsSync
check in readLeanVersion
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I agree with you but the only reason I didn't use exists() here is because it is deprecated for some reason. In general I prefer all IO to be async as hard drives and network drives can have random very long delays depending on what's going on and I hate apps that force me to wait for them to do synchronous IO... but if you feel strongly about it I can change this to readFileSync - it will have ripple effects all over removing async behavior up the chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, no, I think we completely agree. Async is better, we should be using it.
but the only reason I didn't use exists() here is because it is deprecated for some reason.
Ah, but the recommended replacement is not existsSync, but access or stat. To quote the docs:
Stability: 0 - Deprecated: Use fs.stat() or fs.access() instead.
Also in our use case it's recommended to use readFile and catch the file not exists error:
Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right about the race condition, and thanks for the pointer to fs.stat(). I filed a new work item to clean this up across the code base.
Co-authored-by: Gabriel Ebner <gebner@gebner.org>
Fixes #115
Turns out the work to support "untitled" files broke the "ad hoc" files. Now I've tested the following scenarios:
This last option now has 3 LeanClients running, one for the folder, and one for the adhoc package root, and one for 'untitled' files.
For "adhoc" files the extension searches upwards in the directory hierarchy for a Lean package root and creates a new LeanClient for that root.