From 4b9d832321f1e5dcbd6bedfc9816d944929d7173 Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 15 May 2024 03:14:29 +0900 Subject: [PATCH] :+1: Add `denops#interrupt()` function --- autoload/denops.vim | 8 ++++++++ denops/@denops-private/denops.ts | 9 ++++++++- denops/@denops-private/denops_test.ts | 1 + denops/@denops-private/host.ts | 6 ++++++ denops/@denops-private/host/nvim_test.ts | 1 + denops/@denops-private/host/vim_test.ts | 1 + denops/@denops-private/host_test.ts | 1 + denops/@denops-private/service.ts | 14 ++++++++++++-- 8 files changed, 38 insertions(+), 3 deletions(-) diff --git a/autoload/denops.vim b/autoload/denops.vim index 2518646e..09d809c9 100644 --- a/autoload/denops.vim +++ b/autoload/denops.vim @@ -25,6 +25,14 @@ function! denops#request_async(name, method, params, success, failure) abort \) endfunction +function! denops#interrupt(...) abort + let l:args = a:0 ? [a:1] : [] + call denops#_internal#server#chan#notify( + \ 'invoke', + \ ['interrupt', l:args], + \) +endfunction + " Configuration call denops#_internal#conf#define('denops#disabled', 0) call denops#_internal#conf#define('denops#deno', 'deno') diff --git a/denops/@denops-private/denops.ts b/denops/@denops-private/denops.ts index 033e3720..1b682da9 100644 --- a/denops/@denops-private/denops.ts +++ b/denops/@denops-private/denops.ts @@ -13,7 +13,10 @@ const isBatchReturn = is.TupleOf([is.Array, is.String] as const); export type Host = Pick; -export type Service = Pick; +export type Service = Pick< + ServiceOrigin, + "dispatch" | "waitLoaded" | "interrupted" +>; export class DenopsImpl implements Denops { readonly name: string; @@ -37,6 +40,10 @@ export class DenopsImpl implements Denops { this.#service = service; } + get interrupted(): AbortSignal { + return this.#service.interrupted; + } + redraw(force?: boolean): Promise { return this.#host.redraw(force); } diff --git a/denops/@denops-private/denops_test.ts b/denops/@denops-private/denops_test.ts index 0068a82a..fab6f308 100644 --- a/denops/@denops-private/denops_test.ts +++ b/denops/@denops-private/denops_test.ts @@ -23,6 +23,7 @@ Deno.test("DenopsImpl", async (t) => { const service: Service = { dispatch: () => unimplemented(), waitLoaded: () => unimplemented(), + interrupted: new AbortController().signal, }; const denops = new DenopsImpl("dummy", meta, host, service); diff --git a/denops/@denops-private/host.ts b/denops/@denops-private/host.ts index 499a9397..9732ae21 100644 --- a/denops/@denops-private/host.ts +++ b/denops/@denops-private/host.ts @@ -50,6 +50,7 @@ export type Service = { bind(host: Host): void; load(name: string, script: string): Promise; reload(name: string): Promise; + interrupt(reason?: unknown): void; dispatch(name: string, fn: string, args: unknown[]): Promise; dispatchAsync( name: string, @@ -74,6 +75,11 @@ export function invoke( return service.reload( ...ensure(args, is.TupleOf([is.String] as const)), ); + case "interrupt": + service.interrupt( + ...ensure(args, is.ParametersOf([is.OptionalOf(is.Unknown)] as const)), + ); + return Promise.resolve(); case "dispatch": return service.dispatch( ...ensure(args, is.TupleOf([is.String, is.String, is.Array] as const)), diff --git a/denops/@denops-private/host/nvim_test.ts b/denops/@denops-private/host/nvim_test.ts index 1e0553a2..8d3b623e 100644 --- a/denops/@denops-private/host/nvim_test.ts +++ b/denops/@denops-private/host/nvim_test.ts @@ -21,6 +21,7 @@ Deno.test("Neovim", async (t) => { bind: () => unimplemented(), load: () => unimplemented(), reload: () => unimplemented(), + interrupt: () => unimplemented(), dispatch: () => unimplemented(), dispatchAsync: () => unimplemented(), }; diff --git a/denops/@denops-private/host/vim_test.ts b/denops/@denops-private/host/vim_test.ts index 74533fe4..dda908e7 100644 --- a/denops/@denops-private/host/vim_test.ts +++ b/denops/@denops-private/host/vim_test.ts @@ -22,6 +22,7 @@ Deno.test("Vim", async (t) => { bind: () => unimplemented(), load: () => unimplemented(), reload: () => unimplemented(), + interrupt: () => unimplemented(), dispatch: () => unimplemented(), dispatchAsync: () => unimplemented(), }; diff --git a/denops/@denops-private/host_test.ts b/denops/@denops-private/host_test.ts index ec6ec0a2..73b01988 100644 --- a/denops/@denops-private/host_test.ts +++ b/denops/@denops-private/host_test.ts @@ -12,6 +12,7 @@ Deno.test("invoke", async (t) => { const service: Omit = { load: () => unimplemented(), reload: () => unimplemented(), + interrupt: () => unimplemented(), dispatch: () => unimplemented(), dispatchAsync: () => unimplemented(), }; diff --git a/denops/@denops-private/service.ts b/denops/@denops-private/service.ts index 403140fb..7b62b77d 100644 --- a/denops/@denops-private/service.ts +++ b/denops/@denops-private/service.ts @@ -16,8 +16,9 @@ type Waiter = { * Service manage plugins and is visible from the host (Vim/Neovim) through `invoke()` function. */ export class Service implements Disposable { - #plugins: Map = new Map(); - #waiters: Map = new Map(); + #interruptController = new AbortController(); + #plugins = new Map(); + #waiters = new Map(); #meta: Meta; #host?: Host; @@ -32,6 +33,10 @@ export class Service implements Disposable { return this.#waiters.get(name)!; } + get interrupted(): AbortSignal { + return this.#interruptController.signal; + } + bind(host: Host): void { this.#host = host; } @@ -80,6 +85,11 @@ export class Service implements Disposable { return this.#getWaiter(name).promise; } + interrupt(reason?: unknown): void { + this.#interruptController.abort(reason); + this.#interruptController = new AbortController(); + } + async #dispatch(name: string, fn: string, args: unknown[]): Promise { const plugin = this.#plugins.get(name); if (!plugin) {