Skip to content

Instantly share code, notes, and snippets.

@Milly
Last active April 3, 2023 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Milly/c8a3b32f96ce603eff008906925274f4 to your computer and use it in GitHub Desktop.
Save Milly/c8a3b32f96ce603eff008906925274f4 to your computer and use it in GitHub Desktop.
ddu-source-callbackfreeze
// denops/@ddu-sources/callbackfreeze.ts
import {
BaseSource,
type GatherArguments,
type OnInitArguments,
} from "https://deno.land/x/ddu_vim@v2.7.0/base/source.ts";
import { type Denops } from "https://deno.land/x/ddu_vim@v2.7.0/deps.ts";
import type { Item } from "https://deno.land/x/ddu_vim@v2.7.0/types.ts";
import * as lambda from "https://deno.land/x/denops_std@v4.1.0/lambda/mod.ts";
const TIMEOUT = 10_000; // [msec]
type Params = Record<string, never>;
export class Source extends BaseSource<Params> {
override kind = "word";
override params(): Params {
return {};
}
override async onInit(_: OnInitArguments<Params>): Promise<void> {}
override gather(args: GatherArguments<Params>): ReadableStream<Item[]> {
const { denops } = args;
return new ReadableStream({
start: async (controller) => {
const data = await this.#getDataFromVim(denops);
controller.enqueue([{
word: `Vim's data: ${data}`,
}]);
controller.close();
},
});
}
async #getDataFromVim(denops: Denops): Promise<unknown> {
const data = await new Promise(
(resolve, reject) => {
const id = lambda.register(
denops,
(...args: unknown[]) => resolve(args),
{ once: true },
);
setTimeout(() => reject(new Error("timeout")), TIMEOUT);
// This call is blocked if this source called from denops#request()
denops.eval(
"timer_start(100, {_ -> denops#notify(name, id, ['foobar'])})",
{ id, name: denops.name },
);
},
);
return data;
}
}
Error detected while processing function ddu#ui#do_action[5]
..ddu#ui_action[1]
..ddu#_request[22]
..denops#request[1]
..denops#server#request[4]
..denops#_internal#server#chan#request[4]
..denops#_internal#rpc#vim#request[3]
..function ddu#ui#do_action[5]
..ddu#ui_action[1]
..ddu#_request[22]
..denops#request[1]
..denops#server#request[4]
..denops#_internal#server#chan#request[4]
..denops#_internal#rpc#vim#request:
line 3:
E605: Exception not caught:
Error: Failed to call 'uiAction' with ["default","quit",{}]:
Error: Failed to call 'call' with ["ddu#pop","default"]:
Error: Failed to call 'ddu#pop(default)':
Error: Failed to call 'pop' with ["default",{}]:
Error: timeout
at file:///C:/work/vim/ddu-source-callbackfreeze/denops/@ddu-sources/callbackfreeze.ts:46:33
at Object.action (ext:deno_web/02_timers.js:146:11)
at handleTimerMacrotask (ext:deno_web/02_timers.js:63:10)
at Session.call (https://deno.land/x/msgpack_rpc@v3.1.6/session.ts:207:13)
at async Service.dispatch (file:///C:/work/vim/denops.vim/denops/@denops-private/service.ts:117:14)
at async dispatch (file:///C:/work/vim/denops.vim/denops/@denops-private/host/vim.ts:85:12)
at async Session.<anonymous> (file:///C:/work/vim/denops.vim/denops/@denops-private/host/vim.ts:57:14)
function ddu#ui#do_action[5]
..ddu#ui_action[1]
..ddu#_request[22]
..denops#request[1]
..denops#server#request[4]
..denops#_internal#server#chan#request[4]
..denops#_internal#rpc#vim#re
let $LANG = 'C'
set nocompatible
set rtp^=C:/work/vim/denops.vim
set rtp^=C:/work/vim/ddu.vim
set rtp^=C:/work/vim/ddu-ui-ff
set rtp^=C:/work/vim/ddu-kind-word
set rtp^=C:/work/vim/ddu-source-action
set rtp^=C:/work/vim/ddu-source-callbackfreeze
call ddu#custom#patch_global(#{ ui: 'ff' })
augroup my-ddu-ff
autocmd!
autocmd FileType ddu-ff call SetupDduFF()
augroup END
function! SetupDduFF() abort
nnoremap <buffer><nowait> a <Cmd>call ddu#ui#do_action('chooseAction')<CR>
nnoremap <buffer><nowait> q <Cmd>call ddu#ui#do_action('quit')<CR>
endfunction
function! Test() abort
" Start source-callbackfreeze and ui-ff is shown.
call ddu#start(#{ sources: [#{ name: 'callbackfreeze' }] })
" Press 'a' in ui-ff and source-acition is shown.
call timer_start(2000, {_ -> feedkeys('a')})
" Press 'q' in ui-ff and source-acition is quit.
" Then source-callbackfreeze shows again and refresh data.
" But refresh process deadlocks and Vim freezes.
call timer_start(4000, {_ -> feedkeys('q')})
" The error is caused by source-callbackfreeze timeout.
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment