Create Temporary File For Linting Purposes

What is the recommended procedure for writing temporary files to disk, so they can be linted by a process? I implemented a rudimentary work-around, but wasn’t sure if this was the intended method:

let file = nova.fs.open(nova.extension.path +  "/linting.php", "w");
let range = new Range(0, editor.document.length);
let documentText = editor.getTextInRange(range);
file.write(editor.getTextInRange(range));

Thanks!

1 Like

AFAIK, there is no dedicated API for that. Your snippet is one possible solution, though I think you should not pollute your extension directory with temporary files (I’d use extension.workspaceStoragePath instead, which is guaranteed to be writeable, albeit not to exist when you first write to it). Another solution would be to shell out to mktemp. Finally, are you sure your linting CLI cannot process input from stdin? Because that would obviate the need for a temporary file entirely.

1 Like

Thank you @kopischke for your thoughtful answer!

I agree that my solution is not optimal, and I don’t like writing to the extension directory.
I will follow up on both your suggestions:

  • use workspaceStoragePath
  • try to use stdin for the linter. This would speed up the linting process a fair bit!

Thanks so much in helping me learn. :slight_smile:

@kopischke I have been investigating stdin options for my linter, and it can indeed accept stdin. I have been wracking my brain trying to figure out how to set up the process to pass the editor content (which I have already pulled from the editor and placed in a variable, see my snipped above) to the process as stdin.

Can you give me some recommendations where to read up more on it? I have been searching other extensions, but I can’t discern any that are using processes this way.

Thanks again for your help. :slight_smile:

@kopischke I believe I have gotten something to work after all! :slight_smile:

Something along these lines:

  1. Create process with stdio args as described in the documentation.
  2. Get the write stream object from the process.
  3. Start the process.
  4. Pass the text to be linted to the stream writer object, like this:
self.writer.ready.then(function () {
    let range = new Range(0, editor.document.length);
    let documentText = editor.getTextInRange(range);

    self.writer.write(documentText);
});
self.writer.ready.then(function () {
    self.writer.close();
});
  1. Then on every document update I start on step 3, making sure to kill any previous process still running, so that long-running lints don’t overlap.

Does this sound about right? (It is functional, although I’m not sure if it is optimal or not.)
Here’s my main.js file: https://github.com/GeneaLabs/panic-nova-phpcs/blob/main/Scripts/main.js

1 Like

That looks about right, yes.

1 Like

Just updating this to point out that, as ov Nova 10, there is now a nova.fs.tempdir variable that works great for this.