Leverage Copy

メモの公開場所

online-judge-toolsをVimから呼ぶプラグイン

TL;DR

  • kmykさんのonline-judge-toolsのコマンドを呼ぶ、Vimのラッパーコマンドをプラグインにしました。
  • 自分は普段こんな感じで使っています。
  • 現状、カスタマイズ性は微妙ですが、submitコマンドは多少便利だと思うのでよかったら試してみてください。

はじめに

online-judge-toolsをVimから呼んで楽をする の内容をプラグイン化しました。

https://github.com/maguroguma/vim-oj-helper

READMEでは淡々と仕様について(突貫作業なので抜け漏れは多いながら)書いたつもりですが、 この記事では提案する実際の利用方法についてフランクに書いてみたいと思います。

インストール

Vimの標準のプラグインの作法に則っているため、お使いのプラグインマネージャを使えば、 特に問題なくインストールできるかと思います。私はvim-plug を使っており、以下のようにしてインストールできることを確認しました。

Plug 'maguroguma/vim-oj-helper'

このプラグインは、 oj のサブコマンドである download, test, submit の、Vimのラッパーコマンドを提供します。 oj が実行可能である場合のみコマンド群が定義されるため、 oj への PATH が通っていることを事前に確認してください。

使用方法

ここではABC180に参加しているという想定で説明してみたいと思います。


まずはA問題から解くとして、以下のようにA問題のディレクトリ、ファイルを開いて、 A問題のURLをコメントに書きます。

f:id:maguroguma:20201119012349p:plain
サンプルダウンロードコマンドの実行

ここで :OjDownloadSamples を実行してみましょう。

f:id:maguroguma:20201119012427p:plain
ダウンロード後

実行後、カレントバッファに開いているコードと同じディレクトリ階層に、サンプルケースがダウンロードされています。

ここから問題を解いていきましょう。

f:id:maguroguma:20201119012451p:plain
テストコマンドの実行

コードを書き終わったら、先程ダウンロードしたサンプルでテストを行います。
Pythonで参加しているため :OjLangCommandTest python のように実行してみましょう。

f:id:maguroguma:20201119012535p:plain
テスト後

テストは全て通ったので、提出して問題なさそうです。

f:id:maguroguma:20201119012557p:plain
提出コマンドの実行

カレントバッファで開いているファイルを、その問題に対して提出しましょう。 :OjSubmitCode を実行してみましょう。

f:id:maguroguma:20201119012622p:plain
提出後

これで提出が完了しました。 スクリーンショットでは省いていますが、ブラウザのタブが開いて提出画面にリダイレクトされます。


オプションについて

提出前の確認の有無、あるいは文言のアレンジ

提出はある程度慎重に行いたいものですが、人によっては邪魔かもしれません。 これに関しては、確認の有無と文言をオプションで設定できます。 また、提出可能なコンテストサイトごとに設定でき、デフォルトは以下のように全てのサイトに対して確認が行われます。

" default
let g:oj_helper_submit_confirms = {
    \'atcoder': 'AtCoder: Are you sure you want to submit?',
    \'codeforces': 'Codeforces: Are you sure you want to submit?',
    \'yukicoder': 'yukicoder: Are you sure you want to submit?',
    \'hackerrank': 'HackerRank: Are you sure you want to submit?',
    \}

私の場合、Goの環境違いによりこどふぉでのみオーバーフローで痛い目に会いまくっているので、 こどふぉに関しては提出前に確認をするように設定しています。 また、AtCoderとyukicoderに関しては、確認せずに提出できるようにしています。

" customization
let g:oj_helper_submit_confirms = {
    \'atcoder': '',
    \'codeforces': 'こどふぉだけどオーバーフロー大丈夫?',
    \'yukicoder': '',
    \}

例えばこどふぉの問題に提出しようとすると、以下のような確認がなされます。

f:id:maguroguma:20201119012648p:plain
提出前の確認

他のスクリプト言語コンパイル言語のためのコマンド

デフォルトでいくつかのスクリプト言語のためのコマンドは登録していますが、 必要なものはあとからオプションで追加したり、あるいは上書きできます。

" default
let g:oj_helper_lang_commands = {
      \'go': 'go run',
      \'python': 'python3',
      \'javascript': 'node',
      \}
let g:oj_helper_lang_extensions = {
      \'go': 'go',
      \'python': 'py',
      \'javascript': 'js',
      \}

" customization
let g:oj_helper_lang_commands = {
      \'bash': 'bash',
      \}
let g:oj_helper_lang_extensions = {
      \'bash': 'sh',
      \}

一方でコンパイル言語ですが、、正直競技プログラミングの中でコンパイル作業をしたことがないので、 どういった手段を提供するのがよいのか判断できませんでした。

とりあえず今回は、勝手に以下のような仮定を置いてしまいました。

  1. カレントバッファで開いているファイルを、同じディレクトリ階層にDLしたその問題のサンプルに対してテストしたい。
  2. カレントバッファで開いているファイルと同じディレクトリ階層に、コンパイルされてできた main という実行バイナリが存在している。
  3. :OjExecutableBinTest を実行すると、2のバイナリが1のサンプルに対して実行される。

とりあえず、実行バイナリのファイル名だけはオプションでいじれるようにしました。

" default
let g:oj_helper_executable_binary = 'main'

" customization
let g:oj_helper_executable_binary = 'main.exe'

例えば、Goの例だと以下のスクリーンショットのようになります。

f:id:maguroguma:20201119013534p:plain
バイナリによるテストとディレクトリ構造

他にもいくつかオプションはありますが、これら以外は気にしなくともさほど問題にはならないかなと思います。

おわりに

Vimを使って競技プログラミングを行っている方には、ぜひ使ってみてフィードバックをいただけると大変嬉しいです。 競技プログラミングのメイン言語であるC++に対して使いやすいとはいえないであろう点が懸念ですが。。 しかしながら、ダウンロードと提出コマンドについてはうまくフィットする人も何人かはいるんじゃないかなとも思います。