最近Vimに取り込まれた大規模パッチに関する備忘録

最近2カ月ほどの間に、Vimに変更量1000行以上の大規模なパッチ(Windows関連)をいくつか取り込んでもらえたので、備忘のため記録を残しておこうと思います。


# Wide版APIの有効化とANSI版APIの削除

* [8.1.1081](https://github.com/vim/vim/commit/433a5eb9de861dd01ea3b3dfa3b8fe23527cab54): MS-Windows: cannot use some fonts
* [8.1.1091](https://github.com/vim/vim/commit/f0908e6fe18943ad4453d7d6772fa43049aff4bc): MS-Windows: cannot use multi-byte chars in environment var (関連: [8.1.1104](https://github.com/vim/vim/commit/796cc42d3a4fc7a940da87831a111eeb6b7a5cf3))
* [8.1.1103](https://github.com/vim/vim/commit/0eb035c974c47e65d32439b48e5a056b370ad429): MS-Windows: old API calls are no longer needed

今まで、Windows版Vimでは、`'encoding'` の設定に応じて、ANSI版APIを使用したり、Wide版 (Unicode版) APIを使用したりしていました。しかしANSI版APIはWin9x用のAPIであり、対応OSがWinXP以降になったVim 8.1では本来必要ありませんでした。ただ、Wide版APIを使うには、UTF-8/UTF-16等のエンコーディング変換が必要なことから、ANSI/Wide両方のコードが残ったままとなっており、コードが複雑化していました。

しばらく前の 8.1.0805 ～ 8.1.0811 でマルチバイト機能が常に有効化されるようになりました。これにより、エンコーディング変換機能が常に有効化されたことから、ANSI版APIの完全削除が可能となりました。そこで、ANSI APIの使用を取りやめ、Wide APIに置き換えたのが上記のパッチです。

これにより、現在のコードページでは使用できない文字をフォント名や環境変数に使用することができるようになったり、ソースコードが大幅にシンプルになりました。今後、Windows向けに新たにパッチを書くのも楽になるでしょう。


# VIMDLL機能

VIMDLL機能本体と、追加のバグ修正

* [8.1.1230](https://github.com/vim/vim/commit/afde13b62b8fa25dac4635d5caee8d088b937ee0): a lot of code is shared between vim.exe and gvim.exe
* [8.1.1239](https://github.com/vim/vim/commit/a9dd2d3c759c1eafb9c0572c5707852ed3d38162): key with byte sequence containing CSI does not work
* [8.1.1269](https://github.com/vim/vim/commit/ed5ab2a95972b5ef588bdafab9f197e1dcf0c1df): MS-Windows GUI: multibyte chars with a 0x80 byte do not work
* [8.1.1301](https://github.com/vim/vim/commit/0b75f7c97cd7f2529884c48dca8edb02abda4bc5): when compiled with VIMDLL some messages are not shown
* [8.1.1304](https://github.com/vim/vim/commit/68cbb14bae1013702270b25e886b5ee09e07575a): MS-Windows: compiler warning for unused value
* [8.1.1358](https://github.com/vim/vim/commit/386b43e59498cc7b52a60f09f74bdb44df99386c): cannot enter character with a CSI byte
* [8.1.1369](https://github.com/vim/vim/commit/294d9bf966bbbcb0b49affb9b15534d5b9c93801): get E484 when using system() during GUI startup
* [8.1.1380](https://github.com/vim/vim/commit/fa8f861957f4f9f7a0946d9d61fe90a9882f54e6): MS-Windows building VIMDLL with MSVC: SUBSYSTEM is not set
* [8.1.1500](https://github.com/vim/vim/commit/21f8d93c7184e69aa76a5caa1d3869b6226189e0): wrong shell command when building with VIMDLL and "!" in 'go'
* [8.1.1595](https://github.com/vim/vim/commit/88c47aa692a4b1061f86624ea2503f31314f3975): MS-Windows with VIMDLL: colors wrong in console (注: 正しくは console ではなく GUI)
* [8.1.2361](https://github.com/vim/vim/commit/310c32e8920140f0db747c6c6eb06b1ee53cdb5a): MS-Windows: test failures related to VIMDLL
* [8.2.0055](https://github.com/vim/vim/commit/257a396879ff67a0482841a39237f30a8e1e27c5): cannot use ":gui" in vimrc with VIMDLL enabled

事前準備のためのパッチ

* [8.1.1060](https://github.com/vim/vim/commit/760285dd4f20d25e8ae3166996981b8dddba366a): MS-Windows: get\_cmd\_args() is no longer needed
* [8.1.1102](https://github.com/vim/vim/commit/b26705afb55955306ffbe2a390e02fc052802b77): Win32 exe file contains unused code
* [8.1.1104](https://github.com/vim/vim/commit/796cc42d3a4fc7a940da87831a111eeb6b7a5cf3): MS-Windows: not all environment variables can be used
* [8.1.1185](https://github.com/vim/vim/commit/86ec6d7e1e037e839879a5c05c2ee77db27fb557): mapping for CTRL-X is inconsistent

「[VimのDLL化 for Windows](https://github.com/vim-jp/issues/issues/306)」で議論された機能を実現したものです。Unix版Vimは、vimとgvimは全く同一のバイナリとなっており、実行ファイルの名前を変えるだけで、CUI版かGUI版かの動作を変更できるようになっています。一方、Windows版Vimは、ソースコードの大半は同一ではあるもののそれでも多数の `#ifdef` でコードは分かれており、実行ファイルは完全に別になっていました。これを、共通部分をDLLにまとめることで、合計ファイルサイズを減らそうというものです。(Perl, Python, Rubyなどでも同じようなことが行われているようです。)

かつては、Borland版に(別の)VIMDLL機能というものが含まれており、スタブのgvim.exeと本体のvim32.dllをビルドできるようになっていました。(Vim 5.0でBorland対応とともに導入された模様。) ただ、CUIとGUIを統一したDLLをビルドするものではなく、VIMDLL機能に特段のメリットはありませんでした。しかも現在ではVIMDLL機能はビルドできなくなってしまっていたため、[8.1.1066](https://github.com/vim/vim/commit/89828e9fe6de4d70e0e2ccd3c711bd26632c26a9)で一旦廃止されました。

今回は、関連する数百箇所の `#ifdef` をすべて見直して、CUIとGUIのコードを(スタートアップ部分以外は)完全に統一した上で、Borland版のコードを一部再利用することで、DLL化を再実現しました。また、かつてのVIMDLL機能とは異なり、Visual C++とMinGWの両方に対応しています。こうして以下のメリットが生まれました。

* gvim.exe と vim.exe の合計ファイルサイズの削減  
  DLLを含めても元の約半分。
* gvim.exe と vim.exe 同時使用時の合計メモリサイズ削減  
  同一のDLLを利用するため、メモリが共有されるので。
* [`vim -g` 機能](https://github.com/vim-jp/issues/issues/602)の実現  
  `-g` オプションを指定して vim.exe を起動すると、自動的に gvim.exe に制御を移してGUIを起動する。
* 合計ビルド時間の半減  
  gvim.exe と vim.exe の両方をビルドする必要がないため。

なお、VIMDLL機能はデフォルトでは無効化されています。ビルド時に `VIMDLL=yes` を指定することで有効化できます。


# Borland C++対応の削除

* [8.1.1306](https://github.com/vim/vim/commit/eae1b91fea74842000fc055afc74fe2e7934c6ee): Borland support is outdated and doesn't work

元々は、[別の人が立てたPR](https://github.com/vim/vim/pull/3377)だったのですが、放置されてしまっていたため、私が掘り起こしてマージしてもらいました。

現在のWindows版Vimは、Visual C++とMinGWでビルドできるようになっていますが、かつてはBorland C++ 5.5でもできるようになっていました。しかし、Borlandを使う人がいなくなってしまい、いつの間にかビルドできなくなってしまっていました。Borland C++の後継としては、Embarcadero C++も公開されていますが、これに対応させようという人もいませんでした。そのため、Borland向けのコードをすべて削除することになりました。これにより余計な `#ifdef` が削減され、コードがきれいになりました。