🦍

denops-docker.vimのバグを直した話

2023/04/10に公開

はじめに

普段愛用しているdenops-docker.vim(以降docker.vim)という自作プラグインのバグを直したというちょっとした話です。

docker.vimはVimからdockerコンテナやイメージを操作できるプラグインです。
たとえば、:DockerContainersコマンドで次の画像のようにコンテナ一覧見れたり、コンテナを起動したりアタッチしたりできます。

他にもいろいろ機能があるので詳細を知りたい方はヘルプを参照してください。

バグの概要

docker.vimにはマッピングしたポートをブラウザで開く機能をもっています。
たとえば、0.0.0.0:8080:80というふうにポートをマッピングしている場合、<C-o>でブラウザでホスト側のポートhttp://localhost:8080を開くことができます。

今回修正したバグは次の2点です。

  1. キャンセルするとひとつ目のポートが開く
  2. ポートマッピングされていない場合はhttp://undefined:undefinedと表示されてしまう

修正内容

1に関しては、inputlist()を使ってい次のように実装していましたが、
キャンセルの場合は0が返るので、それを考慮していなかったのが問題でした。

const choice = await denops.call("inputlist", choices) as number;
await open(ports[choice]);

なので、入力してもらう番号は1から開始とし、0はキャンセル扱いという実装にする必要がありました。

-    const choice = await denops.call("inputlist", choices) as number;
-    await open(ports[choice]);
+    const choice = await denops.call("inputlist", choices) as number - 1;
+    if (choice >= 0) {
+      await open(ports[choice]);
+    }

2に関しては、次のように実装していましたが、ポートマッピングしているかどうかの判定が抜けていたのが問題でした。

const hostPort = `http://${p.IP}:${p.PublicPort}`;
ports.push(hostPort);
choices.push(`${i}: ${hostPort}`);

ポートマッピングをしていない場合、PublicPortは存在しないため、PublicPortのときだけ選択肢に追加する必要があったので、シンプルに次のように修正しました。

-    const hostPort = `http://${p.IP}:${p.PublicPort}`;
-    ports.push(hostPort);
-    choices.push(`${i}: ${hostPort}`);
+    if (p.PublicPort) {
+      const hostPort = `http://${p.IP}:${p.PublicPort}`;
+      ports.push(hostPort);
+      choices.push(`${i + 1}: ${hostPort}`);
+    }

ふたつの問題とも初歩的なミスで恥しいですが、まぁこういうこともあるよねって感じですね。

さいごに

最近あんまりがっつりVim活できていないのですが、細々とやっております。
docker.vimについて興味がある方はぜひ触ってみてください。
自分でいうのもあれですが便利です。

Discussion