5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Perforce Command プラグインを作ってみた話 - p4cmd.vim

Last updated at Posted at 2024-12-01

はじめに

作ったのは結構前だけど、アドカレネタとして紹介しておくとともに、これからやりたいこともまとめようと思ったので!

当プラグインはこれ

Perforce コマンドの Add や Edit、Revert、Submit などを Vim/NeoVim 上のコマンドから実行できるようにしたもの。

image.png

中のしくみ

denops を裏に敷いており、TypeScript で書いている。
denops で書いていると、Vim と NeoVim 両方に対応できるというのも良い。

以前、dailynote.vim というプラグインを作ったものを上げたことがあったが、そこから少し変更があったので、そこをメモ程度に残しておく。

コア部分の実装

実際のところは、P4CLI のコマンドを TypeScript 上から、denops.cmd で叩いてるだけ。
でもこれができるってことは無限では?:relaxed:

denops/p4cmd/perforce.ts
import { Denops } from "./deps.ts";

export async function info(denops: Denops): Promise<void> {
  let response = await denops.cmd("!p4 info");
}

export async function add(denops: Denops): Promise<void> {
  let currentFile = await denops.call("expand", "%:p");
  let response = await denops.cmd(`!p4 add ${currentFile}`);
}

export async function edit(denops: Denops): Promise<void> {
  let currentFile = await denops.call("expand", "%:p");
  let response = await denops.cmd(`!p4 edit ${currentFile}`);
}

export async function revert(denops: Denops): Promise<void> {
  let currentFile = await denops.call("expand", "%:p");
  let response = await denops.cmd(`!p4 revert ${currentFile}`);
}

コマンド登録部分

さらにコマンドを Vim/NeoVim 側に認識できるように登録するところは次のように宣言している。
あえて内部で二重にラップしているが、一応追加実装があった際に、差し込めるようにしているため。
現時点ではそこまで必要性を感じてないので、消してもいいかもしれない。

denops/p4cmd/main.ts
import { batch, Denops } from "./deps.ts";
import { add, edit, info, revert } from "./perforce.ts";

export function main(denops: Denops): void {
  denops.dispatcher = {
    async init() {
      await batch.batch(denops, async (denops) => {
        // P4Info
        await denops.cmd(
          `command! -nargs=0 P4Info call denops#request('${denops.name}', 'info', [])`,
        );

        // P4Add
        await denops.cmd(
          `command! -nargs=0 P4Add call denops#request('${denops.name}', 'add', [])`,
        );

        // P4Edit
        await denops.cmd(
          `command! -nargs=0 P4Edit call denops#request('${denops.name}', 'edit', [])`,
        );

        // P4Revert
        await denops.cmd(
          `command! -nargs=0 P4Revert call denops#request('${denops.name}', 'revert', [])`,
        );
      });
    },

    async info(args) {
      info(denops);
    },

    async add(args) {
      add(denops);
    },

    async edit(args) {
      edit(denops);
    },

    async revert(args) {
      revert(denops);
    },
  };
}

プラグインつくるって実はこれだけでもできちゃう。

昔の構成からちょっとだけ違うやつ

Perforce コマンド類などが複数回コールするのを防ぐためのもの。
とりあえずドキュメントに倣って追加しているが…はて :thinking:

plugins/p4cmd.vim
if exists('g:loaded_p4cmd')
  finish
endif
let g:loaded_p4cmd = 1

augroup denops=p4cmd
  autocmd!
  autocmd User DenopsPluginPost:p4cmd call denops#notify('p4cmd', 'init', [])
augroup END

今後の展望

今後は、LazyGit のようなクライアントの Perforce 版が欲しいなと思っているので、そういたものを作りたいと考えている。
ddu 系のプラグインとして作れないかな?

まぁ、この denops では厳しいものとしては、lualine のプラグインとして、Perforce のステータスを見られるようにしたいというのがある。

来年になったらいずれも作ってしまおうという展望。
(どちらかは今年までの宿題にしたいけども笑

さいごに

denops は、TypeScript と Vim の操作としくみををある程度知ってれば、ほんとサクッとやりたいことを実装できてとてもいい。
実は仕事上で表に出せないところでも自分の毎日の自動化のためにプラグインを書いていたりする。
この調子で来年もいろいろ自動化していきたい :v:

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?