bunvim icon indicating copy to clipboard operation
bunvim copied to clipboard

support timeout in `attach()`

Open snoblenet opened this issue 1 year ago • 0 comments

Have you considered supporting timeouts in attach()?

I'm doing the following, but never progressing beyond the attach() call.

import { attach } from 'bunvim';
import { spawn } from 'node:child_process';

import { BUNVIM_LOG, NEOVIM_SOCKET } from '../constants';

const MAX_RETRIES = 10;

export const createNeovimClientName = ({
  cmd,
  args,
}: {
  cmd: string;
  args: string[];
}): string => [cmd, ...args, new Date().valueOf()].join('').replace(/[^a-zA-Z0-9]/g, '');

export const log = (detail: Record<string, any>): void => {
  console.log(`attachToNeovim(): ${JSON.stringify(detail)}`);
}

export const attachToNeovim = async ({
  args = [],
  cmd,
  retryCount = 0,
  retryDelay = 100,
}: {
  args?: string[];
  cmd: string;
  retryCount?: number;
  retryDelay?: number;
}): Promise<string> => {
  log({ cmd, args, retryCount, retryDelay });

  const name = createNeovimClientName({ cmd, args });

  const attachArgs = {
    client: { name },
    logging: {
      file: BUNVIM_LOG,
      level: 'debug',
    },
    socket: NEOVIM_SOCKET,
  };

  log({ attachArgs });

  try {
    const nvimClient = await attach(attachArgs);
    const cmdResult = await nvimClient.call(cmd, args);
    nvimClient.detach();
    return cmdResult;
  } catch (error) {
    if (error.code !== 'ENOENT') {
      throw error;
    }

    log({ error });

    if (retryCount === 0) {
      const child = spawn('nvim', ['--listen', NEOVIM_SOCKET], {
        detached: true,
        stdio: 'ignore',
      });

      child.unref();
    }

    if (retryCount > MAX_RETRIES) {
      throw new Error('attachToNeovim() exceeded maximum retries');
    }

    await new Promise(resolve => setTimeout(resolve, retryDelay));

    return attachToNeovim({
      cmd,
      args,
      retryCount: retryCount + 1,
      retryDelay: retryDelay ** (1 + (retryCount + 1 / 5)),
    });
  }
};

attachToNeovim({
  cmd: 'edit',
  args: ['/Users/steven/code/dotfiles/package.json'],
}).then(result => JSON.stringify({ result }, null, 2));

snoblenet avatar Jul 01 '24 10:07 snoblenet