This is similar to this thread but I believe different enough to warrant its own.
The Crystal language has a formatter that replaces files in-place. You call it like crystal tool format path/to/file.cr
. Here’s the extension command I’ve created:
nova.commands.register("crystal.format", (editor) => {
try {
const crystalPath = nova.path.expanduser("~/path/to/crystal");
const filePath = editor.document.path;
const previousSelectedRanges = editor.selectedRanges;
const process = new Process(
crystalPath,
{ args: ["tool", "format", filePath] }
);
process.start();
editor.selectedRanges = previousSelectedRanges;
} catch (err) {
console.error("Could not call crystal tool format: " + err);
}
});
When I run this command, it does successfully format the code, but the cursor is placed all the way at the end of the document. You can see I’m trying to grab the selected ranges and restore them after the process runs. This doesn’t work. I’ve also tried Process.onDidExit and wrapping the whole thing in a TextEditor.edit function (both inside the edit
callback, and inside the then
function as edit
returns a promise).
The only thing that kind of worked was trying to change the selection in TextEditor.onDidChangeSelection. While it does work, I’m changing the selection in the callback which recursively triggers the callback. Thankfully, Nova kills this recursion eventually.
The core problem seems to be that Nova sets the selection/cursor some time after a file is changed externally. That delay is far past any of the callbacks mentioned above. So I can set the selection all I want in those callbacks, but then ~500ms later Nova moves the cursor to the end of the document regardless.
Am I doing something wrong here? Is there anything else I can try? Is this a known limitation? A bug?