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

Allow running load synchronously #137

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

googleson78
Copy link
Contributor

Motivation:

You can't really do much of anything else before agda finishes loading a file, so I'd rather my interface freeze to indicate that the buffer is not in a workable state.

Another big motivation is that if we can rely on load being synchronous, we can then write scripts that run load and rely on the load having completed in order to then run other commands afterwards. Concretely, I wanted to have a bind for :CornelisLoad<CR>:CornelisQuestionToMeta<CR>, but that doesn't currently work out of the box.

Making this PR in a somewhat WIP state since I want to get feedback:

  1. if you'd accept this
  2. if this is the way to make a command synchronous

Notably, I'm still not sure this actually makes the command run synchronously, because my example of :CornelisLoad<CR>:CornelisQuestionToMeta<CR> still doesn't work, but I'm not sure what's going wrong exactly.

Comment on lines +54 to +66
devShells.default = let
hsPkgs = pkgs.haskell.packages.${defaultGhcVersion};
buildInputs = [
hsPkgs.ghc
hsPkgs.haskell-language-server
pkgs.cabal-install
pkgs.hpack
pkgs.zlib
];
in pkgs.mkShell {
buildInputs = buildInputs;
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is to allow nix users who don't have a global haskell setup to develop cornelis

@isovector
Copy link
Collaborator

Is it possible to make a new command that provides the synchronous behavior? That would be preferable in my book. If so, I'd be willing to merge such a change.

@isovector
Copy link
Collaborator

As for why your test doesn't work, my suspicion is that even though you're running the vim command synchronously, the connection with Agda is still async. You'll probably need to block until you've got a response from Agda.

What that response is? I don't know. But I've found that running agda with --interaction-json has been helpful for watching the communication flow to Agda. If you've got an emacs setup, you can snoop on the channel by opening the buffer to Agda.

@googleson78
Copy link
Contributor Author

Is it possible to make a new command that provides the synchronous behavior?

Yep, that sounds better to me as well, thanks!

You'll probably need to block until you've got a response from Agda.

Right, thanks for the tip!

Side question:

Is there some reason why cornelis doesn't automatically expand question marks into metas? This is the behaviour I remember having with emacs, and it's hard to think of a situation where I wouldn't want to expand a question mark into a metas.

At least with the synchronous version that blocks the buffer until agda responds to the load command, it seems like there are no downsides to always converting question marks to metas.

@googleson78
Copy link
Contributor Author

From looking at the agda mode for emacs, it seems that you simply can't issue any other commands while agda is loading.

They do this by

  1. marking certain commands (e.g. load) as "busy"
  2. any commands that are marked "busy" set a variable called agda2-in-progress
  3. you can't issue commands while agda2-in-progress, except for some special commands (e.g. "restart agda", "exit agda")

Does cornelis perhaps want to replicate this behaviour? From looking through the code base, it seems to me that we only indicate an "agda is busy" when we try to issue a load specifically, and not other commands.

But I'm not sure what exactly happens if you try to issue other commands while e.g. agda is currently reloading a file. I would personally wager that there's not much sense in issuing further commands, because by the time agda is done loading, the buffer would potentially be out of date, and you theoretically can't reliable issue any other actions.

What's your experience with using cornelis? Do you always wait for load to finish before doing anything else?

@isovector
Copy link
Collaborator

isovector commented Feb 19, 2024 via email

@silky
Copy link
Contributor

silky commented Mar 2, 2024

FWIW @googleson78 one thing that occured to me thinking about this work here was that maybe a different way to approach it could be via a callback; so after the results of the load command, say, some back, then you would do your second thing.

I'm not sure if that's significantly easier to implement, but it might be?

@googleson78
Copy link
Contributor Author

The difficult part is

after the results of the load command

I believe, although I'm not 100% sure.

Right now after trying out cornelis for a bit, I'm somewhat convinced the best approach would be to implement the same sort of synchronisation that the emacs agda-mode offers (what I've outlined here), where the whole agda process can be put into a state of "busy" on the nvim plugin side, and then you cannot issue commands while in that state. After that it should also be trivial to block the buffer while the plugin is in the "busy" state.

This however obviously will require some bigger amount of work, so I haven't sat down to do it.

@silky
Copy link
Contributor

silky commented Mar 3, 2024

The difficult part is ...

I guess so.

Glancing around the code, I suppose what one might need to do is have a kind of Map like

Map Response [SomeAction]

that gets populated by your special chained command, and when the Agda response comes in ( https://github.com/isovector/cornelis/blob/master/src/Cornelis/Agda.hs#L74 ? ) read that map, and if there is an action in there for the present response, pop it off, and run it.

But maybe that's a terribl idea for some reason. Obviously it will fail some race conditions, but probably that won't actually matter if the way it's used is restricted.

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.

3 participants