事ここに至りWindowsのCLI上にコーディング環境を構築せんと大号令をかけたのである。
Windows Terminalが組み込まれ、Unix環境のX Window Systemで端末エミュレータを使うのと似たような作業環境を構築できるようになった。そうなると、自然に「ちょっとしたコーディングもCLI環境上でできるようにしたいなあ」という要求が生じるものである。
まあしかし、MS-DOSからWindowsへの移行を経て、Windows向けのテキストエディタは軒並みGUIアプリになってしまった。特に、日本語環境という世界的に見ても特異な文字エンコーディング多発地帯において、己の半身となりうるCLIのエディタはごくわずかだろう。
Vimを選んだのにはいくつか理由がある:
- 日本語Windows環境での文字エンコーディングの扱いの点で実績がある。
- 元々Vim 香り屋版を使っていた。
- LinuxやmacOSで使用していた「自分好みの設定」があり、流用可能だった。
(1) だけならEmacsという選択肢もあった。
ここ数年はVisual Studio Codeを使っているが、それよりも前にはVimを多用していた時期もあった。香り屋版とはVim 6時代からの付き合いである。
問題は「Vim 6時代からの付き合い」という点だ。Vimにプラグイン機能が組み込まれる遥か前に色々と弄った環境という「秘伝のたれ」に、新たにビルドされた香り屋版のバイナリという「新しいたれ」を継ぎ足してきたため、色々と限界だった。
ということで、公式バイナリで新規に環境構築することにした。ベースとなる_vimrcはLinuxやmacOSで使っていた最小構成の.vimrcを流用した。
ついでにLSPにも対応させた(LinuxやmacOSでは使っていない)。プラグインの組み込みはこんな感じ:
" XXX ホームディレクトリではなくvim.exeと同じディレクトリ上のvimfilesに色々置く。 call plug#begin($VIM . '/vimfiles/plugged') Plug 'prabirshrestha/vim-lsp' Plug 'mattn/vim-lsp-settings' Plug 'vim-denops/denops.vim' Plug 'Shougo/ddc.vim' Plug 'Shougo/ddc-around' Plug 'LumaKernel/ddc-file' Plug 'shun/ddc-vim-lsp' Plug 'Shougo/ddc-converter_remove_overlap' Plug 'Shougo/ddc-matcher_head' Plug 'Shougo/ddc-sorter_rank' Plug 'Shougo/pum.vim' Plug 'Shougo/ddc-ui-pum' call plug#end()
LSPについてはC/C++のみ設定している。
let g:lsp_settings_servers_dir = $VIM . '/vimfiles/etc/lsp' let g:lsp_settings = { \ 'clangd': { \ 'cmd': [ \ g:lsp_settings_servers_dir . '/clangd/clangd', \ '--clang-tidy', \ '--enable-config' \ ], \ } \ }
補完とポップアップ表示まわりはddc.vimとpum.vimの組み合わせを採用した。
call ddc#custom#patch_global('sources', [ \ 'around', \ 'file', \ 'vim-lsp' \ ]) call ddc#custom#patch_global('sourceOptions', { \ 'around': {'mark': 'around'}, \ 'file': { \ 'mark': 'file', \ 'isVolatile': v:true, \ 'forceCompletionPattern': '\S/\S*' \ }, \ 'vim-lsp': { \ 'mark': 'LSP', \ 'matchers': ['matcher_head'], \ 'forceCompletionPattern': '\.|:|->|"\w+/*' \ }, \ '_': { \ 'converters': ['converter_remove_overlap'], \ 'matchers': ['matcher_head'], \ 'sorters': ['sorter_rank'] \ }, \ }) call ddc#custom#patch_global(#{ \ ui: 'pum', \ autoCompleteEvents: ['InsertEnter', 'TextChangedI', 'TextChangedP'], \ }) call ddc#custom#patch_filetype(['ps1', 'dosbatch', 'autohotkey', 'registry'], { \ 'sourceOptions': { \ 'file': {'forceCompletionPattern': '\S\\\S*'}, \ }, \ 'sourceParams': { \ 'file': {'mode': 'win32'}, \ } \ }) call ddc#enable()
補完候補については、矢印キーやCtrl-n/Ctrl-pで操作した場合にはポップアップ上の候補の選択だけ変更するようにした。以下のような感じの設定で、よくあるGUIテキストエディタで補完候補を選択・決定・取り消しする操作と似た感じになる。
inoremap <expr> <CR> pum#visible() ? "<Cmd>call pum#map#confirm()<CR>" : "<CR>" inoremap <expr> <ESC> pum#visible() ? "<Cmd>call pum#map#cancel()<CR>" : "<ESC>" inoremap <expr> <Tab> pum#visible() ? "<Cmd>call pum#map#insert_relative(+1)<CR>" : "<Tab>" inoremap <expr> <S-Tab> pum#visible() ? "<Cmd>call pum#map#insert_relative(-1)<CR>" : "<S-Tab>" inoremap <expr> <Down> pum#visible() ? "<Cmd>call pum#map#select_relative(+1)<CR>" : "<Down>" inoremap <expr> <Up> pum#visible() ? "<Cmd>call pum#map#select_relative(-1)<CR>" : "<Up>" inoremap <expr> <C-n> pum#visible() ? "<Cmd>call pum#map#select_relative(+1)<CR>" : "<C-n>" inoremap <expr> <C-p> pum#visible() ? "<Cmd>call pum#map#select_relative(-1)<CR>" : "<C-p>" inoremap <expr> <PageDown> pum#visible() ? "<Cmd>call pum#map#select_relative_page(+1)<CR>" : "<PageDown>" inoremap <expr> <PageUp> pum#visible() ? "<Cmd>call pum#map#select_relative_page(-1)<CR>" : "<PageUp>"
さて、上記の設定にて、Vim 9.2.0ではいい感じに利用できているのだが、Vim 9.2.0125との組み合わせだと少々問題があるようだ(おま環案件かもしれないが)。
pum#map#select_relative()で選択候補を変更した時、内部での候補の変更は正常に動作しているようなのだが、見た目として「どこ候補を選択しているか?」が分からなくなってしまった。
Vim 9.2.0の時点では、選択候補の表示中の「マッチしていない文字列」の部分の色が変化することで、ぱっと見でどの候補を選択しているかを識別できた。Vim 9.2.0125では、この「色の変化」が無くなってしまったため、どの候補を選択しているか分からないのだ。ただし、内部での「どの候補を選択しているか?」という情報は正しく切り替わっている。
この現象について報告したいのだが、如何せんddc.vimとpum.vimの部分はあれもこれもプラグインだらけであるし、組み合わせに関する設定をあれこれ.vimrcに書く代物なので、ある程度問題の切り分けを行わないと報告先すら覚束ない。ということで放置している。
追伸
Microsoft Editにシンタックスハイライト機能が組み込まれていたなら、それをそのまま使い続けただろう。でも残念ながら組み込まれていない。
GUIになるが、最近色々と進化しているメモ帳も、シンタックスハイライトには未対応だ。
今日日テキストファイルを使う理由の大半はMarkdownなりプログラミング言語なりで「構造化された文字列」を記述することなのだから、シンタックスハイライトの需要は多い気がするのだけどなあ。
