MS-DOSでVimをビルドする

# この記事を3行で要約
MS-DOSやそのエミュレータでVimをビルドするための情報についてまとめました。  
MS-DOSでビルドできる最新のVimのバージョンは7.4.773です。  
ビルドするのが面倒な場合は、7.3.46のビルド済みバイナリが配布されています。


# エミュレータの準備
残念ながら筆者はMS-DOSが動作する実機を持っていないので、[DOSBox-X](https://dosbox-x.com)を利用します。  
[DOSVAXJ3](https://www.nanshiki.co.jp/software/dosvaxj3.html)や[Dosemu2](https://dosemu2.github.io/dosemu2/)でもビルド済みバイナリが動作することは確認していますが、ビルドは未検証です。[MS-DOS Player for Win32-x64](http://takeda-toshiya.my.coocan.jp/msdos/)については何も試していません。  
ホストOSはなんでもいいですが、ここではWSL2上のUbuntu 24.04を使用します。  

## DOXBox-Xの初期設定
まずはDOSBox-Xをインストールしましょう。ここではお手軽にaptを使います。

```shell-session
$ sudo apt install dosbox-x
```
もちろん、ソースからビルドしてインストールすることもできます。
```shell-session
$ git clone https://github.com/joncampbell123/dosbox-x.git
$ cd dosbox-x
$ sudo apt install automake gcc g++ make libncurses-dev nasm libsdl-net1.2-dev libsdl2-net-dev libpcap-dev libslirp-dev fluidsynth libfluidsynth-dev libavdevice60 libavformat-dev libavcodec-dev libavcodec-extra libavcodec-extra60 libswscale-dev libfreetype-dev libxkbfile-dev libxrandr-dev
$ ./build-debug
$ sudo make install
```

インストールが完了したら、DOSBox-Xを起動して以下のコマンドを実行し、デフォルトの設定ファイルを書き出して終了します。

```
Z:\> CONFIG.COM -wcd -all
Z:\> exit
```

書き出された設定ファイルの各値を以下のように変更してください。  
簡単に解説すると、まず`[dosbox]`と`[dosv]`で一旦日本語表示にした後、最後に`chej us`で英語表示に戻しています。筆者の環境ではこうしないとVimを起動したとき表示がおかしくなるのですが、もっとエレガントな方法があるかもしれません。  
CHEJはDOSBox-Xには含まれていないので、別途[Vector](https://www.vector.co.jp/soft/dos/util/se004219.html)からCHEJ 6.10をダウンロードして (エミュレータ上の) `C:¥CHEJ610`に解凍しておいてください。
`[dos]`では、エミュレートするMS-DOSのバージョンを7.1とすることで[ロングファイルネーム](https://ja.wikipedia.org/wiki/%E9%95%B7%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D)を扱えるようにしています。これは、Vimのソースファイルに含まれる`regexp_nfa.c`というファイルのファイル名が8文字を超えているためです。何らかの事情でロングファイルネームを有効にできない場合にはこのファイル名が8文字以下になるようにリネームしてください。
また、`[autoexec]`の`/path/to/drive_c`は適宜読み替えてください。次の節からは、このフォルダ内でVimのソースをビルドするための下準備をしていきます。

```~/.config/dosbox-x/dosbox-x.conf
[dosbox]
language = ja_JP

[dosv]
dosv = jp
getsysfont = true

[dos]
ver = 7.1
lfn = auto

[autoexec]
mount c /path/to/drive_c
c:
set DJGPP=c:¥djgpp¥djgpp.env
set PATH=%path%;c:¥chej610;c:¥djgpp¥bin;c:¥vim¥vim74
alias vi=vim
chej us
```

## おまけ: DOSVAXJ3の初期設定
DOSVAXJ3を使用する場合は設定ファイルの`[autoexec]`に以下を追加するだけでOKです。
```~/.dosboxj/dosboxj.conf
[autoexec]
mount c /path/to/drive_c
c:
set DJGPP=c:¥djgpp¥djgpp.env
set PATH=%path%;c:¥djgpp¥bin;c:¥vim¥vim74
chev us
```
Dosemu2は設定変更の必要はありません。

# DJGPP (コンパイラ) の入手
続いて、コンパイラを入手します。今回は32bitに対応した[DJGPP](https://www.delorie.com/djgpp/)を使用します。Vimはかつて16bitでのビルドにも対応していましたが、筆者は今のところ検証していません。
DJGPPの[配布ページ](https://www.delorie.com/djgpp/getting.html)へ行くと何種類ものファイルが置かれていて面喰らいますが、Vimのビルドに最低限必要なのは以下の5つです。
```
v2/djdev205.zip
v2gnu/gcc1030b.zip
v2gnu/bnu2351b.zip
v2gnu/mak44b.zip
v2misc/csdpmi7b.zip
```
これらを全てダウンロードして解凍し、`C:\DJGPP`へ展開します。
これで下準備は完了です。

# ソースからビルドする
いよいよVimをビルドします。
Vimは7.4以降のある時点からMS-DOSではビルドできなくなっており、その後[patch-7.4.1399](https://github.com/vim/vim/releases/tag/v7.4.1399)でMS-DOSコードが削除されたことが知られています。
そこで、厳密にはどのpatchからビルドが失敗するようになったのか調べてみました。
その結果、[patch-7.4.774でsrc/edit.cに加えられた変更](https://github.com/vim/vim/compare/v7.4.773..v7.4.774)が原因であることが分かりました。
従って、MS-DOSでビルド可能な最新のVimは[patch-7.4.773](https://github.com/vim/vim/releases/tag/v7.4.773)であるということになります。
リンク先から7.4.773のソースをダウンロードして`C:\vim\vim74`に展開したら、DOSBox-Xを起動して`src`フォルダまで移動し、`make`を実行します。
```
C:\> cd vim\vim74\src
C:\> make -f Make_djg.mak
```
ビルドが始まるので完了するまでしばらく待ちます。なお、筆者の環境では1時間以上掛かりました……。

ビルドが終わったら、以下のファイルを`C:\vim\vim74`へ移動してインストールは完了です。
```
C:\vim\vim74\src\*.exe
C:\vim\vim74\src\xxd\xxd.exe
```
# \_vimrcについて
MS-DOSのVimでは、以下の順番でvimrcが読み込まれます。なお、この情報は`:version`で確認できます。
```
  system vimrc file: "$VIM\vimrc"
    user vimrc file: "$HOME\_vimrc"
2nd user vimrc file: "$HOME\vimfiles\vimrc"
3rd user vimrc file: "$VIM\_vimrc"
     user exrc file: "$HOME\_exrc"
 2nd user exrc file: "$VIM\_exrc"
```
なお、ここで`$HOME`は`C:`、`$VIM`は`C:\VIM`に対応しています。
DOSBox-XはホストOSで張ったシンボリックリンクを読むことができるので、以下のようにすればホストOSとvimrcを共用できます。
ただし、DOSBox-X側から_vimrcを編集するとシンボリックリンクがファイルで上書きされ、.vimrcとは別のファイルになってしまうので注意してください。
```shell-session
$ ln -s ~/.vimrc /path/to/drive_c/_vimrc
```
vimrcにMS-DOS固有の設定を記載する場合には`if has('dos32')`を使用してください。16bitのVimの場合は`has('dos16')`です。

## 既知の不具合と対処法
`_vimrc`が存在する場合に引数なしでvimを起動すると、イントロ画面が表示されずにnetrw (Vimに付属しているファイラのplugin) が起動します。
`_vimrc`の中身が空でもこの現象は発生するので、対処法としてはnetrwが起動しないよう`_vimrc`に設定を追加するしかないようです。
Vim 7.4.773 (netrw v153) であれば以下のコードが有効です。
```vimscript
augroup VimStartup
  autocmd!
  autocmd VimEnter * if expand('%') == "" | let g:loaded_netrw=1 | let g:loaded_netrwPlugin=1 | endif
augroup END
```
Vim 7.3.46 (netrw v140) ではnetrwのバージョンが古い為か、以下のようにする必要があります。
```vimscript
let g:loaded_netrw=1
let g:loaded_netrwPlugin=1
```

# 番外編: ビルド済みバイナリを入手する
以上でMS-DOSでのVimのビルドについて一通り説明しましたが、ビルドするのが面倒な方は以下からビルド済みバイナリを入手することもできます。

## vim online
Vimの公式サイトです。[download : vim online](https://www.vim.org/download.php#pc)に簡単な説明があります。
32bit版は以下の2つのファイルが最新です (本体とランタイムファイルをそれぞれ入手する必要があります)。
```
vim73_46d32.zip
vim73_46rt.zip
```
16bit版は以下が最新です。
```
vim71d16.zip
vim71rt.zip
```
いずれのファイルも[こちら](https://ftp.nluug.nl/pub/vim/pc/)から入手することができます。

## FreeDOS
FreeDOS 1.3に同梱されているVimが単体でも[配布されています](https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/repositories/1.3/pkg-html/vim.html)。バージョンは、配布ページでの記載は7.3aですが、中身は7.3.46でした。

# 参考にした記事やWebサイト
https://qiita.com/YamasakiKenta/items/a2602ec5c5b6cfaeebd4

https://www.nanshiki.co.jp/software/dosboxdiff.html

https://pokug.net/entry/2020/02/16/010725#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%87%BA%E5%8A%9B