-
-
Notifications
You must be signed in to change notification settings - Fork 36
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
Add a way to clean up (teardown) a plugin #332
Comments
This issue may be partially replaced by #307's interrupt interface. Dispose by AbortSignal// Interface
export const DenopsInterruptReason = {
PluginUnload: "PluginUnload",
} as const;
export interface Denops {
interrupted: AbortSignal;
}
// Plugin code
export async function main(denops: Denops) {
const attachTeardownLogic = () => {
const { interrupted } = denops;
interrupted.addEventListener("abort", async () => {
if (interrupted.reason === DenopsInterruptReason.PluginUnload) {
if (bufNr != null) {
await denops.cmd(`bwipeout ${bufNr}`);
}
} else {
// Re-attach because AbortSignal is re-assigned.
setTimeout(attachTeardownLogic, 0);
}
});
};
attachTeardownLogic();
const bufNr = await denops.call("bufadd", "my-buffer") as number;
};
|
Returns teardown callback from main()I like it. It's simple and efficient for the purpose. Add subscriptions to Denops interfaceIf we add Dispose by AbortSignalI'm sorry but I don't think this is a good way because I think abort should be emitted only when the plugin is aborted. Not when plugin is successfully shutdown (for restart). |
I think so too.
|
📝 The word |
I want to define the following interface as public. So that plugin developers can access it. Please suggest adding this to denops-core or otherwise. // Interface
export interface PluginModule {
main: PluginMain;
}
export type PluginMain = (denops: Denops) => void | TeardownLogic | Promise<void | TeardownLogic>;
export type TeardownLogic = () => void | Promise<void>; |
This may be a good definition for /**
* Entry point function for denops plugin.
*
* @param denops: A facade instance of Denops visible from each denops plugin.
* @returns A function called before the denops plugin is unloaded.
*/
export type PluginMain = (denops: Denops) => TeardownLogic | Promise<TeardownLogic>;
/**
* The value that `{@link PluginMain}` should return.
*
* ## Function
*
* A function that takes no parameters. This function is called before the denops plugin is unloaded.
*
* ## void
*
* If the denops plugin has no resources to clean up, the function does not need to return anything.
*/
export type TeardownLogic = void | (() => void | Promise<void>); |
Why? I think plugin developers don't need it. |
Of course, the type of |
Should we add events like |
Are you suggesting a preference for the following approach? // New approach
export const main: PluginMain = (denops) => {
// ...
}; as opposed to // Traditional approach
export function main(denops: Denops): void {
// ...
} Is this correct? Otherwise, exposing |
Yes, I want to write like this. |
Got it. In that case, could you create a new issue for discussion? We'll handle exposing the types afterward. Since we'll need to work on deno-denops-core and deno-denops-std to expose the types, it's a bit of a side topic for this particular issue. |
Come to think of it, type Promish<T> = T | Promise<T>;
export interface Module {
main: Entrypoint;
}
export type Entrypoint = (
denops: Denops
) => Promish<void | Disposable | AsyncDisposable>; export const main: Entrypoint = (denops) => {
// ...
return {
[Symbol.dispose]() {
// ...
},
};
}; |
Overall, I agree. |
Allow only |
#385 is merged! |
Currently, there is no event to dispose the plugin on unload, such as before reloading plugin.
Allows the plugin to perform dispose processing.
The proposed API:
Returns teardown callback from
main()
main()
throws an error.Add
subscriptions
to Denops interfaceThe text was updated successfully, but these errors were encountered: